#!/bin/sh
# mk_modmap
# Tries to translate a keytable file into a file parseable by xmodmap
#
# This is a hack, and has a lot of magic numbers and names hardcoded
# into it. Suggestions on how to avoid this are welcome.
#
# Kjetil T. Homme, University of Oslo 1993
# <kjetilho@ifi.uio.no>


case $1 in
	-v*)	verbose=1; shift ;;
esac

cat <<__EOH__
! Converted keytable file to xmodmap file
! with `basename $0` by `whoami`@`hostname` `date`
keysym Alt_R = Alt_R Mode_switch
clear Mod1
clear Mod2
add Mod1 = Alt_L
add Mod2 = Mode_switch
__EOH__

awk -F'#' '
	/[a-z]+.*keycode/ { next }
	/^[ \t]*$/ { next }
	/^string/ { next }
	{ sub("^[ \t]*", "") }
	NF > 1 {
		printf("!");
		for (i = 2; i <= NF; i++) {
			printf(" " $i);
			$i = "";
		}
		print "";
		if ($1 == "")
			next;
	}
	{ print }
' "$@" | awk -v verbose=$verbose '
	BEGIN {
		while (getline < "/usr/include/X11/keysymdef.h" == 1) {
			if ($0 ~ /XK_/) {
				sub(/.*XK_/, "");
				sub(/[\t ].*/, "");
				valid[$0] = 1;
			}
		}
		valid["X386Sys_Req"] = 1;

		shifts["Control"] = shifts["Shift"] = shifts["Alt"] = 1;
		shift_keys[29] = "Control_L";
		shift_keys[97] = "Control_R";
		shift_keys[42] = "Shift_L";
		shift_keys[54] = "Shift_R";
		shift_keys[56] = "Alt_L";

		trans_keys[ 96] = 108; # KP_Enter
		trans_keys[ 97] = 109; # Control_R
		trans_keys[ 98] = 112; # KP_Divide
		trans_keys[101] = 114; # Break
		trans_keys[103] =  98; # Up
		trans_keys[104] =  99; # Prior
		trans_keys[105] = 100; # Left
		trans_keys[106] = 102; # Right
		trans_keys[108] = 104; # Down
		trans_keys[109] = 105; # Next
		trans_keys[110] = 106; # Insert
		trans_keys[111] = 107; # Delete

		trans_names["one"] = "1";
		trans_names["two"] = "2";
		trans_names["three"] = "3";
		trans_names["four"] = "4";
		trans_names["five"] = "5";
		trans_names["six"] = "6";
		trans_names["seven"] = "7";
		trans_names["eight"] = "8";
		trans_names["nine"] = "9";
		trans_names["zero"] = "0";
		trans_names["dead_tilde"] = "asciitilde";
		trans_names["dead_circumflex"] = "asciicircum";
		trans_names["dead_acute"] = "acute";
		trans_names["dead_grave"] = "grave";
		trans_names["dead_diaeresis"] = "diaeresis";
		trans_names["KP_Comma"] = "KP_Decimal";
		trans_names["Last_Console"] = "X386Sys_Req";
	}
	$1 == "keycode" {
		output = "";
		keycode = $2;
		i = ($3 == "=") ? 4 : 3;
		for ( ; i <= NF; i++) {
			if ($i in shifts)
				$i = shift_keys[keycode];
			else if ($i in trans_names)
				$i = trans_names[$i];

			if (valid[$i]) output = output " " $i;
			else msg("Skipped " $i);
		}

		if (keycode in trans_keys)
			keycode = trans_keys[keycode];
		else
			keycode += 8;

		if (keycode >= 115)
			msg("Skipped keycode " keycode-8 ": " output);
	 	else if (output)
			printf("keycode %3d =%s\n", keycode, output);
		next;
	}
	{ print }
	function msg(m) { if (verbose) print m > "/dev/stderr"; }'
