qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] Fix curses interaction with keymaps
@ 2010-02-28 20:03 Samuel Thibault
  2010-02-28 20:13 ` [Qemu-devel] " Samuel Thibault
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Samuel Thibault @ 2010-02-28 20:03 UTC (permalink / raw)
  To: qemu-devel

Hello,

The combination of keymap support (-k option) and curses is currently
very broken.  The patch below fixes it by first extending keymap support
to interpret the shift, ctrl, altgr and addupper keywords in keymaps,
and to fix curses into properly using keymaps.

Samuel

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>

commit 36f0635cb65e1735a7e231d609da98efcda756c5
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Sun Feb 28 20:48:39 2010 +0100

    Fix curses with -k option

diff --git a/curses.c b/curses.c
index 3ce12b9..4b5beac 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 9c1aa7f..36b8b9b 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 6685562..78c7ea3 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 17f6efd..a7600d5 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 a9b4323..f26035c 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 db34b0e..01353a9 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);
 }
 

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [Qemu-devel] Re: [PATCH] Fix curses interaction with keymaps
  2010-02-28 20:03 [Qemu-devel] [PATCH] Fix curses interaction with keymaps Samuel Thibault
@ 2010-02-28 20:13 ` Samuel Thibault
  2010-03-06 22:20 ` [Qemu-devel] " Aurelien Jarno
  2010-03-28 18:39 ` [Qemu-devel] [PATCH] baum: add destroy hook Samuel Thibault
  2 siblings, 0 replies; 5+ messages in thread
From: Samuel Thibault @ 2010-02-28 20:13 UTC (permalink / raw)
  To: qemu-devel

Samuel Thibault, le Sun 28 Feb 2010 21:03:00 +0100, a écrit :
> The combination of keymap support (-k option) and curses is currently
> very broken.  The patch below fixes it by first extending keymap support
> to interpret the shift, ctrl, altgr and addupper keywords in keymaps,
> and to fix curses into properly using keymaps.

(to be applied on top of the two others)

Samuel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH] Fix curses interaction with keymaps
  2010-02-28 20:03 [Qemu-devel] [PATCH] Fix curses interaction with keymaps Samuel Thibault
  2010-02-28 20:13 ` [Qemu-devel] " Samuel Thibault
@ 2010-03-06 22:20 ` Aurelien Jarno
  2010-03-28 18:39 ` [Qemu-devel] [PATCH] baum: add destroy hook Samuel Thibault
  2 siblings, 0 replies; 5+ messages in thread
From: Aurelien Jarno @ 2010-03-06 22:20 UTC (permalink / raw)
  To: Samuel Thibault; +Cc: qemu-devel

On Sun, Feb 28, 2010 at 09:03:00PM +0100, Samuel Thibault wrote:
> Hello,
> 
> The combination of keymap support (-k option) and curses is currently
> very broken.  The patch below fixes it by first extending keymap support
> to interpret the shift, ctrl, altgr and addupper keywords in keymaps,
> and to fix curses into properly using keymaps.
> 
> Samuel
> 
> Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
> 
> commit 36f0635cb65e1735a7e231d609da98efcda756c5
> Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
> Date:   Sun Feb 28 20:48:39 2010 +0100
> 
>     Fix curses with -k option

Thanks, applied.

> diff --git a/curses.c b/curses.c
> index 3ce12b9..4b5beac 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 9c1aa7f..36b8b9b 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 6685562..78c7ea3 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 17f6efd..a7600d5 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 a9b4323..f26035c 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 db34b0e..01353a9 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);
>  }
>  
> 
> 
> 

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Qemu-devel] [PATCH] baum: add destroy hook
  2010-02-28 20:03 [Qemu-devel] [PATCH] Fix curses interaction with keymaps Samuel Thibault
  2010-02-28 20:13 ` [Qemu-devel] " Samuel Thibault
  2010-03-06 22:20 ` [Qemu-devel] " Aurelien Jarno
@ 2010-03-28 18:39 ` Samuel Thibault
  2010-04-08 19:17   ` Aurelien Jarno
  2 siblings, 1 reply; 5+ messages in thread
From: Samuel Thibault @ 2010-03-28 18:39 UTC (permalink / raw)
  To: qemu-devel

Hello,

This adds a destroy hook for the baum character device, to properly
close the BrlAPI connection and free resources.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
 
commit 447c41758cfda0022ea6e09aaf81137b2b27b915
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Sun Mar 28 20:38:38 2010 +0200

    baum: add destroy hook
    
    Add a destroy hook for the baum character device, to properly close the BrlAPI
    connection.

diff --git a/hw/baum.c b/hw/baum.c
index 18633f4..21326ae 100644
--- a/hw/baum.c
+++ b/hw/baum.c
@@ -564,6 +564,18 @@ static void baum_chr_read(void *opaque)
     }
 }
 
+static void baum_close(struct CharDriverState *chr)
+{
+    BaumDriverState *baum = chr->opaque;
+
+    qemu_free_timer(baum->cellCount_timer);
+    if (baum->brlapi) {
+        brlapi__closeConnection(baum->brlapi);
+        qemu_free(baum->brlapi);
+    }
+    qemu_free(baum);
+}
+
 CharDriverState *chr_baum_init(QemuOpts *opts)
 {
     BaumDriverState *baum;
@@ -581,6 +593,7 @@ CharDriverState *chr_baum_init(QemuOpts *opts)
     chr->chr_write = baum_write;
     chr->chr_send_event = baum_send_event;
     chr->chr_accept_input = baum_accept_input;
+    chr->chr_close = baum_close;
 
     handle = qemu_mallocz(brlapi_getHandleSize());
     baum->brlapi = handle;

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH] baum: add destroy hook
  2010-03-28 18:39 ` [Qemu-devel] [PATCH] baum: add destroy hook Samuel Thibault
