On Sun, Jan 17, 2016 at 05:59:50PM +0800, Jonas Ådahl wrote: > On Tue, Dec 08, 2015 at 11:15:01AM +1000, Peter Hutterer wrote: > > Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> > > Took another look at this patch. I noticed a few things. > > First, it doesn't build when screen-share and the RDP backend is > enabled, because of the API changes in the first patch. > > The other thing is that if weston runs on top of a compositor that > doesn't support the .frame event, it will fail to implement support on > its own. In other words, if compositor-wayland runs on an older wl_seat, > it needs to emit wl_pointer.frame events by itself. The same applies to > screen-share. The RDP backend also wasn't updated to emit the new .frame > event.
sorry about that, I'll send the missing pieces asap. However: screen-share only registers seat version 1, which means it will never get frame events anyway. Fixing that is a larger issue that I'd like to keep out of the current patchset. Cheers, Peter > > --- > > Changes to v2: > > - use the new weston axis event struct, client-side is still a per-event > > handler (could be done at some later point) > > - couple of minor improvements to extracting the information out of libinput > > > > clients/eventdemo.c | 57 ++++++++++++++++- > > clients/window.c | 97 ++++++++++++++++++++++++++++- > > clients/window.h | 31 +++++++++ > > desktop-shell/exposay.c | 12 ++++ > > desktop-shell/shell.c | 33 ++++++++++ > > ivi-shell/hmi-controller.c | 15 +++++ > > src/compositor-wayland.c | 66 ++++++++++++++++++++ > > src/compositor-x11.c | 13 ++++ > > src/compositor.h | 16 +++++ > > src/data-device.c | 12 ++++ > > src/input.c | 93 ++++++++++++++++++++++++--- > > src/libinput-device.c | 128 > > ++++++++++++++++++++++++++++---------- > > tests/weston-test-client-helper.c | 32 ++++++++++ > > 13 files changed, 564 insertions(+), 41 deletions(-) > > > > diff --git a/clients/eventdemo.c b/clients/eventdemo.c > > index bdad6fd..e323aa5 100644 > > --- a/clients/eventdemo.c > > +++ b/clients/eventdemo.c > > @@ -259,6 +259,54 @@ axis_handler(struct widget *widget, struct input > > *input, uint32_t time, > > wl_fixed_to_double(value)); > > } > > > > +static void > > +pointer_frame_handler(struct widget *widget, struct input *input, void > > *data) > > +{ > > + printf("pointer frame\n"); > > +} > > + > > +static void > > +axis_source_handler(struct widget *widget, struct input *input, > > + uint32_t source, void *data) > > +{ > > + const char *axis_source; > > + > > + switch (source) { > > + case WL_POINTER_AXIS_SOURCE_WHEEL: > > + axis_source = "wheel"; > > + break; > > + case WL_POINTER_AXIS_SOURCE_FINGER: > > + axis_source = "finger"; > > + break; > > + case WL_POINTER_AXIS_SOURCE_CONTINUOUS: > > + axis_source = "continuous"; > > + break; > > + default: > > + axis_source = "<invalid source value>"; > > + break; > > + } > > + > > + printf("axis source: %s\n", axis_source); > > +} > > + > > +static void > > +axis_stop_handler(struct widget *widget, struct input *input, > > + uint32_t time, uint32_t axis, > > + void *data) > > +{ > > + printf("axis stop time: %d, axis: %s\n", > > + time, > > + axis == WL_POINTER_AXIS_VERTICAL_SCROLL ? "vertical" : > > + "horizontal"); > > +} > > + > > +static void > > +axis_discrete_handler(struct widget *widget, struct input *input, > > + uint32_t axis, int32_t discrete, void *data) > > +{ > > + printf("axis discrete axis: %d value: %d\n", axis, discrete); > > +} > > + > > /** > > * \brief CALLBACK function, Waylands informs about pointer motion > > * \param widget widget > > @@ -347,8 +395,15 @@ eventdemo_create(struct display *d) > > /* Set the callback motion handler for the window */ > > widget_set_motion_handler(e->widget, motion_handler); > > > > + /* Set the callback pointer frame handler for the window */ > > + widget_set_pointer_frame_handler(e->widget, pointer_frame_handler); > > + > > /* Set the callback axis handler for the window */ > > - widget_set_axis_handler(e->widget, axis_handler); > > + widget_set_axis_handlers(e->widget, > > + axis_handler, > > + axis_source_handler, > > + axis_stop_handler, > > + axis_discrete_handler); > > > > /* Initial drawing of the window */ > > window_schedule_resize(e->window, width, height); > > diff --git a/clients/window.c b/clients/window.c > > index 5d69116..7d45acd 100644 > > --- a/clients/window.c > > +++ b/clients/window.c > > @@ -282,6 +282,10 @@ struct widget { > > widget_touch_frame_handler_t touch_frame_handler; > > widget_touch_cancel_handler_t touch_cancel_handler; > > widget_axis_handler_t axis_handler; > > + widget_pointer_frame_handler_t pointer_frame_handler; > > + widget_axis_source_handler_t axis_source_handler; > > + widget_axis_stop_handler_t axis_stop_handler; > > + widget_axis_discrete_handler_t axis_discrete_handler; > > void *user_data; > > int opaque; > > int tooltip_count; > > @@ -1930,6 +1934,26 @@ widget_set_axis_handler(struct widget *widget, > > widget->axis_handler = handler; > > } > > > > +void > > +widget_set_pointer_frame_handler(struct widget *widget, > > + widget_pointer_frame_handler_t handler) > > +{ > > + widget->pointer_frame_handler = handler; > > +} > > + > > +void > > +widget_set_axis_handlers(struct widget *widget, > > + widget_axis_handler_t axis_handler, > > + widget_axis_source_handler_t axis_source_handler, > > + widget_axis_stop_handler_t axis_stop_handler, > > + widget_axis_discrete_handler_t axis_discrete_handler) > > +{ > > + widget->axis_handler = axis_handler; > > + widget->axis_source_handler = axis_source_handler; > > + widget->axis_stop_handler = axis_stop_handler; > > + widget->axis_discrete_handler = axis_discrete_handler; > > +} > > + > > static void > > window_schedule_redraw_task(struct window *window); > > > > @@ -2780,12 +2804,83 @@ pointer_handle_axis(void *data, struct wl_pointer > > *pointer, > > widget->user_data); > > } > > > > +static void > > +pointer_handle_frame(void *data, struct wl_pointer *pointer) > > +{ > > + struct input *input = data; > > + struct widget *widget; > > + > > + widget = input->focus_widget; > > + if (input->grab) > > + widget = input->grab; > > + if (widget && widget->pointer_frame_handler) > > + (*widget->pointer_frame_handler)(widget, > > + input, > > + widget->user_data); > > +} > > + > > +static void > > +pointer_handle_axis_source(void *data, struct wl_pointer *pointer, > > + uint32_t source) > > +{ > > + struct input *input = data; > > + struct widget *widget; > > + > > + widget = input->focus_widget; > > + if (input->grab) > > + widget = input->grab; > > + if (widget && widget->axis_source_handler) > > + (*widget->axis_source_handler)(widget, > > + input, > > + source, > > + widget->user_data); > > +} > > + > > +static void > > +pointer_handle_axis_stop(void *data, struct wl_pointer *pointer, > > + uint32_t time, uint32_t axis) > > +{ > > + struct input *input = data; > > + struct widget *widget; > > + > > + widget = input->focus_widget; > > + if (input->grab) > > + widget = input->grab; > > + if (widget && widget->axis_stop_handler) > > + (*widget->axis_stop_handler)(widget, > > + input, time, > > + axis, > > + widget->user_data); > > +} > > + > > +static void > > +pointer_handle_axis_discrete(void *data, struct wl_pointer *pointer, > > + uint32_t axis, int32_t discrete) > > +{ > > + struct input *input = data; > > + struct widget *widget; > > + > > + widget = input->focus_widget; > > + if (input->grab) > > + widget = input->grab; > > + if (widget && widget->axis_discrete_handler) > > + (*widget->axis_discrete_handler)(widget, > > + input, > > + axis, > > + discrete, > > + widget->user_data); > > +} > > + > > static const struct wl_pointer_listener pointer_listener = { > > pointer_handle_enter, > > pointer_handle_leave, > > pointer_handle_motion, > > pointer_handle_button, > > pointer_handle_axis, > > + pointer_handle_frame, > > + pointer_handle_axis_source, > > + pointer_handle_axis_stop, > > + pointer_handle_axis_discrete, > > }; > > > > static void > > @@ -5178,7 +5273,7 @@ static void > > display_add_input(struct display *d, uint32_t id, int display_seat_version) > > { > > struct input *input; > > - int seat_version = MIN(display_seat_version, 4); > > + int seat_version = MIN(display_seat_version, 5); > > > > input = xzalloc(sizeof *input); > > input->display = d; > > diff --git a/clients/window.h b/clients/window.h > > index b92d10c..ba843cc 100644 > > --- a/clients/window.h > > +++ b/clients/window.h > > @@ -267,6 +267,27 @@ typedef void (*widget_axis_handler_t)(struct widget > > *widget, > > wl_fixed_t value, > > void *data); > > > > +typedef void (*widget_pointer_frame_handler_t)(struct widget *widget, > > + struct input *input, > > + void *data); > > + > > +typedef void (*widget_axis_source_handler_t)(struct widget *widget, > > + struct input *input, > > + uint32_t source, > > + void *data); > > + > > +typedef void (*widget_axis_stop_handler_t)(struct widget *widget, > > + struct input *input, > > + uint32_t time, > > + uint32_t axis, > > + void *data); > > + > > +typedef void (*widget_axis_discrete_handler_t)(struct widget *widget, > > + struct input *input, > > + uint32_t axis, > > + int32_t discrete, > > + void *data); > > + > > struct window * > > window_create(struct display *display); > > struct window * > > @@ -516,6 +537,16 @@ void > > widget_set_axis_handler(struct widget *widget, > > widget_axis_handler_t handler); > > void > > +widget_set_pointer_frame_handler(struct widget *widget, > > + widget_pointer_frame_handler_t handler); > > +void > > +widget_set_axis_handlers(struct widget *widget, > > + widget_axis_handler_t axis_handler, > > + widget_axis_source_handler_t axis_source_handler, > > + widget_axis_stop_handler_t axis_stop_handler, > > + widget_axis_discrete_handler_t axis_discrete_handler); > > + > > +void > > widget_schedule_redraw(struct widget *widget); > > void > > widget_set_use_cairo(struct widget *widget, int use_cairo); > > diff --git a/desktop-shell/exposay.c b/desktop-shell/exposay.c > > index f837859..7aa7630 100644 > > --- a/desktop-shell/exposay.c > > +++ b/desktop-shell/exposay.c > > @@ -392,6 +392,16 @@ exposay_axis(struct weston_pointer_grab *grab, > > } > > > > static void > > +exposay_axis_source(struct weston_pointer_grab *grab, uint32_t source) > > +{ > > +} > > + > > +static void > > +exposay_frame(struct weston_pointer_grab *grab) > > +{ > > +} > > + > > +static void > > exposay_pointer_grab_cancel(struct weston_pointer_grab *grab) > > { > > struct desktop_shell *shell = > > @@ -405,6 +415,8 @@ static const struct weston_pointer_grab_interface > > exposay_ptr_grab = { > > exposay_motion, > > exposay_button, > > exposay_axis, > > + exposay_axis_source, > > + exposay_frame, > > exposay_pointer_grab_cancel, > > }; > > > > diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c > > index 8d168ea..14853bf 100644 > > --- a/desktop-shell/shell.c > > +++ b/desktop-shell/shell.c > > @@ -1598,6 +1598,17 @@ noop_grab_axis(struct weston_pointer_grab *grab, > > } > > > > static void > > +noop_grab_axis_source(struct weston_pointer_grab *grab, > > + uint32_t source) > > +{ > > +} > > + > > +static void > > +noop_grab_frame(struct weston_pointer_grab *grab) > > +{ > > +} > > + > > +static void > > constrain_position(struct weston_move_grab *move, int *cx, int *cy) > > { > > struct shell_surface *shsurf = move->base.shsurf; > > @@ -1681,6 +1692,8 @@ static const struct weston_pointer_grab_interface > > move_grab_interface = { > > move_grab_motion, > > move_grab_button, > > noop_grab_axis, > > + noop_grab_axis_source, > > + noop_grab_frame, > > move_grab_cancel, > > }; > > > > @@ -1845,6 +1858,8 @@ static const struct weston_pointer_grab_interface > > resize_grab_interface = { > > resize_grab_motion, > > resize_grab_button, > > noop_grab_axis, > > + noop_grab_axis_source, > > + noop_grab_frame, > > resize_grab_cancel, > > }; > > > > @@ -2010,6 +2025,8 @@ static const struct weston_pointer_grab_interface > > busy_cursor_grab_interface = { > > busy_cursor_grab_motion, > > busy_cursor_grab_button, > > noop_grab_axis, > > + noop_grab_axis_source, > > + noop_grab_frame, > > busy_cursor_grab_cancel, > > }; > > > > @@ -3208,6 +3225,18 @@ popup_grab_axis(struct weston_pointer_grab *grab, > > } > > > > static void > > +popup_grab_axis_source(struct weston_pointer_grab *grab, uint32_t source) > > +{ > > + weston_pointer_send_axis_source(grab->pointer, source); > > +} > > + > > +static void > > +popup_grab_frame(struct weston_pointer_grab *grab) > > +{ > > + weston_pointer_send_frame(grab->pointer); > > +} > > + > > +static void > > popup_grab_cancel(struct weston_pointer_grab *grab) > > { > > popup_grab_end(grab->pointer); > > @@ -3218,6 +3247,8 @@ static const struct weston_pointer_grab_interface > > popup_grab_interface = { > > popup_grab_motion, > > popup_grab_button, > > popup_grab_axis, > > + popup_grab_axis_source, > > + popup_grab_frame, > > popup_grab_cancel, > > }; > > > > @@ -4921,6 +4952,8 @@ static const struct weston_pointer_grab_interface > > rotate_grab_interface = { > > rotate_grab_motion, > > rotate_grab_button, > > noop_grab_axis, > > + noop_grab_axis_source, > > + noop_grab_frame, > > rotate_grab_cancel, > > }; > > > > diff --git a/ivi-shell/hmi-controller.c b/ivi-shell/hmi-controller.c > > index 354fa4d..15e4bda 100644 > > --- a/ivi-shell/hmi-controller.c > > +++ b/ivi-shell/hmi-controller.c > > @@ -1331,6 +1331,19 @@ pointer_default_grab_axis(struct weston_pointer_grab > > *grab, > > } > > > > static void > > +pointer_default_grab_axis_source(struct weston_pointer_grab *grab, > > + uint32_t source) > > +{ > > + weston_pointer_send_axis_source(grab->pointer, source); > > +} > > + > > +static void > > +pointer_default_grab_frame(struct weston_pointer_grab *grab) > > +{ > > + weston_pointer_send_frame(grab->pointer); > > +} > > + > > +static void > > move_grab_update(struct move_grab *move, wl_fixed_t pointer[2]) > > { > > struct timespec timestamp = {0}; > > @@ -1477,6 +1490,8 @@ static const struct weston_pointer_grab_interface > > pointer_move_grab_workspace_in > > pointer_move_grab_motion, > > pointer_move_workspace_grab_button, > > pointer_default_grab_axis, > > + pointer_default_grab_axis_source, > > + pointer_default_grab_frame, > > pointer_move_workspace_grab_cancel > > }; > > > > diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c > > index f94d166..9ee74c6 100644 > > --- a/src/compositor-wayland.c > > +++ b/src/compositor-wayland.c > > @@ -181,6 +181,8 @@ struct wayland_input { > > > > struct wayland_output *output; > > struct wayland_output *keyboard_focus; > > + > > + struct weston_pointer_axis_event vert, horiz; > > }; > > > > struct gl_renderer_interface *gl_renderer; > > @@ -1432,15 +1434,76 @@ input_handle_axis(void *data, struct wl_pointer > > *pointer, > > weston_event.axis = axis; > > weston_event.value = value; > > > > + if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL && > > + input->vert.has_discrete) { > > + weston_event.has_discrete = true; > > + weston_event.discrete = input->vert.discrete; > > + input->vert.has_discrete = false; > > + } else if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL && > > + input->horiz.has_discrete) { > > + weston_event.has_discrete = true; > > + weston_event.discrete = input->horiz.discrete; > > + input->horiz.has_discrete = false; > > + } > > + > > notify_axis(&input->base, time, &weston_event); > > } > > > > +static void > > +input_handle_frame(void *data, struct wl_pointer *pointer) > > +{ > > + struct wayland_input *input = data; > > + > > + notify_pointer_frame(&input->base); > > +} > > + > > +static void > > +input_handle_axis_source(void *data, struct wl_pointer *pointer, > > + uint32_t source) > > +{ > > + struct wayland_input *input = data; > > + > > + notify_axis_source(&input->base, source); > > +} > > + > > +static void > > +input_handle_axis_stop(void *data, struct wl_pointer *pointer, > > + uint32_t time, uint32_t axis) > > +{ > > + struct wayland_input *input = data; > > + struct weston_pointer_axis_event weston_event; > > + > > + weston_event.axis = axis; > > + weston_event.value = 0; > > + > > + notify_axis(&input->base, time, &weston_event); > > +} > > + > > +static void > > +input_handle_axis_discrete(void *data, struct wl_pointer *pointer, > > + uint32_t axis, int32_t discrete) > > +{ > > + struct wayland_input *input = data; > > + > > + if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL) { > > + input->vert.has_discrete = true; > > + input->vert.discrete = discrete; > > + } else if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) { > > + input->horiz.has_discrete = true; > > + input->horiz.discrete = discrete; > > + } > > +} > > + > > static const struct wl_pointer_listener pointer_listener = { > > input_handle_pointer_enter, > > input_handle_pointer_leave, > > input_handle_motion, > > input_handle_button, > > input_handle_axis, > > + input_handle_frame, > > + input_handle_axis_source, > > + input_handle_axis_stop, > > + input_handle_axis_discrete, > > }; > > > > static void > > @@ -1680,6 +1743,9 @@ display_add_seat(struct wayland_backend *b, uint32_t > > id, uint32_t version) > > > > input->parent.cursor.surface = > > wl_compositor_create_surface(b->parent.compositor); > > + > > + input->vert.axis = WL_POINTER_AXIS_VERTICAL_SCROLL; > > + input->horiz.axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL; > > } > > > > static void > > diff --git a/src/compositor-x11.c b/src/compositor-x11.c > > index 93018da..44ac078 100644 > > --- a/src/compositor-x11.c > > +++ b/src/compositor-x11.c > > @@ -1085,6 +1085,8 @@ x11_backend_deliver_button_event(struct x11_backend > > *b, > > * steps. Therefore move the axis by some pixels every step. */ > > if (state) { > > weston_event.value = -DEFAULT_AXIS_STEP_DISTANCE; > > + weston_event.discrete = -1; > > + weston_event.has_discrete = true; > > weston_event.axis = > > WL_POINTER_AXIS_VERTICAL_SCROLL; > > notify_axis(&b->core_seat, > > @@ -1095,6 +1097,8 @@ x11_backend_deliver_button_event(struct x11_backend > > *b, > > case 5: > > if (state) { > > weston_event.value = DEFAULT_AXIS_STEP_DISTANCE; > > + weston_event.discrete = 1; > > + weston_event.has_discrete = true; > > weston_event.axis = > > WL_POINTER_AXIS_VERTICAL_SCROLL; > > notify_axis(&b->core_seat, > > @@ -1105,6 +1109,8 @@ x11_backend_deliver_button_event(struct x11_backend > > *b, > > case 6: > > if (state) { > > weston_event.value = -DEFAULT_AXIS_STEP_DISTANCE; > > + weston_event.discrete = -1; > > + weston_event.has_discrete = true; > > weston_event.axis = > > WL_POINTER_AXIS_HORIZONTAL_SCROLL; > > notify_axis(&b->core_seat, > > @@ -1115,6 +1121,8 @@ x11_backend_deliver_button_event(struct x11_backend > > *b, > > case 7: > > if (state) { > > weston_event.value = DEFAULT_AXIS_STEP_DISTANCE; > > + weston_event.discrete = 1; > > + weston_event.has_discrete = true; > > weston_event.axis = > > WL_POINTER_AXIS_HORIZONTAL_SCROLL; > > notify_axis(&b->core_seat, > > @@ -1131,6 +1139,7 @@ x11_backend_deliver_button_event(struct x11_backend > > *b, > > weston_compositor_get_time(), button, > > state ? WL_POINTER_BUTTON_STATE_PRESSED : > > WL_POINTER_BUTTON_STATE_RELEASED); > > + notify_pointer_frame(&b->core_seat); > > } > > > > static void > > @@ -1162,6 +1171,7 @@ x11_backend_deliver_motion_event(struct x11_backend > > *b, > > > > notify_motion(&b->core_seat, weston_compositor_get_time(), > > &motion_event); > > + notify_pointer_frame(&b->core_seat); > > > > b->prev_x = x; > > b->prev_y = y; > > @@ -1189,6 +1199,7 @@ x11_backend_deliver_enter_event(struct x11_backend *b, > > > > wl_fixed_from_int(enter_notify->event_y), &x, &y); > > > > notify_pointer_focus(&b->core_seat, &output->base, x, y); > > + notify_pointer_frame(&b->core_seat); > > > > b->prev_x = x; > > b->prev_y = y; > > @@ -1342,6 +1353,7 @@ x11_backend_handle_event(int fd, uint32_t mask, void > > *data) > > > > case XCB_ENTER_NOTIFY: > > x11_backend_deliver_enter_event(b, event); > > + notify_pointer_frame(&b->core_seat); > > break; > > > > case XCB_LEAVE_NOTIFY: > > @@ -1351,6 +1363,7 @@ x11_backend_handle_event(int fd, uint32_t mask, void > > *data) > > if (!b->has_xkb) > > update_xkb_state_from_core(b, > > enter_notify->state); > > notify_pointer_focus(&b->core_seat, NULL, 0, 0); > > + notify_pointer_frame(&b->core_seat); > > break; > > > > case XCB_CLIENT_MESSAGE: > > diff --git a/src/compositor.h b/src/compositor.h > > index bf38784..c9e61a5 100644 > > --- a/src/compositor.h > > +++ b/src/compositor.h > > @@ -256,6 +256,8 @@ struct weston_pointer_motion_event { > > struct weston_pointer_axis_event { > > uint32_t axis; > > wl_fixed_t value; > > + bool has_discrete; > > + int32_t discrete; > > }; > > > > struct weston_pointer_grab; > > @@ -268,6 +270,8 @@ struct weston_pointer_grab_interface { > > void (*axis)(struct weston_pointer_grab *grab, > > uint32_t time, > > struct weston_pointer_axis_event *event); > > + void (*axis_source)(struct weston_pointer_grab *grab, uint32_t source); > > + void (*frame)(struct weston_pointer_grab *grab); > > void (*cancel)(struct weston_pointer_grab *grab); > > }; > > > > @@ -406,6 +410,12 @@ weston_pointer_send_axis(struct weston_pointer > > *pointer, > > uint32_t time, > > struct weston_pointer_axis_event *event); > > void > > +weston_pointer_send_axis_source(struct weston_pointer *pointer, > > + uint32_t source); > > +void > > +weston_pointer_send_frame(struct weston_pointer *pointer); > > + > > +void > > weston_pointer_set_focus(struct weston_pointer *pointer, > > struct weston_view *view, > > wl_fixed_t sx, wl_fixed_t sy); > > @@ -1143,6 +1153,12 @@ void > > notify_axis(struct weston_seat *seat, uint32_t time, > > struct weston_pointer_axis_event *event); > > void > > +notify_axis_source(struct weston_seat *seat, uint32_t source); > > + > > +void > > +notify_pointer_frame(struct weston_seat *seat); > > + > > +void > > notify_key(struct weston_seat *seat, uint32_t time, uint32_t key, > > enum wl_keyboard_key_state state, > > enum weston_key_state_update update_state); > > diff --git a/src/data-device.c b/src/data-device.c > > index 9bb4472..02a9fa7 100644 > > --- a/src/data-device.c > > +++ b/src/data-device.c > > @@ -417,6 +417,16 @@ drag_grab_axis(struct weston_pointer_grab *grab, > > } > > > > static void > > +drag_grab_axis_source(struct weston_pointer_grab *grab, uint32_t source) > > +{ > > +} > > + > > +static void > > +drag_grab_frame(struct weston_pointer_grab *grab) > > +{ > > +} > > + > > +static void > > drag_grab_cancel(struct weston_pointer_grab *grab) > > { > > struct weston_pointer_drag *drag = > > @@ -433,6 +443,8 @@ static const struct weston_pointer_grab_interface > > pointer_drag_grab_interface = > > drag_grab_motion, > > drag_grab_button, > > drag_grab_axis, > > + drag_grab_axis_source, > > + drag_grab_frame, > > drag_grab_cancel, > > }; > > > > diff --git a/src/input.c b/src/input.c > > index b87c51c..de0fba1 100644 > > --- a/src/input.c > > +++ b/src/input.c > > @@ -343,9 +343,51 @@ weston_pointer_send_axis(struct weston_pointer > > *pointer, > > return; > > > > resource_list = &pointer->focus_client->pointer_resources; > > - wl_resource_for_each(resource, resource_list) > > - wl_pointer_send_axis(resource, time, > > - event->axis, event->value); > > + wl_resource_for_each(resource, resource_list) { > > + if (event->has_discrete && > > + wl_resource_get_version(resource) >= > > + WL_POINTER_AXIS_DISCRETE_SINCE_VERSION) > > + wl_pointer_send_axis_discrete(resource, event->axis, > > + event->discrete); > > + > > + if (event->value) > > + wl_pointer_send_axis(resource, time, > > + event->axis, event->value); > > + else if (wl_resource_get_version(resource) >= > > + WL_POINTER_AXIS_STOP_SINCE_VERSION) > > + wl_pointer_send_axis_stop(resource, time, > > + event->axis); > > + } > > +} > > + > > +WL_EXPORT void > > +weston_pointer_send_axis_source(struct weston_pointer *pointer, uint32_t > > source) > > +{ > > + struct wl_resource *resource; > > + struct wl_list *resource_list; > > + > > + resource_list = &pointer->focus_client->pointer_resources; > > + wl_resource_for_each(resource, resource_list) { > > + if (wl_resource_get_version(resource) >= > > + WL_POINTER_AXIS_SOURCE_SINCE_VERSION) { > > + wl_pointer_send_axis_source(resource, source); > > + } > > + } > > +} > > + > > +WL_EXPORT void > > +weston_pointer_send_frame(struct weston_pointer *pointer) > > +{ > > + struct wl_resource *resource; > > + struct wl_list *resource_list; > > + > > + resource_list = &pointer->focus_client->pointer_resources; > > + wl_resource_for_each(resource, resource_list) { > > + if (wl_resource_get_version(resource) >= > > + WL_POINTER_FRAME_SINCE_VERSION) { > > + wl_pointer_send_frame(resource); > > + } > > + } > > } > > > > static void > > @@ -357,6 +399,19 @@ default_grab_pointer_axis(struct weston_pointer_grab > > *grab, > > } > > > > static void > > +default_grab_pointer_axis_source(struct weston_pointer_grab *grab, > > + uint32_t source) > > +{ > > + weston_pointer_send_axis_source(grab->pointer, source); > > +} > > + > > +static void > > +default_grab_pointer_frame(struct weston_pointer_grab *grab) > > +{ > > + weston_pointer_send_frame(grab->pointer); > > +} > > + > > +static void > > default_grab_pointer_cancel(struct weston_pointer_grab *grab) > > { > > } > > @@ -367,6 +422,8 @@ static const struct weston_pointer_grab_interface > > default_grab_pointer_motion, > > default_grab_pointer_button, > > default_grab_pointer_axis, > > + default_grab_pointer_axis_source, > > + default_grab_pointer_frame, > > default_grab_pointer_cancel, > > }; > > > > @@ -830,6 +887,7 @@ weston_pointer_set_focus(struct weston_pointer *pointer, > > wl_resource_for_each(resource, focus_resource_list) { > > wl_pointer_send_leave(resource, serial, > > surface_resource); > > + wl_pointer_send_frame(resource); > > } > > } > > > > @@ -856,6 +914,7 @@ weston_pointer_set_focus(struct weston_pointer *pointer, > > serial, > > view->surface->resource, > > sx, sy); > > + wl_pointer_send_frame(resource); > > } > > > > pointer->focus_serial = serial; > > @@ -1277,9 +1336,6 @@ notify_axis(struct weston_seat *seat, uint32_t time, > > > > weston_compositor_wake(compositor); > > > > - if (!event->value) > > - return; > > - > > if (weston_compositor_run_axis_binding(compositor, pointer, > > time, event)) > > return; > > @@ -1287,6 +1343,28 @@ notify_axis(struct weston_seat *seat, uint32_t time, > > pointer->grab->interface->axis(pointer->grab, time, event); > > } > > > > +WL_EXPORT void > > +notify_axis_source(struct weston_seat *seat, uint32_t source) > > +{ > > + struct weston_compositor *compositor = seat->compositor; > > + struct weston_pointer *pointer = weston_seat_get_pointer(seat); > > + > > + weston_compositor_wake(compositor); > > + > > + pointer->grab->interface->axis_source(pointer->grab, source); > > +} > > + > > +WL_EXPORT void > > +notify_pointer_frame(struct weston_seat *seat) > > +{ > > + struct weston_compositor *compositor = seat->compositor; > > + struct weston_pointer *pointer = weston_seat_get_pointer(seat); > > + > > + weston_compositor_wake(compositor); > > + > > + pointer->grab->interface->frame(pointer->grab); > > +} > > + > > WL_EXPORT int > > weston_keyboard_set_locks(struct weston_keyboard *keyboard, > > uint32_t mask, uint32_t value) > > @@ -1970,6 +2048,7 @@ seat_get_pointer(struct wl_client *client, struct > > wl_resource *resource, > > pointer->focus_serial, > > pointer->focus->surface->resource, > > sx, sy); > > + wl_pointer_send_frame(cr); > > } > > } > > > > @@ -2548,7 +2627,7 @@ weston_seat_init(struct weston_seat *seat, struct > > weston_compositor *ec, > > wl_signal_init(&seat->destroy_signal); > > wl_signal_init(&seat->updated_caps_signal); > > > > - seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 4, > > + seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 5, > > seat, bind_seat); > > > > seat->compositor = ec; > > diff --git a/src/libinput-device.c b/src/libinput-device.c > > index 9860d6e..99b2916 100644 > > --- a/src/libinput-device.c > > +++ b/src/libinput-device.c > > @@ -80,7 +80,7 @@ handle_keyboard_key(struct libinput_device > > *libinput_device, > > STATE_UPDATE_AUTOMATIC); > > } > > > > -static void > > +static bool > > handle_pointer_motion(struct libinput_device *libinput_device, > > struct libinput_event_pointer *pointer_event) > > { > > @@ -97,9 +97,11 @@ handle_pointer_motion(struct libinput_device > > *libinput_device, > > notify_motion(device->seat, > > libinput_event_pointer_get_time(pointer_event), > > &event); > > + > > + return true; > > } > > > > -static void > > +static bool > > handle_pointer_motion_absolute( > > struct libinput_device *libinput_device, > > struct libinput_event_pointer *pointer_event) > > @@ -112,7 +114,7 @@ handle_pointer_motion_absolute( > > uint32_t width, height; > > > > if (!output) > > - return; > > + return false; > > > > time = libinput_event_pointer_get_time(pointer_event); > > width = device->output->current_mode->width; > > @@ -127,9 +129,11 @@ handle_pointer_motion_absolute( > > > > weston_output_transform_coordinate(device->output, x, y, &x, &y); > > notify_motion_absolute(device->seat, time, x, y); > > + > > + return true; > > } > > > > -static void > > +static bool > > handle_pointer_button(struct libinput_device *libinput_device, > > struct libinput_event_pointer *pointer_event) > > { > > @@ -145,21 +149,21 @@ handle_pointer_button(struct libinput_device > > *libinput_device, > > seat_button_count != 1) || > > (button_state == LIBINPUT_BUTTON_STATE_RELEASED && > > seat_button_count != 0)) > > - return; > > + return false; > > > > notify_button(device->seat, > > libinput_event_pointer_get_time(pointer_event), > > libinput_event_pointer_get_button(pointer_event), > > libinput_event_pointer_get_button_state(pointer_event)); > > + return true; > > } > > > > static double > > normalize_scroll(struct libinput_event_pointer *pointer_event, > > enum libinput_pointer_axis axis) > > { > > - static int warned; > > enum libinput_pointer_axis_source source; > > - double value; > > + double value = 0.0; > > > > source = libinput_event_pointer_get_axis_source(pointer_event); > > /* libinput < 0.8 sent wheel click events with value 10. Since 0.8 > > @@ -178,48 +182,101 @@ normalize_scroll(struct libinput_event_pointer > > *pointer_event, > > value = libinput_event_pointer_get_axis_value(pointer_event, > > axis); > > break; > > - default: > > - value = 0; > > - if (warned < 5) { > > - weston_log("Unknown scroll source %d. Event > > discarded\n", > > - source); > > - warned++; > > - } > > - break; > > } > > > > return value; > > } > > > > -static void > > +static int32_t > > +get_axis_discrete(struct libinput_event_pointer *pointer_event, > > + enum libinput_pointer_axis axis) > > +{ > > + enum libinput_pointer_axis_source source; > > + > > + source = libinput_event_pointer_get_axis_source(pointer_event); > > + > > + if (source != LIBINPUT_POINTER_AXIS_SOURCE_WHEEL) > > + return 0; > > + > > + return libinput_event_pointer_get_axis_value_discrete(pointer_event, > > + axis); > > +} > > + > > +static bool > > handle_pointer_axis(struct libinput_device *libinput_device, > > struct libinput_event_pointer *pointer_event) > > { > > + static int warned; > > struct evdev_device *device = > > libinput_device_get_user_data(libinput_device); > > - double value; > > + double vert, horiz; > > + int32_t vert_discrete, horiz_discrete; > > enum libinput_pointer_axis axis; > > struct weston_pointer_axis_event weston_event; > > + enum libinput_pointer_axis_source source; > > + uint32_t wl_axis_source; > > + bool has_vert, has_horiz; > > + > > + has_vert = libinput_event_pointer_has_axis(pointer_event, > > + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); > > + has_horiz = libinput_event_pointer_has_axis(pointer_event, > > + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); > > + > > + if (!has_vert && !has_horiz) > > + return false; > > + > > + source = libinput_event_pointer_get_axis_source(pointer_event); > > + switch (source) { > > + case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL: > > + wl_axis_source = WL_POINTER_AXIS_SOURCE_WHEEL; > > + break; > > + case LIBINPUT_POINTER_AXIS_SOURCE_FINGER: > > + wl_axis_source = WL_POINTER_AXIS_SOURCE_FINGER; > > + break; > > + case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS: > > + wl_axis_source = WL_POINTER_AXIS_SOURCE_CONTINUOUS; > > + break; > > + default: > > + if (warned < 5) { > > + weston_log("Unknown scroll source %d.\n", source); > > + warned++; > > + } > > + return false; > > + } > > + > > + notify_axis_source(device->seat, wl_axis_source); > > + > > + if (has_vert) { > > + axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL; > > + vert_discrete = get_axis_discrete(pointer_event, axis); > > + vert = normalize_scroll(pointer_event, axis); > > > > - axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL; > > - if (libinput_event_pointer_has_axis(pointer_event, axis)) { > > - value = normalize_scroll(pointer_event, axis); > > - weston_event.value = wl_fixed_from_double(value); > > weston_event.axis = WL_POINTER_AXIS_VERTICAL_SCROLL; > > + weston_event.value = wl_fixed_from_double(vert); > > + weston_event.discrete = vert_discrete; > > + weston_event.has_discrete = (vert_discrete != 0); > > + > > notify_axis(device->seat, > > libinput_event_pointer_get_time(pointer_event), > > &weston_event); > > } > > > > - axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL; > > - if (libinput_event_pointer_has_axis(pointer_event, axis)) { > > - value = normalize_scroll(pointer_event, axis); > > - weston_event.value = wl_fixed_from_double(value); > > + if (has_horiz) { > > + axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL; > > + horiz_discrete = get_axis_discrete(pointer_event, axis); > > + horiz = normalize_scroll(pointer_event, axis); > > + > > weston_event.axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL; > > + weston_event.value = wl_fixed_from_double(horiz); > > + weston_event.discrete = horiz_discrete; > > + weston_event.has_discrete = (horiz_discrete != 0); > > + > > notify_axis(device->seat, > > libinput_event_pointer_get_time(pointer_event), > > &weston_event); > > } > > + > > + return true; > > } > > > > static void > > @@ -296,7 +353,10 @@ evdev_device_process_event(struct libinput_event > > *event) > > { > > struct libinput_device *libinput_device = > > libinput_event_get_device(event); > > + struct evdev_device *device = > > + libinput_device_get_user_data(libinput_device); > > int handled = 1; > > + bool need_frame = false; > > > > switch (libinput_event_get_type(event)) { > > case LIBINPUT_EVENT_KEYBOARD_KEY: > > @@ -304,21 +364,22 @@ evdev_device_process_event(struct libinput_event > > *event) > > libinput_event_get_keyboard_event(event)); > > break; > > case LIBINPUT_EVENT_POINTER_MOTION: > > - handle_pointer_motion(libinput_device, > > + need_frame = handle_pointer_motion(libinput_device, > > libinput_event_get_pointer_event(event)); > > break; > > case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: > > - handle_pointer_motion_absolute( > > - libinput_device, > > - libinput_event_get_pointer_event(event)); > > + need_frame = handle_pointer_motion_absolute( > > + libinput_device, > > + libinput_event_get_pointer_event(event)); > > break; > > case LIBINPUT_EVENT_POINTER_BUTTON: > > - handle_pointer_button(libinput_device, > > + need_frame = handle_pointer_button(libinput_device, > > libinput_event_get_pointer_event(event)); > > break; > > case LIBINPUT_EVENT_POINTER_AXIS: > > - handle_pointer_axis(libinput_device, > > - libinput_event_get_pointer_event(event)); > > + need_frame = handle_pointer_axis( > > + libinput_device, > > + libinput_event_get_pointer_event(event)); > > break; > > case LIBINPUT_EVENT_TOUCH_DOWN: > > handle_touch_down(libinput_device, > > @@ -342,6 +403,9 @@ evdev_device_process_event(struct libinput_event *event) > > libinput_event_get_type(event)); > > } > > > > + if (need_frame) > > + notify_pointer_frame(device->seat); > > + > > return handled; > > } > > > > diff --git a/tests/weston-test-client-helper.c > > b/tests/weston-test-client-helper.c > > index 16786d9..97c4395 100644 > > --- a/tests/weston-test-client-helper.c > > +++ b/tests/weston-test-client-helper.c > > @@ -197,12 +197,44 @@ pointer_handle_axis(void *data, struct wl_pointer > > *wl_pointer, > > axis, wl_fixed_to_double(value)); > > } > > > > +static void > > +pointer_handle_frame(void *data, struct wl_pointer *wl_pointer) > > +{ > > + fprintf(stderr, "test-client: got pointer frame\n"); > > +} > > + > > +static void > > +pointer_handle_axis_source(void *data, struct wl_pointer *wl_pointer, > > + uint32_t source) > > +{ > > + fprintf(stderr, "test-client: got pointer axis source %u\n", source); > > +} > > + > > +static void > > +pointer_handle_axis_stop(void *data, struct wl_pointer *wl_pointer, > > + uint32_t time, uint32_t axis) > > +{ > > + fprintf(stderr, "test-client: got pointer axis stop\n"); > > +} > > + > > +static void > > +pointer_handle_axis_discrete(void *data, struct wl_pointer *wl_pointer, > > + uint32_t axis, int32_t value) > > +{ > > + fprintf(stderr, "test-client: got pointer axis discrete %u %d\n", > > + axis, value); > > +} > > + > > static const struct wl_pointer_listener pointer_listener = { > > pointer_handle_enter, > > pointer_handle_leave, > > pointer_handle_motion, > > pointer_handle_button, > > pointer_handle_axis, > > + pointer_handle_frame, > > + pointer_handle_axis_source, > > + pointer_handle_axis_stop, > > + pointer_handle_axis_discrete, > > }; > > > > static void > > -- > > 2.5.0 > > > > _______________________________________________ > > wayland-devel mailing list > > wayland-devel@lists.freedesktop.org > > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel