ia64/xen-unstable

changeset 15075:dfbbb4d3b0dd

[qemu] Fix keypad handling for VNC.

Signed-off-by: Christian Limpach <Christian.Limpach@xensource.com>
author Christian Limpach <Christian.Limpach@xensource.com>
date Thu May 10 19:33:05 2007 +0100 (2007-05-10)
parents 23c4790512db
children 16319e70f77d
files tools/ioemu/keymaps.c tools/ioemu/vnc.c tools/ioemu/vnc_keysym.h
line diff
     1.1 --- a/tools/ioemu/keymaps.c	Thu May 10 18:02:55 2007 +0100
     1.2 +++ b/tools/ioemu/keymaps.c	Thu May 10 19:33:05 2007 +0100
     1.3 @@ -32,6 +32,12 @@ static int get_keysym(const char *name)
     1.4      return 0;
     1.5  }
     1.6  
     1.7 +struct key_range {
     1.8 +    int start;
     1.9 +    int end;
    1.10 +    struct key_range *next;
    1.11 +};
    1.12 +
    1.13  #define MAX_NORMAL_KEYCODE 512
    1.14  #define MAX_EXTRA_COUNT 256
    1.15  typedef struct {
    1.16 @@ -41,8 +47,34 @@ typedef struct {
    1.17  	uint16_t keycode;
    1.18      } keysym2keycode_extra[MAX_EXTRA_COUNT];
    1.19      int extra_count;
    1.20 +    struct key_range *keypad_range;
    1.21 +    struct key_range *numlock_range;
    1.22  } kbd_layout_t;
    1.23  
    1.24 +static void add_to_key_range(struct key_range **krp, int code) {
    1.25 +    struct key_range *kr;
    1.26 +    for (kr = *krp; kr; kr = kr->next) {
    1.27 +	if (code >= kr->start && code <= kr->end)
    1.28 +	    break;
    1.29 +	if (code == kr->start - 1) {
    1.30 +	    kr->start--;
    1.31 +	    break;
    1.32 +	}
    1.33 +	if (code == kr->end + 1) {
    1.34 +	    kr->end++;
    1.35 +	    break;
    1.36 +	}
    1.37 +    }
    1.38 +    if (kr == NULL) {
    1.39 +	kr = qemu_mallocz(sizeof(*kr));
    1.40 +	if (kr) {
    1.41 +	    kr->start = kr->end = code;
    1.42 +	    kr->next = *krp;
    1.43 +	    *krp = kr;
    1.44 +	}
    1.45 +    }
    1.46 +}
    1.47 +
    1.48  static kbd_layout_t *parse_keyboard_layout(const char *language,
    1.49  					   kbd_layout_t * k)
    1.50  {
    1.51 @@ -87,7 +119,15 @@ static kbd_layout_t *parse_keyboard_layo
    1.52                      //		    fprintf(stderr, "Warning: unknown keysym %s\n", line);
    1.53  		} else {
    1.54  		    const char *rest = end_of_keysym + 1;
    1.55 -		    int keycode = strtol(rest, NULL, 0);
    1.56 +		    char *rest2;
    1.57 +		    int keycode = strtol(rest, &rest2, 0);
    1.58 +
    1.59 +		    if (rest && strstr(rest, "numlock")) {
    1.60 +			add_to_key_range(&k->keypad_range, keycode);
    1.61 +			add_to_key_range(&k->numlock_range, keysym);
    1.62 +			fprintf(stderr, "keypad keysym %04x keycode %d\n", keysym, keycode);
    1.63 +		    }
    1.64 +
    1.65  		    /* if(keycode&0x80)
    1.66  		       keycode=(keycode<<8)^0x80e0; */
    1.67  		    if (keysym < MAX_NORMAL_KEYCODE) {
    1.68 @@ -143,3 +183,25 @@ static int keysym2scancode(void *kbd_lay
    1.69      }
    1.70      return 0;
    1.71  }
    1.72 +
    1.73 +static int keycodeIsKeypad(void *kbd_layout, int keycode)
    1.74 +{
    1.75 +    kbd_layout_t *k = kbd_layout;
    1.76 +    struct key_range *kr;
    1.77 +
    1.78 +    for (kr = k->keypad_range; kr; kr = kr->next)
    1.79 +	if (keycode >= kr->start && keycode <= kr->end)
    1.80 +	    return 1;
    1.81 +    return 0;
    1.82 +}
    1.83 +
    1.84 +static int keysymIsNumlock(void *kbd_layout, int keysym)
    1.85 +{
    1.86 +    kbd_layout_t *k = kbd_layout;
    1.87 +    struct key_range *kr;
    1.88 +
    1.89 +    for (kr = k->numlock_range; kr; kr = kr->next)
    1.90 +	if (keysym >= kr->start && keysym <= kr->end)
    1.91 +	    return 1;
    1.92 +    return 0;
    1.93 +}
     2.1 --- a/tools/ioemu/vnc.c	Thu May 10 18:02:55 2007 +0100
     2.2 +++ b/tools/ioemu/vnc.c	Thu May 10 19:33:05 2007 +0100
     2.3 @@ -909,6 +909,12 @@ static void reset_keys(VncState *vs)
     2.4      }
     2.5  }
     2.6  
     2.7 +static void press_key(VncState *vs, int keysym)
     2.8 +{
     2.9 +    kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) & 0x7f);
    2.10 +    kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
    2.11 +}
    2.12 +
    2.13  static void do_key_event(VncState *vs, int down, uint32_t sym)
    2.14  {
    2.15      int keycode;
    2.16 @@ -936,6 +942,28 @@ static void do_key_event(VncState *vs, i
    2.17              return;
    2.18          }
    2.19          break;
    2.20 +    case 0x45:			/* NumLock */
    2.21 +	if (!down)
    2.22 +	    vs->modifiers_state[keycode] ^= 1;
    2.23 +	break;
    2.24 +    }
    2.25 +
    2.26 +    if (keycodeIsKeypad(vs->kbd_layout, keycode)) {
    2.27 +        /* If the numlock state needs to change then simulate an additional
    2.28 +           keypress before sending this one.  This will happen if the user
    2.29 +           toggles numlock away from the VNC window.
    2.30 +        */
    2.31 +        if (keysymIsNumlock(vs->kbd_layout, sym & 0xFFFF)) {
    2.32 +	    if (!vs->modifiers_state[0x45]) {
    2.33 +		vs->modifiers_state[0x45] = 1;
    2.34 +		press_key(vs, 0xff7f);
    2.35 +	    }
    2.36 +	} else {
    2.37 +	    if (vs->modifiers_state[0x45]) {
    2.38 +		vs->modifiers_state[0x45] = 0;
    2.39 +		press_key(vs, 0xff7f);
    2.40 +	    }
    2.41 +        }
    2.42      }
    2.43  
    2.44      if (is_graphic_console()) {
    2.45 @@ -1427,6 +1455,7 @@ int vnc_display_init(DisplayState *ds, c
    2.46      vs->kbd_layout = init_keyboard_layout(keyboard_layout);
    2.47      if (!vs->kbd_layout)
    2.48  	exit(1);
    2.49 +    vs->modifiers_state[0x45] = 1; /* NumLock on - on boot */
    2.50  
    2.51      vs->ds->data = NULL;
    2.52      vs->ds->dpy_update = vnc_dpy_update;
     3.1 --- a/tools/ioemu/vnc_keysym.h	Thu May 10 18:02:55 2007 +0100
     3.2 +++ b/tools/ioemu/vnc_keysym.h	Thu May 10 19:33:05 2007 +0100
     3.3 @@ -232,6 +232,19 @@ static name2keysym_t name2keysym[]={
     3.4  {"Home", 0xff50},      /* XK_Home */
     3.5  {"End", 0xff57},       /* XK_End */
     3.6  {"Scroll_Lock", 0xff14}, /* XK_Scroll_Lock */
     3.7 +{"KP_Home", 0xff95},
     3.8 +{"KP_Left", 0xff96},
     3.9 +{"KP_Up", 0xff97},
    3.10 +{"KP_Right", 0xff98},
    3.11 +{"KP_Down", 0xff99},
    3.12 +{"KP_Prior", 0xff9a},
    3.13 +{"KP_Page_Up", 0xff9a},
    3.14 +{"KP_Next", 0xff9b},
    3.15 +{"KP_Page_Down", 0xff9b},
    3.16 +{"KP_End", 0xff9c},
    3.17 +{"KP_Begin", 0xff9d},
    3.18 +{"KP_Insert", 0xff9e},
    3.19 +{"KP_Delete", 0xff9f},
    3.20  {"F1", 0xffbe},        /* XK_F1 */
    3.21  {"F2", 0xffbf},        /* XK_F2 */
    3.22  {"F3", 0xffc0},        /* XK_F3 */
    3.23 @@ -259,6 +272,7 @@ static name2keysym_t name2keysym[]={
    3.24  {"KP_8", 0xffb8},      /* XK_KP_8 */
    3.25  {"KP_9", 0xffb9},      /* XK_KP_9 */
    3.26  {"KP_Add", 0xffab},    /* XK_KP_Add */
    3.27 +{"KP_Separator", 0xffac},/* XK_KP_Separator */
    3.28  {"KP_Decimal", 0xffae},  /* XK_KP_Decimal */
    3.29  {"KP_Divide", 0xffaf},   /* XK_KP_Divide */
    3.30  {"KP_Enter", 0xff8d},    /* XK_KP_Enter */