@ 2010-04-08 19:17   ` Aurelien Jarno
  0 siblings, 0 replies; 5+ messages in thread
From: Aurelien Jarno @ 2010-04-08 19:17 UTC (permalink / raw)
  To: Samuel Thibault; +Cc: qemu-devel

On Sun, Mar 28, 2010 at 08:39:42PM +0200, Samuel Thibault wrote:
> Hello,
> 
> This adds a destroy hook for the baum character device, to properly
> close the BrlAPI connection and free resources.
> 
> Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>

Thanks, applied.

> commit 447c41758cfda0022ea6e09aaf81137b2b27b915
> Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
> Date:   Sun Mar 28 20:38:38 2010 +0200
> 
>     baum: add destroy hook
>     
>     Add a destroy hook for the baum character device, to properly close the BrlAPI
>     connection.
> 
> diff --git a/hw/baum.c b/hw/baum.c
> index 18633f4..21326ae 100644
> --- a/hw/baum.c
> +++ b/hw/baum.c
> @@ -564,6 +564,18 @@ static void baum_chr_read(void *opaque)
>      }
>  }
>  
> +static void baum_close(struct CharDriverState *chr)
> +{
> +    BaumDriverState *baum = chr->opaque;
> +
> +    qemu_free_timer(baum->cellCount_timer);
> +    if (baum->brlapi) {
> +        brlapi__closeConnection(baum->brlapi);
> +        qemu_free(baum->brlapi);
> +    }
> +    qemu_free(baum);
> +}
> +
>  CharDriverState *chr_baum_init(QemuOpts *opts)
>  {
>      BaumDriverState *baum;
> @@ -581,6 +593,7 @@ CharDriverState *chr_baum_init(QemuOpts *opts)
>      chr->chr_write = baum_write;
>      chr->chr_send_event = baum_send_event;
>      chr->chr_accept_input = baum_accept_input;
> +    chr->chr_close = baum_close;
>  
>      handle = qemu_mallocz(brlapi_getHandleSize());
>      baum->brlapi = handle;
> 
> 
> 

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-04-08 21:51 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-28 20:03 [Qemu-devel] [PATCH] Fix curses interaction with keymaps Samuel Thibault
2010-02-28 20:13 ` [Qemu-devel] " Samuel Thibault
2010-03-06 22:20 ` [Qemu-devel] " Aurelien Jarno
2010-03-28 18:39 ` [Qemu-devel] [PATCH] baum: add destroy hook Samuel Thibault
2010-04-08 19:17   ` Aurelien Jarno

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).