Beispiel #1
0
key_translation
xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state)
{
	key_translation tr = { 0, 0 };

	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
		   from the local state. Currently, only shift is implemented. */
		if (state & ShiftMask)
		{
			tr.modifiers = MapLeftShiftMask;
		}
	}

	if (tr.scancode != 0)
	{
		DEBUG_KBD(("Found key translation, scancode=0x%x, modifiers=0x%x\n",
			   tr.scancode, tr.modifiers));
		return tr;
	}

	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 ((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 (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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
/* Handle special key combinations */
RD_BOOL
handle_special_keys(uint32 keysym, unsigned int state, uint32 ev_time, RD_BOOL pressed)
{
	DEBUG_KBD(("handle_special_keys (keysym 0x%x, %s state 0x%x, pressed %d)\n",
		   keysym, get_ksname(keysym), state, pressed));

	DEBUG_KBD(("Control_L %d, Control_R %d, Alt_L %d, Alt_R %d\n",
		   get_key_state(state, XK_Control_L),
		   get_key_state(state, XK_Control_R),
		   get_key_state(state, XK_Alt_L),
		   get_key_state(state, XK_Alt_R)));

	if (keysym == XK_Alt_L || keysym == XK_Alt_R
	    || keysym == XK_Control_L || keysym == XK_Control_R) {
		int new_state = state;

		if (pressed)
			new_state |= get_keysym_mask(keysym);
		else
			new_state &= ~get_keysym_mask(keysym);

		new_state &= ~get_keysym_mask(XK_Num_Lock);

		if (pressed) {
			if ((new_state & (get_keysym_mask(XK_Alt_L)
					  | get_keysym_mask(XK_Alt_R))) &&
			    (new_state & (get_keysym_mask(XK_Control_L)
					  | get_keysym_mask(XK_Control_R)))) {
				ctrl_alt_pressed = True;
				DEBUG_KBD(("Ctrl-Alt Pressed\n"));
			}
		} else {
			if (ctrl_alt_pressed && !new_state) {
				DEBUG_KBD(("Ctrl-Alt Released\n"));
				if (g_ungrab_on_ctrlalt)
					xwin_ungrab_keyboard();
			}
		}
	} else if (pressed) {
		ctrl_alt_pressed = False;
		if (!get_keysym_mask(keysym))
			xwin_grab_keyboard();
	}

	switch (keysym)
	{
		case XK_Return:
			if ((get_key_state(state, XK_Alt_L) || get_key_state(state, XK_Alt_R))
			    && (get_key_state(state, XK_Control_L)
				|| get_key_state(state, XK_Control_R)))
			{
				/* Ctrl-Alt-Enter: toggle full screen */
				if (pressed)
					xwin_toggle_fullscreen();
				return True;
			}
			break;

		case XK_Break:
			/* Send Break sequence E0 46 E0 C6 */
			if (pressed)
			{
				rdp_send_scancode(ev_time, RDP_KEYPRESS,
						  (SCANCODE_EXTENDED | 0x46));
				rdp_send_scancode(ev_time, RDP_KEYPRESS,
						  (SCANCODE_EXTENDED | 0xc6));
			}
			/* No release sequence */
			return True;
			break;

		case XK_Pause:
			/* According to MS Keyboard Scan Code
			   Specification, pressing Pause should result
			   in E1 1D 45 E1 9D C5. I'm not exactly sure
			   of how this is supposed to be sent via
			   RDP. The code below seems to work, but with
			   the side effect that Left Ctrl stays
			   down. Therefore, we release it when Pause
			   is released. */
			if (pressed)
			{
				rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xe1, 0);
				rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x1d, 0);
				rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x45, 0);
				rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xe1, 0);
				rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x9d, 0);
				rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xc5, 0);
			}
			else
			{
				/* Release Left Ctrl */
				rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYRELEASE,
					       0x1d, 0);
			}
			return True;
			break;

		case XK_Meta_L:	/* Windows keys */
		case XK_Super_L:
		case XK_Hyper_L:
			send_winkey(ev_time, pressed, True);
			return True;
			break;

		case XK_Meta_R:
		case XK_Super_R:
		case XK_Hyper_R:
			send_winkey(ev_time, pressed, False);
			return True;
			break;

		case XK_space:
			/* Prevent access to the Windows system menu in single app mode */
			if (g_win_button_size
			    && (get_key_state(state, XK_Alt_L) || get_key_state(state, XK_Alt_R)))
				return True;
			break;

		case XK_Num_Lock:
			/* Synchronize on key release */
			if (g_numlock_sync && !pressed)
				rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0,
					       ui_get_numlock_state(read_keyboard_state()), 0);

			/* Inhibit */
			return True;
			break;
		case XK_Overlay1_Enable:
			/* Toggle SeamlessRDP */
			if (pressed)
				ui_seamless_toggle();
			break;

	}
	return False;
}