#! /bin/sh
# Copyright (c) 1995-2001 SuSE GmbH Nuernberg, Germany.
#
# Author:   Burchard Steinbild <bs@suse.de>
#           Werner Fink <werner@suse.de>
#
# /etc/init.d/kbd
#
#   and symbolic its link
#
# /sbin/rckbd
#
### BEGIN INIT INFO
# Provides:       kbd
# Required-Start: $remote_fs
# Required-Stop:
# X-SuSE-Should-Start:	fbset setserial
# X-SuSE-Should-Stop: 
# Default-Start:  1 2 3 5 S
# Default-Stop:
# Description:    Keyboard settings (don't disable!)
### END INIT INFO

. /etc/rc.status
. /etc/sysconfig/console
. /etc/sysconfig/keyboard

test -e /etc/SuSEconfig/profile && . /etc/SuSEconfig/profile
LOCALE_CHARMAP=`locale charmap`
LC_ALL=POSIX

MACHINE=`/bin/uname -m 2> /dev/null`
if [ "$MACHINE" = "sparc" -o "$MACHINE" = "sparc64" ]; then 
   # Test if we have a serial console. 
   (test -c /dev/tty1 && > /dev/tty1 ) > /dev/null 2>&1 || exit 0
fi

# The variable NON_SUSE_KERNEL determines whether we need to chvt 
# to a console before some console settings apply.
# We have no magic to find out about this (at boot time), so we 
# leave it to the user to read this comment and put NON_SUSE_KERNEL="yes"
# into /etc/sysconfig/console

KBDBASE="/usr/share/kbd"

KTABLE=${KEYTABLE%.map*}
KTABLE=${KTABLE##*/}
TTY=`/usr/bin/tty`

#
# first search the wanted keytable.
#
if [ $MACHINE = ppc -o $MACHINE = ppc64 ]; then
	test -f /proc/cpuinfo || mount -n -t proc proc /proc 2>/dev/null
	while read line; do
	       case "$line" in
		  *MacRISC*)	MACHINE="mac";;
		  *CHRP*)  	MACHINE="chrp";;
		  *PReP*)  	MACHINE="prep" ;;
		  *iSeries*)    exit 0 ;;
		esac
	done < /proc/cpuinfo
fi

case "$MACHINE" in
  i?86|ia64|alpha|prep|chrp|ppc64|x86_64) KDBLIB="${KBDBASE}/keymaps/i386/*/"     ;;
  sparc*)    
     case "$KTABLE" in
        sun*) KDBLIB="${KBDBASE}/keymaps/sun/"        ;;
        *)    KDBLIB="${KBDBASE}/keymaps/i386/*/"     ;;
     esac
     ;;
  mac)       KDBLIB="${KBDBASE}/keymaps/mac/all/" ;;
  *)         echo "No available keymaps for machine $MACHINE found"; exit 1
     ;;
esac
#
# load usb drivers in runlevel S
#
case "${PREVLEVEL}${RUNLEVEL}" in
	N1|NS)
	test -f /etc/sysconfig/hotplug &&  . /etc/sysconfig/hotplug && test "$HOTPLUG_START_USB" = "yes" && {
	test -f /proc/cpuinfo || mount -n -t proc proc /proc 2>/dev/null
	test -d /proc/bus/usb || modprobe usbcore >/dev/null 2>&1
	mount usbdevfs >/dev/null 2>&1
	for i in $HOTPLUG_USB_HOSTCONTROLLER_LIST ;do echo -n $i" " ;modprobe $i >/dev/null 2>&1 ;done;echo
	sleep 3
	grep ^I: /proc/bus/usb/devices | grep HID && for i in input hid keybdev;do modprobe $i >/dev/null 2>&1 ;done
	}
	;;
esac

KEYMAP=""
if test -e /$KEYTABLE ; then
    KEYMAP=$KEYTABLE
else
    KEYTABLE=$KTABLE
    K="${KDBLIB}${KEYTABLE}"
    case "$KEYTABLE" in
	*.gz)  KDBPATH="${K}" ;;
	*.map) KDBPATH="${K} ${K}.gz" ;;
	*)     KDBPATH="${K} ${K}.gz ${K}.map.gz ${K}.map" ;;
    esac
    for K in ${KDBPATH} ; do	
	test -e "$K" || continue
	test -n "$KEYMAP" && KEYMAP="$KEYMAP $K" || KEYMAP=$K
    done
