Hi, Just a quick questions:
1) Is there any way to un-normalize the values? 2) What happens with >1000hz gaming mice for example which need microsecond granularity timestamps? On Mon, Jun 29, 2015 at 3:54 PM, Peter Hutterer <[email protected]> wrote: > On Fri, Jun 26, 2015 at 12:38:01PM +0800, Jonas Ådahl wrote: >> A wl_relative_pointer object is an extension to the wl_pointer interface >> only used for emitting relative pointer events. It will only emit events >> when the parent pointer has focus. >> >> To get a relative pointer object, use the get_relative_pointer request >> of the global wl_relative_pointer_manager object. When stabilizing it >> might make more sense to just add it to wl_seat instead of having a >> single use global interface. >> >> All interface names are currently prefixed with underscore in order to >> avoid any future conflicts with stable protocol. >> >> Signed-off-by: Jonas Ådahl <[email protected]> >> --- >> >> Changes since v2: >> >> * Updated copyright. >> * Updated the license text to corrected one. >> * Clarified that relative motion events are unaffected by clamping. >> * Clarified that pointer acceleration behaviour is device specific. >> * Clarified that the order of relative_motion and motion is not >> guaranteed. >> * Explained that button events etc are to be fetched from the >> corresponding wl_pointer object. >> * Clarified that relative motion events are in x/y coordinate space. >> * Added an 'unstable protocol' warning explaining compatibility etc. >> >> >> Makefile.am | 7 +- >> protocol/relative-pointer.xml | 127 ++++++++++++++++++++++++++++ >> src/compositor.c | 3 + >> src/compositor.h | 5 ++ >> src/input.c | 186 >> ++++++++++++++++++++++++++++++++++++++---- >> 5 files changed, 309 insertions(+), 19 deletions(-) >> create mode 100644 protocol/relative-pointer.xml >> >> diff --git a/Makefile.am b/Makefile.am >> index 0a30cb4..70c436f 100644 >> --- a/Makefile.am >> +++ b/Makefile.am >> @@ -105,7 +105,9 @@ nodist_weston_SOURCES = >> \ >> protocol/presentation_timing-protocol.c \ >> protocol/presentation_timing-server-protocol.h \ >> protocol/scaler-protocol.c \ >> - protocol/scaler-server-protocol.h >> + protocol/scaler-server-protocol.h \ >> + protocol/relative-pointer-protocol.c \ >> + protocol/relative-pointer-server-protocol.h >> >> BUILT_SOURCES += $(nodist_weston_SOURCES) >> >> @@ -1183,7 +1185,8 @@ EXTRA_DIST += \ >> protocol/presentation_timing.xml \ >> protocol/scaler.xml \ >> protocol/ivi-application.xml \ >> - protocol/ivi-hmi-controller.xml >> + protocol/ivi-hmi-controller.xml \ >> + protocol/relative-pointer.xml >> >> # >> # manual test modules in tests subdirectory >> diff --git a/protocol/relative-pointer.xml b/protocol/relative-pointer.xml >> new file mode 100644 >> index 0000000..185d33b >> --- /dev/null >> +++ b/protocol/relative-pointer.xml >> @@ -0,0 +1,127 @@ >> +<?xml version="1.0" encoding="UTF-8"?> >> +<protocol name="relative_pointer"> >> + >> + <copyright> >> + Copyright © 2014 Jonas Ådahl >> + Copyright © 2015 Red Hat Inc. >> + >> + Permission is hereby granted, free of charge, to any person obtaining a >> + copy of this software and associated documentation files (the >> "Software"), >> + to deal in the Software without restriction, including without >> limitation >> + the rights to use, copy, modify, merge, publish, distribute, sublicense, >> + and/or sell copies of the Software, and to permit persons to whom the >> + Software is furnished to do so, subject to the following conditions: >> + >> + The above copyright notice and this permission notice (including the >> next >> + paragraph) shall be included in all copies or substantial portions of >> the >> + Software. >> + >> + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS >> OR >> + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, >> + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL >> + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR >> OTHER >> + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING >> + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER >> + DEALINGS IN THE SOFTWARE. >> + </copyright> >> + >> + <interface name="_wl_relative_pointer_manager" version="1"> >> + <description summary="get relative pointer objects"> >> + A global interface used for getting the relative pointer object for a >> + given seat. >> + >> + Warning! The protocol described in this file is experimental. Each >> version >> + of this protocol should be considered incompatible with any other >> version, >> + and a client binding to a version different to the one advertised >> will be >> + terminated. When the protocol is stabalized, backward compatibility is > > typo: stabilized, but I would say "once the protocol is declared stable" > anyway > > Reviewed-by: Peter Hutterer <[email protected]> > otherwise > > Cheers, > Peter > >> + guaranteed, the '_' prefix will be removed from the name and the >> version >> + will be reset to 1. >> + </description> >> + >> + <request name="get_relative_pointer"> >> + <description summary="get a relative pointer object"> >> + Create a relative pointer interface given a wl_pointer object. See >> + the wl_relative_pointer interface for more details. >> + </description> >> + >> + <arg name="id" type="new_id" interface="_wl_relative_pointer"/> >> + <arg name="pointer" type="object" interface="wl_pointer"/> >> + </request> >> + </interface> >> + >> + <interface name="_wl_relative_pointer" version="1"> >> + <description summary="relative pointer object"> >> + A wl_relative_pointer object is an extension to the wl_pointer >> interface >> + used for emitting relative pointer events. It shares the same focus as >> + wl_pointer objects of the same seat and will only emit events when it >> + has focus. >> + </description> >> + >> + <request name="release" type="destructor"> >> + <description summary="release the relative pointer object"/> >> + </request> >> + >> + <event name="relative_motion"> >> + <description summary="relative pointer motion"> >> + Relative x/y pointer motion in from the pointer of the seat >> associated >> + with this object. >> + >> + A relative motion is in the same dimension as regular wl_pointer >> motion >> + events, except they do not represent an absolute position. For >> example, >> + moving a pointer from (x, y) to (x', y') would have the equivalent >> + relative motion (x' - x, y' - y). If a pointer motion caused the >> + absolute pointer position to be clipped by for example the edge of >> the >> + monitor, the relative motion is unaffected by the clipping and will >> + represent the unclipped motion. >> + >> + This event also contains non-accelerated motion deltas. The >> + non-accelerated delta is, when applicable, the regular pointer >> motion >> + delta as it was before having applied motion acceleration >> + transformations. The compositor will have applied the same >> processing >> + (such as normalization) meaning the events will have roughly the >> same >> + magnitude as accelerated motion events. >> + >> + Note that the non-accelerated delta does not represent 'raw' events >> as >> + they were read from some device. Pointer motion acceleration is >> device- >> + and configuration-specific and non-accelerated deltas and >> accelerated >> + deltas may have the same value on some devices. >> + >> + Relative motions are not coupled to wl_pointer.motion events, and >> can >> + be sent in combination with such events, but also independently. >> There >> + may also be scenarious where wl_pointer.motion is sent, but there >> is no >> + relative motion. The order of an absolute and relative motion event >> + originating from the same physical motion is not guaranteed. >> + >> + The motion vectors are encoded as double fixed point values. >> + >> + A double fixed point value is a 64 bit data type encoded as two >> separate >> + signed 32 bit integers. The integral part of the value is stored in >> one >> + of the integers and the fractional part in the other. >> + >> + If the client needs button events, it can receive them from a >> wl_pointer >> + object of the same seat that the wl_relative_pointer object is >> + associated with. >> + </description> >> + >> + <arg name="time" type="uint" >> + summary="timestamp with millisecond granularity"/> >> + <arg name="dx_int" type="int" >> + summary="integral part of the x component of the motion vector"/> >> + <arg name="dx_frac" type="int" >> + summary="fractional part of the x component of the motion >> vector"/> >> + <arg name="dy_int" type="int" >> + summary="integral part of the y component of the motion vector"/> >> + <arg name="dy_frac" type="int" >> + summary="fractional part of the y component of the motion >> vector"/> >> + <arg name="dx_unaccel_int" type="int" >> + summary="integral part of the x component of the unaccelerated >> motion vector"/> >> + <arg name="dx_unaccel_frac" type="int" >> + summary="fractional part of the x component of the unaccelerated >> motion vector"/> >> + <arg name="dy_unaccel_int" type="int" >> + summary="integral part of the y component of the unaccelerated >> motion vector"/> >> + <arg name="dy_unaccel_frac" type="int" >> + summary="fractional part of the y component of the unaccelerated >> motion vector"/> >> + </event> >> + </interface> >> + >> +</protocol> >> diff --git a/src/compositor.c b/src/compositor.c >> index 5594d30..b462531 100644 >> --- a/src/compositor.c >> +++ b/src/compositor.c >> @@ -4560,6 +4560,9 @@ weston_compositor_init(struct weston_compositor *ec, >> weston_plane_init(&ec->primary_plane, ec, 0, 0); >> weston_compositor_stack_plane(ec, &ec->primary_plane, NULL); >> >> + if (weston_input_init(ec) != 0) >> + return -1; >> + >> s = weston_config_get_section(ec->config, "keyboard", NULL, NULL); >> weston_config_section_get_string(s, "keymap_rules", >> (char **) &xkb_names.rules, NULL); >> diff --git a/src/compositor.h b/src/compositor.h >> index 331b758..55cc88f 100644 >> --- a/src/compositor.h >> +++ b/src/compositor.h >> @@ -340,7 +340,9 @@ struct weston_pointer { >> struct weston_seat *seat; >> >> struct wl_list resource_list; >> + struct wl_list relative_resource_list; >> struct wl_list focus_resource_list; >> + struct wl_list relative_focus_resource_list; >> struct weston_view *focus; >> uint32_t focus_serial; >> struct wl_listener focus_view_listener; >> @@ -1584,6 +1586,9 @@ weston_output_mode_switch_to_native(struct >> weston_output *output); >> int >> noop_renderer_init(struct weston_compositor *ec); >> >> +int >> +weston_input_init(struct weston_compositor *compositor); >> + >> struct weston_compositor * >> backend_init(struct wl_display *display, int *argc, char *argv[], >> struct weston_config *config); >> diff --git a/src/input.c b/src/input.c >> index 9131287..b48a6c9 100644 >> --- a/src/input.c >> +++ b/src/input.c >> @@ -32,7 +32,9 @@ >> #include <limits.h> >> >> #include "../shared/os-compatibility.h" >> +#include "../shared/util.h" >> #include "compositor.h" >> +#include "protocol/relative-pointer-server-protocol.h" >> >> static void >> empty_region(pixman_region32_t *region) >> @@ -47,6 +49,49 @@ static void unbind_resource(struct wl_resource *resource) >> } >> >> WL_EXPORT void >> +weston_pointer_motion_to_abs(struct weston_pointer *pointer, >> + struct weston_pointer_motion_event *event, >> + wl_fixed_t *x, wl_fixed_t *y) >> +{ >> + if (event->mask & WESTON_POINTER_MOTION_ABS) { >> + *x = wl_fixed_from_double(event->x); >> + *y = wl_fixed_from_double(event->y); >> + } else if (event->mask & WESTON_POINTER_MOTION_REL) { >> + *x = pointer->x + wl_fixed_from_double(event->dx); >> + *y = pointer->y + wl_fixed_from_double(event->dy); >> + } else { >> + assert(!"invalid motion event"); >> + *x = *y = 0; >> + } >> +} >> + >> +static int >> +weston_pointer_motion_to_rel(struct weston_pointer *pointer, >> + struct weston_pointer_motion_event *event, >> + double *dx, double *dy, >> + double *dx_unaccel, double *dy_unaccel) >> +{ >> + if (event->mask & WESTON_POINTER_MOTION_REL && >> + event->mask & WESTON_POINTER_MOTION_REL_NOACCEL) { >> + *dx = event->dx; >> + *dy = event->dy; >> + *dx_unaccel = event->dx_unaccel; >> + *dy_unaccel = event->dy_unaccel; >> + return 1; >> + } else if (event->mask & WESTON_POINTER_MOTION_REL) { >> + *dx_unaccel = *dx = event->dx; >> + *dy_unaccel = *dy = event->dy; >> + return 1; >> + } else if (event->mask & WESTON_POINTER_MOTION_REL_NOACCEL) { >> + *dx_unaccel = *dx = event->dx_unaccel; >> + *dy_unaccel = *dy = event->dy_unaccel; >> + return 1; >> + } else { >> + return 0; >> + } >> +} >> + >> +WL_EXPORT void >> weston_seat_repick(struct weston_seat *seat) >> { >> const struct weston_pointer *pointer = seat->pointer; >> @@ -162,6 +207,42 @@ default_grab_pointer_focus(struct weston_pointer_grab >> *grab) >> } >> >> static void >> +weston_pointer_send_relative_motion(struct weston_pointer *pointer, >> + uint32_t time, >> + struct weston_pointer_motion_event *event) >> +{ >> + double dx, dy, dx_unaccel, dy_unaccel; >> + int32_t dx_int, dx_frac; >> + int32_t dy_int, dy_frac; >> + int32_t dx_unaccel_int, dx_unaccel_frac; >> + int32_t dy_unaccel_int, dy_unaccel_frac; >> + struct wl_list *resource_list; >> + struct wl_resource *resource; >> + >> + if (weston_pointer_motion_to_rel(pointer, event, >> + &dx, &dy, >> + &dx_unaccel, &dy_unaccel)) { >> + resource_list = &pointer->relative_focus_resource_list; >> + wl_double_fixed_from_double(dx, &dx_int, &dx_frac); >> + wl_double_fixed_from_double(dy, &dy_int, &dy_frac); >> + wl_double_fixed_from_double(dx_unaccel, >> + &dx_unaccel_int, >> + &dx_unaccel_frac); >> + wl_double_fixed_from_double(dy_unaccel, >> + &dy_unaccel_int, >> + &dy_unaccel_frac); >> + wl_resource_for_each(resource, resource_list) { >> + _wl_relative_pointer_send_relative_motion( >> + resource, time, >> + dx_int, dx_frac, >> + dy_int, dy_frac, >> + dx_unaccel_int, dx_unaccel_frac, >> + dy_unaccel_int, dy_unaccel_frac); >> + } >> + } >> +} >> + >> +static void >> default_grab_pointer_motion(struct weston_pointer_grab *grab, uint32_t time, >> struct weston_pointer_motion_event *event) >> { >> @@ -187,6 +268,8 @@ default_grab_pointer_motion(struct weston_pointer_grab >> *grab, uint32_t time, >> pointer->sx, pointer->sy); >> } >> } >> + >> + weston_pointer_send_relative_motion(pointer, time, event); >> } >> >> static void >> @@ -503,7 +586,9 @@ weston_pointer_create(struct weston_seat *seat) >> return NULL; >> >> wl_list_init(&pointer->resource_list); >> + wl_list_init(&pointer->relative_resource_list); >> wl_list_init(&pointer->focus_resource_list); >> + wl_list_init(&pointer->relative_focus_resource_list); >> weston_pointer_set_default_grab(pointer, >> >> seat->compositor->default_pointer_grab); >> wl_list_init(&pointer->focus_resource_listener.link); >> @@ -665,6 +750,7 @@ weston_pointer_set_focus(struct weston_pointer *pointer, >> struct wl_display *display = pointer->seat->compositor->wl_display; >> uint32_t serial; >> struct wl_list *focus_resource_list; >> + struct wl_list *relative_focus_resource_list; >> int refocus = 0; >> >> if ((!pointer->focus && view) || >> @@ -674,6 +760,7 @@ weston_pointer_set_focus(struct weston_pointer *pointer, >> refocus = 1; >> >> focus_resource_list = &pointer->focus_resource_list; >> + relative_focus_resource_list = &pointer->relative_focus_resource_list; >> >> if (!wl_list_empty(focus_resource_list) && refocus) { >> serial = wl_display_next_serial(display); >> @@ -683,6 +770,8 @@ weston_pointer_set_focus(struct weston_pointer *pointer, >> } >> >> move_resources(&pointer->resource_list, focus_resource_list); >> + move_resources(&pointer->relative_resource_list, >> + relative_focus_resource_list); >> } >> >> if (find_resource_for_view(&pointer->resource_list, view) && refocus) { >> @@ -700,6 +789,9 @@ weston_pointer_set_focus(struct weston_pointer *pointer, >> move_resources_for_client(focus_resource_list, >> &pointer->resource_list, >> surface_client); >> + move_resources_for_client(relative_focus_resource_list, >> + &pointer->relative_resource_list, >> + surface_client); >> >> wl_resource_for_each(resource, focus_resource_list) { >> wl_pointer_send_enter(resource, >> @@ -932,23 +1024,6 @@ weston_pointer_move_to(struct weston_pointer *pointer, >> } >> >> WL_EXPORT void >> -weston_pointer_motion_to_abs(struct weston_pointer *pointer, >> - struct weston_pointer_motion_event *event, >> - wl_fixed_t *x, wl_fixed_t *y) >> -{ >> - if (event->mask & WESTON_POINTER_MOTION_ABS) { >> - *x = wl_fixed_from_double(event->x); >> - *y = wl_fixed_from_double(event->y); >> - } else if (event->mask & WESTON_POINTER_MOTION_REL) { >> - *x = pointer->x + wl_fixed_from_double(event->dx); >> - *y = pointer->y + wl_fixed_from_double(event->dy); >> - } else { >> - assert(!"invalid motion event"); >> - *x = *y = 0; >> - } >> -} >> - >> -WL_EXPORT void >> weston_pointer_move(struct weston_pointer *pointer, >> struct weston_pointer_motion_event *event) >> { >> @@ -2008,6 +2083,72 @@ bind_seat(struct wl_client *client, void *data, >> uint32_t version, uint32_t id) >> wl_seat_send_name(resource, seat->seat_name); >> } >> >> +static void >> +relative_pointer_release(struct wl_client *client, >> + struct wl_resource *resource) >> +{ >> + wl_resource_destroy(resource); >> +} >> + >> +static const struct _wl_relative_pointer_interface >> relative_pointer_interface = { >> + relative_pointer_release >> +}; >> + >> +static void >> +relative_pointer_manager_get_relative_pointer(struct wl_client *client, >> + struct wl_resource *resource, >> + uint32_t id, >> + struct wl_resource >> *pointer_resource) >> +{ >> + struct weston_pointer *pointer = >> + wl_resource_get_user_data(pointer_resource); >> + struct wl_resource *cr; >> + struct weston_view *focus; >> + >> + cr = wl_resource_create(client, &_wl_relative_pointer_interface, >> + wl_resource_get_version(resource), id); >> + if (cr == NULL) { >> + wl_client_post_no_memory(client); >> + return; >> + } >> + >> + /* May be moved to focused list later by either >> + * weston_pointer_set_focus or directly if this client is already >> + * focused */ >> + wl_list_insert(&pointer->relative_resource_list, >> + wl_resource_get_link(cr)); >> + wl_resource_set_implementation(cr, &relative_pointer_interface, >> + pointer, >> + unbind_resource); >> + >> + focus = pointer->focus; >> + if (focus && focus->surface->resource && >> + wl_resource_get_client(focus->surface->resource) == client) { >> + wl_list_remove(wl_resource_get_link(cr)); >> + wl_list_insert(&pointer->relative_focus_resource_list, >> + wl_resource_get_link(cr)); >> + } >> +} >> + >> +static const struct _wl_relative_pointer_manager_interface >> relative_pointer_manager = { >> + relative_pointer_manager_get_relative_pointer, >> +}; >> + >> +static void >> +bind_relative_pointer_manager(struct wl_client *client, void *data, >> + uint32_t version, uint32_t id) >> +{ >> + struct weston_compositor *compositor = data; >> + struct wl_resource *resource; >> + >> + resource = wl_resource_create(client, >> + &_wl_relative_pointer_manager_interface, >> + 1, id); >> + wl_resource_set_implementation(resource, &relative_pointer_manager, >> + compositor, >> + NULL); >> +} >> + >> #ifdef ENABLE_XKBCOMMON >> int >> weston_compositor_xkb_init(struct weston_compositor *ec, >> @@ -2429,3 +2570,14 @@ weston_seat_release(struct weston_seat *seat) >> >> wl_signal_emit(&seat->destroy_signal, seat); >> } >> + >> +int >> +weston_input_init(struct weston_compositor *compositor) >> +{ >> + if (!wl_global_create(compositor->wl_display, >> + &_wl_relative_pointer_manager_interface, 1, >> + compositor, bind_relative_pointer_manager)) >> + return -1; >> + >> + return 0; >> +} >> -- >> 2.1.4 >> >> _______________________________________________ >> wayland-devel mailing list >> [email protected] >> http://lists.freedesktop.org/mailman/listinfo/wayland-devel >> > _______________________________________________ > wayland-devel mailing list > [email protected] > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
