--- sourceforge.net/trunk/rdesktop/xkeymap.c 2002/09/11 09:52:30 115 +++ sourceforge.net/trunk/rdesktop/xkeymap.c 2002/09/17 16:57:07 183 @@ -25,6 +25,7 @@ #include #include #include +#include #include "rdesktop.h" #include "scancodes.h" @@ -177,6 +178,11 @@ MASK_ADD_BITS(modifiers, MapLocalStateMask); } + if (strstr(line_rest, "inhibit")) + { + MASK_ADD_BITS(modifiers, MapInhibitMask); + } + add_to_keymap(keyname, scancode, modifiers, mapname); if (strstr(line_rest, "addupper")) @@ -197,30 +203,52 @@ /* Before connecting and creating UI */ void -xkeymap_init1(void) +xkeymap_init(void) { + unsigned int max_keycode; int i; - /* Zeroing keymap */ - for (i = 0; i < KEYMAP_SIZE; i++) - { - keymap[i].scancode = 0; - keymap[i].modifiers = 0; - } - if (strcmp(keymapname, "none")) - { xkeymap_read(keymapname); - } + XDisplayKeycodes(display, &min_keycode, (int *) &max_keycode); } -/* After connecting and creating UI */ -void -xkeymap_init2(void) +/* Handles, for example, multi-scancode keypresses (which is not + possible via keymap-files) */ +BOOL +handle_special_keys(KeySym keysym, uint32 ev_time, BOOL pressed) { - unsigned int max_keycode; - XDisplayKeycodes(display, &min_keycode, (int *) &max_keycode); + switch (keysym) + { + case XK_Break: /* toggle full screen */ + if (pressed && (get_key_state(XK_Alt_L) || get_key_state(XK_Alt_R))) + { + xwin_toggle_fullscreen(); + return True; + } + break; + + case XK_Meta_L: /* Windows keys */ + case XK_Super_L: + case XK_Hyper_L: + 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); + } + return True; + break; + } + return False; } @@ -231,6 +259,13 @@ tr = keymap[keysym & KEYMAP_MASK]; + if (tr.modifiers & MapInhibitMask) + { + DEBUG_KBD(("Inhibiting key\n")); + tr.scancode = 0; + return tr; + } + if (tr.modifiers & MapLocalStateMask) { /* The modifiers to send for this key should be obtained @@ -255,6 +290,15 @@ if ((keycode >= min_keycode) && (keycode <= 0x60)) { tr.scancode = keycode - min_keycode; + + /* The modifiers to send for this key should be + obtained from the local state. Currently, only + shift is implemented. */ + if (state & ShiftMask) + { + tr.modifiers = MapLeftShiftMask; + } + fprintf(stderr, "Sending guessed scancode 0x%x\n", tr.scancode); } else @@ -298,25 +342,6 @@ return ksname; } -BOOL -inhibit_key(KeySym keysym) -{ - switch (keysym) - { - case XK_Caps_Lock: - return True; - break; - case XK_Multi_key: - return True; - break; - case XK_Num_Lock: - return True; - break; - default: - break; - } - return False; -} void ensure_remote_modifiers(uint32 ev_time, key_translation tr) @@ -338,20 +363,34 @@ break; } - /* Shift */ + /* Shift. Left shift and right shift are treated as equal; either is fine. */ if (MASK_HAS_BITS(tr.modifiers, MapShiftMask) != MASK_HAS_BITS(remote_modifier_state, MapShiftMask)) { /* The remote modifier state is not correct */ - if (MASK_HAS_BITS(tr.modifiers, MapShiftMask)) + if (MASK_HAS_BITS(tr.modifiers, MapLeftShiftMask)) { - /* Needs this modifier. Send down. */ + /* Needs left shift. Send down. */ rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LSHIFT); } + else if (MASK_HAS_BITS(tr.modifiers, MapRightShiftMask)) + { + /* Needs right shift. Send down. */ + rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RSHIFT); + } else { - /* Should not use this modifier. Send up. */ - rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT); + /* Should not use this modifier. Send up for shift currently pressed. */ + if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask)) + /* Left shift is down */ + rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT); + else + { + assert(MASK_HAS_BITS(remote_modifier_state, MapRightShiftMask)); + /* Right shift is down */ + rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT); + } + } } @@ -395,6 +434,34 @@ } +void +reset_modifier_keys() +{ + /* reset keys */ + uint32 ev_time; + ev_time = time(NULL); + + if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask) && !get_key_state(XK_Shift_L)) + rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT); + + if (MASK_HAS_BITS(remote_modifier_state, MapRightShiftMask) && !get_key_state(XK_Shift_R)) + rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT); + + if (MASK_HAS_BITS(remote_modifier_state, MapLeftCtrlMask) && !get_key_state(XK_Control_L)) + rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL); + + if (MASK_HAS_BITS(remote_modifier_state, MapRightCtrlMask) && !get_key_state(XK_Control_R)) + rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RCTRL); + + if (MASK_HAS_BITS(remote_modifier_state, MapLeftAltMask) && !get_key_state(XK_Alt_L)) + rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LALT); + + if (MASK_HAS_BITS(remote_modifier_state, MapRightAltMask) && + !get_key_state(XK_Alt_R) && !get_key_state(XK_Mode_switch)) + rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT); +} + + static void update_modifier_state(uint16 modifiers, BOOL pressed) {