#!/bin/bash

# This script configures rc.keymap and hal fdi keyboard policy with preferred keyboard map. 

# This program is free software; you can redistribute it and/or modify it 
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your option)
# any later version. Please take a look at http://www.gnu.org/copyleft/gpl.htm

# Original code from keyboardconfig, Jean-Philippe Guillemin <jp.guillemin~at~free~dot~fr>
# Modified by:	Pierrick Le Brun <akuna~at~free~dot~fr>
# Modified by:  George Vlahavas <vlahavas~at~gmail~dot~com>

# Translations only work with utf8 locales
if [ ! `echo $LANG | grep -i utf` ]; then
	LANG=C
fi

# Gettext internationalization
export TEXTDOMAIN="keyboardsetup"
export TEXTDOMAINDIR="/usr/share/locale"
. gettext.sh

# Path to icon
iconpath="/usr/share/salixtools/pixmaps"

# Path to the keymaps list file
keymapsdir="/usr/share/salixtools/"

# Just to be sure
unset keymap numstate xkblayout xkbvariant xkboptions

backtohome=$(pwd)

usage(){
	echo "`eval_gettext 'USAGE: keyboardsetup [keymap] [numlock state (on or off)]'`"
	echo "`eval_gettext '(If you want to specify a numlock state, you also have to specify a keymap)'`"
	echo "`eval_gettext 'EXAMPLE: keyboardsetup uk on'`"
	exit 1
}

