static Bool shiftStatus = FALSE ; static Bool shiftLDown = FALSE ; static Bool shiftRDown = FALSE ; static Bool shiftLocked = FALSE ; static Bool capsLocked = FALSE ; Bool modifierKludge(uint32 ev_time,Bool down,KeySym keySym) { uint16 scancode = 0 ; if (keySym == XK_Shift_L) { shiftLDown = down ; } else if (keySym == XK_Shift_R) { shiftRDown = down ; } else if (keySym == XK_Caps_Lock && down) { capsLocked = (capsLocked ? FALSE : TRUE) ; } else if (keySym == XK_Shift_Lock && down) { shiftLocked = (shiftLocked ? FALSE : TRUE) ; } if (capsLocked || shiftLocked) { if (shiftLDown || shiftRDown) { shiftStatus = FALSE ; } else { shiftStatus = TRUE ; } } else { if (shiftLDown || shiftRDown) { shiftStatus = TRUE ; } else { shiftStatus = FALSE ; } } scancode = XKeysym2PCKeyCode[keySym & KS_MASK] ; if (down && (shiftStatus == FALSE) && (scancode & 0x100)) { rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x2a, 0); rdp_send_input(ev_time, RDP_INPUT_SCANCODE, ((scancode==0xb8)?KBD_FLAG_EXT:0), scancode&0x7f, 0); rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN | KBD_FLAG_UP, 0x2a, 0); return FALSE ; } if (down && (shiftStatus == TRUE) && (scancode < 0x100)) { rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN | KBD_FLAG_UP, 0x2a, 0); rdp_send_input(ev_time, RDP_INPUT_SCANCODE, ((scancode==0xb8)?KBD_FLAG_EXT:0), scancode&0x7f, 0); rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x2a, 0); return FALSE ; } return TRUE ; } static int lastbuttons = 0; void vncKey (Bool down, KeySym keySym, struct rfbClientRec* cl) { uint32 ev_time = time(NULL); uint16 scancode = 0; scancode = XKeysym2PCKeyCode[keySym&KS_MASK]; DEBUG(("Down: %d, Keysym: %c(0x%x), scancode: 0x%x\n", down,(keySym>' ' && keySym<0x100)?keySym:' ',keySym,scancode)); if (scancode) { if (! modifierKludge(ev_time,down,keySym)) { return ; } if (down) { if(scancode & 0x200) { rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_EXT, 0xb8/*&0x7f*/, 0); } rdp_send_input(ev_time, RDP_INPUT_SCANCODE, ((scancode==0xb8)?KBD_FLAG_EXT:0), scancode&0x7f, 0); if(scancode & 0x200) rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_EXT | KBD_FLAG_DOWN | KBD_FLAG_UP, 0xb8/*&0x7f*/, 0); } else { rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN | KBD_FLAG_UP | ((scancode==0xb8)?KBD_FLAG_EXT:0), scancode&0x7f, 0); } } else { error("invalid scancode: 0x%x(%d)\n",keySym,keySym); } }