On Thu, Jul 16, 2015 at 3:37 AM, Peter Hutterer <[email protected]> wrote: > On Thu, Jul 16, 2015 at 03:23:20PM +0800, Jonas Ådahl wrote: >> On Thu, Jul 16, 2015 at 03:37:30PM +0900, x414e54 wrote: >> > On Wed, Jul 15, 2015 at 11:55 AM, Peter Hutterer >> > <[email protected]> wrote: >> > > 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. >> > >> > Unaccelerated un-normalzied is fine. But it would be nice to have this >> > reflected in the wayland spec just to make sure it is consistent >> > between window managers. >> >> I have no objections to removing the note about the compositor having >> applied the normalizations, partly because it is not correct when >> running on libinput anymore, but also because it might not be a good >> idea to be to specific about how they look as at some backends we might >> not be able to provide exactly that type of information (remote desktop >> for example). >> >> > >> > > >> > >> 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? >> > >> > You could probably say the same for 500hz and 1000hz mice. I do not >> > think it is your/our place to say if someone would notice or not, some >> > people may some people might not. >> > >> > Not necessarily mice but definitely when using head tracking and eye >> > tracking it is noticeable. Also it helps you to create more accurate >> > prediction and allows you to render frames ahead. >> > >> > Considering the original events are reported in nanoseconds/ktime if >> > it came from evdev? (I may be wrong). It does not seem like too much >> > trouble just to pass the original nanosecond time along even if it is >> > in two 32 bit integers sec and nsec. >> >> Libinput exposes the time value as a uint32_t in milleseconds. It gets >> the timestamp from a 'struct timeval' which is in microseconds. In other >> words, we'd need to expose the lost time data via additional API in >> libinput. I'm no input device expert so I'm not going to have any strong >> objections to adding more information, unless someone have an objective >> objection to it. >> >> How correct are the timestamps from the kernel for such devices? > > honestly not sure, but even if they're not as precise now any increase in > precision would automatically feed through to everything else in the stack > if we expose the time in finer-grained units. so adding a get_time_usec() > for all the events seems sensible. not sure about nsec being worthwhile > though. > Benjamin, what's the precision in HID? >
There is no formal rule for HID. It depends on the USB connection and speed. For most of generic unifying Logitech devices they are reporting one report every 8 ms (125Hz). But Logitech had to develop special receivers for their gaming mice to be able to report 1000Hz. And those 1000Hz mice are still using HID. So I believe if the hardware makers were capable of reporting 100K Hz, they would do it :) Cheers, Benjamin > Cheers, > Peter > >> > There is one mouse available called the Asus ROG Gladius. So there are >> > definitely people using it now. >> > >> > > >> > > 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
