<div dir="ltr"><div>Bump.  I just pushed Jasper's simple patch before seeing Daniel's comment about this one.  Did we ever figure out pekka's crash?  I'd like to see this committed soon.<br><br></div>--Jason Ekstrand<br>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Jul 25, 2014 at 5:01 AM, Pekka Paalanen <span dir="ltr"><<a href="mailto:ppaalanen@gmail.com" target="_blank">ppaalanen@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Wed, 16 Jul 2014 23:05:10 +0200<br>
Jonny Lamb <<a href="mailto:jonny.lamb@collabora.co.uk">jonny.lamb@collabora.co.uk</a>> wrote:<br>
<br>
> The compositor reads the values out from weston.ini, the weston<br>
> compositor passes on the values, the weston-info client prints out the<br>
> values, and the values are respected in toytoolkit.<br>
> ---<br>
>  clients/weston-info.c    | 89 +++++++++++++++++++++++++++++++++++++++++++++++-<br>
>  clients/window.c         | 24 +++++++++++--<br>
>  src/compositor-wayland.c | 18 ++++++++--<br>
>  src/compositor.c         |  5 +++<br>
>  src/compositor.h         |  3 ++<br>
>  src/input.c              | 12 +++++--<br>
>  6 files changed, 142 insertions(+), 9 deletions(-)<br>
><br>
> diff --git a/clients/weston-info.c b/clients/weston-info.c<br>
> index df869e3..c53ac74 100644<br>
> --- a/clients/weston-info.c<br>
> +++ b/clients/weston-info.c<br>
> @@ -32,6 +32,8 @@<br>
><br>
>  #include "../shared/os-compatibility.h"<br>
><br>
> +#define MIN(x,y) (((x) < (y)) ? (x) : (y))<br>
> +<br>
>  typedef void (*print_info_t)(void *info);<br>
>  typedef void (*destroy_info_t)(void *info);<br>
><br>
> @@ -87,9 +89,13 @@ struct shm_info {<br>
>  struct seat_info {<br>
>       struct global_info global;<br>
>       struct wl_seat *seat;<br>
> +     struct weston_info *info;<br>
><br>
>       uint32_t capabilities;<br>
>       char *name;<br>
> +<br>
> +     int32_t repeat_rate;<br>
> +     int32_t repeat_delay;<br>
>  };<br>
><br>
>  struct weston_info {<br>
> @@ -291,14 +297,89 @@ print_seat_info(void *data)<br>
>               printf(" touch");<br>
><br>
>       printf("\n");<br>
> +<br>
> +     if (seat->repeat_rate > 0)<br>
> +             printf("\tkeyboard repeat rate: %d\n", seat->repeat_rate);<br>
> +     if (seat->repeat_delay > 0)<br>
> +             printf("\tkeyboard repeat delay: %d\n", seat->repeat_delay);<br>
> +}<br>
> +<br>
> +static void<br>
> +keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,<br>
> +                    uint32_t format, int fd, uint32_t size)<br>
> +{<br>
> +}<br>
> +<br>
> +static void<br>
> +keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,<br>
> +                   uint32_t serial, struct wl_surface *surface,<br>
> +                   struct wl_array *keys)<br>
> +{<br>
> +}<br>
> +<br>
> +static void<br>
> +keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,<br>
> +                   uint32_t serial, struct wl_surface *surface)<br>
> +{<br>
>  }<br>
><br>
>  static void<br>
> +keyboard_handle_key(void *data, struct wl_keyboard *keyboard,<br>
> +                 uint32_t serial, uint32_t time, uint32_t key,<br>
> +                 uint32_t state)<br>
> +{<br>
> +}<br>
> +<br>
> +static void<br>
> +keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,<br>
> +                       uint32_t serial, uint32_t mods_depressed,<br>
> +                       uint32_t mods_latched, uint32_t mods_locked,<br>
> +                       uint32_t group)<br>
> +{<br>
> +}<br>
> +<br>
> +static void<br>
> +keyboard_handle_repeat_info(void *data, struct wl_keyboard *keyboard,<br>
> +                         int32_t rate, int32_t delay)<br>
> +{<br>
> +     struct seat_info *seat = data;<br>
> +<br>
> +     seat->repeat_rate = rate;<br>
> +     seat->repeat_delay = delay;<br>
> +}<br>
> +<br>
> +static const struct wl_keyboard_listener keyboard_listener = {<br>
> +     keyboard_handle_keymap,<br>
> +     keyboard_handle_enter,<br>
> +     keyboard_handle_leave,<br>
> +     keyboard_handle_key,<br>
> +     keyboard_handle_modifiers,<br>
> +     keyboard_handle_repeat_info,<br>
> +};<br>
> +<br>
> +static void<br>
>  seat_handle_capabilities(void *data, struct wl_seat *wl_seat,<br>
>                        enum wl_seat_capability caps)<br>
>  {<br>
>       struct seat_info *seat = data;<br>
> +<br>
>       seat->capabilities = caps;<br>
> +<br>
> +     /* we want listen for repeat_info from wl_keyboard, but only<br>
> +      * do so if the seat info is >= 4 and if we actually have a<br>
> +      * keyboard */<br>
> +     if (seat->global.version < 4)<br>
> +             return;<br>
> +<br>
> +     if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {<br>
> +             struct wl_keyboard *keyboard;<br>
> +<br>
> +             keyboard = wl_seat_get_keyboard(seat->seat);<br>
> +             wl_keyboard_add_listener(keyboard, &keyboard_listener,<br>
> +                                      seat);<br>
> +<br>
> +             seat->info->roundtrip_needed = true;<br>
> +     }<br>
>  }<br>
><br>
>  static void<br>
> @@ -330,14 +411,20 @@ add_seat_info(struct weston_info *info, uint32_t id, uint32_t version)<br>
>  {<br>
>       struct seat_info *seat = xzalloc(sizeof *seat);<br>
><br>
> +     /* required to set roundtrip_needed to true in capabilities<br>
> +      * handler */<br>
> +     seat->info = info;<br>
> +<br>
>       init_global_info(info, &seat->global, id, "wl_seat", version);<br>
>       seat->global.print = print_seat_info;<br>
>       seat->global.destroy = destroy_seat_info;<br>
><br>
>       seat->seat = wl_registry_bind(info->registry,<br>
> -                                   id, &wl_seat_interface, 2);<br>
> +                                   id, &wl_seat_interface, MIN(version, 4));<br>
>       wl_seat_add_listener(seat->seat, &seat_listener, seat);<br>
><br>
> +     seat->repeat_rate = seat->repeat_delay = -1;<br>
> +<br>
>       info->roundtrip_needed = true;<br>
>  }<br>
><br>
> diff --git a/clients/window.c b/clients/window.c<br>
> index b82a93e..906dce6 100644<br>
> --- a/clients/window.c<br>
> +++ b/clients/window.c<br>
> @@ -334,6 +334,9 @@ struct input {<br>
>               xkb_mod_mask_t shift_mask;<br>
>       } xkb;<br>
><br>
> +     int32_t repeat_rate;<br>
> +     int32_t repeat_delay;<br>
> +<br>
>       struct task repeat_task;<br>
>       int repeat_timer_fd;<br>
>       uint32_t repeat_sym;<br>
> @@ -2865,9 +2868,9 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard,<br>
>               input->repeat_key = key;<br>
>               input->repeat_time = time;<br>
>               its.it_interval.tv_sec = 0;<br>
> -             its.it_interval.tv_nsec = 25 * 1000 * 1000;<br>
> +             its.it_interval.tv_nsec = 1000000000 / input->repeat_rate;<br>
>               its.it_value.tv_sec = 0;<br>
> -             its.it_value.tv_nsec = 400 * 1000 * 1000;<br>
> +             its.it_value.tv_nsec = input->repeat_delay * 1000 * 1000;<br>
<br>
</div></div>This may get nsec > 999999999, which seems to just make the timer fail.<br>
The first thing I tried was repeat_delay=1000 and got no repeat at<br>
all. It works, if I set it to 999 instead. :-)<br>
<br>
Also repeat_rate=1 would hit a similar problem.<br>
<div><div class="h5"><br>
>               timerfd_settime(input->repeat_timer_fd, 0, &its, NULL);<br>
>       }<br>
>  }<br>
> @@ -2899,12 +2902,24 @@ keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,<br>
>               input->modifiers |= MOD_SHIFT_MASK;<br>
>  }<br>
><br>
> +static void<br>
> +keyboard_handle_repeat_info(void *data, struct wl_keyboard *keyboard,<br>
> +                         int32_t rate, int32_t delay)<br>
> +{<br>
> +     struct input *input = data;<br>
> +<br>
> +     input->repeat_rate = rate;<br>
> +     input->repeat_delay = delay;<br>
> +}<br>
> +<br>
>  static const struct wl_keyboard_listener keyboard_listener = {<br>
>       keyboard_handle_keymap,<br>
>       keyboard_handle_enter,<br>
>       keyboard_handle_leave,<br>
>       keyboard_handle_key,<br>
>       keyboard_handle_modifiers,<br>
> +     keyboard_handle_repeat_info<br>
> +<br>
>  };<br>
><br>
>  static void<br>
> @@ -4944,7 +4959,7 @@ display_add_input(struct display *d, uint32_t id)<br>
>       input = xzalloc(sizeof *input);<br>
>       input->display = d;<br>
>       input->seat = wl_registry_bind(d->registry, id, &wl_seat_interface,<br>
> -                                    MIN(d->seat_version, 3));<br>
> +                                    MIN(d->seat_version, 4));<br>
>       input->touch_focus = NULL;<br>
>       input->pointer_focus = NULL;<br>
>       input->keyboard_focus = NULL;<br>
> @@ -4965,6 +4980,9 @@ display_add_input(struct display *d, uint32_t id)<br>
><br>
>       input->pointer_surface = wl_compositor_create_surface(d->compositor);<br>
><br>
> +     input->repeat_rate = 40;<br>
> +     input->repeat_delay = 400;<br>
> +<br>
>       input->repeat_timer_fd = timerfd_create(CLOCK_MONOTONIC,<br>
>                                               TFD_CLOEXEC | TFD_NONBLOCK);<br>
>       input->repeat_task.run = keyboard_repeat_func;<br>
> diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c<br>
> index a4dcec2..c57b5dc 100644<br>
> --- a/src/compositor-wayland.c<br>
> +++ b/src/compositor-wayland.c<br>
> @@ -1573,12 +1573,24 @@ input_handle_modifiers(void *data, struct wl_keyboard *keyboard,<br>
>       notify_modifiers(&input->base, serial_out);<br>
>  }<br>
><br>
> +static void<br>
> +input_handle_repeat_info(void *data, struct wl_keyboard *keyboard,<br>
> +                      int32_t rate, int32_t delay)<br>
> +{<br>
> +     struct wayland_input *input = data;<br>
> +     struct wayland_compositor *c = input->compositor;<br>
> +<br>
> +     c->base.kb_repeat_rate = rate;<br>
> +     c->base.kb_repeat_delay = delay;<br>
> +}<br>
> +<br>
>  static const struct wl_keyboard_listener keyboard_listener = {<br>
>       input_handle_keymap,<br>
>       input_handle_keyboard_enter,<br>
>       input_handle_keyboard_leave,<br>
>       input_handle_key,<br>
>       input_handle_modifiers,<br>
> +     input_handle_repeat_info,<br>
>  };<br>
><br>
>  static void<br>
> @@ -1614,7 +1626,7 @@ static const struct wl_seat_listener seat_listener = {<br>
>  };<br>
><br>
>  static void<br>
> -display_add_seat(struct wayland_compositor *c, uint32_t id)<br>
> +display_add_seat(struct wayland_compositor *c, uint32_t id, uint32_t version)<br>
>  {<br>
>       struct wayland_input *input;<br>
><br>
> @@ -1625,7 +1637,7 @@ display_add_seat(struct wayland_compositor *c, uint32_t id)<br>
>       weston_seat_init(&input->base, &c->base, "default");<br>
>       input->compositor = c;<br>
>       input->parent.seat = wl_registry_bind(c->parent.registry, id,<br>
> -                                           &wl_seat_interface, 1);<br>
> +                                           &wl_seat_interface, MIN(version, 4));<br>
<br>
</div></div>You are bumping the wl_seat version straight from 1 up to 4, but you<br>
didn't implement the additions in versions 2 and 3. This leads to the<br>
following crash in the Wayland backend:<br>
<br>
Program received signal SIGSEGV, Segmentation fault.<br>
0x0000000000000000 in ?? ()<br>
(gdb) bt<br>
#0  0x0000000000000000 in ?? ()<br>
#1  0x00007ffff79c7eec in ffi_call_unix64 () from /usr/lib64/libffi.so.6<br>
#2  0x00007ffff79c78bd in ffi_call () from /usr/lib64/libffi.so.6<br>
#3  0x00007ffff5dc435e in wl_closure_invoke (closure=<optimized out>,<br>
    flags=<optimized out>, target=0x6455e0, opcode=1, data=0x6451b0)<br>
    at src/connection.c:934<br>
