From 0695908a9f8e5ff2f380005d1dacbfacebaa06dd Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Tue, 12 Aug 2014 14:58:27 +0200 Subject: [PATCH] clients: use repeat_info event details The weston-info client prints out the values, and the values are respected in toytoolkit when actually repeating keys.. --- clients/weston-info.c | 89 ++++++++++++++++++++++++++++++++++++++++++- clients/window.c | 49 +++++++++++++++++++++--- 2 files changed, 132 insertions(+), 6 deletions(-) diff --git a/clients/weston-info.c b/clients/weston-info.c index df869e3b..c53ac74e 100644 --- a/clients/weston-info.c +++ b/clients/weston-info.c @@ -32,6 +32,8 @@ #include "../shared/os-compatibility.h" +#define MIN(x,y) (((x) < (y)) ? (x) : (y)) + typedef void (*print_info_t)(void *info); typedef void (*destroy_info_t)(void *info); @@ -87,9 +89,13 @@ struct shm_info { struct seat_info { struct global_info global; struct wl_seat *seat; + struct weston_info *info; uint32_t capabilities; char *name; + + int32_t repeat_rate; + int32_t repeat_delay; }; struct weston_info { @@ -291,14 +297,89 @@ print_seat_info(void *data) printf(" touch"); printf("\n"); + + if (seat->repeat_rate > 0) + printf("\tkeyboard repeat rate: %d\n", seat->repeat_rate); + if (seat->repeat_delay > 0) + printf("\tkeyboard repeat delay: %d\n", seat->repeat_delay); +} + +static void +keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, + uint32_t format, int fd, uint32_t size) +{ +} + +static void +keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, + uint32_t serial, struct wl_surface *surface, + struct wl_array *keys) +{ +} + +static void +keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, + uint32_t serial, struct wl_surface *surface) +{ } +static void +keyboard_handle_key(void *data, struct wl_keyboard *keyboard, + uint32_t serial, uint32_t time, uint32_t key, + uint32_t state) +{ +} + +static void +keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, + uint32_t serial, uint32_t mods_depressed, + uint32_t mods_latched, uint32_t mods_locked, + uint32_t group) +{ +} + +static void +keyboard_handle_repeat_info(void *data, struct wl_keyboard *keyboard, + int32_t rate, int32_t delay) +{ + struct seat_info *seat = data; + + seat->repeat_rate = rate; + seat->repeat_delay = delay; +} + +static const struct wl_keyboard_listener keyboard_listener = { + keyboard_handle_keymap, + keyboard_handle_enter, + keyboard_handle_leave, + keyboard_handle_key, + keyboard_handle_modifiers, + keyboard_handle_repeat_info, +}; + static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, enum wl_seat_capability caps) { struct seat_info *seat = data; + seat->capabilities = caps; + + /* we want listen for repeat_info from wl_keyboard, but only + * do so if the seat info is >= 4 and if we actually have a + * keyboard */ + if (seat->global.version < 4) + return; + + if (caps & WL_SEAT_CAPABILITY_KEYBOARD) { + struct wl_keyboard *keyboard; + + keyboard = wl_seat_get_keyboard(seat->seat); + wl_keyboard_add_listener(keyboard, &keyboard_listener, + seat); + + seat->info->roundtrip_needed = true; + } } static void @@ -330,14 +411,20 @@ add_seat_info(struct weston_info *info, uint32_t id, uint32_t version) { struct seat_info *seat = xzalloc(sizeof *seat); + /* required to set roundtrip_needed to true in capabilities + * handler */ + seat->info = info; + init_global_info(info, &seat->global, id, "wl_seat", version); seat->global.print = print_seat_info; seat->global.destroy = destroy_seat_info; seat->seat = wl_registry_bind(info->registry, - id, &wl_seat_interface, 2); + id, &wl_seat_interface, MIN(version, 4)); wl_seat_add_listener(seat->seat, &seat_listener, seat); + seat->repeat_rate = seat->repeat_delay = -1; + info->roundtrip_needed = true; } diff --git a/clients/window.c b/clients/window.c index 85e5de82..a8bc2602 100644 --- a/clients/window.c +++ b/clients/window.c @@ -334,6 +334,11 @@ struct input { xkb_mod_mask_t shift_mask; } xkb; + int32_t repeat_rate_sec; + int32_t repeat_rate_nsec; + int32_t repeat_delay_sec; + int32_t repeat_delay_nsec; + struct task repeat_task; int repeat_timer_fd; uint32_t repeat_sym; @@ -2864,10 +2869,10 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard, input->repeat_sym = sym; input->repeat_key = key; input->repeat_time = time; - its.it_interval.tv_sec = 0; - its.it_interval.tv_nsec = 25 * 1000 * 1000; - its.it_value.tv_sec = 0; - its.it_value.tv_nsec = 400 * 1000 * 1000; + its.it_interval.tv_sec = input->repeat_rate_sec; + its.it_interval.tv_nsec = input->repeat_rate_nsec; + its.it_value.tv_sec = input->repeat_delay_sec; + its.it_value.tv_nsec = input->repeat_delay_nsec; timerfd_settime(input->repeat_timer_fd, 0, &its, NULL); } } @@ -2899,12 +2904,44 @@ keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, input->modifiers |= MOD_SHIFT_MASK; } +static void +set_repeat_info(struct input *input, int32_t rate, int32_t delay) +{ + input->repeat_rate_sec = input->repeat_rate_nsec = 0; + input->repeat_delay_sec = input->repeat_delay_nsec = 0; + + /* a rate of zero disables any repeating, regardless of the delay's + * value */ + if (rate == 0) + return; + + if (rate == 1) + input->repeat_rate_sec = 1; + else + input->repeat_rate_nsec = 1000000000 / rate; + + input->repeat_delay_sec = delay / 1000; + delay -= (input->repeat_delay_sec * 1000); + input->repeat_delay_nsec = delay * 1000 * 1000; +} + +static void +keyboard_handle_repeat_info(void *data, struct wl_keyboard *keyboard, + int32_t rate, int32_t delay) +{ + struct input *input = data; + + set_repeat_info(input, rate, delay); +} + static const struct wl_keyboard_listener keyboard_listener = { keyboard_handle_keymap, keyboard_handle_enter, keyboard_handle_leave, keyboard_handle_key, keyboard_handle_modifiers, + keyboard_handle_repeat_info + }; static void @@ -4969,7 +5006,7 @@ display_add_input(struct display *d, uint32_t id) input = xzalloc(sizeof *input); input->display = d; input->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, - MIN(d->seat_version, 3)); + MIN(d->seat_version, 4)); input->touch_focus = NULL; input->pointer_focus = NULL; input->keyboard_focus = NULL; @@ -4990,6 +5027,8 @@ display_add_input(struct display *d, uint32_t id) input->pointer_surface = wl_compositor_create_surface(d->compositor); + set_repeat_info(input, 40, 400); + input->repeat_timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); input->repeat_task.run = keyboard_repeat_func;