diff options
-rw-r--r-- | curses.c | 89 | ||||
-rw-r--r-- | curses_keys.h | 32 | ||||
-rw-r--r-- | keymaps.c | 60 | ||||
-rw-r--r-- | keymaps.h | 17 | ||||
-rw-r--r-- | sdl.c | 20 | ||||
-rw-r--r-- | vnc.c | 25 |
6 files changed, 149 insertions, 94 deletions
@@ -159,11 +159,10 @@ static void curses_cursor_position(DisplayState *ds, int x, int y) #include "curses_keys.h" static kbd_layout_t *kbd_layout = NULL; -static int keycode2keysym[CURSES_KEYS]; static void curses_refresh(DisplayState *ds) { - int chr, nextchr, keysym, keycode; + int chr, nextchr, keysym, keycode, keycode_alt; if (invalidate) { clear(); @@ -204,43 +203,58 @@ static void curses_refresh(DisplayState *ds) #endif keycode = curses2keycode[chr]; - if (keycode == -1) - continue; + keycode_alt = 0; /* alt key */ if (keycode == 1) { nextchr = getch(); if (nextchr != ERR) { + chr = nextchr; + keycode_alt = ALT; keycode = curses2keycode[nextchr]; nextchr = ERR; - if (keycode == -1) - continue; - keycode |= ALT; + if (keycode != -1) { + keycode |= ALT; - /* process keys reserved for qemu */ - if (keycode >= QEMU_KEY_CONSOLE0 && - keycode < QEMU_KEY_CONSOLE0 + 9) { - erase(); - wnoutrefresh(stdscr); - console_select(keycode - QEMU_KEY_CONSOLE0); + /* process keys reserved for qemu */ + if (keycode >= QEMU_KEY_CONSOLE0 && + keycode < QEMU_KEY_CONSOLE0 + 9) { + erase(); + wnoutrefresh(stdscr); + console_select(keycode - QEMU_KEY_CONSOLE0); - invalidate = 1; - continue; + invalidate = 1; + continue; + } } } } - if (kbd_layout && !(keycode & GREY)) { - keysym = keycode2keysym[keycode & KEY_MASK]; - if (keysym == -1) - keysym = chr; + if (kbd_layout) { + keysym = -1; + if (chr < CURSES_KEYS) + keysym = curses2keysym[chr]; + + if (keysym == -1) { + if (chr < ' ') + keysym = (chr + '@' - 'A' + 'a') | KEYSYM_CNTRL; + else + keysym = chr; + } - keycode &= ~KEY_MASK; - keycode |= keysym2scancode(kbd_layout, keysym); + keycode = keysym2scancode(kbd_layout, keysym & KEYSYM_MASK); + if (keycode == 0) + continue; + + keycode |= (keysym & ~KEYSYM_MASK) >> 16; + keycode |= keycode_alt; } + if (keycode == -1) + continue; + if (is_graphic_console()) { /* since terminals don't know about key press and release * events, we need to emit both for each key received */ @@ -250,12 +264,20 @@ static void curses_refresh(DisplayState *ds) kbd_put_keycode(CNTRL_CODE); if (keycode & ALT) kbd_put_keycode(ALT_CODE); + if (keycode & ALTGR) { + kbd_put_keycode(SCANCODE_EMUL0); + kbd_put_keycode(ALT_CODE); + } if (keycode & GREY) kbd_put_keycode(GREY_CODE); kbd_put_keycode(keycode & KEY_MASK); if (keycode & GREY) kbd_put_keycode(GREY_CODE); kbd_put_keycode((keycode & KEY_MASK) | KEY_RELEASE); + if (keycode & ALTGR) { + kbd_put_keycode(SCANCODE_EMUL0); + kbd_put_keycode(ALT_CODE | KEY_RELEASE); + } if (keycode & ALT) kbd_put_keycode(ALT_CODE | KEY_RELEASE); if (keycode & CNTRL) @@ -263,7 +285,7 @@ static void curses_refresh(DisplayState *ds) if (keycode & SHIFT) kbd_put_keycode(SHIFT_CODE | KEY_RELEASE); } else { - keysym = curses2keysym[chr]; + keysym = curses2qemu[chr]; if (keysym == -1) keysym = chr; @@ -301,8 +323,6 @@ static void curses_setup(void) static void curses_keyboard_setup(void) { - int i, keycode, keysym; - #if defined(__APPLE__) /* always use generic keymaps */ if (!keyboard_layout) @@ -313,27 +333,6 @@ static void curses_keyboard_setup(void) if (!kbd_layout) exit(1); } - - for (i = 0; i < CURSES_KEYS; i ++) - keycode2keysym[i] = -1; - - for (i = 0; i < CURSES_KEYS; i ++) { - if (curses2keycode[i] == -1) - continue; - - keycode = curses2keycode[i] & KEY_MASK; - if (keycode2keysym[keycode] >= 0) - continue; - - for (keysym = 0; keysym < CURSES_KEYS; keysym ++) - if (curses2keycode[keysym] == keycode) { - keycode2keysym[keycode] = keysym; - break; - } - - if (keysym >= CURSES_KEYS) - keycode2keysym[keycode] = i; - } } void curses_display_init(DisplayState *ds, int full_screen) diff --git a/curses_keys.h b/curses_keys.h index 5059d37e00..1decd1119d 100644 --- a/curses_keys.h +++ b/curses_keys.h @@ -28,20 +28,36 @@ #define KEY_RELEASE 0x80 #define KEY_MASK 0x7f -#define SHIFT_CODE 0x2a -#define SHIFT 0x0080 #define GREY_CODE 0xe0 -#define GREY 0x0100 +#define GREY SCANCODE_GREY +#define SHIFT_CODE 0x2a +#define SHIFT SCANCODE_SHIFT #define CNTRL_CODE 0x1d -#define CNTRL 0x0200 +#define CNTRL SCANCODE_CTRL #define ALT_CODE 0x38 -#define ALT 0x0400 +#define ALT SCANCODE_ALT +#define ALTGR SCANCODE_ALTGR + +#define KEYSYM_MASK 0x0ffffff +#define KEYSYM_SHIFT (SCANCODE_SHIFT << 16) +#define KEYSYM_CNTRL (SCANCODE_CTRL << 16) +#define KEYSYM_ALT (SCANCODE_ALT << 16) +#define KEYSYM_ALTGR (SCANCODE_ALTGR << 16) /* curses won't detect a Control + Alt + 1, so use Alt + 1 */ #define QEMU_KEY_CONSOLE0 (2 | ALT) /* (curses2keycode['1'] | ALT) */ #define CURSES_KEYS KEY_MAX /* KEY_MAX defined in <curses.h> */ +static const int curses2keysym[CURSES_KEYS] = { + [0 ... (CURSES_KEYS - 1)] = -1, + + [0x7f] = KEY_BACKSPACE, + ['\r'] = KEY_ENTER, + ['\n'] = KEY_ENTER, + [KEY_BTAB] = '\t' | KEYSYM_SHIFT, +}; + static const int curses2keycode[CURSES_KEYS] = { [0 ... (CURSES_KEYS - 1)] = -1, @@ -225,7 +241,7 @@ static const int curses2keycode[CURSES_KEYS] = { }; -static const int curses2keysym[CURSES_KEYS] = { +static const int curses2qemu[CURSES_KEYS] = { [0 ... (CURSES_KEYS - 1)] = -1, ['\n'] = '\n', @@ -449,9 +465,9 @@ static const name2keysym_t name2keysym[] = { { "ydiaeresis", 0x0ff }, /* Special keys */ - { "BackSpace", 0x07f }, + { "BackSpace", KEY_BACKSPACE }, { "Tab", '\t' }, - { "Return", '\n' }, + { "Return", KEY_ENTER }, { "Right", KEY_RIGHT }, { "Left", KEY_LEFT }, { "Up", KEY_UP }, @@ -59,6 +59,29 @@ static void add_to_key_range(struct key_range **krp, int code) { } } +static void add_keysym(char *line, int keysym, int keycode, kbd_layout_t *k) { + 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++; + } + } +} + static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table, const char *language, kbd_layout_t * k) @@ -111,27 +134,22 @@ static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table, //fprintf(stderr, "keypad 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 (rest && strstr(rest, "shift")) + keycode |= SCANCODE_SHIFT; + if (rest && strstr(rest, "altgr")) + keycode |= SCANCODE_ALTGR; + if (rest && strstr(rest, "ctrl")) + keycode |= SCANCODE_CTRL; + + add_keysym(line, keysym, keycode, k); + + if (rest && strstr(rest, "addupper")) { + char *c; + for (c = line; *c; c++) + *c = toupper(*c); + keysym = get_keysym(table, line); + if (keysym) + add_keysym(line, keysym, keycode | SCANCODE_SHIFT, k); } } } @@ -51,6 +51,23 @@ typedef struct { struct key_range *numlock_range; } kbd_layout_t; +/* scancode without modifiers */ +#define SCANCODE_KEYMASK 0xff +/* scancode without grey or up bit */ +#define SCANCODE_KEYCODEMASK 0x7f + +/* "grey" keys will usually need a 0xe0 prefix */ +#define SCANCODE_GREY 0x80 +#define SCANCODE_EMUL0 0xE0 +/* "up" flag */ +#define SCANCODE_UP 0x80 + +/* Additional modifiers to use if not catched another way. */ +#define SCANCODE_SHIFT 0x100 +#define SCANCODE_CTRL 0x200 +#define SCANCODE_ALT 0x400 +#define SCANCODE_ALTGR 0x800 + void *init_keyboard_layout(const name2keysym_t *table, const char *language); int keysym2scancode(void *kbd_layout, int keysym); @@ -248,7 +248,7 @@ static uint8_t sdl_keyevent_to_keycode_generic(const SDL_KeyboardEvent *ev) if (keysym == 92 && ev->keysym.scancode == 133) { keysym = 0xa5; } - return keysym2scancode(kbd_layout, keysym); + return keysym2scancode(kbd_layout, keysym) & SCANCODE_KEYMASK; } /* specific keyboard conversions from scan codes */ @@ -343,9 +343,9 @@ static void reset_keys(void) int i; for(i = 0; i < 256; i++) { if (modifiers_state[i]) { - if (i & 0x80) - kbd_put_keycode(0xe0); - kbd_put_keycode(i | 0x80); + if (i & SCANCODE_GREY) + kbd_put_keycode(SCANCODE_EMUL0); + kbd_put_keycode(i | SCANCODE_UP); modifiers_state[i] = 0; } } @@ -359,7 +359,7 @@ static void sdl_process_key(SDL_KeyboardEvent *ev) /* specific case */ v = 0; if (ev->type == SDL_KEYUP) - v |= 0x80; + v |= SCANCODE_UP; kbd_put_keycode(0xe1); kbd_put_keycode(0x1d | v); kbd_put_keycode(0x45 | v); @@ -392,17 +392,17 @@ static void sdl_process_key(SDL_KeyboardEvent *ev) case 0x3a: /* caps lock */ /* SDL does not send the key up event, so we generate it */ kbd_put_keycode(keycode); - kbd_put_keycode(keycode | 0x80); + kbd_put_keycode(keycode | SCANCODE_UP); return; } /* now send the key code */ - if (keycode & 0x80) - kbd_put_keycode(0xe0); + if (keycode & SCANCODE_GREY) + kbd_put_keycode(SCANCODE_EMUL0); if (ev->type == SDL_KEYUP) - kbd_put_keycode(keycode | 0x80); + kbd_put_keycode(keycode | SCANCODE_UP); else - kbd_put_keycode(keycode & 0x7f); + kbd_put_keycode(keycode & SCANCODE_KEYCODEMASK); } static void sdl_update_caption(void) @@ -1482,9 +1482,9 @@ 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); + if (i & SCANCODE_GREY) + kbd_put_keycode(SCANCODE_EMUL0); + kbd_put_keycode(i | SCANCODE_UP); vs->modifiers_state[i] = 0; } } @@ -1492,8 +1492,13 @@ static void reset_keys(VncState *vs) static void press_key(VncState *vs, int keysym) { - kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) & 0x7f); - kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) | 0x80); + int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK; + if (keycode & SCANCODE_GREY) + kbd_put_keycode(SCANCODE_EMUL0); + kbd_put_keycode(keycode & SCANCODE_KEYCODEMASK); + if (keycode & SCANCODE_GREY) + kbd_put_keycode(SCANCODE_EMUL0); + kbd_put_keycode(keycode | SCANCODE_UP); } static void do_key_event(VncState *vs, int down, int keycode, int sym) @@ -1566,12 +1571,12 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym) } if (is_graphic_console()) { - if (keycode & 0x80) - kbd_put_keycode(0xe0); + if (keycode & SCANCODE_GREY) + kbd_put_keycode(SCANCODE_EMUL0); if (down) - kbd_put_keycode(keycode & 0x7f); + kbd_put_keycode(keycode & SCANCODE_KEYCODEMASK); else - kbd_put_keycode(keycode | 0x80); + kbd_put_keycode(keycode | SCANCODE_UP); } else { /* QEMU console emulation */ if (down) { @@ -1679,7 +1684,7 @@ static void key_event(VncState *vs, int down, uint32_t sym) lsym = lsym - 'A' + 'a'; } - keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF); + keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK; do_key_event(vs, down, keycode, sym); } |