[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [PVFB] Fix shift key for graphical vnc display
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1185181397 -3600 # Node ID 7bdc9f6407d324dbe4748adc24e2d4feab8953e1 # Parent c64f2a0dc2d721734f5058d7bbfe9e900522c277 [PVFB] Fix shift key for graphical vnc display There is a problem in the input of the key in the VNC connection on the PV domain. When client's keyboard is not the same as the kind of the keyboard of PVFB and GuestOS, it is not possible to input it correctly. This patch handled the state of shift from the set keymap. When client's keyboard is not same as the kind of PVFB/GuestOS, it is possible to input it correctly. It was confirmed to input it correctly mutually with this patch between en-us and ja. Signed-off-by: Takanori Kasai <kasai.takanori@xxxxxxxxxxxxxx> --- tools/xenfb/vncfb.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 105 insertions(+), 5 deletions(-) diff -r c64f2a0dc2d7 -r 7bdc9f6407d3 tools/xenfb/vncfb.c --- a/tools/xenfb/vncfb.c Mon Jul 23 10:02:37 2007 +0100 +++ b/tools/xenfb/vncfb.c Mon Jul 23 10:03:17 2007 +0100 @@ -55,11 +55,46 @@ unsigned char keycode_table[512]; unsigned char keycode_table[512]; static void *kbd_layout; +uint8_t modifiers_state[256]; static int btnmap[] = { BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, BTN_SIDE, BTN_EXTRA, BTN_FORWARD, BTN_BACK, BTN_TASK }; + +static void press_key_shift_down(struct xenfb* xenfb, int down, int scancode) +{ + if (down) + xenfb_send_key(xenfb, 1, keycode_table[0x2a]); + + if (xenfb_send_key(xenfb, down, keycode_table[scancode]) < 0) + fprintf(stderr, "Key %d %s lost (%s)\n", + scancode, "down", strerror(errno)); + + if (!down) + xenfb_send_key(xenfb, 0, keycode_table[0x2a]); +} + +static void press_key_shift_up(struct xenfb* xenfb, int down, int scancode) +{ + if (down) { + if (modifiers_state[0x2a]) + xenfb_send_key(xenfb, 0, keycode_table[0x2a]); + if (modifiers_state[0x36]) + xenfb_send_key(xenfb, 0, keycode_table[0x36]); + } + + if (xenfb_send_key(xenfb, down, keycode_table[scancode]) < 0) + fprintf(stderr, "Key %d %s lost (%s)\n", + scancode, "down", strerror(errno)); + + if (!down) { + if (modifiers_state[0x2a]) + xenfb_send_key(xenfb, 1, keycode_table[0x2a]); + if (modifiers_state[0x36]) + xenfb_send_key(xenfb, 1, keycode_table[0x36]); + } +} static void on_kbd_event(rfbBool down, rfbKeySym keycode, rfbClientPtr cl) { @@ -75,14 +110,75 @@ static void on_kbd_event(rfbBool down, r rfbScreenInfoPtr server = cl->screen; struct xenfb *xenfb = server->screenData; int scancode; - - if (keycode >= 'A' && keycode <= 'Z') + int shift = 0; + int shift_keys = 0; + + if (keycode >= 'A' && keycode <= 'Z') { keycode += 'a' - 'A'; - - scancode = keycode_table[keysym2scancode(kbd_layout, keycode)]; + shift = 1; + } + else { + shift = keysymIsShift(kbd_layout, keycode); + } + shift_keys = modifiers_state[0x2a] | modifiers_state[0x36]; + + scancode = keysym2scancode(kbd_layout, keycode); if (scancode == 0) return; - if (xenfb_send_key(xenfb, down, scancode) < 0) + + switch(scancode) { + case 0x2a: /* Left Shift */ + case 0x36: /* Right Shift */ + case 0x1d: /* Left CTRL */ + case 0x9d: /* Right CTRL */ + case 0x38: /* Left ALT */ + case 0xb8: /* Right ALT */ + if (down) + modifiers_state[scancode] = 1; + else + modifiers_state[scancode] = 0; + xenfb_send_key(xenfb, down, keycode_table[scancode]); + return; + case 0x45: /* NumLock */ + if (!down) + modifiers_state[scancode] ^= 1; + xenfb_send_key(xenfb, down, keycode_table[scancode]); + return; + } + + if (keycodeIsKeypad(kbd_layout, scancode)) { + /* If the numlock state needs to change then simulate an additional + keypress before sending this one. This will happen if the user + toggles numlock away from the VNC window. + */ + if (keysymIsNumlock(kbd_layout, keycode)) { + if (!modifiers_state[0x45]) { + modifiers_state[0x45] = 1; + xenfb_send_key(xenfb, 1, keycode_table[0x45]); + xenfb_send_key(xenfb, 0, keycode_table[0x45]); + } + } else { + if (modifiers_state[0x45]) { + modifiers_state[0x45] = 0; + xenfb_send_key(xenfb, 1, keycode_table[0x45]); + xenfb_send_key(xenfb, 0, keycode_table[0x45]); + } + } + } + + /* If the shift state needs to change then simulate an additional + keypress before sending this one. + */ + if (shift && !shift_keys) { + press_key_shift_down(xenfb, down, scancode); + return; + } + else if (!shift && shift_keys) { + press_key_shift_up(xenfb, down, scancode); + return; + } + + if (xenfb_send_key(xenfb, down, keycode_table[scancode]) < 0) fprintf(stderr, "Key %d %s lost (%s)\n", scancode, down ? "down" : "up", strerror(errno)); @@ -314,6 +410,10 @@ int main(int argc, char **argv) atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80]; } + for (i = 0; i < 256; i++ ) { + modifiers_state[i] = 0; + } + fake_argv[2] = portstr; if (title != NULL) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |