--- sourceforge.net/trunk/rdesktop/xkeymap.c 2003/06/06 11:09:24 414 +++ sourceforge.net/trunk/rdesktop/xkeymap.c 2003/09/08 08:27:57 466 @@ -1,7 +1,9 @@ /* rdesktop: A Remote Desktop Protocol client. User interface services - X keyboard mapping + Copyright (C) Matthew Chapman 1999-2002 + 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 @@ -35,16 +37,18 @@ #define KEYMAP_MASK 0xffff #define KEYMAP_MAX_LINE_LENGTH 80 -extern Display *display; +extern Display *g_display; extern char keymapname[16]; extern int keylayout; -extern int win_button_size; -extern BOOL enable_compose; +extern int g_win_button_size; +extern BOOL g_enable_compose; +extern BOOL g_use_rdp5; static 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 void update_modifier_state(uint8 scancode, BOOL pressed); @@ -140,7 +144,7 @@ if (strncmp(line, "enable_compose", 15) == 0) { DEBUG_KBD(("Enabling compose handling\n")); - enable_compose = True; + g_enable_compose = True; continue; } @@ -235,7 +239,45 @@ keymap_loaded = True; } - XDisplayKeycodes(display, &min_keycode, (int *) &max_keycode); + XDisplayKeycodes(g_display, &min_keycode, (int *) &max_keycode); +} + +static void +send_winkey(uint32 ev_time, BOOL pressed, BOOL leftkey) +{ + uint8 winkey; + + if (leftkey) + winkey = SCANCODE_CHAR_LWIN; + else + winkey = SCANCODE_CHAR_RWIN; + + if (pressed) + { + if (g_use_rdp5) + { + rdp_send_scancode(ev_time, RDP_KEYPRESS, winkey); + } + 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 + { + /* key released */ + if (g_use_rdp5) + { + rdp_send_scancode(ev_time, RDP_KEYRELEASE, winkey); + } + else + { + rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_ESC); + rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL); + } + } } /* Handles, for example, multi-scancode keypresses (which is not @@ -298,24 +340,18 @@ case XK_Meta_L: /* Windows keys */ case XK_Super_L: case XK_Hyper_L: + send_winkey(ev_time, pressed, True); + return True; + case XK_Meta_R: case XK_Super_R: case XK_Hyper_R: - if (pressed) - { - rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LCTRL); - rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_ESC); - } - else - { - rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_ESC); - rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL); - } + send_winkey(ev_time, pressed, False); return True; case XK_space: /* Prevent access to the Windows system menu in single app mode */ - if (win_button_size + if (g_win_button_size && (get_key_state(state, XK_Alt_L) || get_key_state(state, XK_Alt_R))) return True; @@ -414,6 +450,21 @@ return ksname; } +void +save_remote_modifiers() +{ + saved_remote_modifier_state = remote_modifier_state; +} + +void +restore_remote_modifiers(uint32 ev_time) +{ + key_translation dummy; + + dummy.scancode = 0; + dummy.modifiers = saved_remote_modifier_state; + ensure_remote_modifiers(ev_time, dummy); +} void ensure_remote_modifiers(uint32 ev_time, key_translation tr)