diff -Nru rdesktop-1.4.1.orig/rdesktop.c rdesktop-1.4.1/rdesktop.c --- rdesktop-1.4.1.orig/rdesktop.c 2005-04-23 01:12:28 +0300 +++ rdesktop-1.4.1/rdesktop.c 2005-09-23 12:12:07 +0300 @@ -85,6 +85,7 @@ BOOL g_numlock_sync = False; BOOL g_owncolmap = False; BOOL g_ownbackstore = True; /* We can't rely on external BackingStore */ +BOOL g_raw_keyboard = False; uint32 g_embed_wnd; uint32 g_rdp5_performanceflags = RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS; @@ -169,6 +170,7 @@ 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"); } void @@ -388,7 +390,7 @@ #endif while ((c = getopt(argc, argv, - VNCOPT "u:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1) + VNCOPT "u:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045yh?")) != -1) { switch (c) { @@ -680,7 +682,11 @@ case '5': g_use_rdp5 = True; - break; + break; + + case 'y': + g_raw_keyboard = True; + break; case 'h': case '?': diff -Nru rdesktop-1.4.1.orig/scancodes.h rdesktop-1.4.1/scancodes.h --- rdesktop-1.4.1.orig/scancodes.h 2003-10-28 05:20:43 +0200 +++ rdesktop-1.4.1/scancodes.h 2005-09-23 16:17:34 +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 @@ -353,9 +353,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 -Nru rdesktop-1.4.1.orig/xkeymap.c rdesktop-1.4.1/xkeymap.c --- rdesktop-1.4.1.orig/xkeymap.c 2005-04-28 12:41:57 +0300 +++ rdesktop-1.4.1/xkeymap.c 2005-09-26 12:46:06 +0300 @@ -4,12 +4,12 @@ Copyright (C) Matthew Chapman 1999-2005 Copyright (C) Peter Astrand 2003 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -52,6 +52,8 @@ 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, BOOL pressed); static void @@ -174,7 +176,7 @@ scancode = strtol(p, &line_rest, 16); /* flags */ - /* FIXME: Should allow case-insensitive flag names. + /* FIXME: Should allow case-insensitive flag names. Fix by using lex+yacc... */ modifiers = 0; if (strstr(line_rest, "altgr")) @@ -206,7 +208,7 @@ if (strstr(line_rest, "addupper")) { - /* Automatically add uppercase key, with same modifiers + /* Automatically add uppercase key, with same modifiers plus shift */ for (p = keyname; *p; p++) *p = toupper((int) *p); @@ -617,7 +619,7 @@ Window wdummy; int dummy; - XQueryPointer(g_display, g_wnd, &wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state); + XQueryPointer(g_display, g_wnd, &wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state); return state; #endif } @@ -668,10 +670,12 @@ && !get_key_state(state, XK_ISO_Level3_Shift)) rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT); - reset_winkey(ev_time); + 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); + if (g_numlock_sync) + rdp_send_input(ev_time, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(state), 0); } @@ -754,3 +758,153 @@ rdp_send_input(time, RDP_INPUT_SCANCODE, flags, scancode, 0); } } + +typedef unsigned char byte; +typedef unsigned int dword; + +static byte vkscancode[ 128] = { + /* 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_DNARROW, SCANCODE_CHAR_PAGEDOWN, SCANCODE_CHAR_INSERT, SCANCODE_CHAR_DELETE, SCANCODE_CHAR_NUMERICENTER, SCANCODE_CHAR_RCTRL, SCANCODE_CHAR_PAUSE, SCANCODE_CHAR_PRINT, + /* 70 - 77 */ SCANCODE_CHAR_NUMERICSLASH, SCANCODE_CHAR_RALT, 0, SCANCODE_CHAR_LWIN, SCANCODE_CHAR_RWIN, SCANCODE_CHAR_APPLICATION, 0, 0, + /* 78 - 7f */ 0, 0, 0, 0, 0, 0, 0, 0 +}; + + +static inline int vk_handle_special_keys( uint32 keysym, uint32 ev_time, BOOL pressed) { + + 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: + 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); + + 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 -Nru rdesktop-1.4.1.orig/xwin.c rdesktop-1.4.1/xwin.c --- rdesktop-1.4.1.orig/xwin.c 2005-04-17 01:09:31 +0300 +++ rdesktop-1.4.1/xwin.c 2005-09-23 11:33:11 +0300 @@ -40,6 +40,7 @@ extern char g_title[]; extern int g_server_bpp; extern int g_win_button_size; +extern BOOL g_raw_keyboard; Display *g_display; Time g_last_gesturetime; @@ -1341,6 +1342,8 @@ } } +extern void vk_handle_key( XKeyEvent *xkey); + /* Process events in Xlib queue Returns 0 after user quit, 1 otherwise */ static int @@ -1365,7 +1368,13 @@ continue; } - flags = 0; + if( g_raw_keyboard && ((xevent.type == KeyPress) || (xevent.type == KeyRelease))) { + g_last_gesturetime = xevent.xkey.time; + vk_handle_key( (XKeyEvent*)&xevent); + continue; + } + + flags = 0; switch (xevent.type) { @@ -1419,7 +1428,7 @@ save_remote_modifiers(tr.scancode); ensure_remote_modifiers(ev_time, tr); rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode); - restore_remote_modifiers(ev_time, tr.scancode); + restore_remote_modifiers(ev_time, tr.scancode); break; @@ -1444,7 +1453,7 @@ rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode); break; - case ButtonPress: + case ButtonPress: flags = MOUSE_FLAG_DOWN; /* fall through */