Esempio n. 1
0
static int uxkb_dev_process(struct kbd_dev *kbd,
			    uint16_t key_state,
			    uint16_t code,
			    struct uterm_input_event *out)
{
	struct xkb_state *state;
	struct xkb_keymap *keymap;
	xkb_keycode_t keycode;
	const xkb_keysym_t *keysyms;
	int num_keysyms;

	if (!kbd)
		return -EINVAL;

	state = kbd->uxkb.state;
	keymap = xkb_state_get_map(state);
	keycode = code + EVDEV_KEYCODE_OFFSET;

	num_keysyms = xkb_key_get_syms(state, keycode, &keysyms);

	if (key_state == KEY_PRESSED)
		xkb_state_update_key(state, keycode, XKB_KEY_DOWN);
	else if (key_state == KEY_RELEASED)
		xkb_state_update_key(state, keycode, XKB_KEY_UP);

	if (key_state == KEY_RELEASED)
		return -ENOKEY;

	if (key_state == KEY_REPEATED && !xkb_key_repeats(keymap, keycode))
		return -ENOKEY;

	if (num_keysyms <= 0)
		return -ENOKEY;

	/*
	 * TODO: xkbcommon actually supports multiple keysyms
	 * per key press. Here we're just using the first one,
	 * but we might want to support this feature.
	 */
	out->keycode = code;
	out->keysym = keysyms[0];
	out->mods = shl_get_xkb_mods(state);
	out->unicode = xkb_keysym_to_utf32(out->keysym) ? : UTERM_INPUT_INVALID;

	return 0;
}
static void
clutter_wayland_handle_key (void *data,
                            struct wl_keyboard *keyboard,
                            uint32_t serial, uint32_t _time,
                            uint32_t key, uint32_t state)
{
  ClutterInputDeviceWayland *device = data;
  ClutterStageCogl          *stage_cogl = device->keyboard_focus;
  ClutterEvent              *event;

  if (!device->xkb)
    return;

  event = _clutter_key_event_new_from_evdev ((ClutterInputDevice *) device,
                                             stage_cogl->wrapper,
                                             device->xkb,
                                             _time, key, state);

  _clutter_event_push (event, FALSE);

  if (!xkb_key_repeats (xkb_state_get_map (device->xkb), key))
    return;

  if (state)
    {
      if (device->repeat_key != XKB_KEYCODE_INVALID)
        g_source_remove (device->repeat_source);
      device->repeat_key = key;
      device->repeat_time = _time + KEY_REPEAT_DELAY;
      device->repeat_source = g_timeout_add (KEY_REPEAT_DELAY,
                                             clutter_wayland_repeat_key,
                                             device);
      device->is_initial_repeat = TRUE;
    }
  else if (device->repeat_key == key)
    {
      g_source_remove (device->repeat_source);
      device->repeat_key = XKB_KEYCODE_INVALID;
    }
}