[PATCH weston] input: send wl_keyboard.repeat_info with rate and delay info
Jonny Lamb
jonny.lamb at collabora.co.uk
Thu Nov 28 06:34:59 PST 2013
The compositor reads the values out from weston.ini, the weston
compositor passes on the values, the weston-info client prints out the
values, and the values are respected in toytoolkit.
---
clients/weston-info.c | 106 ++++++++++++++++++++++++++++++++++++++++++++---
clients/window.c | 24 +++++++++--
src/compositor-wayland.c | 18 ++++++--
src/compositor.c | 5 +++
src/compositor.h | 3 ++
src/input.c | 12 +++++-
6 files changed, 154 insertions(+), 14 deletions(-)
diff --git a/clients/weston-info.c b/clients/weston-info.c
index 4cc0572..9af3240 100644
--- a/clients/weston-info.c
+++ b/clients/weston-info.c
@@ -29,6 +29,8 @@
#include "../shared/os-compatibility.h"
+#define MIN(x,y) (((x) < (y)) ? (x) : (y))
+
typedef void (*print_info_t)(void *info);
struct global_info {
@@ -85,6 +87,9 @@ struct seat_info {
uint32_t capabilities;
char *name;
+
+ int32_t repeat_rate;
+ int32_t repeat_delay;
};
struct weston_info {
@@ -270,22 +275,105 @@ 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,
+};
+
+/* This is a struct so we don't have to add a (circular) pointer in
+ * seat_info to weston_info just so roundtrip_needed can be set to
+ * true. */
+struct seat_async_data {
+ struct seat_info *seat;
+ struct weston_info *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;
+ struct seat_async_data *async_data = data;
+
+ async_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 (async_data->seat->global.version < 4)
+ return;
+
+ if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {
+ struct wl_keyboard *keyboard;
+
+ keyboard = wl_seat_get_keyboard(async_data->seat->seat);
+ wl_keyboard_add_listener(keyboard, &keyboard_listener,
+ async_data->seat);
+
+ async_data->info->roundtrip_needed = true;
+ }
}
static void
seat_handle_name(void *data, struct wl_seat *wl_seat,
const char *name)
{
- struct seat_info *seat = data;
- seat->name = strdup(name);
+ struct seat_async_data *async_data = data;
+ async_data->seat->name = strdup(name);
}
static const struct wl_seat_listener seat_listener = {
@@ -297,13 +385,19 @@ static void
add_seat_info(struct weston_info *info, uint32_t id, uint32_t version)
{
struct seat_info *seat = xmalloc(sizeof *seat);
+ struct seat_async_data *async_data = xmalloc(sizeof *async_data);
+
+ async_data->seat = seat;
+ async_data->info = info;
init_global_info(info, &seat->global, id, "wl_seat", version);
seat->global.print = print_seat_info;
seat->seat = wl_registry_bind(info->registry,
- id, &wl_seat_interface, 2);
- wl_seat_add_listener(seat->seat, &seat_listener, seat);
+ id, &wl_seat_interface, MIN(version, 4));
+ wl_seat_add_listener(seat->seat, &seat_listener, async_data);
+
+ seat->repeat_rate = seat->repeat_delay = -1;
info->roundtrip_needed = true;
}
diff --git a/clients/window.c b/clients/window.c
index a201ebb..a8fb39e 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -334,6 +334,9 @@ struct input {
xkb_mod_mask_t shift_mask;
} xkb;
+ int32_t repeat_rate;
+ int32_t repeat_delay;
+
struct task repeat_task;
int repeat_timer_fd;
uint32_t repeat_sym;
@@ -2936,9 +2939,9 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
input->repeat_key = key;
input->repeat_time = time;
its.it_interval.tv_sec = 0;
- its.it_interval.tv_nsec = 25 * 1000 * 1000;
+ its.it_interval.tv_nsec = (1000 / input->repeat_rate) * 1000 * 1000;
its.it_value.tv_sec = 0;
- its.it_value.tv_nsec = 400 * 1000 * 1000;
+ its.it_value.tv_nsec = input->repeat_delay * 1000 * 1000;
timerfd_settime(input->repeat_timer_fd, 0, &its, NULL);
}
}
@@ -2970,12 +2973,24 @@ keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
input->modifiers |= MOD_SHIFT_MASK;
}
+static void
+keyboard_handle_repeat_info(void *data, struct wl_keyboard *keyboard,
+ int32_t rate, int32_t delay)
+{
+ struct input *input = data;
+
+ input->repeat_rate = rate;
+ input->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
@@ -4778,7 +4793,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;
@@ -4796,6 +4811,9 @@ display_add_input(struct display *d, uint32_t id)
input->pointer_surface = wl_compositor_create_surface(d->compositor);
+ input->repeat_rate = 25;
+ input->repeat_delay = 400;
+
input->repeat_timer_fd = timerfd_create(CLOCK_MONOTONIC,
TFD_CLOEXEC | TFD_NONBLOCK);
input->repeat_task.run = keyboard_repeat_func;
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index 7b280b8..eb80d49 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -1276,12 +1276,24 @@ input_handle_modifiers(void *data, struct wl_keyboard *keyboard,
notify_modifiers(&input->base, serial_out);
}
+static void
+input_handle_repeat_info(void *data, struct wl_keyboard *keyboard,
+ int32_t rate, int32_t delay)
+{
+ struct wayland_input *input = data;
+ struct wayland_compositor *c = input->compositor;
+
+ c->base.kb_repeat_rate = rate;
+ c->base.kb_repeat_delay = delay;
+}
+
static const struct wl_keyboard_listener keyboard_listener = {
input_handle_keymap,
input_handle_keyboard_enter,
input_handle_keyboard_leave,
input_handle_key,
input_handle_modifiers,
+ input_handle_repeat_info,
};
static void
@@ -1317,7 +1329,7 @@ static const struct wl_seat_listener seat_listener = {
};
static void
-display_add_seat(struct wayland_compositor *c, uint32_t id)
+display_add_seat(struct wayland_compositor *c, uint32_t id, uint32_t version)
{
struct wayland_input *input;
@@ -1328,7 +1340,7 @@ display_add_seat(struct wayland_compositor *c, uint32_t id)
weston_seat_init(&input->base, &c->base, "default");
input->compositor = c;
input->parent.seat = wl_registry_bind(c->parent.registry, id,
- &wl_seat_interface, 1);
+ &wl_seat_interface, MIN(version, 4));
wl_list_insert(c->input_list.prev, &input->link);
wl_seat_add_listener(input->parent.seat, &seat_listener, input);
@@ -1353,7 +1365,7 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
wl_registry_bind(registry, name,
&wl_shell_interface, 1);
} else if (strcmp(interface, "wl_seat") == 0) {
- display_add_seat(c, name);
+ display_add_seat(c, name, version);
} else if (strcmp(interface, "wl_shm") == 0) {
c->parent.shm =
wl_registry_bind(registry, name, &wl_shm_interface, 1);
diff --git a/src/compositor.c b/src/compositor.c
index cfcb273..947f9b0 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -3373,6 +3373,11 @@ weston_compositor_init(struct weston_compositor *ec,
if (weston_compositor_xkb_init(ec, &xkb_names) < 0)
return -1;
+ weston_config_section_get_int(s, "repeat-rate",
+ &ec->kb_repeat_rate, 25);
+ weston_config_section_get_int(s, "repeat-delay",
+ &ec->kb_repeat_delay, 400);
+
ec->ping_handler = NULL;
screenshooter_create(ec);
diff --git a/src/compositor.h b/src/compositor.h
index 8c19619..50c834d 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -626,6 +626,9 @@ struct weston_compositor {
/* Raw keyboard processing (no libxkbcommon initialization or handling) */
int use_xkbcommon;
+
+ int32_t kb_repeat_rate;
+ int32_t kb_repeat_delay;
};
struct weston_buffer {
diff --git a/src/input.c b/src/input.c
index ae0e832..e5d2b51 100644
--- a/src/input.c
+++ b/src/input.c
@@ -1643,6 +1643,14 @@ seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
wl_resource_get_link(cr))
wl_data_device_set_keyboard_focus(seat);
}
+
+ /* if wl_seat's version is at least 4, the wl_keyboard's
+ * version must be 4, so we support repeat_info */
+ if (wl_resource_get_version(resource) >= 4) {
+ wl_keyboard_send_repeat_info(cr,
+ seat->compositor->kb_repeat_rate,
+ seat->compositor->kb_repeat_delay);
+ }
}
static void
@@ -1698,7 +1706,7 @@ bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
enum wl_seat_capability caps = 0;
resource = wl_resource_create(client,
- &wl_seat_interface, MIN(version, 3), id);
+ &wl_seat_interface, MIN(version, 4), id);
wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource));
wl_resource_set_implementation(resource, &seat_interface, data,
unbind_resource);
@@ -2057,7 +2065,7 @@ weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
wl_list_init(&seat->drag_resource_list);
wl_signal_init(&seat->destroy_signal);
- seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 3,
+ seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 4,
seat, bind_seat);
seat->compositor = ec;
--
1.8.4.2
More information about the wayland-devel
mailing list