diff -urN rdesktop.orig/l2wscancodes.c rdesktop/l2wscancodes.c --- rdesktop.orig/l2wscancodes.c 1970-01-01 03:00:00 +0300 +++ rdesktop/l2wscancodes.c 2010-01-24 18:28:00 +0300 @@ -0,0 +1,369 @@ +#include "X11/XKBlib.h" +#include "X11/keysym.h" + +#include "scancodes.h" + +void init_l2w_scancode_conv_mx(Display* g_display, int *vks) { + int i, j; + KeySym *ks; + int keysums_per_scancode; + const int first_scan_code = 8; + ks = XGetKeyboardMapping(g_display, first_scan_code, 256 - first_scan_code, &keysums_per_scancode); + + + for (i = 0; i < 255; ++i) + vks[i] = 0; + + int scancode; + for (scancode = first_scan_code; scancode < 255; ++scancode) { + for (j = 0; j < keysums_per_scancode; ++j) { + if(vks[scancode]) continue; + switch (ks[(scancode - first_scan_code) * keysums_per_scancode + j]) { + //F1 - F12 + case XK_F1: vks[scancode] = SCANCODE_CHAR_F1; + break; + + case XK_F2: vks[scancode] = SCANCODE_CHAR_F2; + break; + + case XK_F3: vks[scancode] = SCANCODE_CHAR_F3; + break; + + case XK_F4: vks[scancode] = SCANCODE_CHAR_F4; + break; + + case XK_F5: vks[scancode] = SCANCODE_CHAR_F5; + break; + + case XK_F6: vks[scancode] = SCANCODE_CHAR_F6; + break; + + case XK_F7: vks[scancode] = SCANCODE_CHAR_F7; + break; + + case XK_F8: vks[scancode] = SCANCODE_CHAR_F8; + break; + + case XK_F9: vks[scancode] = SCANCODE_CHAR_F9; + break; + + case XK_F10: vks[scancode] = SCANCODE_CHAR_F10; + break; + + case XK_F11: vks[scancode] = SCANCODE_CHAR_F11; + break; + + case XK_F12: vks[scancode] = SCANCODE_CHAR_F12; + break; + + //1, 2, 3 ... 0 + + case XK_1: vks[scancode] = SCANCODE_CHAR_1; + break; + + case XK_2: vks[scancode] = SCANCODE_CHAR_2; + break; + + case XK_3: vks[scancode] = SCANCODE_CHAR_3; + break; + + case XK_4: vks[scancode] = SCANCODE_CHAR_4; + break; + + case XK_5: vks[scancode] = SCANCODE_CHAR_5; + break; + + case XK_6: vks[scancode] = SCANCODE_CHAR_6; + break; + + case XK_7: vks[scancode] = SCANCODE_CHAR_7; + break; + + case XK_8: vks[scancode] = SCANCODE_CHAR_8; + break; + + case XK_9: vks[scancode] = SCANCODE_CHAR_9; + break; + + case XK_0: vks[scancode] = SCANCODE_CHAR_0; + break; + + // - = + case XK_minus: vks[scancode] = SCANCODE_CHAR_MINUS; + break; + + case XK_equal: vks[scancode] = SCANCODE_CHAR_EQUAL; + break; + + //A - J (10 keys) + case XK_A: vks[scancode] = SCANCODE_CHAR_A; + break; + + case XK_B: vks[scancode] = SCANCODE_CHAR_B; + break; + + case XK_C: vks[scancode] = SCANCODE_CHAR_C; + break; + + case XK_D: vks[scancode] = SCANCODE_CHAR_D; + break; + + case XK_E: vks[scancode] = SCANCODE_CHAR_E; + break; + + case XK_F: vks[scancode] = SCANCODE_CHAR_F; + break; + + case XK_G: vks[scancode] = SCANCODE_CHAR_G; + break; + + case XK_H: vks[scancode] = SCANCODE_CHAR_H; + break; + + case XK_I: vks[scancode] = SCANCODE_CHAR_I; + break; + + case XK_J: vks[scancode] = SCANCODE_CHAR_J; + break; + + //K - T(10 keys) + case XK_K: vks[scancode] = SCANCODE_CHAR_K; + break; + + case XK_L: vks[scancode] = SCANCODE_CHAR_L; + break; + + case XK_M: vks[scancode] = SCANCODE_CHAR_M; + break; + + case XK_N: vks[scancode] = SCANCODE_CHAR_N; + break; + + case XK_O: vks[scancode] = SCANCODE_CHAR_O; + break; + + case XK_P: vks[scancode] = SCANCODE_CHAR_P; + break; + + case XK_Q: vks[scancode] = SCANCODE_CHAR_Q; + break; + + case XK_R: vks[scancode] = SCANCODE_CHAR_R; + break; + + case XK_S: vks[scancode] = SCANCODE_CHAR_S; + break; + + case XK_T: vks[scancode] = SCANCODE_CHAR_T; + break; + + //U - Z (6 keys) + case XK_U: vks[scancode] = SCANCODE_CHAR_U; + break; + + case XK_V: vks[scancode] = SCANCODE_CHAR_V; + break; + + case XK_W: vks[scancode] = SCANCODE_CHAR_W; + break; + + case XK_X: vks[scancode] = SCANCODE_CHAR_X; + break; + + case XK_Y: vks[scancode] = SCANCODE_CHAR_Y; + break; + + case XK_Z: vks[scancode] = SCANCODE_CHAR_Z; + break; + + //[ ] ; ' , . / + case XK_bracketleft: vks[scancode] = SCANCODE_CHAR_BRACKETLEFT; + break; + + case XK_bracketright: vks[scancode] = SCANCODE_CHAR_BRACKETRIGHT; + break; + + case XK_apostrophe: vks[scancode] = SCANCODE_CHAR_APOSTROPHE; + break; + + case XK_semicolon: vks[scancode] = SCANCODE_CHAR_SEMICOLON; + break; + + case XK_comma: vks[scancode] = SCANCODE_CHAR_COMMA; + break; + + case XK_period: vks[scancode] = SCANCODE_CHAR_DOT; + break; + + case XK_slash: vks[scancode] = SCANCODE_CHAR_SLASH; + break; + + //~ backslash + case XK_grave : vks[scancode] = SCANCODE_CHAR_GRAVE; + break; + + case XK_backslash: vks[scancode] = SCANCODE_CHAR_BACKSLASH; + break; + + + //Esc, Tab, CapsLock, LShift, LCtrl, LWin(LSuper), LAlt + case XK_Escape: vks[scancode] = SCANCODE_CHAR_ESC; + break; + + case XK_Tab: vks[scancode] = SCANCODE_CHAR_TAB; + break; + + case XK_Caps_Lock: vks[scancode] = SCANCODE_CHAR_CAPSLOCK; + break; + + case XK_Shift_L: vks[scancode] = SCANCODE_CHAR_LSHIFT; + break; + + case XK_Control_L: vks[scancode] = SCANCODE_CHAR_LCTRL; + break; + + case XK_Alt_L: vks[scancode] = SCANCODE_CHAR_LALT; + break; + + case XK_Super_L: vks[scancode] = SCANCODE_CHAR_LWIN; + break; + + //BSpace, RShift, RCtrl, RAlt, Apps, Ins, Del, RSuper + + case XK_BackSpace: vks[scancode] = SCANCODE_CHAR_BACKSPACE; + break; + + case XK_Menu: vks[scancode] = SCANCODE_CHAR_APPLICATION; + break; + + case XK_Insert: vks[scancode] = SCANCODE_CHAR_INSERT; + break; + + case XK_Shift_R: vks[scancode] = SCANCODE_CHAR_RSHIFT; + break; + + case XK_Control_R: vks[scancode] = SCANCODE_CHAR_RCTRL; + break; + + case XK_Alt_R: vks[scancode] = SCANCODE_CHAR_RALT; + break; + + case XK_Super_R: vks[scancode] = SCANCODE_CHAR_RWIN; + break; + + case XK_Delete: vks[scancode] = SCANCODE_CHAR_DELETE; + break; + + //Space, Enter, Up, Down, Right, Left + case XK_Left: vks[scancode] = SCANCODE_CHAR_LARROW; + break; + + case XK_Up: vks[scancode] = SCANCODE_CHAR_UPARROW; + break; + + case XK_Right: vks[scancode] = SCANCODE_CHAR_RARROW; + break; + + case XK_Down: vks[scancode] = SCANCODE_CHAR_DNARROW; + break; + + case XK_Return: vks[scancode] = SCANCODE_CHAR_ENTER; + break; + + case XK_space: vks[scancode] = SCANCODE_CHAR_SPACE; + break; + + + + //ScrollLock, PrintScreen, PauseBreak, PgUp, PgDn, Home, End + case XK_Home: vks[scancode] = SCANCODE_CHAR_HOME; + break; + + case XK_End: vks[scancode] = SCANCODE_CHAR_END; + break; + + case XK_Page_Up: vks[scancode] = SCANCODE_CHAR_PAGEUP; + break; + + case XK_Page_Down: vks[scancode] = SCANCODE_CHAR_PAGEDOWN; + break; + + case XK_Print: vks[scancode] = SCANCODE_CHAR_PRINT; + break; + + case XK_Pause: vks[scancode] = SCANCODE_CHAR_PAUSE; + break; + + case XK_Scroll_Lock: vks[scancode] = SCANCODE_CHAR_SCROLLLOCK; + break; + + /////// + //Num block + ////// + + + //0, 1, ... 9 + case XK_KP_1: vks[scancode] = SCANCODE_CHAR_NUMERIC1; + break; + + case XK_KP_2: vks[scancode] = SCANCODE_CHAR_NUMERIC2; + break; + + case XK_KP_3: vks[scancode] = SCANCODE_CHAR_NUMERIC3; + break; + + case XK_KP_4: vks[scancode] = SCANCODE_CHAR_NUMERIC4; + break; + + case XK_KP_5: vks[scancode] = SCANCODE_CHAR_NUMERIC5; + break; + + case XK_KP_6: vks[scancode] = SCANCODE_CHAR_NUMERIC6; + break; + + case XK_KP_7: vks[scancode] = SCANCODE_CHAR_NUMERIC7; + break; + + case XK_KP_8: vks[scancode] = SCANCODE_CHAR_NUMERIC8; + break; + + case XK_KP_9: vks[scancode] = SCANCODE_CHAR_NUMERIC9; + break; + + case XK_KP_0: vks[scancode] = SCANCODE_CHAR_NUMERIC0; + break; + + + // / * - + . + case XK_KP_Divide: vks[scancode] = SCANCODE_CHAR_NUMERICSLASH; + break; + + case XK_KP_Add: vks[scancode] = SCANCODE_CHAR_NUMERICPLUS; + break; + + case XK_KP_Subtract: vks[scancode] = SCANCODE_CHAR_NUMERICMINUS; + break; + + case XK_KP_Multiply: vks[scancode] = SCANCODE_CHAR_NUMERICSTAR; + break; + + case XK_KP_Delete: + case XK_KP_Decimal: + case XK_KP_Separator: vks[scancode] = SCANCODE_CHAR_NUMERICDOT; + break; + + + //Enter, Num Lock + case XK_KP_Enter: vks[scancode] = SCANCODE_CHAR_NUMERICENTER; + break; + + case XK_Num_Lock: vks[scancode] = SCANCODE_CHAR_NUMLOCK; + break; + + + + } + } + } + +} diff -urN rdesktop.orig/l2wscancodes.h rdesktop/l2wscancodes.h --- rdesktop.orig/l2wscancodes.h 1970-01-01 03:00:00 +0300 +++ rdesktop/l2wscancodes.h 2010-01-24 18:28:00 +0300 @@ -0,0 +1,14 @@ +/* + * File: l2wscancodes.h + * Author: alex + * + * Created on 6 Декабрь 2009 г., 20:59 + */ + +#ifndef _L2WSCANCODES_H +#define _L2WSCANCODES_H + +extern void init_l2w_scancode_conv_mx(Display * g_display, int *vks); + +#endif /* _L2WSCANCODES_H */ + diff -urN rdesktop.orig/Makefile.in rdesktop/Makefile.in --- rdesktop.orig/Makefile.in 2009-08-03 19:17:44 +0400 +++ rdesktop/Makefile.in 2010-01-24 18:28:00 +0300 @@ -28,7 +28,7 @@ SCARDOBJ = @SCARDOBJ@ RDPOBJ = tcp.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o rdp5.o channels.o rdpdr.o serial.o printer.o disk.o parallel.o printercache.o mppc.o pstcache.o lspci.o seamless.o ssl.o -X11OBJ = rdesktop.o xwin.o xkeymap.o ewmhints.o xclip.o cliprdr.o +X11OBJ = l2wscancodes.o rdesktop.o xwin.o xkeymap.o ewmhints.o xclip.o cliprdr.o VNCOBJ = vnc/rdp2vnc.o vnc/vnc.o vnc/xkeymap.o vnc/x11stubs.o .PHONY: all @@ -81,7 +81,7 @@ proto: cat proto.head > proto.h cproto -DMAKE_PROTO \ - bitmap.c cache.c channels.c cliprdr.c disk.c mppc.c ewmhints.c \ + l2wscancodes.o bitmap.c cache.c channels.c cliprdr.c disk.c mppc.c ewmhints.c \ iso.c licence.c mcs.c orders.c parallel.c printer.c printercache.c \ pstcache.c rdesktop.c rdp5.c rdp.c rdpdr.c rdpsnd.c \ secure.c serial.c tcp.c xclip.c xkeymap.c xwin.c lspci.c seamless.c \ diff -urN rdesktop.orig/rdesktop.c rdesktop/rdesktop.c --- rdesktop.orig/rdesktop.c 2009-08-03 19:17:44 +0400 +++ rdesktop/rdesktop.c 2010-01-24 18:28:00 +0300 @@ -91,6 +91,8 @@ RD_BOOL g_owncolmap = False; RD_BOOL g_ownbackstore = True; /* We can't rely on external BackingStore */ RD_BOOL g_seamless_rdp = False; +RD_BOOL g_raw_keyboard = False; +RD_BOOL g_ind_raw_converter = False; uint32 g_embed_wnd; uint32 g_rdp5_performanceflags = RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS; @@ -211,6 +213,8 @@ fprintf(stderr, " -0: attach to console\n"); fprintf(stderr, " -4: use RDP version 4\n"); fprintf(stderr, " -5: use RDP version 5 (default)\n"); + fprintf(stderr, " -y: use raw keyboard (default no)\n"); + fprintf(stderr, " -Y: use raw keyboard with platform-independent raw-converter (default no)\n"); } static void @@ -450,7 +454,7 @@ #endif while ((c = getopt(argc, argv, - VNCOPT "Au:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1) + VNCOPT "Au:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045Yyh?")) != -1) { switch (c) { @@ -783,6 +787,11 @@ case '5': g_use_rdp5 = True; break; + case 'Y': + g_ind_raw_converter = True; + case 'y': + g_raw_keyboard = True; + break; case 'h': case '?': diff -urN rdesktop.orig/scancodes.h rdesktop/scancodes.h --- rdesktop.orig/scancodes.h 2009-08-27 12:40:33 +0400 +++ rdesktop/scancodes.h 2010-01-24 18:28:00 +0300 @@ -152,7 +152,7 @@ #define SCANCODE_KEY_43 0x1c #define SCANCODE_CHAR_ENTER SCANCODE_KEY_43 -#define SCANCODE_KEY_44 0x2a +#define SCANCODE_KEY_44 (SCANCODE_EXTENDED | 0x2a) #define SCANCODE_CHAR_LSHIFT SCANCODE_KEY_44 /* Only on international keyboard */ @@ -191,7 +191,7 @@ /* Only on Brazilian and some Far East keyboards */ #define SCANCODE_KEY_56 0x73 -#define SCANCODE_KEY_57 0x36 +#define SCANCODE_KEY_57 (SCANCODE_EXTENDED | 0x36) #define SCANCODE_CHAR_RSHIFT SCANCODE_KEY_57 #define SCANCODE_KEY_58 0x1d @@ -352,10 +352,15 @@ /* Key 124: The Print Screen sequence is complicated, and hardcoded in xkeymap.c */ +#define SCANCODE_KEY_124 0xff +#define SCANCODE_CHAR_PRINT SCANCODE_KEY_124 #define SCANCODE_KEY_125 0x46 #define SCANCODE_CHAR_SCROLLLOCK SCANCODE_KEY_125 +#define SCANCODE_KEY_126 (SCANCODE_EXTENDED | 0x59) +#define SCANCODE_CHAR_PAUSE SCANCODE_KEY_126 + /* Key 126: The Pause and Break sequences is complicated, and hardcoded in xkeymap.c */ diff -urN rdesktop.orig/xkeymap.c rdesktop/xkeymap.c --- rdesktop.orig/xkeymap.c 2009-08-03 19:17:44 +0400 +++ rdesktop/xkeymap.c 2010-01-24 18:28:00 +0300 @@ -33,6 +33,7 @@ #include #include "rdesktop.h" #include "scancodes.h" +#include "l2wscancodes.h" #define KEYMAP_SIZE 0xffff+1 #define KEYMAP_MASK 0xffff @@ -49,12 +50,15 @@ extern RD_BOOL g_enable_compose; extern RD_BOOL g_use_rdp5; extern RD_BOOL g_numlock_sync; +extern RD_BOOL g_ind_raw_converter; +extern int scancodes_table[]; static RD_BOOL keymap_loaded; static key_translation *keymap[KEYMAP_SIZE]; static int min_keycode; static uint16 remote_modifier_state = 0; static uint16 saved_remote_modifier_state = 0; +static uint32 vkmenu, vkcontrol, vklshift, vkrshift, vknumlock; static void update_modifier_state(uint8 scancode, RD_BOOL pressed); @@ -943,6 +947,7 @@ rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT); reset_winkey(ev_time); + vknumlock = get_key_state(state, XK_Num_Lock); if (g_numlock_sync) rdp_send_input(ev_time, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(state), 0); @@ -1028,3 +1033,176 @@ rdp_send_input(time, RDP_INPUT_SCANCODE, flags, scancode, 0); } } + +typedef unsigned char byte; +typedef unsigned int dword; + +static byte vkscancode[256] = { + /* 00 - 07 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 08 - 0f */ 0, SCANCODE_CHAR_ESC, SCANCODE_CHAR_1, SCANCODE_CHAR_2, SCANCODE_CHAR_3, SCANCODE_CHAR_4, SCANCODE_CHAR_5, SCANCODE_CHAR_6, + /* 10 - 17 */ SCANCODE_CHAR_7, SCANCODE_CHAR_8, SCANCODE_CHAR_9, SCANCODE_CHAR_0, SCANCODE_CHAR_MINUS, SCANCODE_CHAR_EQUAL, SCANCODE_CHAR_BACKSPACE, SCANCODE_CHAR_TAB, + /* 18 - 1f */ SCANCODE_CHAR_Q, SCANCODE_CHAR_W, SCANCODE_CHAR_E, SCANCODE_CHAR_R, SCANCODE_CHAR_T, SCANCODE_CHAR_Y, SCANCODE_CHAR_U, SCANCODE_CHAR_I, + /* 20 - 27 */ SCANCODE_CHAR_O, SCANCODE_CHAR_P, SCANCODE_CHAR_BRACKETLEFT, SCANCODE_CHAR_BRACKETRIGHT, SCANCODE_CHAR_ENTER, SCANCODE_CHAR_LCTRL, SCANCODE_CHAR_A, SCANCODE_CHAR_S, + /* 28 - 2f */ SCANCODE_CHAR_D, SCANCODE_CHAR_F, SCANCODE_CHAR_G, SCANCODE_CHAR_H, SCANCODE_CHAR_J, SCANCODE_CHAR_K, SCANCODE_CHAR_L, SCANCODE_CHAR_SEMICOLON, + /* 30 - 37 */ SCANCODE_CHAR_APOSTROPHE, SCANCODE_CHAR_GRAVE, SCANCODE_CHAR_LSHIFT, SCANCODE_KEY_42, SCANCODE_CHAR_Z, SCANCODE_CHAR_X, SCANCODE_CHAR_C, SCANCODE_CHAR_V, + /* 38 - 3f */ SCANCODE_CHAR_B, SCANCODE_CHAR_N, SCANCODE_CHAR_M, SCANCODE_CHAR_COMMA, SCANCODE_CHAR_DOT, SCANCODE_CHAR_SLASH, SCANCODE_CHAR_RSHIFT, SCANCODE_CHAR_NUMERICSTAR, + /* 40 - 47 */ SCANCODE_CHAR_LALT, SCANCODE_CHAR_SPACE, SCANCODE_CHAR_CAPSLOCK, SCANCODE_CHAR_F1, SCANCODE_CHAR_F2, SCANCODE_CHAR_F3, SCANCODE_CHAR_F4, SCANCODE_CHAR_F5, + /* 48 - 4f */ SCANCODE_CHAR_F6, SCANCODE_CHAR_F7, SCANCODE_CHAR_F8, SCANCODE_CHAR_F9, SCANCODE_CHAR_F10, SCANCODE_CHAR_NUMLOCK, SCANCODE_CHAR_SCROLLLOCK, SCANCODE_CHAR_NUMERIC7, + /* 50 - 57 */ SCANCODE_CHAR_NUMERIC8, SCANCODE_CHAR_NUMERIC9, SCANCODE_CHAR_NUMERICMINUS, SCANCODE_CHAR_NUMERIC4, SCANCODE_CHAR_NUMERIC5, SCANCODE_CHAR_NUMERIC6, SCANCODE_CHAR_NUMERICPLUS, SCANCODE_CHAR_NUMERIC1, + /* 58 - 5f */ SCANCODE_CHAR_NUMERIC2, SCANCODE_CHAR_NUMERIC3, SCANCODE_CHAR_NUMERIC0, SCANCODE_CHAR_NUMERICDOT, 0, 0, 0, SCANCODE_CHAR_F11, + /* 60 - 67 */ SCANCODE_CHAR_F12, SCANCODE_CHAR_HOME, SCANCODE_CHAR_UPARROW, SCANCODE_CHAR_PAGEUP, SCANCODE_CHAR_LARROW, 0, SCANCODE_CHAR_RARROW, SCANCODE_CHAR_END, + /* 68 - 6f */ SCANCODE_CHAR_NUMERICENTER, SCANCODE_CHAR_RCTRL, SCANCODE_CHAR_NUMERICSLASH, SCANCODE_CHAR_DELETE, SCANCODE_CHAR_RALT, SCANCODE_CHAR_RCTRL, SCANCODE_CHAR_HOME, SCANCODE_CHAR_UPARROW, + /* 70 - 77 */ SCANCODE_CHAR_PAGEUP, SCANCODE_CHAR_LARROW, SCANCODE_CHAR_RARROW, SCANCODE_CHAR_END, SCANCODE_CHAR_DNARROW, SCANCODE_CHAR_PAGEDOWN, SCANCODE_CHAR_INSERT, SCANCODE_CHAR_DELETE, + /* 78 - 7f */ 0, 0, 0, 0, 0, 0, 0, 0, + + /* 80 - 87 */ 0, 0, 0, 0, 0, SCANCODE_CHAR_LWIN, 0, SCANCODE_CHAR_APPLICATION, + /* 88 - 8f */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 90 - 97 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 98 - 9f */ 0, 0, 0, 0, 0, 0, 0, 0, + /* a0 - a7 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* a8 - af */ 0, 0, 0, 0, 0, 0, 0, 0, + /* b0 - b7 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* b8 - bf */ 0, 0, 0, 0, 0, 0, 0, 0, + /* c0 - c7 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* c8 - cf */ 0, 0, 0, 0, 0, 0, 0, 0, + /* d0 - d7 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* d8 - df */ 0, 0, 0, 0, 0, 0, 0, 0, + /* e0 - e7 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* e8 - ef */ 0, 0, 0, 0, 0, 0, 0, 0, + /* f0 - f7 */ 0, 0, 0, 0, 0, 0, 0, 0, + /* f8 - ff */ 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static inline int vk_handle_special_keys( uint32 keysym, uint32 ev_time, RD_BOOL pressed) { + + RD_BOOL leftkey = 0; + + switch( keysym) { + case SCANCODE_CHAR_NUMLOCK: + if( !pressed) + vknumlock = !vknumlock; + return 0; + + case SCANCODE_CHAR_ENTER: + case SCANCODE_CHAR_NUMERICENTER: + if( pressed && vkmenu && vkcontrol) { + /* Ctrl-Alt-Enter: toggle full screen */ + xwin_toggle_fullscreen(); + return 1; + } + return 0; + + case SCANCODE_CHAR_PAUSE: + if( pressed) { + if( vkcontrol) { + rdp_send_scancode( ev_time, RDP_KEYPRESS, (SCANCODE_EXTENDED | 0x46)); + rdp_send_scancode( ev_time, RDP_KEYPRESS, (SCANCODE_EXTENDED | 0xc6)); + } + else { + rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xe1, 0); + rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x1d, 0); + rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x45, 0); + rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xe1, 0); + rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x9d, 0); + rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xc5, 0); + } + } + else { + /* Release Left Ctrl */ + if( vkcontrol) + rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, 0x1d, 0); + } + return 1; + + case SCANCODE_CHAR_PRINT: + if( vkmenu) + rdp_send_input( ev_time, RDP_INPUT_SCANCODE, pressed ? RDP_KEYPRESS : RDP_KEYRELEASE, 0x54, 0); + else if( vkcontrol && (vklshift || vklshift)) + rdp_send_input( ev_time, RDP_INPUT_SCANCODE, pressed ? RDP_KEYPRESS : RDP_KEYRELEASE, SCANCODE_EXTENDED|0x37, 0); + else { +#if 0 + if( pressed) { + rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, SCANCODE_CHAR_LSHIFT, 0); + rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, SCANCODE_EXTENDED|0x37, 0); + } + else { + rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, SCANCODE_EXTENDED|0x37, 0); + rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT, 0); + } +#endif + } + return 1; + + case SCANCODE_CHAR_LWIN: + leftkey = True; + case SCANCODE_CHAR_RWIN: + if( pressed) { + if( g_use_rdp5) { + rdp_send_scancode(ev_time, RDP_KEYPRESS, keysym); + } + else { + /* RDP4 doesn't support winkey. Fake with Ctrl-Esc */ + rdp_send_scancode( ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LCTRL); + rdp_send_scancode( ev_time, RDP_KEYPRESS, SCANCODE_CHAR_ESC); + } + } + else { + if( g_use_rdp5) { + rdp_send_scancode(ev_time, RDP_KEYRELEASE, keysym); + } + else { + rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_ESC); + rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL); + } + } + return 1; + + case SCANCODE_CHAR_INSERT: + case SCANCODE_CHAR_DELETE: + case SCANCODE_CHAR_LARROW: + case SCANCODE_CHAR_HOME: + case SCANCODE_CHAR_END: + case SCANCODE_CHAR_UPARROW: + case SCANCODE_CHAR_DNARROW: + case SCANCODE_CHAR_PAGEUP: + case SCANCODE_CHAR_PAGEDOWN: + case SCANCODE_CHAR_RARROW: + case SCANCODE_CHAR_NUMERICSLASH: + case SCANCODE_CHAR_APPLICATION: + rdp_send_scancode( ev_time, pressed ? RDP_KEYPRESS : RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT); + rdp_send_scancode( ev_time, pressed ? RDP_KEYPRESS : RDP_KEYRELEASE, keysym); + return 1; + } + return 0; +} + + +void vk_handle_key( XKeyEvent *xkey) { + + uint32 vk, ev_time, pressed = (xkey->type == KeyPress); + + if (g_ind_raw_converter) + vk = scancodes_table[ xkey->keycode]; + else + vk = vkscancode[ xkey->keycode]; + + DEBUG_KBD(( "vk_handle_key( scancode=0x%x) vk = 0x%x\n", xkey->keycode, vk)); + + if( !vk) + return; + + ev_time = time( 0); + + if( (vk == SCANCODE_CHAR_LCTRL) || (vk == SCANCODE_CHAR_RCTRL)) + vkcontrol = pressed; + else if( (vk == SCANCODE_CHAR_LALT) || (vk == SCANCODE_CHAR_RALT)) + vkmenu = pressed; + else if( vk == SCANCODE_CHAR_LSHIFT) + vklshift = pressed; + else if( vk == SCANCODE_CHAR_RSHIFT) + vkrshift = pressed; + else if( vk_handle_special_keys( vk, ev_time, pressed)) + return; + + rdp_send_input( ev_time, RDP_INPUT_SCANCODE, pressed ? RDP_KEYPRESS : RDP_KEYRELEASE, vk, 0); +} diff -urN rdesktop.orig/xwin.c rdesktop/xwin.c --- rdesktop.orig/xwin.c 2009-08-03 19:17:44 +0400 +++ rdesktop/xwin.c 2010-01-24 18:28:00 +0300 @@ -29,6 +29,11 @@ #include #include "rdesktop.h" #include "xproto.h" +#include "X11/XKBlib.h" +#include "X11/keysym.h" + +#include "scancodes.h" +#include "l2wscancodes.h" extern int g_width; extern int g_height; @@ -39,11 +44,14 @@ extern RD_BOOL g_fullscreen; extern RD_BOOL g_grab_keyboard; extern RD_BOOL g_hide_decorations; +extern RD_BOOL g_ind_raw_converter; +int scancodes_table[256]; extern char g_title[]; /* Color depth of the RDP session. As of RDP 5.1, it may be 8, 15, 16 or 24. */ extern int g_server_depth; extern int g_win_button_size; +extern RD_BOOL g_raw_keyboard; Display *g_display; Time g_last_gesturetime; @@ -136,6 +144,8 @@ so its endianess doesn't matter) */ static RD_BOOL g_no_translate_image = False; +static RD_BOOL g_modeswitch_down = False; + /* endianness */ static RD_BOOL g_host_be; @@ -1846,6 +1856,10 @@ if (!select_visual(screen_num)) return False; + if (g_ind_raw_converter){ + init_l2w_scancode_conv_mx(g_display, scancodes_table); + } + if (g_no_translate_image) { DEBUG(("Performance optimization possible: avoiding image translation (colour depth conversion).\n")); @@ -2267,6 +2281,8 @@ } } +extern void vk_handle_key( XKeyEvent *xkey); + /* Process events in Xlib queue Returns 0 after user quit, 1 otherwise */ @@ -2291,6 +2307,12 @@ continue; } + if( g_raw_keyboard && ((xevent.type == KeyPress) || (xevent.type == KeyRelease))) { + g_last_gesturetime = xevent.xkey.time; + vk_handle_key( (XKeyEvent*)&xevent); + continue; + } + switch (xevent.type) { case VisibilityNotify: @@ -2338,6 +2360,11 @@ str, sizeof(str), &keysym, NULL); } + + // Mode_switch during XGrabKeyboard fix: Ungrab Keyboard during Mode_switch + if ( keysym == XK_Mode_switch ) g_modeswitch_down = True; + if ( g_focused && g_modeswitch_down ) XUngrabKeyboard(g_display, CurrentTime); + DEBUG_KBD(("KeyPress for keysym (0x%lx, %s)\n", keysym, get_ksname(keysym))); @@ -2354,6 +2381,11 @@ XLookupString((XKeyEvent *) & xevent, str, sizeof(str), &keysym, NULL); + + // Mode_switch during XGrabKeyboard fix: Regrab Keyboard after Mode_switch + if ( keysym == XK_Mode_switch ) g_modeswitch_down = False; + if ( g_focused && !g_modeswitch_down ) XGrabKeyboard(g_display, g_wnd, True, GrabModeAsync, GrabModeAsync, CurrentTime); + DEBUG_KBD(("\nKeyRelease for keysym (0x%lx, %s)\n", keysym, get_ksname(keysym)));