aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--curses.c89
-rw-r--r--curses_keys.h32
-rw-r--r--keymaps.c60
-rw-r--r--keymaps.h17
-rw-r--r--sdl.c20
-rw-r--r--vnc.c25
6 files changed, 149 insertions, 94 deletions
diff --git a/curses.c b/curses.c
index 3ce12b9237..4b5beac1dc 100644
--- a/curses.c
+++ b/curses.c
@@ -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 },
diff --git a/keymaps.c b/keymaps.c
index 668556298a..78c7ea375c 100644
--- a/keymaps.c
+++ b/keymaps.c
@@ -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);
}
}
}
diff --git a/keymaps.h b/keymaps.h
index 17f6efdb6e..a7600d5751 100644
--- a/keymaps.h
+++ b/keymaps.h
@@ -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);
diff --git a/sdl.c b/sdl.c
index a9b4323900..f26035c8ce 100644
--- a/sdl.c
+++ b/sdl.c
@@ -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)
diff --git a/vnc.c b/vnc.c
index db34b0e2a8..01353a96c8 100644
--- a/vnc.c
+++ b/vnc.c
@@ -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);
}