diff --git a/src/bin/Makefile.mk b/src/bin/Makefile.mk index 667a644b7..9922a9019 100644 --- a/src/bin/Makefile.mk +++ b/src/bin/Makefile.mk @@ -445,13 +445,17 @@ src/bin/generated/www-server-protocol.h \ src/bin/generated/screenshooter-protocol.c \ src/bin/generated/screenshooter-server-protocol.h \ src/bin/generated/xdg-foreign-unstable-v1-protocol.c \ -src/bin/generated/xdg-foreign-unstable-v1-server-protocol.h +src/bin/generated/xdg-foreign-unstable-v1-server-protocol.h \ +src/bin/generated/relative-pointer-unstable-v1-protocol.c \ +src/bin/generated/relative-pointer-unstable-v1-server-protocol.h src/bin/e_comp_wl_extensions.c: \ src/bin/generated/screenshooter-server-protocol.h \ src/bin/generated/session-recovery-server-protocol.h \ src/bin/generated/xdg-foreign-unstable-v1-protocol.c \ - src/bin/generated/xdg-foreign-unstable-v1-server-protocol.h + src/bin/generated/xdg-foreign-unstable-v1-server-protocol.h \ + src/bin/generated/relative-pointer-unstable-v1-protocol.c \ + src/bin/generated/relative-pointer-unstable-v1-server-protocol.h src/bin/e_comp_wl.c: \ src/bin/generated/www-server-protocol.h diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h index a78f5cd0c..4da861a0d 100644 --- a/src/bin/e_comp_wl.h +++ b/src/bin/e_comp_wl.h @@ -121,6 +121,11 @@ typedef struct E_Comp_Wl_Extension_Data struct wl_global *global; } zxdg_importer_v1; /* end xdg-foreign */ + struct + { + struct wl_global *global; + Eina_List *resources; + } zwp_relative_pointer_manager_v1; } E_Comp_Wl_Extension_Data; struct _E_Comp_Wl_Data @@ -391,6 +396,8 @@ E_API Eina_Bool e_comp_wl_client_is_grabbed(const E_Client *ec); E_API Eina_Bool e_comp_wl_grab_client_mouse_move(const Ecore_Event_Mouse_Move *ev); E_API Eina_Bool e_comp_wl_grab_client_mouse_button(const Ecore_Event_Mouse_Button *ev); +E_API void e_comp_wl_extension_relative_motion_event(uint64_t time_usec, double dx, double dy, double dx_unaccel, double dy_unaccel); + # ifndef HAVE_WAYLAND_ONLY EINTERN void e_comp_wl_xwayland_client_queue(E_Client *ec); static inline E_Comp_X_Client_Data * diff --git a/src/bin/e_comp_wl_extensions.c b/src/bin/e_comp_wl_extensions.c index 517579b27..0b36e7ccf 100644 --- a/src/bin/e_comp_wl_extensions.c +++ b/src/bin/e_comp_wl_extensions.c @@ -7,6 +7,7 @@ #include "session-recovery-server-protocol.h" #include "www-server-protocol.h" #include "xdg-foreign-unstable-v1-server-protocol.h" +#include "relative-pointer-unstable-v1-server-protocol.h" /* mutter uses 32, seems reasonable */ #define HANDLE_LEN 32 @@ -416,6 +417,44 @@ _e_comp_wl_zxdg_importer_v1_import(struct wl_client *client, struct wl_resource ///////////////////////////////////////////////////////// +static void +_e_comp_wl_zwp_relative_pointer_manager_v1_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +_relative_pointer_destroy(struct wl_resource *resource) +{ + e_comp_wl->extensions->zwp_relative_pointer_manager_v1.resources = + eina_list_remove(e_comp_wl->extensions->zwp_relative_pointer_manager_v1.resources, resource); +} + +static void +_e_comp_wl_zwp_relative_pointer_v1_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + + +static const struct zwp_relative_pointer_v1_interface _e_zwp_relative_pointer_v1_interface = +{ + _e_comp_wl_zwp_relative_pointer_v1_destroy, +}; + +static void +_e_comp_wl_zwp_relative_pointer_manager_v1_get_relative_pointer(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *pointer) +{ + struct wl_resource *res; + + res = wl_resource_create(client, &zwp_relative_pointer_v1_interface, wl_resource_get_version(resource), id); + wl_resource_set_implementation(res, &_e_zwp_relative_pointer_v1_interface, pointer, _relative_pointer_destroy); + e_comp_wl->extensions->zwp_relative_pointer_manager_v1.resources = + eina_list_append(e_comp_wl->extensions->zwp_relative_pointer_manager_v1.resources, res); +} + +///////////////////////////////////////////////////////// + static const struct zwp_e_session_recovery_interface _e_session_recovery_interface = { _e_comp_wl_session_recovery_get_uuid, @@ -445,6 +484,11 @@ static const struct zxdg_importer_v1_interface _e_zxdg_importer_v1_interface = _e_comp_wl_zxdg_importer_v1_import, }; +static const struct zwp_relative_pointer_manager_v1_interface _e_zwp_relative_pointer_manager_v1_interface = +{ + _e_comp_wl_zwp_relative_pointer_manager_v1_destroy, + _e_comp_wl_zwp_relative_pointer_manager_v1_get_relative_pointer, +}; #define GLOBAL_BIND_CB(NAME, IFACE, ...) \ static void \ @@ -467,6 +511,7 @@ GLOBAL_BIND_CB(screenshooter, zwp_screenshooter_interface) GLOBAL_BIND_CB(www, www_interface) GLOBAL_BIND_CB(zxdg_exporter_v1, zxdg_exporter_v1_interface) GLOBAL_BIND_CB(zxdg_importer_v1, zxdg_importer_v1_interface) +GLOBAL_BIND_CB(zwp_relative_pointer_manager_v1, zwp_relative_pointer_manager_v1_interface) #define GLOBAL_CREATE_OR_RETURN(NAME, IFACE, VERSION) \ @@ -511,6 +556,7 @@ e_comp_wl_extensions_init(void) GLOBAL_CREATE_OR_RETURN(zxdg_exporter_v1, zxdg_exporter_v1_interface, 1); e_comp_wl->extensions->zxdg_exporter_v1.surfaces = eina_hash_string_superfast_new(NULL); GLOBAL_CREATE_OR_RETURN(zxdg_importer_v1, zxdg_importer_v1_interface, 1); + GLOBAL_CREATE_OR_RETURN(zwp_relative_pointer_manager_v1, zwp_relative_pointer_manager_v1_interface, 1); ecore_event_handler_add(ECORE_WL2_EVENT_SYNC_DONE, _dmabuf_add, NULL); @@ -519,3 +565,28 @@ e_comp_wl_extensions_init(void) return EINA_TRUE; } + +E_API void +e_comp_wl_extension_relative_motion_event(uint64_t time_usec, double dx, double dy, double dx_unaccel, double dy_unaccel) +{ + Eina_List *l; + struct wl_resource *res; + E_Client *focused; + struct wl_client *wc; + uint32_t hi, lo; + + focused = e_client_focused_get(); + if ((!focused) || e_object_is_del(E_OBJECT(focused))) return; + + wc = wl_resource_get_client(focused->comp_data->surface); + + hi = time_usec >> 32; + lo = (uint32_t)time_usec; + + EINA_LIST_FOREACH(e_comp_wl->extensions->zwp_relative_pointer_manager_v1.resources, l, res) + { + if (wl_resource_get_client(res) != wc) continue; + zwp_relative_pointer_v1_send_relative_motion(res, hi, lo, wl_fixed_from_double(dx), + wl_fixed_from_double(dy), wl_fixed_from_double(dx_unaccel), wl_fixed_from_double(dy_unaccel)); + } +} diff --git a/src/modules/wl_drm/e_mod_main.c b/src/modules/wl_drm/e_mod_main.c index 1d962ea4e..656f6e20a 100644 --- a/src/modules/wl_drm/e_mod_main.c +++ b/src/modules/wl_drm/e_mod_main.c @@ -1,3 +1,4 @@ +#define E_COMP_WL #include "e.h" #include @@ -9,6 +10,7 @@ E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Wl_Drm" }; static Ecore_Event_Handler *activate_handler; static Ecore_Event_Handler *output_handler; +static Ecore_Event_Handler *input_handler; static Eina_Bool session_state = EINA_FALSE; static const char *conn_types[] = @@ -820,6 +822,13 @@ static E_Comp_Screen_Iface drmiface = .key_up = _drm2_key_up, }; +static Eina_Bool +_pointer_motion(void *d EINA_UNUSED, int t EINA_UNUSED, Elput_Event_Pointer_Motion *ev) +{ + e_comp_wl_extension_relative_motion_event(ev->time_usec, ev->dx, ev->dy, ev->dx_unaccel, ev->dy_unaccel); + return ECORE_CALLBACK_RENEW; +} + E_API void * e_modapi_init(E_Module *m) { @@ -889,6 +898,8 @@ e_modapi_init(E_Module *m) ecore_event_handler_add(ECORE_DRM2_EVENT_OUTPUT_CHANGED, _e_mod_drm_cb_output, NULL); + input_handler = ecore_event_handler_add(ELPUT_EVENT_POINTER_MOTION, (Ecore_Event_Handler_Cb)_pointer_motion, NULL); + return m; } @@ -901,5 +912,7 @@ e_modapi_shutdown(E_Module *m EINA_UNUSED) if (activate_handler) ecore_event_handler_del(activate_handler); activate_handler = NULL; + E_FREE_FUNC(input_handler, ecore_event_handler_del); + return 1; } diff --git a/src/protocol/relative-pointer-unstable-v1.xml b/src/protocol/relative-pointer-unstable-v1.xml new file mode 100644 index 000000000..ca6f81d12 --- /dev/null +++ b/src/protocol/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. + + + + + + + + + + +