diff --git a/relative-pointer-unstable-v1.xml b/relative-pointer-unstable-v1.xml new file mode 100644 index 0000000..ca6f81d --- /dev/null +++ b/relative-pointer-unstable-v1.xml @@ -0,0 +1,136 @@ + + + + + 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. + + + + This protocol specifies a set of interfaces used for making clients able to + receive relative pointer events not obstructed by barriers (such as the + monitor edge or other pointer barriers). + + To start receiving relative pointer events, a client must first bind the + global interface "wp_relative_pointer_manager" which, if a compositor + supports relative pointer motion events, is exposed by the registry. After + having created the relative pointer manager proxy object, the client uses + it to create the actual relative pointer object using the + "get_relative_pointer" request given a wl_pointer. The relative pointer + motion events will then, when applicable, be transmitted via the proxy of + the newly created relative pointer object. See the documentation of the + relative pointer interface for more details. + + Warning! The protocol described in this file is experimental and backward + incompatible changes may be made. Backward compatible changes may be added + together with the corresponding interface version bump. Backward + incompatible changes are done by bumping the version number in the protocol + and interface names and resetting the interface version. Once the protocol + is to be declared stable, the 'z' prefix and the version number in the + protocol and interface names are removed and the interface version number is + reset. + + + + + A global interface used for getting the relative pointer object for a + given pointer. + + + + + Used by the client to notify the server that it will no longer use this + relative pointer manager object. + + + + + + Create a relative pointer interface given a wl_pointer object. See the + wp_relative_pointer interface for more details. + + + + + + + + + A wp_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. + + + + + + + + + Relative x/y pointer motion 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 and other + transformations such as normalization. + + 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 scenarios 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. + + If the client needs button events or focus state, it can receive them + from a wl_pointer object of the same seat that the wp_relative_pointer + object is associated with. + + + + + + + + + + + diff --git a/relative_pointer.c b/relative_pointer.c new file mode 100644 index 0000000..d775fae --- /dev/null +++ b/relative_pointer.c @@ -0,0 +1,133 @@ +/* Wayland compositor running on top of an X server. + +Copyright (C) 2022 to various contributors. + +This file is part of 12to11. + +12to11 is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or (at your +option) any later version. + +12to11 is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with 12to11. If not, see . */ + +#include "compositor.h" +#include "relative-pointer-unstable-v1.h" + +/* The zwp_relative_pointer_manager_v1 global. */ +static struct wl_global *relative_pointer_manager_global; + +static void +DestroyRelativePointer (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static struct zwp_relative_pointer_v1_interface relative_pointer_impl = + { + .destroy = DestroyRelativePointer, + }; + +static void +HandleRelativePointerResourceDestroy (struct wl_resource *resource) +{ + RelativePointer *relative_pointer; + + relative_pointer = wl_resource_get_user_data (resource); + XLSeatDestroyRelativePointer (relative_pointer); +} + + + +static void +Destroy (struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +GetRelativePointer (struct wl_client *client, struct wl_resource *resource, + uint32_t id, struct wl_resource *pointer_resource) +{ + struct wl_resource *relative_pointer_resource; + Pointer *pointer; + RelativePointer *relative_pointer; + Seat *seat; + + pointer = wl_resource_get_user_data (pointer_resource); + seat = XLPointerGetSeat (pointer); + relative_pointer_resource + = wl_resource_create (client, &zwp_relative_pointer_v1_interface, + wl_resource_get_version (pointer_resource), + id); + + if (!relative_pointer_resource) + { + wl_resource_post_no_memory (pointer_resource); + return; + } + + relative_pointer = XLSeatGetRelativePointer (seat, + relative_pointer_resource); + wl_resource_set_implementation (relative_pointer_resource, + &relative_pointer_impl, relative_pointer, + HandleRelativePointerResourceDestroy); +} + +static const struct zwp_relative_pointer_manager_v1_interface manager_impl = + { + .destroy = Destroy, + .get_relative_pointer = GetRelativePointer, + }; + +static void +HandleBind (struct wl_client *client, void *data, + uint32_t version, uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, + &zwp_relative_pointer_manager_v1_interface, + version, id); + + if (!resource) + { + wl_client_post_no_memory (client); + return; + } + + wl_resource_set_implementation (resource, &manager_impl, NULL, NULL); +} + +void +XLInitRelativePointer (void) +{ + relative_pointer_manager_global + = wl_global_create (compositor.wl_display, + &zwp_relative_pointer_manager_v1_interface, + 1, NULL, HandleBind); +} + +void +XLRelativePointerSendRelativeMotion (struct wl_resource *resource, + uint64_t microsecond_time, double dx, + double dy) +{ + uint32_t time_hi, time_lo; + + time_hi = microsecond_time >> 32; + time_lo = microsecond_time >> 32; + + zwp_relative_pointer_v1_send_relative_motion (resource, time_hi, time_lo, + wl_fixed_from_double (dx), + wl_fixed_from_double (dy), + wl_fixed_from_double (dx), + wl_fixed_from_double (dy)); +}