John Haxby
2008-Nov-14 17:31 UTC
[Xen-devel] [PATCH 1 of 2] Fix keymap handling for vnc console
Fix keymap handling for international keyboards. Signed-off-by: John Haxby <john.haxby@oracle.com> 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@lists.xensource.com http://lists.xensource.com/xen-devel