--- sourceforge.net/trunk/rdesktop/xkeymap.c 2002/07/29 19:21:51 73 +++ sourceforge.net/trunk/rdesktop/xkeymap.c 2002/09/17 08:18:41 170 @@ -41,6 +41,8 @@ static int min_keycode; static uint16 remote_modifier_state = 0; +static void update_modifier_state(uint16 modifiers, BOOL pressed); + static void add_to_keymap(char *keyname, uint8 scancode, uint16 modifiers, char *mapname) { @@ -53,9 +55,8 @@ return; } - DEBUG_KBD("Adding translation, keysym=0x%x, scancode=0x%x, " - "modifiers=0x%x\n", (unsigned int) keysym, scancode, - modifiers); + DEBUG_KBD(("Adding translation, keysym=0x%x, scancode=0x%x, " + "modifiers=0x%x\n", (unsigned int) keysym, scancode, modifiers)); keymap[keysym & KEYMAP_MASK].scancode = scancode; keymap[keysym & KEYMAP_MASK].modifiers = modifiers; @@ -117,14 +118,14 @@ if (strncmp(line, "map ", 4) == 0) { keylayout = strtol(line + 4, NULL, 16); - DEBUG_KBD("Keylayout 0x%x\n", keylayout); + DEBUG_KBD(("Keylayout 0x%x\n", keylayout)); continue; } /* compose */ if (strncmp(line, "enable_compose", 15) == 0) { - DEBUG_KBD("Enabling compose handling\n"); + DEBUG_KBD(("Enabling compose handling\n")); enable_compose = True; continue; } @@ -140,8 +141,7 @@ p = strchr(line, ' '); if (p == NULL) { - error("Bad line %d in keymap %s\n", line_num, - mapname); + error("Bad line %d in keymap %s\n", line_num, mapname); continue; } else @@ -177,6 +177,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 +202,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 +258,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 @@ -244,23 +278,31 @@ if (tr.scancode != 0) { DEBUG_KBD - ("Found key translation, scancode=0x%x, modifiers=0x%x\n", - tr.scancode, tr.modifiers); + (("Found key translation, scancode=0x%x, modifiers=0x%x\n", + tr.scancode, tr.modifiers)); return tr; } - printf("No translation for (keysym 0x%lx, %s)\n", keysym, - get_ksname(keysym)); + fprintf(stderr, "No translation for (keysym 0x%lx, %s)\n", keysym, get_ksname(keysym)); /* not in keymap, try to interpret the raw scancode */ if ((keycode >= min_keycode) && (keycode <= 0x60)) { tr.scancode = keycode - min_keycode; - printf("Sending guessed scancode 0x%x\n", tr.scancode); + + /* 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 { - printf("No good guess for keycode 0x%x found\n", keycode); + fprintf(stderr, "No good guess for keycode 0x%x found\n", keycode); } return tr; @@ -299,22 +341,6 @@ return ksname; } -BOOL -inhibit_key(KeySym keysym) -{ - switch (keysym) - { - case XK_Caps_Lock: - return True; - break; - case XK_Multi_key: - return True; - break; - default: - break; - } - return False; -} void ensure_remote_modifiers(uint32 ev_time, key_translation tr) @@ -344,14 +370,13 @@ if (MASK_HAS_BITS(tr.modifiers, MapShiftMask)) { /* Needs this modifier. Send down. */ - rdp_send_scancode(ev_time, RDP_KEYPRESS, - SCANCODE_CHAR_LSHIFT); + rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LSHIFT); } else { /* Should not use this modifier. Send up. */ - rdp_send_scancode(ev_time, RDP_KEYRELEASE, - SCANCODE_CHAR_LSHIFT); + rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT); + rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT); } } @@ -363,14 +388,12 @@ if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask)) { /* Needs this modifier. Send down. */ - rdp_send_scancode(ev_time, RDP_KEYPRESS, - SCANCODE_CHAR_RALT); + rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RALT); } else { /* Should not use this modifier. Send up. */ - rdp_send_scancode(ev_time, RDP_KEYRELEASE, - SCANCODE_CHAR_RALT); + rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT); } } @@ -379,67 +402,86 @@ != MASK_HAS_BITS(remote_modifier_state, MapNumLockMask)) { /* The remote modifier state is not correct */ - DEBUG_KBD("Remote NumLock state is incorrect. Toggling\n"); + uint16 new_remote_state = 0; + if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask)) { - /* Needs this modifier. Toggle */ - rdp_send_scancode(ev_time, RDP_KEYPRESS, - SCANCODE_CHAR_NUMLOCK); - rdp_send_scancode(ev_time, RDP_KEYRELEASE, - SCANCODE_CHAR_NUMLOCK); + DEBUG_KBD(("Remote NumLock state is incorrect, activating NumLock.\n")); + new_remote_state |= KBD_FLAG_NUMLOCK; } else { - /* Should not use this modifier. Toggle */ - rdp_send_scancode(ev_time, RDP_KEYPRESS, - SCANCODE_CHAR_NUMLOCK); - rdp_send_scancode(ev_time, RDP_KEYRELEASE, - SCANCODE_CHAR_NUMLOCK); + DEBUG_KBD(("Remote NumLock state is incorrect, deactivating NumLock.\n")); } + + rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, new_remote_state, 0); + update_modifier_state(SCANCODE_CHAR_NUMLOCK, True); } +} + + +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) { +#ifdef WITH_DEBUG_KBD + uint16 old_modifier_state; + + old_modifier_state = remote_modifier_state; +#endif - DEBUG_KBD("Before updating modifier_state:0x%x, pressed=0x%x\n", - remote_modifier_state, pressed); switch (modifiers) { case SCANCODE_CHAR_LSHIFT: - MASK_CHANGE_BIT(remote_modifier_state, - MapLeftShiftMask, pressed); + MASK_CHANGE_BIT(remote_modifier_state, MapLeftShiftMask, pressed); break; case SCANCODE_CHAR_RSHIFT: - MASK_CHANGE_BIT(remote_modifier_state, - MapRightShiftMask, pressed); + MASK_CHANGE_BIT(remote_modifier_state, MapRightShiftMask, pressed); break; case SCANCODE_CHAR_LCTRL: - MASK_CHANGE_BIT(remote_modifier_state, - MapLeftCtrlMask, pressed); + MASK_CHANGE_BIT(remote_modifier_state, MapLeftCtrlMask, pressed); break; case SCANCODE_CHAR_RCTRL: - MASK_CHANGE_BIT(remote_modifier_state, - MapRightCtrlMask, pressed); + MASK_CHANGE_BIT(remote_modifier_state, MapRightCtrlMask, pressed); break; case SCANCODE_CHAR_LALT: - MASK_CHANGE_BIT(remote_modifier_state, MapLeftAltMask, - pressed); + MASK_CHANGE_BIT(remote_modifier_state, MapLeftAltMask, pressed); break; case SCANCODE_CHAR_RALT: - MASK_CHANGE_BIT(remote_modifier_state, - MapRightAltMask, pressed); + MASK_CHANGE_BIT(remote_modifier_state, MapRightAltMask, pressed); break; case SCANCODE_CHAR_LWIN: - MASK_CHANGE_BIT(remote_modifier_state, MapLeftWinMask, - pressed); + MASK_CHANGE_BIT(remote_modifier_state, MapLeftWinMask, pressed); break; case SCANCODE_CHAR_RWIN: - MASK_CHANGE_BIT(remote_modifier_state, - MapRightWinMask, pressed); + MASK_CHANGE_BIT(remote_modifier_state, MapRightWinMask, pressed); break; case SCANCODE_CHAR_NUMLOCK: /* KeyReleases for NumLocks are sent immediately. Toggle the @@ -449,16 +491,21 @@ BOOL newNumLockState; newNumLockState = (MASK_HAS_BITS - (remote_modifier_state, - MapNumLockMask) == False); + (remote_modifier_state, MapNumLockMask) == False); MASK_CHANGE_BIT(remote_modifier_state, - MapNumLockMask, - newNumLockState); + MapNumLockMask, newNumLockState); } break; } - DEBUG_KBD("After updating modifier_state:0x%x\n", - remote_modifier_state); + +#ifdef WITH_DEBUG_KBD + if (old_modifier_state != remote_modifier_state) + { + DEBUG_KBD(("Before updating modifier_state:0x%x, pressed=0x%x\n", + old_modifier_state, pressed)); + DEBUG_KBD(("After updating modifier_state:0x%x\n", remote_modifier_state)); + } +#endif } @@ -470,15 +517,14 @@ if (scancode & SCANCODE_EXTENDED) { - DEBUG_KBD("Sending extended scancode=0x%x, flags=0x%x\n", - scancode & ~SCANCODE_EXTENDED, flags); + DEBUG_KBD(("Sending extended scancode=0x%x, flags=0x%x\n", + scancode & ~SCANCODE_EXTENDED, flags)); rdp_send_input(time, RDP_INPUT_SCANCODE, flags | KBD_FLAG_EXT, scancode & ~SCANCODE_EXTENDED, 0); } else { - DEBUG_KBD("Sending scancode=0x%x, flags=0x%x\n", scancode, - flags); + DEBUG_KBD(("Sending scancode=0x%x, flags=0x%x\n", scancode, flags)); rdp_send_input(time, RDP_INPUT_SCANCODE, flags, scancode, 0); } }