static void update_modifier_state(uint8 scancode, BOOL pressed) { #ifdef WITH_DEBUG_KBD uint16 old_modifier_state; old_modifier_state = remote_modifier_state; #endif switch (scancode) { case SCANCODE_CHAR_LSHIFT: MASK_CHANGE_BIT(remote_modifier_state, MapLeftShiftMask, pressed); break; case SCANCODE_CHAR_RSHIFT: MASK_CHANGE_BIT(remote_modifier_state, MapRightShiftMask, pressed); break; case SCANCODE_CHAR_LCTRL: MASK_CHANGE_BIT(remote_modifier_state, MapLeftCtrlMask, pressed); break; case SCANCODE_CHAR_RCTRL: MASK_CHANGE_BIT(remote_modifier_state, MapRightCtrlMask, pressed); break; case SCANCODE_CHAR_LALT: MASK_CHANGE_BIT(remote_modifier_state, MapLeftAltMask, pressed); break; case SCANCODE_CHAR_RALT: MASK_CHANGE_BIT(remote_modifier_state, MapRightAltMask, pressed); break; case SCANCODE_CHAR_LWIN: MASK_CHANGE_BIT(remote_modifier_state, MapLeftWinMask, pressed); break; case SCANCODE_CHAR_RWIN: MASK_CHANGE_BIT(remote_modifier_state, MapRightWinMask, pressed); break; case SCANCODE_CHAR_NUMLOCK: /* KeyReleases for NumLocks are sent immediately. Toggle the modifier state only on Keypress */ if (pressed) { BOOL newNumLockState; newNumLockState = (MASK_HAS_BITS (remote_modifier_state, MapNumLockMask) == False); MASK_CHANGE_BIT(remote_modifier_state, MapNumLockMask, newNumLockState); } break; } #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 }
void reset_modifier_keys(unsigned int state) { /* reset keys */ uint32 ev_time; ev_time = time(NULL); if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask) && !get_key_state(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(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(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(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(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(state, XK_Alt_R) && !get_key_state(state, XK_Mode_switch)) rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT); }
void reset_modifier_keys() { unsigned int state = read_keyboard_state(); /* reset keys */ uint32 ev_time; ev_time = time(NULL); printf("remote_modifier_state: %.8X\n", remote_modifier_state); if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask) && !get_key_state(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(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(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(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(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(state, XK_Alt_R) && !get_key_state(state, XK_Mode_switch) && !get_key_state(state, XK_ISO_Level3_Shift)) rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT); reset_winkey(ev_time); if (g_numlock_sync) rdp_send_input(ev_time, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(state), 0); }
void ensure_remote_modifiers(uint32 ev_time, key_translation tr) { /* If this key is a modifier, do nothing */ if (is_modifier(tr.scancode)) return; if (!g_numlock_sync) { /* NumLock */ if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask) != MASK_HAS_BITS(remote_modifier_state, MapNumLockMask)) { /* The remote modifier state is not correct */ uint16 new_remote_state; if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask)) { DEBUG_KBD(("Remote NumLock state is incorrect, activating NumLock.\n")); new_remote_state = KBD_FLAG_NUMLOCK; remote_modifier_state = MapNumLockMask; } else { DEBUG_KBD(("Remote NumLock state is incorrect, deactivating NumLock.\n")); new_remote_state = 0; remote_modifier_state = 0; } rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, new_remote_state, 0); } } /* 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, MapLeftShiftMask)) { /* 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 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 /* Right shift is down */ rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT); } } /* AltGr */ if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask) != MASK_HAS_BITS(remote_modifier_state, MapAltGrMask)) { /* The remote modifier state is not correct */ if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask)) { /* Needs this modifier. Send down. */ 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); } } }
key_translation xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state) { key_translation tr = { 0, 0, 0, 0 }; key_translation *ptr; ptr = keymap[keysym & KEYMAP_MASK]; if (ptr) { tr = *ptr; if (tr.seq_keysym == 0) /* Normal scancode translation */ { if (MASK_HAS_BITS(tr.modifiers, MapInhibitMask)) { DEBUG_KBD(("Inhibiting key\n")); tr.scancode = 0; return tr; } if (MASK_HAS_BITS(tr.modifiers, MapLocalStateMask)) { /* The modifiers to send for this key should be obtained from the local state. Currently, only shift is implemented. */ if (MASK_HAS_BITS(state, ShiftMask)) { tr.modifiers = MapLeftShiftMask; } } /* Windows interprets CapsLock+Ctrl+key differently from Shift+Ctrl+key. Since we are simulating CapsLock with Shifts, things like Ctrl+f with CapsLock on breaks. To solve this, we are releasing Shift if Ctrl is on, but only if Shift isn't physically pressed. */ if (MASK_HAS_BITS(tr.modifiers, MapShiftMask) && MASK_HAS_BITS(remote_modifier_state, MapCtrlMask) && !MASK_HAS_BITS(state, ShiftMask)) { DEBUG_KBD(("Non-physical Shift + Ctrl pressed, releasing Shift\n")); MASK_REMOVE_BITS(tr.modifiers, MapShiftMask); } DEBUG_KBD(("Found scancode translation, scancode=0x%x, modifiers=0x%x\n", tr.scancode, tr.modifiers)); } } else { if (keymap_loaded) warning("No translation for (keysym 0x%lx, %s)\n", keysym, get_ksname(keysym)); /* not in keymap, try to interpret the raw scancode */ if (((int) 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 (MASK_HAS_BITS(state, ShiftMask)) { tr.modifiers = MapLeftShiftMask; } DEBUG_KBD(("Sending guessed scancode 0x%x\n", tr.scancode)); } else { DEBUG_KBD(("No good guess for keycode 0x%x found\n", keycode)); } } return tr; }