#4  0x00007ffff5dc165f in dispatch_event (display=0x640dc0,<br>
    queue=<optimized out>) at src/wayland-client.c:1111<br>
#5  0x00007ffff5dc16e3 in dispatch_queue (display=0x640dc0, queue=0x640ec8)<br>
    at src/wayland-client.c:1216<br>
#6  0x00007ffff5dc2748 in wl_display_dispatch_queue (display=0x640dc0,<br>
    queue=0x640ec8) at src/wayland-client.c:1366<br>
#7  0x00007ffff63de94e in wayland_compositor_handle_event (fd=15, mask=1,<br>
    data=0x63f900) at src/compositor-wayland.c:1834<br>
#8  0x00007ffff7bd3280 in wl_event_loop_dispatch (loop=0x6301e0,<br>
    timeout=<optimized out>) at src/event-loop.c:419<br>
#9  0x00007ffff7bd16b5 in wl_display_run (display=0x630150)<br>
    at src/wayland-server.c:969<br>
#10 0x0000000000411ddb in main (argc=1, argv=0x7fffffffdcf8)<br>
    at src/compositor.c:4408<br>
(gdb)<br>
<br>
I didn't look further, but I suppose it is the <a href="http://wl_seat.name" target="_blank">wl_seat.name</a> event<br>
causing this.<br>
<div><div class="h5"><br>
>       wl_list_insert(c->input_list.prev, &input->link);<br>
><br>
>       wl_seat_add_listener(input->parent.seat, &seat_listener, input);<br>
> @@ -1781,7 +1793,7 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,<br>
>                       wl_registry_bind(registry, name,<br>
>                                        &_wl_fullscreen_shell_interface, 1);<br>
>       } else if (strcmp(interface, "wl_seat") == 0) {<br>
> -             display_add_seat(c, name);<br>
> +             display_add_seat(c, name, version);<br>
>       } else if (strcmp(interface, "wl_output") == 0) {<br>
>               wayland_compositor_register_output(c, name);<br>
>       } else if (strcmp(interface, "wl_shm") == 0) {<br>
> diff --git a/src/compositor.c b/src/compositor.c<br>
> index 17fce8d..745e194 100644<br>
> --- a/src/compositor.c<br>
> +++ b/src/compositor.c<br>
> @@ -3712,6 +3712,11 @@ weston_compositor_init(struct weston_compositor *ec,<br>
>       if (weston_compositor_xkb_init(ec, &xkb_names) < 0)<br>
>               return -1;<br>
><br>
> +     weston_config_section_get_int(s, "repeat-rate",<br>
> +                                   &ec->kb_repeat_rate, 40);<br>
> +     weston_config_section_get_int(s, "repeat-delay",<br>
> +                                   &ec->kb_repeat_delay, 400);<br>
> +<br>
>       text_backend_init(ec);<br>
><br>
>       wl_data_device_manager_init(ec->wl_display);<br>
> diff --git a/src/compositor.h b/src/compositor.h<br>
> index bef5e1d..d0436d1 100644<br>
> --- a/src/compositor.h<br>
> +++ b/src/compositor.h<br>
> @@ -643,6 +643,9 @@ struct weston_compositor {<br>
><br>
>       /* Raw keyboard processing (no libxkbcommon initialization or handling) */<br>
>       int use_xkbcommon;<br>
> +<br>
> +     int32_t kb_repeat_rate;<br>
> +     int32_t kb_repeat_delay;<br>
>  };<br>
><br>
>  struct weston_buffer {<br>
> diff --git a/src/input.c b/src/input.c<br>
> index 2c799f4..ffa2626 100644<br>
> --- a/src/input.c<br>
> +++ b/src/input.c<br>
> @@ -1758,6 +1758,14 @@ seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,<br>
>                   wl_resource_get_link(cr))<br>
>                       wl_data_device_set_keyboard_focus(seat);<br>
>       }<br>
> +<br>
> +     /* if wl_seat's version is at least 4, the wl_keyboard's<br>
> +      * version must be 4, so we support repeat_info */<br>
> +     if (wl_resource_get_version(resource) >= 4) {<br>
> +             wl_keyboard_send_repeat_info(cr,<br>
> +                                          seat->compositor->kb_repeat_rate,<br>
> +                                          seat->compositor->kb_repeat_delay);<br>
> +     }<br>
>  }<br>
><br>
>  static void<br>
> @@ -1813,7 +1821,7 @@ bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)<br>
>       enum wl_seat_capability caps = 0;<br>
><br>
>       resource = wl_resource_create(client,<br>
> -                                   &wl_seat_interface, MIN(version, 3), id);<br>
> +                                   &wl_seat_interface, MIN(version, 4), id);<br>
>       wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource));<br>
>       wl_resource_set_implementation(resource, &seat_interface, data,<br>
>                                      unbind_resource);<br>
> @@ -2207,7 +2215,7 @@ weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,<br>
>       wl_signal_init(&seat->destroy_signal);<br>
>       wl_signal_init(&seat->updated_caps_signal);<br>
><br>
> -     seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 3,<br>
> +     seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 4,<br>
>                                       seat, bind_seat);<br>
><br>
>       seat->compositor = ec;<br>
<br>
</div></div>It might have made it a bit easier to patch compositor, wayland-backend<br>
and clients in separate commits, so I could have applied the compositor<br>
patch at least.<br>
<br>
Also, could you add updates to the weston.ini man page, please?<br>
<br>
<br>
Thanks,<br>
pq<br>
<div class="HOEnZb"><div class="h5">_______________________________________________<br>
wayland-devel mailing list<br>
<a href="mailto:wayland-devel@lists.freedesktop.org">wayland-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/wayland-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/wayland-devel</a><br>
</div></div></blockquote></div><br></div>