fi
#
# setup kbdrate and led status
#
function set_kbdrate () {
	if test -n "$KBD_RATE" -a -n "$KBD_DELAY" -a ! "$MACHINE" = "mac" ; then
		#echo -n "Setting keyboard repeat rate $KBD_RATE and delay time $KBD_DELAY"
		echo -n "Keyboard: "
		/bin/kbdrate -r $KBD_RATE -d $KBD_DELAY
		rc_status -v1
	fi
	# setleds
	if test "$KBD_NUMLOCK" = "yes"; then
		LEDOPT="+num"
		touch /var/run/numlock-on
	elif test "$KBD_NUMLOCK" = "no"; then
		LEDOPT="-num"
		rm -f /var/run/numlock-on
	elif test "$KBD_NUMLOCK" = "bios"; then
		/usr/sbin/hwinfo --bios|grep -q 'Num Lock: on'
                if test $? -eq 0; then
                	LEDOPT="+num"
			touch /var/run/numlock-on
		else
			rm -f /var/run/numlock-on
		fi
	fi 
        if test "$KBD_CAPSLOCK" = "yes"; then
                LEDOPT="$LEDOPT +caps"
        else
                LEDOPT="$LEDOPT -caps"
        fi  
        if test "$KBD_SCRLOCK" = "yes"; then
                LEDOPT="$LEDOPT +scroll"
        else
                LEDOPT="$LEDOPT -scroll"
        fi  
        if test -n "$LEDOPT" && type -p setleds &> /dev/null ; then
                cd /dev || exit 1
                if test -z "$KBD_TTY"; then
                        KBD_TTY="tty[1-9]*"
                fi
                for tty in $KBD_TTY; do
                        ( test -c $tty && > $tty ) &> /dev/null && setleds -D $LEDOPT < $tty
                done
        fi
}
#
rc_reset
case "$1" in
    start|restart|reload)
	if test -z "$KEYTABLE"; then
	    echo "No keyboard map to load"
	else
	    if test -z "$KEYMAP" ; then
		if test -r /etc/defkeymap.map ; then
		    echo "Can not find a keymap for ${KEYTABLE}, trying fallback."
		    KEYMAP=/etc/defkeymap.map
		else
		    echo "Can not find a keymap for ${KEYTABLE}, Exit."
		    rc_failed
		fi
	    else
		if test ! -e "$KEYMAP" ; then
		    echo "Found more than one keymap ${KEYTABLE}"
		    KEYMAP=$K
		    echo "Using $KEYMAP."
		    echo "If you want another one, please add complete path to"
		    echo "KEYTABLE in /etc/sysconfig/keyboard."
		fi
	    fi
	    rc_status && retmsg="`loadkeys $KEYMAP 2>&1`"
	    if test $? -eq 0 && ( > /var/run/keymap ) > /dev/null 2>&1 ; then
		echo "$KEYMAP"    > /var/run/keymap
	    else
		case "$RUNLEVEL" in
		    S|N|1|\#) true ;;
		    *) rc_failed ;;
		esac
	    fi
	    echo "Loading keymap ${retmsg#Loading*${KBDBASE}/keymaps/*/}"
	    rc_status -v1
	    set_kbdrate
	fi
	
	# Disable CAPS LOCK key if wanted
	if test "$KBD_DISABLE_CAPS_LOCK" = "yes"; then
		loadkeys disable.capslock >/dev/null 2>&1 || echo "Could not disable Caps Lock"
	fi

	# Load compose tables
	case "$RUNLEVEL" in
	    S|N|1|\#) COMPOSETABLE="" ;;
	esac
	if test ! -z "$COMPOSETABLE"; then
		unset COMPOSELOADED COMPOSECLEAR
		for name in $COMPOSETABLE; do
			# Test for compose clear flag
			if test "$name" = "-c" -o "$name" = "clear"; then
				COMPOSECLEAR=-c
				continue
			fi
			# Handle the first table differently ...
			if test -z "$COMPOSELOADED"; then
				echo -n "Loading compose table $name"
				loadkeys $COMPOSECLEAR compose.$name >/dev/null 2>&1
				rc_check
				#if test $name = clear; then rc_reset; fi
				COMPOSELOADED=1
			else
				echo -n " $name"
				loadkeys compose.$name >/dev/null 2>&1
				rc_check
			fi
		done
		if test ! -z "$COMPOSELOADED"; then 
			rc_status -v
		fi
	fi
	
	if test -z "$KBD_TTY"; then
		KBD_TTY="tty1 tty2 tty3 tty4 tty5 tty6 tty7 tty8 tty9 tty10 tty11 tty12 tty13 tty14 tty15 tty16 tty17 tty18 tty19 tty20 tty21 tty22 tty23 tty24"
	fi

	# Unicode mode	
	if test -x /bin/kbd_mode ; then
	    case $LOCALE_CHARMAP in
		UTF-8)
 		    echo Start Unicode mode
	            for i in $KBD_TTY; do
	    	            if test -w /dev/$i; then
	    		            # The chvt is not needed for SuSE kernels
	    		            test "X$NON_SUSE_KERNEL" = "Xyes" && chvt ${i#tty}
				    # Tell the console output driver that the bytes
				    # arriving are UTF-8 encoded multibyte sequences.
				    echo -n -e '\033%G' > /dev/$i
                                    rc_status
                            fi
          	    done				    
		    # Set the keyboard driver in Unicode mode.
		    # (Default is ASCII mode.)
		    # This really does nothing with the way normal
		    # keys are handled in the kernel. All it does is:
		    # - It is necessary for `dumpkeys' in order to
		    #   not drop U+XXXX entries from the keymaps.
		    # - It is necessary for `loadkeys' in order to
		    #   avoid warnings.
		    # - Unicode characters typed as Alt-x1 ... Alt-xn
		    #   (where x1,...,xn are digits on the numeric keypad)
		    #    will be emitted in UTF-8.
		    case $TTY in
				/dev/console|/dev/tty[0-9]*)
		    			kbd_mode -u 
					rc_status
		    			;;
		    		*)
					echo "kbd_mode not called for $TTY"
					;;
		    esac		
	            ;;
	        *)
		    echo Stop Unicode mode
		    for i in $KBD_TTY; do
			if test -w /dev/$i; then
				    # The chvt is not needed for SuSE kernels
				    test "X$NON_SUSE_KERNEL" = "Xyes" && chvt ${i#tty}
				    echo -n -e '\033%@' > /dev/$i
				    rc_status
			    fi
		    done
		    case $TTY in
				/dev/console|/dev/tty[0-9]*)
		    			kbd_mode -a 
					rc_status
		    			;;
		    		*)
					echo "kbd_mode not called for $TTY"
					;;
		    esac		
	            ;;
	    esac
	    if test "X$NON_SUSE_KERNEL" = "Xyes" ; then
	    	chvt $FGCONS
	    fi
	    rc_status -v1
	fi
	
	# setfont
	if test -d ${KBDBASE}/consolefonts -a \
		-n "$CONSOLE_FONT" -a "$CONSOLE_FONT" != "YAST_ASK"
	then
	    if test ! -z "$CONSOLE_UNICODEMAP"; then 
		    UMAP="-u $CONSOLE_UNICODEMAP"
	    fi
	    if test ! -z "$CONSOLE_SCREENMAP"; then 
		    SMAP="-m $CONSOLE_SCREENMAP"
	    fi
	    if test -x /bin/setfont ; then
		echo "Loading console font $CONSOLE_FONT $UMAP $SMAP $CONSOLE_MAGIC"
		FGCONS=`/bin/fgconsole`
		for i in $KBD_TTY; do
			if test -w /dev/$i; then
				# The chvt is not needed for SuSE kernels
				test "X$NON_SUSE_KERNEL" = "Xyes" && chvt ${i#tty}
				/bin/setfont -c /dev/$i $CONSOLE_FONT $UMAP $SMAP
				rc_status
				if test -n "$CONSOLE_MAGIC" -a "$CONSOLE_MAGIC" != "none"; then
				    echo -en "\033$CONSOLE_MAGIC" > /dev/$i
			            rc_status
				fi
			fi
		done
		if test "X$NON_SUSE_KERNEL" = "Xyes" ; then
			chvt $FGCONS
		fi
		rc_status -v1
	    fi
	fi

	case "$RUNLEVEL" in
	    S|N|1|\#) true ;;
	    *)
	        case $LOCALE_CHARMAP in
		    UTF-8)
		        # Change the keyboard mapping in such a way that the
		        # non-ASCII keys produce UTF-8 encoded multibyte sequences
			# instead of single bytes >= 0x80 in a legacy 8-bit encoding.
		        ( dumpkeys | loadkeys --unicode ) > /dev/null 2>&1
		        ;;
		    *) 
		        ;;
		esac
		dumpkeys=yes
		if type -p cmp > /dev/null 2>&1 && \
		   dumpkeys | cmp -s /etc/defkeymap.map
		then
		   dumpkeys=no
		fi
		if test "$dumpkeys" = "yes" ; then
		    ( dumpkeys > /etc/defkeymap.map ) > /dev/null 2>&1
		fi
	esac

	;;
    stop)
	;;
    check|status)
	if test -r /var/run/keymap ; then
	    read current < /var/run/keymap
	    echo "Keymap $current is loaded."
	else
	    rc_failed 3
	fi
	;;
    *)
	echo "Usage: $0 {start|stop|restart|reload|status|check}"
	exit 2
	;;
esac
rc_exit
