Fix keymap handling for international keyboards.
Signed-off-by: John Haxby <john.haxby@xxxxxxxxxx>
diff --git a/keymaps.c b/keymaps.c
index 1984678..4029500 100644
--- a/keymaps.c
+++ b/keymaps.c
@@ -22,60 +22,62 @@
* THE SOFTWARE.
*/
+static int cmp_keysym(const void *a, const void *b) {
+ return strcmp(((name2keysym_t *) a)->name, ((name2keysym_t *) b)->name);
+}
+
static int get_keysym(const char *name)
{
- name2keysym_t *p;
- for(p = name2keysym; p->name != NULL; p++) {
- if (!strcmp(p->name, name))
- return p->keysym;
+ static int n = -1;
+ int l, r, m;
+
+ if (n < 0) {
+ for (n = 0; name2keysym[n].name; n++);
+ qsort(name2keysym, n, sizeof(name2keysym_t), cmp_keysym);
+ }
+ l = 0;
+ r = n-1;
+ while (l <= r) {
+ m = (l + r) / 2;
+ int cmp = strcmp(name2keysym[m].name, name);
+ if (cmp < 0)
+ l = m + 1;
+ else if (cmp > 0)
+ r = m - 1;
+ else
+ return name2keysym[m].keysym;
+ }
+ if (name[0] == 'U') {
+ /* unicode symbol key */
+ char *ptr;
+ int k = strtol(name+1, &ptr, 16);
+ return *ptr ? 0 : k;
}
return 0;
}
-struct key_range {
- int start;
- int end;
- struct key_range *next;
-};
+#define MAX_SCANCODE 256
+#define KEY_LOCALSTATE 0x1
+#define KEY_KEYPAD 0x2
-#define MAX_NORMAL_KEYCODE 512
-#define MAX_EXTRA_COUNT 256
typedef struct {
- uint16_t keysym2keycode[MAX_NORMAL_KEYCODE];
- struct {
- int keysym;
- uint16_t keycode;
- } keysym2keycode_extra[MAX_EXTRA_COUNT];
- int extra_count;
- struct key_range *keypad_range;
- struct key_range *numlock_range;
- struct key_range *shift_range;
- struct key_range *localstate_range;
-} kbd_layout_t;
+ int keysym;
+ int keycode;
+} keysym2keycode_t;
-static void add_to_key_range(struct key_range **krp, int code) {
- struct key_range *kr;
- for (kr = *krp; kr; kr = kr->next) {
- if (code >= kr->start && code <= kr->end)
- break;
- if (code == kr->start - 1) {
- kr->start--;
- break;
- }
- if (code == kr->end + 1) {
- kr->end++;
- break;
- }
- }
- if (kr == NULL) {
- kr = qemu_mallocz(sizeof(*kr));
- if (kr) {
- kr->start = kr->end = code;
- kr->next = *krp;
- *krp = kr;
- }
- }
-}
+typedef struct {
+ int n;
+ keysym2keycode_t k[MAX_SCANCODE];
+} keysym_map_t;
+
+typedef struct {
+ keysym_map_t plain;
+ keysym_map_t shift;
+ keysym_map_t altgr;
+ keysym_map_t shift_altgr;
+ keysym_map_t numlock;
+ uint32_t flags [MAX_SCANCODE];
+} kbd_layout_t;
static kbd_layout_t *parse_keyboard_layout(const char *language,
kbd_layout_t * k)
@@ -97,143 +99,209 @@ static kbd_layout_t *parse_keyboard_layout(const char
*language,
"Could not read keymap file: '%s'\n", file_name);
return 0;
}
- for(;;) {
- if (fgets(line, 1024, f) == NULL)
- break;
- len = strlen(line);
- if (len > 0 && line[len - 1] == '\n')
- line[len - 1] = '\0';
- if (line[0] == '#')
+ while (fgets(line, 1024, f)) {
+ char *ptr = strchr(line, '#');
+ char keyname[1024], p1[1024], p2[1024];
+ int keysym, keycode;
+ int shift = 0;
+ int altgr = 0;
+ int addupper = 0;
+ int numlock = 0;
+ int inhibit = 0;
+
+ if (ptr)
+ *ptr-- = '\0';
+ else
+ ptr = &line[strlen(line)-1];
+ while (isspace(*ptr))
+ *ptr-- = '\0';
+ if (!*line)
+ continue;
+ if (strncmp(line, "map ", 4) == 0)
+ continue;
+ if (sscanf(line, "include %s", p1) == 1) {
+ parse_keyboard_layout(p1, k);
continue;
- if (!strncmp(line, "map ", 4))
+ }
+ if (sscanf(line, "%s %i %s %s", keyname, &keycode, p1, p2) == 4) {
+ shift = (strcmp(p1, "shift") == 0 || strcmp(p2, "shift") == 0);
+ altgr = (strcmp(p1, "altgr") == 0 || strcmp(p2, "altgr") == 0);
+ } else if (sscanf(line, "%s %i %s", keyname, &keycode, p1) == 3) {
+ shift = (strcmp(p1, "shift") == 0);
+ altgr = (strcmp(p1, "altgr") == 0);
+ addupper = (strcmp(p1, "addupper") == 0);
+ numlock = (strcmp(p1, "numlock") == 0);
+ inhibit = (strcmp(p1, "inhibit") == 0);
+ } else if (sscanf(line, "%s %i", keyname, &keycode) != 2)
+ /* silently ignore spurious lines */
+ continue;
+
+ if (inhibit)
+ continue;
+ if ((keysym = get_keysym(keyname)) == 0) {
+ fprintf(stderr, "%s: warning: unknown keysym %s\n",
+ file_name, keyname);
continue;
- if (!strncmp(line, "include ", 8)) {
- parse_keyboard_layout(line + 8, k);
- } else {
- char *end_of_keysym = line;
- while (*end_of_keysym != 0 && *end_of_keysym != ' ')
- end_of_keysym++;
- if (*end_of_keysym) {
- int keysym;
- *end_of_keysym = 0;
- keysym = get_keysym(line);
- if (keysym == 0) {
- // fprintf(stderr, "Warning: unknown keysym
%s\n", line);
- } else {
- const char *rest = end_of_keysym + 1;
- char *rest2;
- int keycode = strtol(rest, &rest2, 0);
-
- if (rest && strstr(rest, "numlock")) {
- add_to_key_range(&k->keypad_range, keycode);
- add_to_key_range(&k->numlock_range, keysym);
- //fprintf(stderr, "keypad keysym %04x keycode %d\n",
keysym, keycode);
- }
- if (rest && strstr(rest, "shift")) {
- add_to_key_range(&k->shift_range, keysym);
- //fprintf(stderr, "shift keysym %04x keycode %d\n",
keysym, keycode);
- }
- if (rest && strstr(rest, "localstate")) {
- add_to_key_range(&k->localstate_range, keycode);
- //fprintf(stderr, "localstate keysym %04x keycode
%d\n", keysym, keycode);
- }
-
- /* if(keycode&0x80)
- keycode=(keycode<<8)^0x80e0; */
- if (keysym < MAX_NORMAL_KEYCODE) {
- //fprintf(stderr,"Setting keysym %s (%d) to
%d\n",line,keysym,keycode);
- k->keysym2keycode[keysym] = keycode;
- } else {
- if (k->extra_count >= MAX_EXTRA_COUNT) {
- fprintf(stderr,
- "Warning: Could not assign keysym %s (0x%x)
because of memory constraints.\n",
- line, keysym);
- } else {
-#if 0
- fprintf(stderr, "Setting %d: %d,%d\n",
- k->extra_count, keysym, keycode);
-#endif
- k->keysym2keycode_extra[k->extra_count].
- keysym = keysym;
- k->keysym2keycode_extra[k->extra_count].
- keycode = keycode;
- k->extra_count++;
- }
- }
- }
- }
+ }
+ if (keycode <= 0 || keycode >= MAX_SCANCODE) {
+ fprintf(stderr, "%s: warning: keycode %#x for %s out of range\n",
+ file_name, keycode, keyname);
+ continue;
+ }
+ if (numlock)
+ k->numlock.k[keycode].keysym = keysym;
+ else if (shift && altgr)
+ k->shift_altgr.k[keycode].keysym = keysym;
+ else if (altgr)
+ k->altgr.k[keycode].keysym = keysym;
+ else if (shift)
+ k->shift.k[keycode].keysym = keysym;
+ else {
+ k->plain.k[keycode].keysym = keysym;
+ if (addupper)
+ k->shift.k[keycode].keysym = keysym + 'A' - 'a';
}
}
fclose(f);
return k;
}
+static int cmp_map (const void *a, const void *b) {
+ return ((keysym2keycode_t *) b)->keysym - ((keysym2keycode_t *) a)->keysym;
+}
+
+static void sort_map (keysym_map_t *map) {
+ int i;
+ for (i = 0; i < MAX_SCANCODE; i++)
+ map->k[i].keycode = i;
+ /* sort undefined scancodes to the end */
+ qsort(map->k, MAX_SCANCODE, sizeof(keysym2keycode_t), cmp_map);
+ for (map->n = 0; map->n < MAX_SCANCODE; map->n++)
+ if (!map->k[map->n].keysym)
+ break;
+}
+
static void *init_keyboard_layout(const char *language)
{
- return parse_keyboard_layout(language, 0);
+ kbd_layout_t *k = parse_keyboard_layout(language, NULL);
+ if (k) {
+ int i;
+ for (i = 0; i < MAX_SCANCODE; i++) {
+ if (!(k->shift.k[i].keysym
+ || k->altgr.k[i].keysym
+ || k->shift_altgr.k[i].keysym))
+ k->flags[i] |= KEY_LOCALSTATE;
+ if (k->numlock.k[i].keysym)
+ k->flags[i] |= KEY_KEYPAD;
+ }
+ sort_map(&k->plain);
+ sort_map(&k->shift);
+ sort_map(&k->altgr);
+ sort_map(&k->shift_altgr);
+ sort_map(&k->numlock);
+ }
+ return k;
}
-static int keysym2scancode(void *kbd_layout, int keysym)
+static int keysym2scancode_map (keysym_map_t *map, int keysym)
{
- kbd_layout_t *k = kbd_layout;
- if (keysym < MAX_NORMAL_KEYCODE) {
- if (k->keysym2keycode[keysym] == 0)
- fprintf(stderr, "Warning: no scancode found for keysym %d\n",
- keysym);
- return k->keysym2keycode[keysym];
- } else {
- int i;
-#ifdef XK_ISO_Left_Tab
- if (keysym == XK_ISO_Left_Tab)
- keysym = XK_Tab;
-#endif
- for (i = 0; i < k->extra_count; i++)
- if (k->keysym2keycode_extra[i].keysym == keysym)
- return k->keysym2keycode_extra[i].keycode;
+ int l = 0, r = map->n - 1, m;
+ while (l <= r) {
+ m = (l + r) / 2;
+ if (map->k[m].keysym == keysym)
+ return map->k[m].keycode;
+ else if (map->k[m].keysym < keysym)
+ r = m - 1;
+ else
+ l = m + 1;
}
return 0;
}
-static inline int keycode_is_keypad(void *kbd_layout, int keycode)
+static int keysym2scancode(void *kbd_layout, int keysym)
{
kbd_layout_t *k = kbd_layout;
- struct key_range *kr;
+ int scancode;
- for (kr = k->keypad_range; kr; kr = kr->next)
- if (keycode >= kr->start && keycode <= kr->end)
- return 1;
+ if ((scancode = keysym2scancode_map(&k->plain, keysym)))
+ return scancode;
+ if ((scancode = keysym2scancode_map(&k->numlock, keysym)))
+ return scancode;
+ if ((scancode = keysym2scancode_map(&k->shift, keysym)))
+ return scancode;
+ if ((scancode = keysym2scancode_map(&k->altgr, keysym)))
+ return scancode;
+ if ((scancode = keysym2scancode_map(&k->shift_altgr, keysym)))
+ return scancode;
return 0;
}
-static inline int keysym_is_numlock(void *kbd_layout, int keysym)
+static int keysym2scancode1(void *kbd_layout, int keysym,
+ int *shift, int *altgr)
{
kbd_layout_t *k = kbd_layout;
- struct key_range *kr;
+ int s;
+
+ /* normal case: keysym can be found the expected modifier's map */
+ if (*shift && *altgr && (s = keysym2scancode_map(&k->shift_altgr, keysym)))
+ return s;
+ if (*altgr && (s = keysym2scancode_map(&k->altgr, keysym)))
+ return s;
+ if (*shift && (s = keysym2scancode_map(&k->shift, keysym)))
+ return s;
+ if ((s = keysym2scancode_map(&k->plain, keysym)))
+ return s;
+ if ((s = keysym2scancode_map(&k->numlock, keysym)))
+ return s;
- for (kr = k->numlock_range; kr; kr = kr->next)
- if (keysym >= kr->start && keysym <= kr->end)
- return 1;
+ /* fallback for when there is some keyboard/state mismatch */
+ if ((s = keysym2scancode_map(&k->plain, keysym))) {
+ *shift = 0;
+ *altgr = 0;
+ return s;
+ }
+ if ((s = keysym2scancode_map(&k->shift, keysym))) {
+ *shift = 1;
+ *altgr = 0;
+ return s;
+ }
+ if ((s = keysym2scancode_map(&k->altgr, keysym))) {
+ *shift = 0;
+ *altgr = 1;
+ return s;
+ }
+ if ((s = keysym2scancode_map(&k->shift_altgr, keysym))) {
+ *shift = 1;
+ *altgr = 1;
+ return s;
+ }
return 0;
-}
+}
-static inline int keysym_is_shift(void *kbd_layout, int keysym)
+static int keycode_is_keypad(void *kbd_layout, int keycode)
{
kbd_layout_t *k = kbd_layout;
- struct key_range *kr;
-
- for (kr = k->shift_range; kr; kr = kr->next)
- if (keysym >= kr->start && keysym <= kr->end)
- return 1;
+ if (keycode >= 0 && keycode < MAX_SCANCODE)
+ return !!(k->flags[keycode] & KEY_KEYPAD);
return 0;
}
-static inline int keycode_is_shiftable(void *kbd_layout, int keycode)
+static int keysym_is_numlock(void *kbd_layout, int keysym)
+{
+ kbd_layout_t *k = kbd_layout;
+ return (keysym2scancode_map(&k->numlock, keysym) != 0);
+}
+
+static int keysym_is_shift(void *kbd_layout, int keysym)
{
kbd_layout_t *k = kbd_layout;
- struct key_range *kr;
+ return (keysym2scancode_map(&k->shift, keysym) != 0);
+}
- for (kr = k->localstate_range; kr; kr = kr->next)
- if (keycode >= kr->start && keycode <= kr->end)
- return 0;
- return 1;
+static int keycode_is_shiftable(void *kbd_layout, int keycode)
+{
+ kbd_layout_t *k = kbd_layout;
+ if (keycode >= 0 || keycode < MAX_SCANCODE)
+ return !(k->flags[keycode] & KEY_LOCALSTATE);
+ return 0;
}
diff --git a/vnc.c b/vnc.c
index 2cf3a31..a24eb39 100644
--- a/vnc.c
+++ b/vnc.c
@@ -1258,14 +1258,22 @@ static void pointer_event(VncState *vs, int
button_mask, int x, int y)
check_pointer_type_change(vs, kbd_mouse_is_absolute());
}
+static void put_keycode(int keycode, int down)
+{
+ if (keycode & 0x80)
+ kbd_put_keycode(0xe0);
+ if (down)
+ kbd_put_keycode(keycode & 0x7f);
+ else
+ kbd_put_keycode(keycode | 0x80);
+}
+
static void reset_keys(VncState *vs)
{
int i;
for(i = 0; i < 256; i++) {
if (vs->modifiers_state[i]) {
- if (i & 0x80)
- kbd_put_keycode(0xe0);
- kbd_put_keycode(i | 0x80);
+ put_keycode(i, 0);
vs->modifiers_state[i] = 0;
}
}
@@ -1273,69 +1281,34 @@ static void reset_keys(VncState *vs)
static void press_key(VncState *vs, int keysym)
{
- kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) & 0x7f);
- kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
+ put_keycode(keysym2scancode(vs->kbd_layout, keysym), 1);
+ put_keycode(keysym2scancode(vs->kbd_layout, keysym), 0);
}
-static void press_key_shift_down(VncState *vs, int down, int keycode)
+static void twiddle_modifiers(VncState *vs, int down, int shift, int altgr)
{
- if (down)
- kbd_put_keycode(0x2a & 0x7f);
-
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- if (down)
- kbd_put_keycode(keycode & 0x7f);
- else
- kbd_put_keycode(keycode | 0x80);
-
- if (!down)
- kbd_put_keycode(0x2a | 0x80);
-}
-
-static void press_key_shift_up(VncState *vs, int down, int keycode)
-{
- if (down) {
- if (vs->modifiers_state[0x2a])
- kbd_put_keycode(0x2a | 0x80);
- if (vs->modifiers_state[0x36])
- kbd_put_keycode(0x36 | 0x80);
- }
-
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- if (down)
- kbd_put_keycode(keycode & 0x7f);
- else
- kbd_put_keycode(keycode | 0x80);
-
- if (!down) {
- if (vs->modifiers_state[0x2a])
- kbd_put_keycode(0x2a & 0x7f);
- if (vs->modifiers_state[0x36])
- kbd_put_keycode(0x36 & 0x7f);
- }
+ if (shift && !(vs->modifiers_state[0x2a] || vs->modifiers_state[0x36]))
+ put_keycode(0x2a, down);
+ if (!shift && vs->modifiers_state[0x2a])
+ put_keycode(0x2a, !down);
+ if (!shift && vs->modifiers_state[0x36])
+ put_keycode(0x36, !down);
+ if (altgr && !vs->modifiers_state[0xb8])
+ put_keycode(0xb8, down);
+ if (!altgr && vs->modifiers_state[0xb8])
+ put_keycode(0xb8, !down);
}
static void do_key_event(VncState *vs, int down, uint32_t sym)
{
int keycode;
- int shift_keys = 0;
+ int altgr = 0;
int shift = 0;
int keypad = 0;
- if (is_graphic_console()) {
- if (sym >= 'A' && sym <= 'Z') {
- sym = sym - 'A' + 'a';
- shift = 1;
- }
- else {
- shift = keysym_is_shift(vs->kbd_layout, sym & 0xFFFF);
- }
- }
- shift_keys = vs->modifiers_state[0x2a] | vs->modifiers_state[0x36];
-
- keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
+ shift = (vs->modifiers_state[0x2a] || vs->modifiers_state[0x36]);
+ altgr = vs->modifiers_state[0xb8];
+ keycode = keysym2scancode1(vs->kbd_layout, sym & 0xFFFF, &shift, &altgr);
if (keycode == 0) {
fprintf(stderr, "Key lost : keysym=0x%x(%d)\n", sym, sym);
return;
@@ -1348,17 +1321,9 @@ static void do_key_event(VncState *vs, int down,
uint32_t sym)
case 0x1d: /* Left CTRL */
case 0x9d: /* Right CTRL */
case 0x38: /* Left ALT */
- case 0xb8: /* Right ALT */
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- if (down) {
- vs->modifiers_state[keycode] = 1;
- kbd_put_keycode(keycode & 0x7f);
- }
- else {
- vs->modifiers_state[keycode] = 0;
- kbd_put_keycode(keycode | 0x80);
- }
+ case 0xb8: /* Right ALT aka AltGr */
+ vs->modifiers_state[keycode] = down;
+ put_keycode(keycode, down);
return;
case 0x02 ... 0x0a: /* '1' to '9' keys */
if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
@@ -1369,13 +1334,15 @@ static void do_key_event(VncState *vs, int down,
uint32_t sym)
}
break;
case 0x3a: /* CapsLock */
+ if (is_graphic_console())
+ return;
case 0x45: /* NumLock */
if (down) {
- kbd_put_keycode(keycode & 0x7f);
+ put_keycode(keycode, 1);
}
else {
vs->modifiers_state[keycode] ^= 1;
- kbd_put_keycode(keycode | 0x80);
+ put_keycode(keycode, 0);
}
return;
}
@@ -1384,7 +1351,10 @@ static void do_key_event(VncState *vs, int down,
uint32_t sym)
if (keypad) {
/* If the numlock state needs to change then simulate an additional
keypress before sending this one. This will happen if the user
- toggles numlock away from the VNC window.
+ toggles numlock away from the VNC window. This isn't perfect as
+ pressing the shift key will typically and temporarily have the
+ effect of inverting the numlock setting: the shift key will be
+ effectively cancelled out.
*/
if (keysym_is_numlock(vs->kbd_layout, sym & 0xFFFF)) {
if (!vs->modifiers_state[0x45]) {
@@ -1403,22 +1373,14 @@ static void do_key_event(VncState *vs, int down,
uint32_t sym)
/* If the shift state needs to change then simulate an additional
keypress before sending this one. Ignore for non shiftable keys.
*/
- if (shift && !shift_keys) {
- press_key_shift_down(vs, down, keycode);
- return;
- }
- else if (!shift && shift_keys && !keypad &&
- keycode_is_shiftable(vs->kbd_layout, keycode)) {
- press_key_shift_up(vs, down, keycode);
- return;
- }
-
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- if (down)
- kbd_put_keycode(keycode & 0x7f);
- else
- kbd_put_keycode(keycode | 0x80);
+ if (keycode_is_shiftable(vs->kbd_layout, keycode) && !keypad) {
+ if (down)
+ twiddle_modifiers(vs, down, shift, altgr);
+ put_keycode(keycode, down);
+ if (!down)
+ twiddle_modifiers(vs, down, shift, altgr);
+ } else
+ put_keycode(keycode, down);
} else {
/* QEMU console emulation */
if (down) {
@@ -2514,7 +2476,7 @@ void vnc_display_init(DisplayState *ds)
vs->kbd_layout = init_keyboard_layout(keyboard_layout);
if (!vs->kbd_layout)
exit(1);
- vs->modifiers_state[0x45] = 1; /* NumLock on - on boot */
+ vs->modifiers_state[0x45] = 0; /* NumLock off - on boot */
vs->ds->data = NULL;
vs->ds->dpy_update = vnc_dpy_update;
diff --git a/vnc_keysym.h b/vnc_keysym.h
index aa0fd9b..226789a 100644
--- a/vnc_keysym.h
+++ b/vnc_keysym.h
@@ -262,6 +262,783 @@ static name2keysym_t name2keysym[]={
{ "tcedilla", 0x01fe},
{ "abovedot", 0x01ff},
+ /* latin3 extensions */
+ { "Hstroke", 0x02a1 },
+ { "Hcircumflex", 0x02a6 },
+ { "Iabovedot", 0x02a9 },
+ { "Gbreve", 0x02ab },
+ { "Jcircumflex", 0x02ac },
+ { "hstroke", 0x02b1 },
+ { "hcircumflex", 0x02b6 },
+ { "idotless", 0x02b9 },
+ { "gbreve", 0x02bb },
+ { "jcircumflex", 0x02bc },
+ { "Cabovedot", 0x02c5 },
+ { "Ccircumflex", 0x02c6 },
+ { "Gabovedot", 0x02d5 },
+ { "Gcircumflex", 0x02d8 },
+ { "Ubreve", 0x02dd },
+ { "Scircumflex", 0x02de },
+ { "cabovedot", 0x02e5 },
+ { "ccircumflex", 0x02e6 },
+ { "gabovedot", 0x02f5 },
+ { "gcircumflex", 0x02f8 },
+ { "ubreve", 0x02fd },
+ { "scircumflex", 0x02fe },
+
+ /* latin4 extensions */
+ { "kra", 0x03a2 },
+ { "kappa", 0x03a2 },
+ { "Rcedilla", 0x03a3 },
+ { "Itilde", 0x03a5 },
+ { "Lcedilla", 0x03a6 },
+ { "Emacron", 0x03aa },
+ { "Gcedilla", 0x03ab },
+ { "Tslash", 0x03ac },
+ { "rcedilla", 0x03b3 },
+ { "itilde", 0x03b5 },
+ { "lcedilla", 0x03b6 },
+ { "emacron", 0x03ba },
+ { "gcedilla", 0x03bb },
+ { "tslash", 0x03bc },
+ { "ENG", 0x03bd },
+ { "eng", 0x03bf },
+ { "Amacron", 0x03c0 },
+ { "Iogonek", 0x03c7 },
+ { "Eabovedot", 0x03cc },
+ { "Imacron", 0x03cf },
+ { "Ncedilla", 0x03d1 },
+ { "Omacron", 0x03d2 },
+ { "Kcedilla", 0x03d3 },
+ { "Uogonek", 0x03d9 },
+ { "Utilde", 0x03dd },
+ { "Umacron", 0x03de },
+ { "amacron", 0x03e0 },
+ { "iogonek", 0x03e7 },
+ { "eabovedot", 0x03ec },
+ { "imacron", 0x03ef },
+ { "ncedilla", 0x03f1 },
+ { "omacron", 0x03f2 },
+ { "kcedilla", 0x03f3 },
+ { "uogonek", 0x03f9 },
+ { "utilde", 0x03fd },
+ { "umacron", 0x03fe },
+
+ /* latin8 extensions */
+ { "Babovedot", 0x1001e02 },
+ { "babovedot", 0x1001e03 },
+ { "Dabovedot", 0x1001e0a },
+ { "Wgrave", 0x1001e80 },
+ { "Wacute", 0x1001e82 },
+ { "dabovedot", 0x1001e0b },
+ { "Ygrave", 0x1001ef2 },
+ { "Fabovedot", 0x1001e1e },
+ { "fabovedot", 0x1001e1f },
+ { "Mabovedot", 0x1001e40 },
+ { "mabovedot", 0x1001e41 },
+ { "Pabovedot", 0x1001e56 },
+ { "wgrave", 0x1001e81 },
+ { "pabovedot", 0x1001e57 },
+ { "wacute", 0x1001e83 },
+ { "Sabovedot", 0x1001e60 },
+ { "ygrave", 0x1001ef3 },
+ { "Wdiaeresis", 0x1001e84 },
+ { "wdiaeresis", 0x1001e85 },
+ { "sabovedot", 0x1001e61 },
+ { "Wcircumflex", 0x1000174 },
+ { "Tabovedot", 0x1001e6a },
+ { "Ycircumflex", 0x1000176 },
+ { "wcircumflex", 0x1000175 },
+ { "tabovedot", 0x1001e6b },
+ { "ycircumflex", 0x1000177 },
+
+ /* latin9 extensions */
+ { "OE", 0x13bc },
+ { "oe", 0x13bd },
+ { "Ydiaeresis", 0x13be },
+
+ /* katakana */
+ { "overline", 0x047e },
+ { "kana_fullstop", 0x04a1 },
+ { "kana_openingbracket", 0x04a2 },
+ { "kana_closingbracket", 0x04a3 },
+ { "kana_comma", 0x04a4 },
+ { "kana_conjunctive", 0x04a5 },
+ { "kana_middledot", 0x04a5 },
+ { "kana_WO", 0x04a6 },
+ { "kana_a", 0x04a7 },
+ { "kana_i", 0x04a8 },
+ { "kana_u", 0x04a9 },
+ { "kana_e", 0x04aa },
+ { "kana_o", 0x04ab },
+ { "kana_ya", 0x04ac },
+ { "kana_yu", 0x04ad },
+ { "kana_yo", 0x04ae },
+ { "kana_tsu", 0x04af },
+ { "kana_tu", 0x04af },
+ { "prolongedsound", 0x04b0 },
+ { "kana_A", 0x04b1 },
+ { "kana_I", 0x04b2 },
+ { "kana_U", 0x04b3 },
+ { "kana_E", 0x04b4 },
+ { "kana_O", 0x04b5 },
+ { "kana_KA", 0x04b6 },
+ { "kana_KI", 0x04b7 },
+ { "kana_KU", 0x04b8 },
+ { "kana_KE", 0x04b9 },
+ { "kana_KO", 0x04ba },
+ { "kana_SA", 0x04bb },
+ { "kana_SHI", 0x04bc },
+ { "kana_SU", 0x04bd },
+ { "kana_SE", 0x04be },
+ { "kana_SO", 0x04bf },
+ { "kana_TA", 0x04c0 },
+ { "kana_CHI", 0x04c1 },
+ { "kana_TI", 0x04c1 },
+ { "kana_TSU", 0x04c2 },
+ { "kana_TU", 0x04c2 },
+ { "kana_TE", 0x04c3 },
+ { "kana_TO", 0x04c4 },
+ { "kana_NA", 0x04c5 },
+ { "kana_NI", 0x04c6 },
+ { "kana_NU", 0x04c7 },
+ { "kana_NE", 0x04c8 },
+ { "kana_NO", 0x04c9 },
+ { "kana_HA", 0x04ca },
+ { "kana_HI", 0x04cb },
+ { "kana_FU", 0x04cc },
+ { "kana_HU", 0x04cc },
+ { "kana_HE", 0x04cd },
+ { "kana_HO", 0x04ce },
+ { "kana_MA", 0x04cf },
+ { "kana_MI", 0x04d0 },
+ { "kana_MU", 0x04d1 },
+ { "kana_ME", 0x04d2 },
+ { "kana_MO", 0x04d3 },
+ { "kana_YA", 0x04d4 },
+ { "kana_YU", 0x04d5 },
+ { "kana_YO", 0x04d6 },
+ { "kana_RA", 0x04d7 },
+ { "kana_RI", 0x04d8 },
+ { "kana_RU", 0x04d9 },
+ { "kana_RE", 0x04da },
+ { "kana_RO", 0x04db },
+ { "kana_WA", 0x04dc },
+ { "kana_N", 0x04dd },
+ { "voicedsound", 0x04de },
+ { "semivoicedsound", 0x04df },
+ { "kana_switch", 0xff7e },
+
+ /* arabic */
+ { "Farsi_0", 0x10006f0 },
+ { "Farsi_1", 0x10006f1 },
+ { "Farsi_2", 0x10006f2 },
+ { "Farsi_3", 0x10006f3 },
+ { "Farsi_4", 0x10006f4 },
+ { "Farsi_5", 0x10006f5 },
+ { "Farsi_6", 0x10006f6 },
+ { "Farsi_7", 0x10006f7 },
+ { "Farsi_8", 0x10006f8 },
+ { "Farsi_9", 0x10006f9 },
+ { "Arabic_percent", 0x100066a },
+ { "Arabic_superscript_alef", 0x1000670 },
+ { "Arabic_tteh", 0x1000679 },
+ { "Arabic_peh", 0x100067e },
+ { "Arabic_tcheh", 0x1000686 },
+ { "Arabic_ddal", 0x1000688 },
+ { "Arabic_rreh", 0x1000691 },
+ { "Arabic_comma", 0x05ac },
+ { "Arabic_fullstop", 0x10006d4 },
+ { "Arabic_0", 0x1000660 },
+ { "Arabic_1", 0x1000661 },
+ { "Arabic_2", 0x1000662 },
+ { "Arabic_3", 0x1000663 },
+ { "Arabic_4", 0x1000664 },
+ { "Arabic_5", 0x1000665 },
+ { "Arabic_6", 0x1000666 },
+ { "Arabic_7", 0x1000667 },
+ { "Arabic_8", 0x1000668 },
+ { "Arabic_9", 0x1000669 },
+ { "Arabic_semicolon", 0x05bb },
+ { "Arabic_question_mark", 0x05bf },
+ { "Arabic_hamza", 0x05c1 },
+ { "Arabic_maddaonalef", 0x05c2 },
+ { "Arabic_hamzaonalef", 0x05c3 },
+ { "Arabic_hamzaonwaw", 0x05c4 },
+ { "Arabic_hamzaunderalef", 0x05c5 },
+ { "Arabic_hamzaonyeh", 0x05c6 },
+ { "Arabic_alef", 0x05c7 },
+ { "Arabic_beh", 0x05c8 },
+ { "Arabic_tehmarbuta", 0x05c9 },
+ { "Arabic_teh", 0x05ca },
+ { "Arabic_theh", 0x05cb },
+ { "Arabic_jeem", 0x05cc },
+ { "Arabic_hah", 0x05cd },
+ { "Arabic_khah", 0x05ce },
+ { "Arabic_dal", 0x05cf },
+ { "Arabic_thal", 0x05d0 },
+ { "Arabic_ra", 0x05d1 },
+ { "Arabic_zain", 0x05d2 },
+ { "Arabic_seen", 0x05d3 },
+ { "Arabic_sheen", 0x05d4 },
+ { "Arabic_sad", 0x05d5 },
+ { "Arabic_dad", 0x05d6 },
+ { "Arabic_tah", 0x05d7 },
+ { "Arabic_zah", 0x05d8 },
+ { "Arabic_ain", 0x05d9 },
+ { "Arabic_ghain", 0x05da },
+ { "Arabic_tatweel", 0x05e0 },
+ { "Arabic_feh", 0x05e1 },
+ { "Arabic_qaf", 0x05e2 },
+ { "Arabic_kaf", 0x05e3 },
+ { "Arabic_lam", 0x05e4 },
+ { "Arabic_meem", 0x05e5 },
+ { "Arabic_noon", 0x05e6 },
+ { "Arabic_ha", 0x05e7 },
+ { "Arabic_heh", 0x05e7 },
+ { "Arabic_waw", 0x05e8 },
+ { "Arabic_alefmaksura", 0x05e9 },
+ { "Arabic_yeh", 0x05ea },
+ { "Arabic_fathatan", 0x05eb },
+ { "Arabic_dammatan", 0x05ec },
+ { "Arabic_kasratan", 0x05ed },
+ { "Arabic_fatha", 0x05ee },
+ { "Arabic_damma", 0x05ef },
+ { "Arabic_kasra", 0x05f0 },
+ { "Arabic_shadda", 0x05f1 },
+ { "Arabic_sukun", 0x05f2 },
+ { "Arabic_madda_above", 0x1000653 },
+ { "Arabic_hamza_above", 0x1000654 },
+ { "Arabic_hamza_below", 0x1000655 },
+ { "Arabic_jeh", 0x1000698 },
+ { "Arabic_veh", 0x10006a4 },
+ { "Arabic_keheh", 0x10006a9 },
+ { "Arabic_gaf", 0x10006af },
+ { "Arabic_noon_ghunna", 0x10006ba },
+ { "Arabic_heh_doachashmee", 0x10006be },
+ { "Farsi_yeh", 0x10006cc },
+ { "Arabic_farsi_yeh", 0x10006cc },
+ { "Arabic_yeh_baree", 0x10006d2 },
+ { "Arabic_heh_goal", 0x10006c1 },
+ { "Arabic_switch", 0xff7e },
+
+ /* japanese keyboard */
+ { "Kanji", 0xff21 },
+ { "BackApostrophe", 0xff21 }, /* ??? */
+ { "Muhenkan", 0xff22 },
+ { "Henkan_Mode", 0xff23 },
+ { "Henkan", 0xff23 },
+ { "Henkan_Mode_Real", 0xff23 }, /* deprecated */
+ { "Romaji", 0xff24 },
+ { "Hiragana", 0xff25 },
+ { "Katakana_Real", 0xff25 }, /* deprecated */
+ { "Katakana", 0xff26 },
+ { "Hiragana_Katakana", 0xff27 },
+ { "Zenkaku", 0xff28 },
+ { "Hankaku", 0xff29 },
+ { "Zenkaku_Hankaku", 0xff2a },
+ { "Touroku", 0xff2b },
+ { "Massyo", 0xff2c },
+ { "Kana_Lock", 0xff2d },
+ { "Kana_Shift", 0xff2e },
+ { "Eisu_Shift", 0xff2f },
+ { "Eisu_toggle", 0xff30 },
+ { "Kanji_Bangou", 0xff37 },
+ { "Zen_Koho", 0xff3d },
+ { "Mae_Koho", 0xff3e },
+ { "Henkan_Mode_Ultra", 0xff3e }, /* deprecated */
+ { "backslash_ja", 0xffa5 }, /* ??? */
+
+ /* dead keys */
+ { "dead_grave", 0xfe50 },
+ { "dead_acute", 0xfe51 },
+ { "dead_circumflex", 0xfe52 },
+ { "dead_tilde", 0xfe53 },
+ { "dead_macron", 0xfe54 },
+ { "dead_breve", 0xfe55 },
+ { "dead_abovedot", 0xfe56 },
+ { "dead_diaeresis", 0xfe57 },
+ { "dead_abovering", 0xfe58 },
+ { "dead_doubleacute", 0xfe59 },
+ { "dead_caron", 0xfe5a },
+ { "dead_cedilla", 0xfe5b },
+ { "dead_ogonek", 0xfe5c },
+ { "dead_iota", 0xfe5d },
+ { "dead_voiced_sound", 0xfe5e },
+ { "dead_semivoiced_sound", 0xfe5f },
+ { "dead_belowdot", 0xfe60 },
+ { "dead_hook", 0xfe61 },
+ { "dead_horn", 0xfe62 },
+ { "dead_stroke", 0xfe63 },
+ { "dead_abovecomma", 0xfe64 },
+ { "dead_psili", 0xfe64 },
+ { "dead_abovereversedcomma", 0xfe65 },
+ { "dead_dasia", 0xfe66 },
+ { "dead_belowring", 0xfe67 },
+ { "dead_belowmacron", 0xfe68 },
+ { "dead_belowcircumflex", 0xfe69 },
+ { "dead_belowtilde", 0xfe6a },
+ { "dead_belowbreve", 0xfe6b },
+ { "dead_belowdiaeresis", 0xfe6c },
+
+ /* cyrillic */
+ { "Cyrillic_GHE_bar", 0x1000492 },
+ { "Cyrillic_ghe_bar", 0x1000493 },
+ { "Cyrillic_ZHE_descender", 0x1000496 },
+ { "Cyrillic_zhe_descender", 0x1000497 },
+ { "Cyrillic_KA_descender", 0x100049a },
+ { "Cyrillic_ka_descender", 0x100049b },
+ { "Cyrillic_KA_vertstroke", 0x100049c },
+ { "Cyrillic_ka_vertstroke", 0x100049d },
+ { "Cyrillic_EN_descender", 0x10004a2 },
+ { "Cyrillic_en_descender", 0x10004a3 },
+ { "Cyrillic_U_straight", 0x10004ae },
+ { "Cyrillic_u_straight", 0x10004af },
+ { "Cyrillic_U_straight_bar", 0x10004b0 },
+ { "Cyrillic_u_straight_bar", 0x10004b1 },
+ { "Cyrillic_HA_descender", 0x10004b2 },
+ { "Cyrillic_ha_descender", 0x10004b3 },
+ { "Cyrillic_CHE_descender", 0x10004b6 },
+ { "Cyrillic_che_descender", 0x10004b7 },
+ { "Cyrillic_CHE_vertstroke", 0x10004b8 },
+ { "Cyrillic_che_vertstroke", 0x10004b9 },
+ { "Cyrillic_SHHA", 0x10004ba },
+ { "Cyrillic_shha", 0x10004bb },
+ { "Cyrillic_SCHWA", 0x10004d8 },
+ { "Cyrillic_schwa", 0x10004d9 },
+ { "Cyrillic_I_macron", 0x10004e2 },
+ { "Cyrillic_i_macron", 0x10004e3 },
+ { "Cyrillic_O_bar", 0x10004e8 },
+ { "Cyrillic_o_bar", 0x10004e9 },
+ { "Cyrillic_U_macron", 0x10004ee },
+ { "Cyrillic_u_macron", 0x10004ef },
+ { "Serbian_dje", 0x06a1 },
+ { "Macedonia_gje", 0x06a2 },
+ { "Cyrillic_io", 0x06a3 },
+ { "Ukrainian_ie", 0x06a4 },
+ { "Ukranian_je", 0x06a4 },
+ { "Macedonia_dse", 0x06a5 },
+ { "Ukrainian_i", 0x06a6 },
+ { "Ukranian_i", 0x06a6 },
+ { "Ukrainian_yi", 0x06a7 },
+ { "Ukranian_yi", 0x06a7 },
+ { "Cyrillic_je", 0x06a8 },
+ { "Serbian_je", 0x06a8 },
+ { "Cyrillic_lje", 0x06a9 },
+ { "Serbian_lje", 0x06a9 },
+ { "Cyrillic_nje", 0x06aa },
+ { "Serbian_nje", 0x06aa },
+ { "Serbian_tshe", 0x06ab },
+ { "Macedonia_kje", 0x06ac },
+ { "Ukrainian_ghe_with_upturn", 0x06ad },
+ { "Byelorussian_shortu", 0x06ae },
+ { "Cyrillic_dzhe", 0x06af },
+ { "Serbian_dze", 0x06af },
+ { "numerosign", 0x06b0 },
+ { "Serbian_DJE", 0x06b1 },
+ { "Macedonia_GJE", 0x06b2 },
+ { "Cyrillic_IO", 0x06b3 },
+ { "Ukrainian_IE", 0x06b4 },
+ { "Ukranian_JE", 0x06b4 },
+ { "Macedonia_DSE", 0x06b5 },
+ { "Ukrainian_I", 0x06b6 },
+ { "Ukranian_I", 0x06b6 },
+ { "Ukrainian_YI", 0x06b7 },
+ { "Ukranian_YI", 0x06b7 },
+ { "Cyrillic_JE", 0x06b8 },
+ { "Serbian_JE", 0x06b8 },
+ { "Cyrillic_LJE", 0x06b9 },
+ { "Serbian_LJE", 0x06b9 },
+ { "Cyrillic_NJE", 0x06ba },
+ { "Serbian_NJE", 0x06ba },
+ { "Serbian_TSHE", 0x06bb },
+ { "Macedonia_KJE", 0x06bc },
+ { "Ukrainian_GHE_WITH_UPTURN", 0x06bd },
+ { "Byelorussian_SHORTU", 0x06be },
+ { "Cyrillic_DZHE", 0x06bf },
+ { "Serbian_DZE", 0x06bf },
+ { "Cyrillic_yu", 0x06c0 },
+ { "Cyrillic_a", 0x06c1 },
+ { "Cyrillic_be", 0x06c2 },
+ { "Cyrillic_tse", 0x06c3 },
+ { "Cyrillic_de", 0x06c4 },
+ { "Cyrillic_ie", 0x06c5 },
+ { "Cyrillic_ef", 0x06c6 },
+ { "Cyrillic_ghe", 0x06c7 },
+ { "Cyrillic_ha", 0x06c8 },
+ { "Cyrillic_i", 0x06c9 },
+ { "Cyrillic_shorti", 0x06ca },
+ { "Cyrillic_ka", 0x06cb },
+ { "Cyrillic_el", 0x06cc },
+ { "Cyrillic_em", 0x06cd },
+ { "Cyrillic_en", 0x06ce },
+ { "Cyrillic_o", 0x06cf },
+ { "Cyrillic_pe", 0x06d0 },
+ { "Cyrillic_ya", 0x06d1 },
+ { "Cyrillic_er", 0x06d2 },
+ { "Cyrillic_es", 0x06d3 },
+ { "Cyrillic_te", 0x06d4 },
+ { "Cyrillic_u", 0x06d5 },
+ { "Cyrillic_zhe", 0x06d6 },
+ { "Cyrillic_ve", 0x06d7 },
+ { "Cyrillic_softsign", 0x06d8 },
+ { "Cyrillic_yeru", 0x06d9 },
+ { "Cyrillic_ze", 0x06da },
+ { "Cyrillic_sha", 0x06db },
+ { "Cyrillic_e", 0x06dc },
+ { "Cyrillic_shcha", 0x06dd },
+ { "Cyrillic_che", 0x06de },
+ { "Cyrillic_hardsign", 0x06df },
+ { "Cyrillic_YU", 0x06e0 },
+ { "Cyrillic_A", 0x06e1 },
+ { "Cyrillic_BE", 0x06e2 },
+ { "Cyrillic_TSE", 0x06e3 },
+ { "Cyrillic_DE", 0x06e4 },
+ { "Cyrillic_IE", 0x06e5 },
+ { "Cyrillic_EF", 0x06e6 },
+ { "Cyrillic_GHE", 0x06e7 },
+ { "Cyrillic_HA", 0x06e8 },
+ { "Cyrillic_I", 0x06e9 },
+ { "Cyrillic_SHORTI", 0x06ea },
+ { "Cyrillic_KA", 0x06eb },
+ { "Cyrillic_EL", 0x06ec },
+ { "Cyrillic_EM", 0x06ed },
+ { "Cyrillic_EN", 0x06ee },
+ { "Cyrillic_O", 0x06ef },
+ { "Cyrillic_PE", 0x06f0 },
+ { "Cyrillic_YA", 0x06f1 },
+ { "Cyrillic_ER", 0x06f2 },
+ { "Cyrillic_ES", 0x06f3 },
+ { "Cyrillic_TE", 0x06f4 },
+ { "Cyrillic_U", 0x06f5 },
+ { "Cyrillic_ZHE", 0x06f6 },
+ { "Cyrillic_VE", 0x06f7 },
+ { "Cyrillic_SOFTSIGN", 0x06f8 },
+ { "Cyrillic_YERU", 0x06f9 },
+ { "Cyrillic_ZE", 0x06fa },
+ { "Cyrillic_SHA", 0x06fb },
+ { "Cyrillic_E", 0x06fc },
+ { "Cyrillic_SHCHA", 0x06fd },
+ { "Cyrillic_CHE", 0x06fe },
+ { "Cyrillic_HARDSIGN", 0x06ff },
+
+ /* Greek */
+ { "Greek_ALPHAaccent", 0x07a1 },
+ { "Greek_EPSILONaccent", 0x07a2 },
+ { "Greek_ETAaccent", 0x07a3 },
+ { "Greek_IOTAaccent", 0x07a4 },
+ { "Greek_IOTAdieresis", 0x07a5 },
+ { "Greek_IOTAdiaeresis", 0x07a5 },
+ { "Greek_OMICRONaccent", 0x07a7 },
+ { "Greek_UPSILONaccent", 0x07a8 },
+ { "Greek_UPSILONdieresis", 0x07a9 },
+ { "Greek_OMEGAaccent", 0x07ab },
+ { "Greek_accentdieresis", 0x07ae },
+ { "Greek_horizbar", 0x07af },
+ { "Greek_alphaaccent", 0x07b1 },
+ { "Greek_epsilonaccent", 0x07b2 },
+ { "Greek_etaaccent", 0x07b3 },
+ { "Greek_iotaaccent", 0x07b4 },
+ { "Greek_iotadieresis", 0x07b5 },
+ { "Greek_iotaaccentdieresis", 0x07b6 },
+ { "Greek_omicronaccent", 0x07b7 },
+ { "Greek_upsilonaccent", 0x07b8 },
+ { "Greek_upsilondieresis", 0x07b9 },
+ { "Greek_upsilonaccentdieresis", 0x07ba },
+ { "Greek_omegaaccent", 0x07bb },
+ { "Greek_ALPHA", 0x07c1 },
+ { "Greek_BETA", 0x07c2 },
+ { "Greek_GAMMA", 0x07c3 },
+ { "Greek_DELTA", 0x07c4 },
+ { "Greek_EPSILON", 0x07c5 },
+ { "Greek_ZETA", 0x07c6 },
+ { "Greek_ETA", 0x07c7 },
+ { "Greek_THETA", 0x07c8 },
+ { "Greek_IOTA", 0x07c9 },
+ { "Greek_KAPPA", 0x07ca },
+ { "Greek_LAMDA", 0x07cb },
+ { "Greek_LAMBDA", 0x07cb },
+ { "Greek_MU", 0x07cc },
+ { "Greek_NU", 0x07cd },
+ { "Greek_XI", 0x07ce },
+ { "Greek_OMICRON", 0x07cf },
+ { "Greek_PI", 0x07d0 },
+ { "Greek_RHO", 0x07d1 },
+ { "Greek_SIGMA", 0x07d2 },
+ { "Greek_TAU", 0x07d4 },
+ { "Greek_UPSILON", 0x07d5 },
+ { "Greek_PHI", 0x07d6 },
+ { "Greek_CHI", 0x07d7 },
+ { "Greek_PSI", 0x07d8 },
+ { "Greek_OMEGA", 0x07d9 },
+ { "Greek_alpha", 0x07e1 },
+ { "Greek_beta", 0x07e2 },
+ { "Greek_gamma", 0x07e3 },
+ { "Greek_delta", 0x07e4 },
+ { "Greek_epsilon", 0x07e5 },
+ { "Greek_zeta", 0x07e6 },
+ { "Greek_eta", 0x07e7 },
+ { "Greek_theta", 0x07e8 },
+ { "Greek_iota", 0x07e9 },
+ { "Greek_kappa", 0x07ea },
+ { "Greek_lamda", 0x07eb },
+ { "Greek_lambda", 0x07eb },
+ { "Greek_mu", 0x07ec },
+ { "Greek_nu", 0x07ed },
+ { "Greek_xi", 0x07ee },
+ { "Greek_omicron", 0x07ef },
+ { "Greek_pi", 0x07f0 },
+ { "Greek_rho", 0x07f1 },
+ { "Greek_sigma", 0x07f2 },
+ { "Greek_finalsmallsigma", 0x07f3 },
+ { "Greek_tau", 0x07f4 },
+ { "Greek_upsilon", 0x07f5 },
+ { "Greek_phi", 0x07f6 },
+ { "Greek_chi", 0x07f7 },
+ { "Greek_psi", 0x07f8 },
+ { "Greek_omega", 0x07f9 },
+ { "Greek_switch", 0xff7e },
+
+ /* technical */
+ { "leftradical", 0x08a1 },
+ { "topleftradical", 0x08a2 },
+ { "horizconnector", 0x08a3 },
+ { "topintegral", 0x08a4 },
+ { "botintegral", 0x08a5 },
+ { "vertconnector", 0x08a6 },
+ { "topleftsqbracket", 0x08a7 },
+ { "botleftsqbracket", 0x08a8 },
+ { "toprightsqbracket", 0x08a9 },
+ { "botrightsqbracket", 0x08aa },
+ { "topleftparens", 0x08ab },
+ { "botleftparens", 0x08ac },
+ { "toprightparens", 0x08ad },
+ { "botrightparens", 0x08ae },
+ { "leftmiddlecurlybrace", 0x08af },
+ { "rightmiddlecurlybrace", 0x08b0 },
+ { "topleftsummation", 0x08b1 },
+ { "botleftsummation", 0x08b2 },
+ { "topvertsummationconnector", 0x08b3 },
+ { "botvertsummationconnector", 0x08b4 },
+ { "toprightsummation", 0x08b5 },
+ { "botrightsummation", 0x08b6 },
+ { "rightmiddlesummation", 0x08b7 },
+ { "lessthanequal", 0x08bc },
+ { "notequal", 0x08bd },
+ { "greaterthanequal", 0x08be },
+ { "integral", 0x08bf },
+ { "therefore", 0x08c0 },
+ { "variation", 0x08c1 },
+ { "infinity", 0x08c2 },
+ { "nabla", 0x08c5 },
+ { "approximate", 0x08c8 },
+ { "similarequal", 0x08c9 },
+ { "ifonlyif", 0x08cd },
+ { "implies", 0x08ce },
+ { "identical", 0x08cf },
+ { "radical", 0x08d6 },
+ { "includedin", 0x08da },
+ { "includes", 0x08db },
+ { "intersection", 0x08dc },
+ { "union", 0x08dd },
+ { "logicaland", 0x08de },
+ { "logicalor", 0x08df },
+ { "partialderivative", 0x08ef },
+ { "function", 0x08f6 },
+ { "leftarrow", 0x08fb },
+ { "uparrow", 0x08fc },
+ { "rightarrow", 0x08fd },
+ { "downarrow", 0x08fe },
+
+ /* publishing */
+ { "emspace", 0x0aa1 },
+ { "enspace", 0x0aa2 },
+ { "em3space", 0x0aa3 },
+ { "em4space", 0x0aa4 },
+ { "digitspace", 0x0aa5 },
+ { "punctspace", 0x0aa6 },
+ { "thinspace", 0x0aa7 },
+ { "hairspace", 0x0aa8 },
+ { "emdash", 0x0aa9 },
+ { "endash", 0x0aaa },
+ { "signifblank", 0x0aac },
+ { "ellipsis", 0x0aae },
+ { "doubbaselinedot", 0x0aaf },
+ { "onethird", 0x0ab0 },
+ { "twothirds", 0x0ab1 },
+ { "onefifth", 0x0ab2 },
+ { "twofifths", 0x0ab3 },
+ { "threefifths", 0x0ab4 },
+ { "fourfifths", 0x0ab5 },
+ { "onesixth", 0x0ab6 },
+ { "fivesixths", 0x0ab7 },
+ { "careof", 0x0ab8 },
+ { "figdash", 0x0abb },
+ { "leftanglebracket", 0x0abc },
+ { "decimalpoint", 0x0abd },
+ { "rightanglebracket", 0x0abe },
+ { "marker", 0x0abf },
+ { "oneeighth", 0x0ac3 },
+ { "threeeighths", 0x0ac4 },
+ { "fiveeighths", 0x0ac5 },
+ { "seveneighths", 0x0ac6 },
+ { "trademark", 0x0ac9 },
+ { "signaturemark", 0x0aca },
+ { "trademarkincircle", 0x0acb },
+ { "leftopentriangle", 0x0acc },
+ { "rightopentriangle", 0x0acd },
+ { "emopencircle", 0x0ace },
+ { "emopenrectangle", 0x0acf },
+ { "leftsinglequotemark", 0x0ad0 },
+ { "rightsinglequotemark", 0x0ad1 },
+ { "leftdoublequotemark", 0x0ad2 },
+ { "rightdoublequotemark", 0x0ad3 },
+ { "prescription", 0x0ad4 },
+ { "minutes", 0x0ad6 },
+ { "seconds", 0x0ad7 },
+ { "latincross", 0x0ad9 },
+ { "hexagram", 0x0ada },
+ { "filledrectbullet", 0x0adb },
+ { "filledlefttribullet", 0x0adc },
+ { "filledrighttribullet", 0x0add },
+ { "emfilledcircle", 0x0ade },
+ { "emfilledrect", 0x0adf },
+ { "enopencircbullet", 0x0ae0 },
+ { "enopensquarebullet", 0x0ae1 },
+ { "openrectbullet", 0x0ae2 },
+ { "opentribulletup", 0x0ae3 },
+ { "opentribulletdown", 0x0ae4 },
+ { "openstar", 0x0ae5 },
+ { "enfilledcircbullet", 0x0ae6 },
+ { "enfilledsqbullet", 0x0ae7 },
+ { "filledtribulletup", 0x0ae8 },
+ { "filledtribulletdown", 0x0ae9 },
+ { "leftpointer", 0x0aea },
+ { "rightpointer", 0x0aeb },
+ { "club", 0x0aec },
+ { "diamond", 0x0aed },
+ { "heart", 0x0aee },
+ { "maltesecross", 0x0af0 },
+ { "dagger", 0x0af1 },
+ { "doubledagger", 0x0af2 },
+ { "checkmark", 0x0af3 },
+ { "ballotcross", 0x0af4 },
+ { "musicalsharp", 0x0af5 },
+ { "musicalflat", 0x0af6 },
+ { "malesymbol", 0x0af7 },
+ { "femalesymbol", 0x0af8 },
+ { "telephone", 0x0af9 },
+ { "telephonerecorder", 0x0afa },
+ { "phonographcopyright", 0x0afb },
+ { "caret", 0x0afc },
+ { "singlelowquotemark", 0x0afd },
+ { "doublelowquotemark", 0x0afe },
+ { "cursor", 0x0aff },
+
+ /* Caucasus */
+ { "Xabovedot", 0x1001e8a },
+ { "Ibreve", 0x100012c },
+ { "Zstroke", 0x10001b5 },
+ { "Gcaron", 0x10001e6 },
+ { "Ocaron", 0x10001d1 },
+ { "Obarred", 0x100019f },
+ { "xabovedot", 0x1001e8b },
+ { "ibreve", 0x100012d },
+ { "zstroke", 0x10001b6 },
+ { "gcaron", 0x10001e7 },
+ { "ocaron", 0x10001d2 },
+ { "obarred", 0x1000275 },
+ { "SCHWA", 0x100018f },
+ { "schwa", 0x1000259 },
+ { "Lbelowdot", 0x1001e36 },
+ { "lbelowdot", 0x1001e37 },
+
+ /* Thai */
+ { "Thai_kokai", 0x0da1 },
+ { "Thai_khokhai", 0x0da2 },
+ { "Thai_khokhuat", 0x0da3 },
+ { "Thai_khokhwai", 0x0da4 },
+ { "Thai_khokhon", 0x0da5 },
+ { "Thai_khorakhang", 0x0da6 },
+ { "Thai_ngongu", 0x0da7 },
+ { "Thai_chochan", 0x0da8 },
+ { "Thai_choching", 0x0da9 },
+ { "Thai_chochang", 0x0daa },
+ { "Thai_soso", 0x0dab },
+ { "Thai_chochoe", 0x0dac },
+ { "Thai_yoying", 0x0dad },
+ { "Thai_dochada", 0x0dae },
+ { "Thai_topatak", 0x0daf },
+ { "Thai_thothan", 0x0db0 },
+ { "Thai_thonangmontho", 0x0db1 },
+ { "Thai_thophuthao", 0x0db2 },
+ { "Thai_nonen", 0x0db3 },
+ { "Thai_dodek", 0x0db4 },
+ { "Thai_totao", 0x0db5 },
+ { "Thai_thothung", 0x0db6 },
+ { "Thai_thothahan", 0x0db7 },
+ { "Thai_thothong", 0x0db8 },
+ { "Thai_nonu", 0x0db9 },
+ { "Thai_bobaimai", 0x0dba },
+ { "Thai_popla", 0x0dbb },
+ { "Thai_phophung", 0x0dbc },
+ { "Thai_fofa", 0x0dbd },
+ { "Thai_phophan", 0x0dbe },
+ { "Thai_fofan", 0x0dbf },
+ { "Thai_phosamphao", 0x0dc0 },
+ { "Thai_moma", 0x0dc1 },
+ { "Thai_yoyak", 0x0dc2 },
+ { "Thai_rorua", 0x0dc3 },
+ { "Thai_ru", 0x0dc4 },
+ { "Thai_loling", 0x0dc5 },
+ { "Thai_lu", 0x0dc6 },
+ { "Thai_wowaen", 0x0dc7 },
+ { "Thai_sosala", 0x0dc8 },
+ { "Thai_sorusi", 0x0dc9 },
+ { "Thai_sosua", 0x0dca },
+ { "Thai_hohip", 0x0dcb },
+ { "Thai_lochula", 0x0dcc },
+ { "Thai_oang", 0x0dcd },
+ { "Thai_honokhuk", 0x0dce },
+ { "Thai_paiyannoi", 0x0dcf },
+ { "Thai_saraa", 0x0dd0 },
+ { "Thai_maihanakat", 0x0dd1 },
+ { "Thai_saraaa", 0x0dd2 },
+ { "Thai_saraam", 0x0dd3 },
+ { "Thai_sarai", 0x0dd4 },
+ { "Thai_saraii", 0x0dd5 },
+ { "Thai_saraue", 0x0dd6 },
+ { "Thai_sarauee", 0x0dd7 },
+ { "Thai_sarau", 0x0dd8 },
+ { "Thai_sarauu", 0x0dd9 },
+ { "Thai_phinthu", 0x0dda },
+ { "Thai_maihanakat_maitho", 0x0dde },
+ { "Thai_baht", 0x0ddf },
+ { "Thai_sarae", 0x0de0 },
+ { "Thai_saraae", 0x0de1 },
+ { "Thai_sarao", 0x0de2 },
+ { "Thai_saraaimaimuan", 0x0de3 },
+ { "Thai_saraaimaimalai", 0x0de4 },
+ { "Thai_lakkhangyao", 0x0de5 },
+ { "Thai_maiyamok", 0x0de6 },
+ { "Thai_maitaikhu", 0x0de7 },
+ { "Thai_maiek", 0x0de8 },
+ { "Thai_maitho", 0x0de9 },
+ { "Thai_maitri", 0x0dea },
+ { "Thai_maichattawa", 0x0deb },
+ { "Thai_thanthakhat", 0x0dec },
+ { "Thai_nikhahit", 0x0ded },
+ { "Thai_leksun", 0x0df0 },
+ { "Thai_leknung", 0x0df1 },
+ { "Thai_leksong", 0x0df2 },
+ { "Thai_leksam", 0x0df3 },
+ { "Thai_leksi", 0x0df4 },
+ { "Thai_lekha", 0x0df5 },
+ { "Thai_lekhok", 0x0df6 },
+ { "Thai_lekchet", 0x0df7 },
+ { "Thai_lekpaet", 0x0df8 },
+ { "Thai_lekkao", 0x0df9 },
+
/* modifiers */
{"Control_L", 0xffe3}, /* XK_Control_L */
{"Control_R", 0xffe4}, /* XK_Control_R */
@@ -339,48 +1116,20 @@ static name2keysym_t name2keysym[]={
{"KP_Multiply", 0xffaa}, /* XK_KP_Multiply */
{"KP_Subtract", 0xffad}, /* XK_KP_Subtract */
{"help", 0xff6a}, /* XK_Help */
+ { "Break", 0xff6b },
{"Menu", 0xff67}, /* XK_Menu */
{"Print", 0xff61}, /* XK_Print */
+ { "Execute", 0xff62 },
{"Mode_switch", 0xff7e}, /* XK_Mode_switch */
{"Num_Lock", 0xff7f}, /* XK_Num_Lock */
{"Pause", 0xff13}, /* XK_Pause */
{"Escape", 0xff1b}, /* XK_Escape */
{"ISO_Left_Tab", 0xfe20},/* XK_ISO_Left_Tab */
+ { "Multi_key", 0xff20 },
+ { "ISO_Next_Group", 0xfe08 },
+ { "ISO_First_Group", 0xfe0c },
+ { "ISO_Last_Group", 0xfe0e },
- /* localized keys */
-{"BackApostrophe", 0xff21},
-{"Muhenkan", 0xff22},
-{"Katakana", 0xff27},
-{"Hankaku", 0xff29},
-{"Zenkaku_Hankaku", 0xff2a},
-{"Henkan_Mode_Real", 0xff23},
-{"Henkan_Mode_Ultra", 0xff3e},
-{"backslash_ja", 0xffa5},
-{"Katakana_Real", 0xff25},
-{"Eisu_toggle", 0xff30},
-
- /* dead keys */
-{"dead_grave", 0xfe50},
-{"dead_acute", 0xfe51},
-{"dead_circumflex", 0xfe52},
-{"dead_tilde", 0xfe53},
-{"dead_macron", 0xfe54},
-{"dead_brev", 0xfe55},
-{"dead_abovedot", 0xfe56},
-{"dead_diaeresis", 0xfe57},
-{"dead_abovering", 0xfe58},
-{"dead_doubleacute", 0xfe59},
-{"dead_caron", 0xfe5a},
-{"dead_cedilla", 0xfe5b},
-{"dead_ogonek", 0xfe5c},
-{"dead_iota", 0xfe5d},
-{"dead_voiced_sound", 0xfe5e},
-{"dead_semivoiced_sound", 0xfe5f},
-{"dead_belowdot", 0xfe60},
-{"dead_hook", 0xfe61},
-{"dead_horn", 0xfe62},
-
-
-{0,0},
+ {0,0},
};
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|