There's nothing fancy about this, we just set a timer and simulate
events using states 2 and 3 for repeat-up and repeat-down events.
---
 src/compositor.c |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/compositor.h |    5 +++
 2 files changed, 77 insertions(+), 0 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 0e33971..8d4ec55 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1438,6 +1438,19 @@ idle_handler(void *data)
        return 1;
 }
 
+static int
+key_repeat_handler(void *data)
+{
+       struct weston_input_device *device = data;
+       int repeat_speed = 100;
+
+       notify_key(&device->input_device, weston_compositor_get_time(), 
device->key_repeat.key, 2);
+       notify_key(&device->input_device, weston_compositor_get_time(), 
device->key_repeat.key, 3);
+       wl_event_source_timer_update(device->key_repeat.source, repeat_speed);
+
+       return 1;
+}
+
 static  void
 weston_input_update_drag_surface(struct wl_input_device *input_device,
                                 int dx, int dy);
@@ -1580,14 +1593,68 @@ update_modifier_state(struct weston_input_device 
*device,
                device->modifier_state &= ~modifier;
 }
 
+static int
+is_repeat_key (uint32_t key)
+{
+       /* Return 0 for keys that should not auto-repeat */
+
+       if (key >= KEY_FN && key <= KEY_FN_B)
+               return 0;
+
+       switch (key) {
+       case KEY_LEFTCTRL:
+       case KEY_RIGHTCTRL:
+       case KEY_LEFTALT:
+       case KEY_RIGHTALT:
+       case KEY_LEFTMETA:
+       case KEY_RIGHTMETA:
+       case KEY_LEFTSHIFT:
+       case KEY_RIGHTSHIFT:
+       case KEY_NUMLOCK:
+       case KEY_SCROLLLOCK:
+               return 0;
+       default:
+               return 1;
+       }
+}
+
 WL_EXPORT void
 notify_key(struct wl_input_device *device,
           uint32_t time, uint32_t key, uint32_t state)
 {
        struct weston_input_device *wd = (struct weston_input_device *) device;
        struct weston_compositor *compositor = wd->compositor;
+       struct wl_event_loop *loop;
+       int repeat_delay = 500;
        uint32_t *k, *end;
 
+       /* FIXME: do this properly when we have xkb map in the compositor */
+       /* For key repeat, use states 2 and 3 for simulated
+        * repeat events to distinguish between real events */
+       if (state != 2 && state != 3 && is_repeat_key(key)) {
+               if (wd->key_repeat.active && key == wd->key_repeat.key && 
!state) {
+                       wl_event_source_remove(wd->key_repeat.source);
+                       wd->key_repeat.key = 0;
+                       wd->key_repeat.active = 0;
+               }
+               if (state) {
+                       if (!wd->key_repeat.active) {
+                               loop = 
wl_display_get_event_loop(compositor->wl_display);
+                               wd->key_repeat.source =
+                                       wl_event_loop_add_timer(loop, 
key_repeat_handler, wd);
+                       }
+
+                       wd->key_repeat.key = key;
+                       wd->key_repeat.active = 1;
+                       wl_event_source_timer_update(wd->key_repeat.source, 
repeat_delay);
+               }
+       }
+
+       if (state == 2)
+               state = 0;
+       if (state == 3)
+               state = 1;
+
        if (state) {
                weston_compositor_idle_inhibit(compositor);
                device->grab_key = key;
@@ -1909,6 +1976,8 @@ weston_input_device_init(struct weston_input_device 
*device,
        device->hotspot_y = 16;
        device->modifier_state = 0;
        device->num_tp = 0;
+       device->key_repeat.key = 0;
+       device->key_repeat.active = 0;
 
        device->drag_surface_destroy_listener.func = 
handle_drag_surface_destroy;
 
@@ -1924,6 +1993,9 @@ weston_input_device_release(struct weston_input_device 
*device)
        if (device->sprite)
                destroy_surface(&device->sprite->surface.resource);
 
+       if (device->key_repeat.active)
+               wl_event_source_remove(device->key_repeat.source);
+
        wl_input_device_release(&device->input_device);
 }
 
diff --git a/src/compositor.h b/src/compositor.h
index b94731b..5ad9943 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -108,6 +108,11 @@ struct weston_input_device {
        struct weston_surface *sprite;
        struct weston_surface *drag_surface;
        struct wl_listener drag_surface_destroy_listener;
+       struct {
+               struct wl_event_source *source;
+               uint32_t key;
+               int active;
+       } key_repeat;
        int32_t hotspot_x, hotspot_y;
        struct wl_list link;
        uint32_t modifier_state;
-- 
1.7.4.1

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to