Beispiel #1
0
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);
	}
}
Beispiel #2
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);
}
Beispiel #3
0
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);
}