--- src/system/ui/x11/sysx11.cc	17 Oct 2004 09:53:57 -0000	1.17
+++ src/system/ui/x11/sysx11.cc	24 Dec 2004 19:36:23 -0000
@@ -4,6 +4,7 @@
  *
  *	Copyright (C) 1999-2002 Stefan Weyergraf
  *	Copyright (C) 1999-2004 Sebastian Biallas (sb@biallas.net)
+ *      Portions Copyright (C) 2004 Apple Computer, Inc.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License version 2 as
@@ -42,24 +43,46 @@
 Display *	gX11Display = NULL;
 Window		gX11Window;
 
-static uint8 x11_key_to_adb_key[256] = {
-	// 0    1    2    3    4    5    6    7    8    9   10   11   12   13   14   15
-	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x35,0x12,0x13,0x14,0x15,0x17,0x16,
-	0x1a,0x1c,0x19,0x1d,0x1b,0x18,0x33,0x30,0x0c,0x0d,0x0e,0x0f,0x11,0x10,0x20,0x22,
-	0x1f,0x23,0x21,0x1e,0x24,0x36,0x00,0x01,0x02,0x03,0x05,0x04,0x26,0x28,0x25,0x29,
-	0x27,0x32,0x38,0x2a,0x06,0x07,0x08,0x09,0x0b,0x2d,0x2e,0x2b,0x2f,0x2c,0x38,0x43,
-	0x37,0x31,0xff,0x7a,0x78,0x63,0x76,0x60,0x61,0x62,0x64,0x65,0x6d,0x47,0xff,0x59,
-	0x5b,0x5c,0x4e,0x56,0x57,0x58,0x45,0x53,0x54,0x55,0x52,0x41,0xff,0xff,0x0a,0x67,
-	0x6f,0x73,0x3e,0x74,0x3b,0xff,0x3c,0x77,0x3d,0x79,0x72,0x75,0x4c,0x36,0xff,0xff,
-	0x4b,0x3a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+static uint8 x11_latin1_keysym_to_adb_key[256] = {
+	// Latin 1   Upper Byte = 0x00
+	// 0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+	0x31,0xff,0xff,0xff,0xff,0xff,0xff,0x27,0xff,0xff,0xff,0xff,0x2b,0x1b,0x2f,0x2c,
+	0x1d,0x12,0x13,0x14,0x15,0x17,0x16,0x1a,0x1c,0x19,0xff,0x29,0xff,0x18,0xff,0xff,
 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x21,0x2a,0x1e,0xff,0xff,
+	0x32,0x00,0x0b,0x08,0x02,0x0e,0x03,0x05,0x04,0x22,0x26,0x28,0x25,0x2e,0x2d,0x1f,
+	0x23,0x0c,0x0f,0x01,0x11,0x20,0x09,0x0d,0x07,0x10,0x06,0xff,0xff,0xff,0xff,0xff,
 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+};
+
+static uint8 x11_function_keysym_to_adb_key[256] = {
+	// Upper byte = 0xff
+	// 0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
+	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x33,0x30,0xff,0xff,0xff,0x24,0xff,0xff,
+	0xff,0xff,0xff,0x71,0x6b,0xff,0xff,0xff,0xff,0xff,0xff,0x35,0xff,0xff,0xff,0xff,
+	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+	0x73,0x3b,0x3e,0x3c,0x3d,0x74,0x79,0x77,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+	0xff,0xff,0xff,0x72,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x47,
+	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x4c,0xff,0xff,
+	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x43,0x45,0xff,0x4e,0x41,0x4b,
+	0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5b,0x5c,0xff,0xff,0xff,0xff,0x7a,0x78,
+	0x63,0x76,0x60,0x61,0x62,0x64,0x65,0x6d,0x67,0x6f,0x69,0xff,0xff,0xff,0xff,0xff,
+	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+	0xff,0x38,0x38,0x36,0x36,0x39,0xff,0xff,0xff,0x37,0x37,0xff,0xff,0xff,0xff,0xff,
+	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
 };
 
 static void handleX11Event(const XEvent &event)
@@ -76,40 +99,45 @@
 		gDisplay->displayShow();
 		break;
 	case KeyRelease: {
-		char buffer[4];
 		SystemEvent ev;
-		XComposeStatus compose;
 		KeySym keysym;
 
-		ev.key.keycode = x11_key_to_adb_key[event.xkey.keycode];
+		sys_lock_mutex(gX11Mutex);
+		keysym = XLookupKeysym((XKeyEvent*)&event, 0);
+		sys_unlock_mutex(gX11Mutex);
+		if ((keysym & 0xff00) == 0xff00) {
+			ev.key.keycode = x11_function_keysym_to_adb_key[keysym & 0x00ff];
+		} else if ((keysym & 0xff00) == 0x0000) {
+			ev.key.keycode = x11_latin1_keysym_to_adb_key[keysym & 0x00ff];
+		} else {
+			ev.key.keycode = 0xff;
+		}
+
 		if ((ev.key.keycode & 0xff) == 0xff) break;
 		ev.type = sysevKey;
 		ev.key.pressed = false;
 
-		sys_lock_mutex(gX11Mutex);
-		XLookupString((XKeyEvent*)&event, buffer, sizeof buffer, &keysym, &compose);
-		sys_unlock_mutex(gX11Mutex);
-		ev.key.chr = buffer[0];
-
 		gKeyboard->handleEvent(ev);
 		break;
 	}
 	case KeyPress: {
-		char buffer[4];
-		XComposeStatus compose;
 		KeySym keysym;
-
 		SystemEvent ev;
-		ev.key.keycode = x11_key_to_adb_key[event.xkey.keycode];
-		if ((ev.key.keycode & 0xff) == 0xff) break;
-		ev.type = sysevKey;
-		ev.key.pressed = true;
-		ev.key.keycode = x11_key_to_adb_key[event.xkey.keycode];
 
 		sys_lock_mutex(gX11Mutex);
-		XLookupString((XKeyEvent*)&event, buffer, sizeof buffer, &keysym, &compose);
+		keysym = XLookupKeysym((XKeyEvent*)&event, 0);
 		sys_unlock_mutex(gX11Mutex);
-		ev.key.chr = buffer[0];
+		if ((keysym & 0xff00) == 0xff00) {
+			ev.key.keycode = x11_function_keysym_to_adb_key[keysym & 0x00ff];
+		} else if ((keysym & 0xff00) == 0x0000) {
+			ev.key.keycode = x11_latin1_keysym_to_adb_key[keysym & 0x00ff];
+		} else {
+			ev.key.keycode = 0xff;
+		}
+
+		if ((ev.key.keycode & 0xff) == 0xff) break;
+		ev.type = sysevKey;
+		ev.key.pressed = true;
 
 		gKeyboard->handleEvent(ev);
 		break;