if [ $# -gt 2 ]; then
	echo "`eval_gettext 'ERROR: Too many arguments'`"
	usage
fi

if [ ! -z $1 ]; then
	key=$1
	if [ `grep "^$key|" $keymapsdir/keymaps` ]; then
		keymap="$key.map"
		if [ ! -z $2 ]; then
			numstate=$2
			if [ $numstate = "on" ] || [ $numstate = "off" ]; then
				sleep 0 # do nothing
			else
				echo "`eval_gettext 'ERROR: $numstate is not a valid option.'`"
				usage
			fi
		else
			if [ -x /etc/rc.d/rc.numlock ]; then
				numstate="on"
			else
				numstate="off"
			fi
		fi
	else
		echo "`eval_gettext 'ERROR: $key is not a valid keymap. You can look in $keymapsdir/keymaps for a list of valid keymaps'`"
		usage
	fi
else

# Start of interactive section

	# Take a look at "Xdialog" and use it instead of "dialog" in case X is running
	if [[ "$DISPLAY" && "$(which Xdialog 2>&1 | grep -v "which: no")" ]]; then
		dialog="Xdialog --wrap --left --screen-center"
		xflag='yes'
	else
		dialog="dialog"
		xflag='no'
	fi

	# create the buffer directory
	buffer="$(mktemp -d -p /tmp temp.XXXXXXXX)"

	# remove the buffer directory on any type of exit
	trap 'rm -rf $buffer 2>/dev/null' TERM INT EXIT
	
	# Set the locale in en_US, to avoid problems with Xlib
	export LANG=${LANG:-en_US}

	# Path needs to be extended in case you're only half a root :)
	export PATH="/usr/sbin:/sbin:${PATH}"

	keymapdir='/usr/share/kbd/keymaps/i386'
	cd $keymapdir

	# Probing the current keymap

	if [ ! -e /etc/rc.d/rc.keymap ] ; then 
	cat << "EORC" > /etc/rc.d/rc.keymap
#!/bin/sh
# Load the keyboard map.  More maps are in /usr/share/kbd/keymaps.
if [ -x /usr/bin/loadkeys ]; then
 /usr/bin/loadkeys -u us.map
fi
EORC
	fi

	currentkeymap=$(grep "^[[:space:]]*\/usr\/bin\/loadkeys.*" /etc/rc.d/rc.keymap \
		| sed -e 's/^.*loadkeys -u *\(.*\)$/\1/')

	if [ "$currentkeymap" ] ; then
		[ ! "$(echo $currentkeymap | grep 'map')" ] && currentkeymap="${currentkeymap}.map"

		# We get the corresponding current path/key.map
		currentpathkeymap="$(ls */* \
		| egrep "azerty|qwerty|dvorak|qwertz" \
		| grep "\/$currentkeymap" \
		| sed -e 's/^\(.*\).gz$/\1/')"

	fi

	[ ! "$currentpathkeymap" ] && currentpathkeymap="qwerty/us.map"

	list="$(ls */* \
		| egrep "azerty|qwerty|dvorak|qwertz" \
		| egrep 'map.gz' \
		| sed -e 's/^\(.*\).gz$/\"\1\" \" \" \\/')"

	if [ -x /etc/rc.d/rc.numlock ]; then
		numprecheck="on"
	else
		numprecheck="off"
	fi

	if [ "$xflag" = "yes" ] ; then
	answer="$(eval $dialog \
	--stdout \
	--title \"`eval_gettext 'Keyboard configuration'`\" \
	--default-item \"$currentpathkeymap\" \
	--ok-label \"`eval_gettext 'OK'`\" \
	--cancel-label \"`eval_gettext 'Exit'`\" \
	--icon \"$iconpath\" \
	--check \"numlock\" \"$numprecheck\" \
	--menu \
	\"\\n`eval_gettext 'Please select your preferred keyboard map:'`\" 0 0 11 "$list" )"
	else
	answer="$(eval $dialog \
	--stdout \
	--title \"`eval_gettext 'Keyboard configuration'`\" \
	--default-item \"$currentpathkeymap\" \
	--ok-label \"`eval_gettext 'OK'`\" \
	--cancel-label \"`eval_gettext 'Exit'`\" \
	--icon \"$iconpath\" \
	--menu \
	\"\\n        `eval_gettext 'Please select your preferred keyboard map:'`\" 20 80 11 "$list" )"
	fi

	# Don't do anything if Cancel or the close button was pressed
	retval=$?
	if [ $retval -eq 1 ] || [ $retval -eq 255 ]; then
		exit 0
	fi

	pathkeymap="$(echo "$answer" | head -n1)"

	if [ "$pathkeymap" ] ; then
		keymap="$(basename $pathkeymap)"

		# We need the keymap without ".map"
		key=${keymap%.map}
	fi

	if [ "$xflag" = "yes" ] ; then
	  numlock="$(echo "$answer" | tail -n1)"
	fi
fi

# End of interactive section

if [ "$numstate" = "on" ]; then
	numlock="checked"
elif [ "$numstate" = "off" ]; then
	numlock="unchecked"
fi

if [ "$numlock" = "checked" ] ; then
	[ -e /etc/rc.d/rc.numlock ] && chmod 755 /etc/rc.d/rc.numlock
	[ -x /usr/bin/numlockx ] && /usr/bin/numlockx on
	for t in 1 2 3 4 5 6 7 8 ; do
		setleds +num < /dev/tty$t > /dev/null
	done
else
	[ -e /etc/rc.d/rc.numlock ] && chmod 644 /etc/rc.d/rc.numlock
	[ -x /usr/bin/numlockx ] && /usr/bin/numlockx off
	for t in 1 2 3 4 5 6 7 8 ; do
		setleds -num < /dev/tty$t > /dev/null
	done
fi

# Keymaps path to a system dir where it'll be installed
grep "^$key|.*|.*|.*" $keymapsdir/keymaps \
  | sed -e "s/^.*|\(.*\)|\(.*\)|\(.*\)/\1|\2|\3/" > $buffer/xkb

xkblayout="$(sed -e "s/^\(.*\)|.*|.*/\1/" $buffer/xkb)"
xkbvariant="$(sed -e "s/^.*|\(.*\)|.*/\1/" $buffer/xkb)"
xkboptions="$(sed -e "s/^.*|.*|\(.*\)/\1/" $buffer/xkb)"

rm -f $buffer/xkb
# Fall back to keymap if no xkb maping available
if [ ! "$xkblayout" ]; then
	xkblayout="$key"
	xkbvariant=""
	xkboptions=""
fi

/usr/bin/loadkeys $keymap 1>&2 2>/dev/null
[ "$xflag" = "yes" ] && \
/usr/bin/setxkbmap -layout "$xkblayout" -variant "$xkbvariant" -option "$xkboptions" 1>&2 2>/dev/null
sed -i "s/\(^[ \t]*\/usr\/bin\/loadkeys -u\).*$/\1 $keymap/" /etc/rc.d/rc.keymap

if [ ! -a /etc/hal/fdi/policy/10-keymap.fdi ]; then
	if [ -a /usr/share/hal/fdi/policy/10osvendor/10-keymap.fdi ] ; then
		cp -f /usr/share/hal/fdi/policy/10osvendor/10-keymap.fdi /etc/hal/fdi/policy/10-keymap.fdi
	fi
fi
if [ -a /etc/hal/fdi/policy/10-keymap.fdi ]; then
	sed -i "s/\"input.xkb.layout\" type=\"string\">.*</\"input.xkb.layout\" type=\"string\">"$xkblayout"</" \
	/etc/hal/fdi/policy/10-keymap.fdi
	sed -i "s|\(<merge key=\"input.xkb.variant\" type=\"string\"\).*|\1>"$xkbvariant"</merge>|" \
	/etc/hal/fdi/policy/10-keymap.fdi
	sed -i "s/\"input.xkb.options\" type=\"string\">.*</\"input.xkb.options\" type=\"string\">"$xkboptions"</" \
	/etc/hal/fdi/policy/10-keymap.fdi
	# Re-starting hal daemon
	/etc/rc.d/rc.hald restart
fi

cd $backtohome
