diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2012-04-10 00:03:30 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2012-04-10 00:19:40 -0400 |
commit | a00d60f6ac23ea1418025fb474e56c86af6f003e (patch) | |
tree | c806c787b65a2223387012d00a859e7615e6587e | |
parent | 4014a6b05bfda06d2f5e55d9408012f14032f7c9 (diff) |
evdev: Get key state from kernel on vt enter
We need this to correctly initialize compositor key state, modifier state and
to send the right keys in the key enter event.
-rw-r--r-- | src/evdev.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/evdev.c b/src/evdev.c index d328264..9cb13cc 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -557,6 +557,45 @@ device_removed(struct evdev_input_device *device) free(device); } +static void +evdev_notify_keyboard_focus(struct evdev_input *input) +{ + struct evdev_input_device *device; + struct wl_array keys; + unsigned int i, set; + char evdev_keys[(KEY_CNT + 7) / 8], all_keys[(KEY_CNT + 7) / 8]; + uint32_t *k; + int ret; + + memset(all_keys, 0, sizeof all_keys); + wl_list_for_each(device, &input->devices_list, link) { + memset(evdev_keys, 0, sizeof evdev_keys); + ret = ioctl(device->fd, + EVIOCGKEY(sizeof evdev_keys), evdev_keys); + if (ret < 0) { + fprintf(stderr, "failed to get keys for device %s\n", + device->devnode); + continue; + } + for (i = 0; i < ARRAY_LENGTH(evdev_keys); i++) + all_keys[i] |= evdev_keys[i]; + } + + wl_array_init(&keys); + for (i = 0; i < KEY_CNT; i++) { + set = all_keys[i >> 3] & (1 << (i & 7)); + if (set) { + k = wl_array_add(&keys, sizeof *k); + *k = i; + } + } + + notify_keyboard_focus(&input->base.input_device, + weston_compositor_get_time(), &keys); + + wl_array_release(&keys); +} + void evdev_add_devices(struct udev *udev, struct weston_input_device *input_base) { @@ -585,6 +624,8 @@ evdev_add_devices(struct udev *udev, struct weston_input_device *input_base) } udev_enumerate_unref(e); + evdev_notify_keyboard_focus(input); + if (wl_list_empty(&input->devices_list)) { fprintf(stderr, "warning: no input devices on entering Weston. " @@ -716,6 +757,9 @@ evdev_remove_devices(struct weston_input_device *input_base) wl_list_for_each_safe(device, next, &input->devices_list, link) device_removed(device); + + notify_keyboard_focus(&input->base.input_device, + weston_compositor_get_time(), NULL); } void |