[PATCH weston 3/3] clients: use repeat_info event details

Jonny Lamb jonny.lamb at collabora.co.uk
Tue Aug 12 05:58:27 PDT 2014


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 df869e3..c53ac74 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 85e5de8..a8bc260 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;
-- 
2.1.0.rc1



More information about the wayland-devel mailing list