|
|
1.1 ! root 1: /* ! 2: * QEMU keysym to keycode conversion using rdesktop keymaps ! 3: * ! 4: * Copyright (c) 2004 Johannes Schindelin ! 5: * ! 6: * Permission is hereby granted, free of charge, to any person obtaining a copy ! 7: * of this software and associated documentation files (the "Software"), to deal ! 8: * in the Software without restriction, including without limitation the rights ! 9: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ! 10: * copies of the Software, and to permit persons to whom the Software is ! 11: * furnished to do so, subject to the following conditions: ! 12: * ! 13: * The above copyright notice and this permission notice shall be included in ! 14: * all copies or substantial portions of the Software. ! 15: * ! 16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ! 17: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ! 19: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ! 20: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ! 21: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ! 22: * THE SOFTWARE. ! 23: */ ! 24: ! 25: #include "keymaps.h" ! 26: #include "sysemu.h" ! 27: ! 28: static int get_keysym(const name2keysym_t *table, ! 29: const char *name) ! 30: { ! 31: const name2keysym_t *p; ! 32: for(p = table; p->name != NULL; p++) { ! 33: if (!strcmp(p->name, name)) ! 34: return p->keysym; ! 35: } ! 36: return 0; ! 37: } ! 38: ! 39: ! 40: static void add_to_key_range(struct key_range **krp, int code) { ! 41: struct key_range *kr; ! 42: for (kr = *krp; kr; kr = kr->next) { ! 43: if (code >= kr->start && code <= kr->end) ! 44: break; ! 45: if (code == kr->start - 1) { ! 46: kr->start--; ! 47: break; ! 48: } ! 49: if (code == kr->end + 1) { ! 50: kr->end++; ! 51: break; ! 52: } ! 53: } ! 54: if (kr == NULL) { ! 55: kr = qemu_mallocz(sizeof(*kr)); ! 56: kr->start = kr->end = code; ! 57: kr->next = *krp; ! 58: *krp = kr; ! 59: } ! 60: } ! 61: ! 62: static void add_keysym(char *line, int keysym, int keycode, kbd_layout_t *k) { ! 63: if (keysym < MAX_NORMAL_KEYCODE) { ! 64: //fprintf(stderr,"Setting keysym %s (%d) to %d\n",line,keysym,keycode); ! 65: k->keysym2keycode[keysym] = keycode; ! 66: } else { ! 67: if (k->extra_count >= MAX_EXTRA_COUNT) { ! 68: fprintf(stderr, ! 69: "Warning: Could not assign keysym %s (0x%x) because of memory constraints.\n", ! 70: line, keysym); ! 71: } else { ! 72: #if 0 ! 73: fprintf(stderr, "Setting %d: %d,%d\n", ! 74: k->extra_count, keysym, keycode); ! 75: #endif ! 76: k->keysym2keycode_extra[k->extra_count]. ! 77: keysym = keysym; ! 78: k->keysym2keycode_extra[k->extra_count]. ! 79: keycode = keycode; ! 80: k->extra_count++; ! 81: } ! 82: } ! 83: } ! 84: ! 85: static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table, ! 86: const char *language, ! 87: kbd_layout_t * k) ! 88: { ! 89: FILE *f; ! 90: char * filename; ! 91: char line[1024]; ! 92: int len; ! 93: ! 94: filename = qemu_find_file(QEMU_FILE_TYPE_KEYMAP, language); ! 95: ! 96: if (!k) ! 97: k = qemu_mallocz(sizeof(kbd_layout_t)); ! 98: if (!(filename && (f = fopen(filename, "r")))) { ! 99: fprintf(stderr, ! 100: "Could not read keymap file: '%s'\n", language); ! 101: return NULL; ! 102: } ! 103: qemu_free(filename); ! 104: for(;;) { ! 105: if (fgets(line, 1024, f) == NULL) ! 106: break; ! 107: len = strlen(line); ! 108: if (len > 0 && line[len - 1] == '\n') ! 109: line[len - 1] = '\0'; ! 110: if (line[0] == '#') ! 111: continue; ! 112: if (!strncmp(line, "map ", 4)) ! 113: continue; ! 114: if (!strncmp(line, "include ", 8)) { ! 115: parse_keyboard_layout(table, line + 8, k); ! 116: } else { ! 117: char *end_of_keysym = line; ! 118: while (*end_of_keysym != 0 && *end_of_keysym != ' ') ! 119: end_of_keysym++; ! 120: if (*end_of_keysym) { ! 121: int keysym; ! 122: *end_of_keysym = 0; ! 123: keysym = get_keysym(table, line); ! 124: if (keysym == 0) { ! 125: // fprintf(stderr, "Warning: unknown keysym %s\n", line); ! 126: } else { ! 127: const char *rest = end_of_keysym + 1; ! 128: char *rest2; ! 129: int keycode = strtol(rest, &rest2, 0); ! 130: ! 131: if (rest && strstr(rest, "numlock")) { ! 132: add_to_key_range(&k->keypad_range, keycode); ! 133: add_to_key_range(&k->numlock_range, keysym); ! 134: //fprintf(stderr, "keypad keysym %04x keycode %d\n", keysym, keycode); ! 135: } ! 136: ! 137: if (rest && strstr(rest, "shift")) ! 138: keycode |= SCANCODE_SHIFT; ! 139: if (rest && strstr(rest, "altgr")) ! 140: keycode |= SCANCODE_ALTGR; ! 141: if (rest && strstr(rest, "ctrl")) ! 142: keycode |= SCANCODE_CTRL; ! 143: ! 144: add_keysym(line, keysym, keycode, k); ! 145: ! 146: if (rest && strstr(rest, "addupper")) { ! 147: char *c; ! 148: for (c = line; *c; c++) ! 149: *c = toupper(*c); ! 150: keysym = get_keysym(table, line); ! 151: if (keysym) ! 152: add_keysym(line, keysym, keycode | SCANCODE_SHIFT, k); ! 153: } ! 154: } ! 155: } ! 156: } ! 157: } ! 158: fclose(f); ! 159: return k; ! 160: } ! 161: ! 162: ! 163: void *init_keyboard_layout(const name2keysym_t *table, const char *language) ! 164: { ! 165: return parse_keyboard_layout(table, language, NULL); ! 166: } ! 167: ! 168: ! 169: int keysym2scancode(void *kbd_layout, int keysym) ! 170: { ! 171: kbd_layout_t *k = kbd_layout; ! 172: if (keysym < MAX_NORMAL_KEYCODE) { ! 173: if (k->keysym2keycode[keysym] == 0) ! 174: fprintf(stderr, "Warning: no scancode found for keysym %d\n", ! 175: keysym); ! 176: return k->keysym2keycode[keysym]; ! 177: } else { ! 178: int i; ! 179: #ifdef XK_ISO_Left_Tab ! 180: if (keysym == XK_ISO_Left_Tab) ! 181: keysym = XK_Tab; ! 182: #endif ! 183: for (i = 0; i < k->extra_count; i++) ! 184: if (k->keysym2keycode_extra[i].keysym == keysym) ! 185: return k->keysym2keycode_extra[i].keycode; ! 186: } ! 187: return 0; ! 188: } ! 189: ! 190: int keycode_is_keypad(void *kbd_layout, int keycode) ! 191: { ! 192: kbd_layout_t *k = kbd_layout; ! 193: struct key_range *kr; ! 194: ! 195: for (kr = k->keypad_range; kr; kr = kr->next) ! 196: if (keycode >= kr->start && keycode <= kr->end) ! 197: return 1; ! 198: return 0; ! 199: } ! 200: ! 201: int keysym_is_numlock(void *kbd_layout, int keysym) ! 202: { ! 203: kbd_layout_t *k = kbd_layout; ! 204: struct key_range *kr; ! 205: ! 206: for (kr = k->numlock_range; kr; kr = kr->next) ! 207: if (keysym >= kr->start && keysym <= kr->end) ! 208: return 1; ! 209: return 0; ! 210: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.