void simulateKeyWithUnichar(Display *dpy, MouseEvent *pEvent) { #define kNumModifierKeyState 4 uint32_t modifierKeyStates[kNumModifierKeyState] = {0, kX11ModifierShift, kX11ModifierMod1, kX11ModifierShift | kX11ModifierMod1}; KeySym keysym = ucs2keysym(pEvent->value); KeyCode x11Keycode = XKeysymToKeycode(dpy, keysym); if (x11Keycode != 0) { int modifierIndex = 0; for (modifierIndex = 0; modifierIndex < kNumModifierKeyState; modifierIndex++) if (keyboardMapping[(x11Keycode - minKeycode) * keysymsPerKeycode + modifierIndex] == keysym) break; if (modifierIndex == kNumModifierKeyState) modifierIndex = 0; KeyCode shiftKeycode = 0, mod1Keycode = 0; if (modifierKeyStates[modifierIndex] & kX11ModifierShift) { shiftKeycode = XKeysymToKeycode(dpy, XK_Shift_L); if (shiftKeycode == 0) shiftKeycode = XKeysymToKeycode(dpy, XK_Shift_R); } if (modifierKeyStates[modifierIndex] & kX11ModifierMod1) mod1Keycode = XKeysymToKeycode(dpy, XK_Mode_switch); if (shiftKeycode) XTestFakeKeyEvent(dpy, shiftKeycode, True, 0); if (mod1Keycode) XTestFakeKeyEvent(dpy, mod1Keycode, True, 0); XTestFakeKeyEvent(dpy, x11Keycode, True, 0); if (shiftKeycode) XTestFakeKeyEvent(dpy, shiftKeycode, False, 0); if (mod1Keycode) XTestFakeKeyEvent(dpy, mod1Keycode, False, 0); XTestFakeKeyEvent(dpy, x11Keycode, False, 0); } }
static PyObject * virtkey_send_unicode(PyObject * self,PyObject *args, Bool press){ virtkey * cvirt = (virtkey *)self; long in = 0; long out = 0; int flags = 0; if ((PyArg_ParseTuple(args, "i", &in))){//find unicode arg in args tuple. out = keysym2keycode(cvirt, ucs2keysym(in), &flags); } if (flags) change_locked_mods(flags,press,cvirt); return virtkey_send(cvirt, out, press); }
KeyActionSpec KeyMap::PCtoX(UINT virtkey, DWORD keyData) { UINT numkeys = 0; KeyActionSpec kas; kas.releaseModifiers = 0; bool extended = ((keyData & 0x1000000) != 0); vnclog.Print(8, "VK %.2x (%.8x)", virtkey, keyData); if (extended) { vnclog.Print(8, " [ext]"); switch (virtkey) { case VK_MENU : virtkey = VK_RMENU; break; case VK_CONTROL: virtkey = VK_RCONTROL; break; case VK_RETURN: virtkey = VK_KEYPAD_ENTER; break; } } else { switch (virtkey) { case VK_HOME: virtkey = VK_KEYPAD_HOME; break; case VK_LEFT: virtkey = VK_KEYPAD_LEFT; break; case VK_UP: virtkey = VK_KEYPAD_UP; break; case VK_RIGHT: virtkey = VK_KEYPAD_RIGHT; break; case VK_DOWN: virtkey = VK_KEYPAD_DOWN; break; case VK_PRIOR: virtkey = VK_KEYPAD_PRIOR; break; case VK_NEXT: virtkey = VK_KEYPAD_NEXT; break; case VK_END: virtkey = VK_KEYPAD_END; break; case VK_CLEAR: virtkey = VK_KEYPAD_BEGIN; break; case VK_INSERT: virtkey = VK_KEYPAD_INSERT; break; case VK_DELETE: virtkey = VK_KEYPAD_DELETE; break; } } // Try looking it up in our table UINT mapsize = sizeof(keymap) / sizeof(vncKeymapping); // Look up the desired code in the table for (UINT i = 0; i < mapsize; i++) { if (keymap[i].wincode == virtkey) { kas.keycodes[numkeys++] = keymap[i].Xcode; break; } } if (numkeys != 0) { // A special case - use Meta instead of Alt if ScrollLock is on UINT key = kas.keycodes[numkeys - 1]; if ((key == XK_Alt_L || key == XK_Alt_R) && GetKeyState(VK_SCROLL)) { if (key == XK_Alt_L) kas.keycodes[numkeys - 1] = XK_Meta_L; else kas.keycodes[numkeys - 1] = XK_Meta_R; } vnclog.Print(8, ": keymap gives %.4x", key); } else { // not found in table vnclog.Print(8, ": not in keymap"); // Try a simple conversion to ASCII, using the current keyboard mapping GetKeyboardState(keystate); // If Left Ctrl & Alt are both pressed and ToAscii() gives a valid keysym. // (This is for AltGr on international keyboards (= LCtrl-Alt). // e.g. Ctrl-Alt-Q gives @ on German keyboards.) if (((keystate[VK_RMENU] & 0x80) != 0) && ((keystate[VK_LCONTROL] & 0x80) != 0)) { // Windows doesn't have a proper AltGr key event. It instead handles // AltGr with fake left Ctrl and right Alt key events. Xvnc will // automatically insert an AltGr (ISO Level 3 Shift) event if necessary // (if it receives a key symbol that could not have been generated any // other way), and unfortunately X11 doesn't generally like the sequence // Ctrl + Alt + AltGr. Thus, for Windows viewers, we have to temporarily // release Ctrl and Alt, then process the AltGr-modified symbol, then // press Ctrl and Alt again. if (GetKeyState(VK_LCONTROL) & 0x8000) kas.releaseModifiers |= KEYMAP_LCONTROL; if (GetKeyState(VK_RMENU) & 0x8000) kas.releaseModifiers |= KEYMAP_RALT; // This is for Windows '95, and possibly other systems. The above // GetKeyState() calls don't work in '95 - they always return 0. // But if we're at this point in the code, we know that left Ctrl and // right Alt are pressed, so let's release those keys if we haven't // registered them as already having been released. if (kas.releaseModifiers == 0) kas.releaseModifiers = KEYMAP_LCONTROL | KEYMAP_RALT; } else { // There are no keysyms corresponding to control characters, e.g. Ctrl-F. // The server already knows whether the Ctrl key is pressed, so we are // interested in the key that would be sent if the Ctrl key were not // pressed. keystate[VK_CONTROL] = keystate[VK_LCONTROL] = keystate[VK_RCONTROL] = 0; } int ret = ToUnicode(virtkey, 0, keystate, buf, 10, 0); if (ret == 0) { // Most Ctrl+Alt combinations will fail to produce a symbol, so // try it again with Ctrl unconditionally disabled. keystate[VK_CONTROL] = keystate[VK_LCONTROL] = keystate[VK_RCONTROL] = 0; ret = ToUnicode(virtkey, 0, keystate, buf, 10, 0); } unsigned keysym = ucs2keysym(buf[0]); if (ret == 1 && keysym != 0) { // If the key means anything in this keyboard layout if (((keystate[VK_RMENU] & 0x80) != 0) && ((keystate[VK_LCONTROL] & 0x80) != 0)) vnclog.Print(8, "\n Ctrl-Alt: UCS->KS (w/o mods): "); else vnclog.Print(8, "\n UCS->KS (w/o ctrl): "); kas.keycodes[numkeys++] = keysym; vnclog.Print(8, " %.2x->%.2x", buf[0], keysym); } if (ret < 0 || ret > 1) { // NOTE: For some reason, TigerVNC never gets a return value > 1 from // ToUnicode(), but we do, even though we're using basically the same // keyboard handling logic. Not sure why. WCHAR dead_char = buf[0]; while (ret < 0) { // Need to clear out the state that the dead key has caused. // This is the recommended method by Microsoft's engineers: // http://blogs.msdn.com/b/michkap/archive/2007/10/27/5717859.aspx ret = ToUnicode(virtkey, 0, keystate, buf, 10, 0); } kas.keycodes[numkeys++] = ucs2keysym(ucs2combining(dead_char)); vnclog.Print(8, " %.2x->%.2x", dead_char, kas.keycodes[numkeys - 1]); } } vnclog.Print(8, "\n"); kas.keycodes[numkeys] = VoidKeyCode; return kas; };
static KeySym keysym_for_unichar (SpiDEController *controller, gunichar unichar) { return ucs2keysym ((long) unichar); }