direct-io.hg

annotate tools/ioemu/keymaps.c @ 12730:897bb9b7ed06

Tidy.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author Ewan Mellor <ewan@xensource.com>
date Mon Dec 04 18:05:32 2006 +0000 (2006-12-04)
parents c7f4a89eb054
children 00618037d37d
rev   line source
chris@10673 1 /*
chris@10673 2 * QEMU keysym to keycode conversion using rdesktop keymaps
chris@10673 3 *
chris@10673 4 * Copyright (c) 2004 Johannes Schindelin
chris@10673 5 *
chris@10673 6 * Permission is hereby granted, free of charge, to any person obtaining a copy
chris@10673 7 * of this software and associated documentation files (the "Software"), to deal
chris@10673 8 * in the Software without restriction, including without limitation the rights
chris@10673 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
chris@10673 10 * copies of the Software, and to permit persons to whom the Software is
chris@10673 11 * furnished to do so, subject to the following conditions:
chris@10673 12 *
chris@10673 13 * The above copyright notice and this permission notice shall be included in
chris@10673 14 * all copies or substantial portions of the Software.
chris@10673 15 *
chris@10673 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
chris@10673 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
chris@10673 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
chris@10673 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
chris@10673 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
chris@10673 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
chris@10673 22 * THE SOFTWARE.
chris@10673 23 */
chris@10673 24
chris@10673 25 static int get_keysym(const char *name)
chris@10673 26 {
chris@10673 27 name2keysym_t *p;
chris@10673 28 for(p = name2keysym; p->name != NULL; p++) {
chris@10673 29 if (!strcmp(p->name, name))
chris@10673 30 return p->keysym;
chris@10673 31 }
chris@10673 32 return 0;
chris@10673 33 }
chris@10673 34
chris@10673 35 #define MAX_NORMAL_KEYCODE 512
chris@10673 36 #define MAX_EXTRA_COUNT 256
chris@10673 37 typedef struct {
chris@10673 38 uint16_t keysym2keycode[MAX_NORMAL_KEYCODE];
ewan@12729 39 int keysym2numlock[MAX_NORMAL_KEYCODE];
chris@10673 40 struct {
chris@10673 41 int keysym;
ewan@12729 42 int numlock;
chris@10673 43 uint16_t keycode;
chris@10673 44 } keysym2keycode_extra[MAX_EXTRA_COUNT];
chris@10673 45 int extra_count;
chris@10673 46 } kbd_layout_t;
chris@10673 47
chris@10673 48 static kbd_layout_t *parse_keyboard_layout(const char *language,
chris@10673 49 kbd_layout_t * k)
chris@10673 50 {
chris@10673 51 FILE *f;
chris@10673 52 char file_name[1024];
chris@10673 53 char line[1024];
chris@10673 54 int len;
ewan@12729 55 int *keycode2numlock;
ewan@12729 56 int i;
chris@10673 57
chris@10673 58 snprintf(file_name, sizeof(file_name),
chris@10673 59 "%s/keymaps/%s", bios_dir, language);
chris@10673 60
chris@10673 61 if (!k)
chris@10673 62 k = qemu_mallocz(sizeof(kbd_layout_t));
chris@10673 63 if (!k)
chris@10673 64 return 0;
chris@10673 65 if (!(f = fopen(file_name, "r"))) {
chris@10673 66 fprintf(stderr,
chris@10673 67 "Could not read keymap file: '%s'\n", file_name);
chris@10673 68 return 0;
chris@10673 69 }
ewan@12729 70
ewan@12729 71 /* Allocate a temporary map tracking which keycodes change when numlock is
ewan@12729 72 set. Keycodes are 16 bit, so 65536 is safe. */
ewan@12729 73 keycode2numlock = malloc(65536 * sizeof(int));
ewan@12729 74 if (!keycode2numlock) {
ewan@12729 75 perror("Could not read keymap file");
ewan@12729 76 return 0;
ewan@12729 77 }
ewan@12729 78
chris@10673 79 for(;;) {
chris@10673 80 if (fgets(line, 1024, f) == NULL)
chris@10673 81 break;
chris@10673 82 len = strlen(line);
chris@10673 83 if (len > 0 && line[len - 1] == '\n')
chris@10673 84 line[len - 1] = '\0';
chris@10673 85 if (line[0] == '#')
chris@10673 86 continue;
chris@10673 87 if (!strncmp(line, "map ", 4))
chris@10673 88 continue;
chris@10673 89 if (!strncmp(line, "include ", 8)) {
chris@10673 90 parse_keyboard_layout(line + 8, k);
chris@10673 91 } else {
chris@10673 92 char *end_of_keysym = line;
chris@10673 93 while (*end_of_keysym != 0 && *end_of_keysym != ' ')
chris@10673 94 end_of_keysym++;
chris@10673 95 if (*end_of_keysym) {
chris@10673 96 int keysym;
chris@10673 97 *end_of_keysym = 0;
chris@10673 98 keysym = get_keysym(line);
chris@10673 99 if (keysym == 0) {
chris@10673 100 // fprintf(stderr, "Warning: unknown keysym %s\n", line);
chris@10673 101 } else {
ewan@12729 102 char *rest = end_of_keysym + 1;
ewan@12729 103 int keycode = strtol(rest, &rest, 0);
ewan@12729 104 int numlock = (rest != NULL &&
ewan@12729 105 strstr(rest, "numlock") != NULL);
ewan@12729 106
ewan@12729 107 keycode2numlock[keycode] = numlock;
ewan@12729 108
chris@10673 109 /* if(keycode&0x80)
chris@10673 110 keycode=(keycode<<8)^0x80e0; */
chris@10673 111 if (keysym < MAX_NORMAL_KEYCODE) {
chris@10673 112 //fprintf(stderr,"Setting keysym %s (%d) to %d\n",line,keysym,keycode);
chris@10673 113 k->keysym2keycode[keysym] = keycode;
ewan@12729 114 k->keysym2numlock[keysym] = numlock;
chris@10673 115 } else {
chris@10673 116 if (k->extra_count >= MAX_EXTRA_COUNT) {
chris@10673 117 fprintf(stderr,
chris@10673 118 "Warning: Could not assign keysym %s (0x%x) because of memory constraints.\n",
chris@10673 119 line, keysym);
chris@10673 120 } else {
chris@10673 121 #if 0
chris@10673 122 fprintf(stderr, "Setting %d: %d,%d\n",
chris@10673 123 k->extra_count, keysym, keycode);
chris@10673 124 #endif
chris@10673 125 k->keysym2keycode_extra[k->extra_count].
chris@10673 126 keysym = keysym;
chris@10673 127 k->keysym2keycode_extra[k->extra_count].
chris@10673 128 keycode = keycode;
ewan@12729 129 k->keysym2keycode_extra[k->extra_count].
ewan@12729 130 numlock = numlock;
chris@10673 131 k->extra_count++;
chris@10673 132 }
chris@10673 133 }
chris@10673 134 }
chris@10673 135 }
chris@10673 136 }
chris@10673 137 }
chris@10673 138 fclose(f);
ewan@12729 139
ewan@12730 140 for (i = 0; i < MAX_NORMAL_KEYCODE; i++) {
ewan@12729 141 if (k->keysym2numlock[i] != 1) {
ewan@12729 142 k->keysym2numlock[i] = -keycode2numlock[k->keysym2keycode[i]];
ewan@12729 143 }
ewan@12729 144 }
ewan@12729 145
ewan@12730 146 for (i = 0; i < k->extra_count; i++) {
ewan@12729 147 if (k->keysym2keycode_extra[i].numlock != 1) {
ewan@12729 148 k->keysym2keycode_extra[i].numlock =
ewan@12729 149 -keycode2numlock[k->keysym2keycode_extra[i].keycode];
ewan@12729 150 }
ewan@12729 151 }
ewan@12729 152
ewan@12729 153 free(keycode2numlock);
ewan@12729 154
chris@10673 155 return k;
chris@10673 156 }
chris@10673 157
chris@10673 158 static void *init_keyboard_layout(const char *language)
chris@10673 159 {
chris@10673 160 return parse_keyboard_layout(language, 0);
chris@10673 161 }
chris@10673 162
chris@10673 163 static int keysym2scancode(void *kbd_layout, int keysym)
chris@10673 164 {
chris@10673 165 kbd_layout_t *k = kbd_layout;
chris@10673 166 if (keysym < MAX_NORMAL_KEYCODE) {
chris@10673 167 if (k->keysym2keycode[keysym] == 0)
chris@10673 168 fprintf(stderr, "Warning: no scancode found for keysym %d\n",
chris@10673 169 keysym);
chris@10673 170 return k->keysym2keycode[keysym];
chris@10673 171 } else {
chris@10673 172 int i;
chris@10673 173 #ifdef XK_ISO_Left_Tab
chris@10673 174 if (keysym == XK_ISO_Left_Tab)
chris@10673 175 keysym = XK_Tab;
chris@10673 176 #endif
chris@10673 177 for (i = 0; i < k->extra_count; i++)
chris@10673 178 if (k->keysym2keycode_extra[i].keysym == keysym)
chris@10673 179 return k->keysym2keycode_extra[i].keycode;
chris@10673 180 }
chris@10673 181 return 0;
chris@10673 182 }
ewan@12729 183
ewan@12729 184 /**
ewan@12729 185 * Returns 1 if the given keysym requires numlock to be pressed, -1 if it
ewan@12729 186 * requires it to be cleared, and 0 otherwise.
ewan@12729 187 */
ewan@12729 188 static int keysym2numlock(void *kbd_layout, int keysym)
ewan@12729 189 {
ewan@12729 190 kbd_layout_t *k = kbd_layout;
ewan@12729 191 if (keysym < MAX_NORMAL_KEYCODE) {
ewan@12729 192 return k->keysym2numlock[keysym];
ewan@12729 193 } else {
ewan@12729 194 int i;
ewan@12729 195 #ifdef XK_ISO_Left_Tab
ewan@12729 196 if (keysym == XK_ISO_Left_Tab)
ewan@12729 197 keysym = XK_Tab;
ewan@12729 198 #endif
ewan@12729 199 for (i = 0; i < k->extra_count; i++)
ewan@12729 200 if (k->keysym2keycode_extra[i].keysym == keysym)
ewan@12729 201 return k->keysym2keycode_extra[i].numlock;
ewan@12729 202 }
ewan@12729 203 return 0;
ewan@12729 204 }