On Wed, Jul 15, 2015 at 08:23:09AM +0900, x414e54 wrote: > Hi, > > Just a quick questions: > > 1) Is there any way to un-normalize the values?
not at this point, no. fwiw as of libinput 0.19 the normalization only applies to the accelerated delta, the unaccelerated one is generally in device-specific units. Except on touchpads, where we still normalize it to a 1000dpi mouse, we may review that at some point. but since the normalization is "magic", you can't unnormalize them. > 2) What happens with >1000hz gaming mice for example which need > microsecond granularity timestamps? naïve question: do people notice the difference between 1000Hz and 2000Hz? Cheers, Peter > 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
