diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h index b1fcaca07..56d2a1290 100644 --- a/include/rootston/desktop.h +++ b/include/rootston/desktop.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -65,6 +66,7 @@ struct roots_desktop { struct wlr_pointer_constraints_v1 *pointer_constraints; struct wlr_presentation *presentation; struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager_v1; + struct wlr_relative_pointer_manager_v1 *relative_pointer_manager; struct wl_listener new_output; struct wl_listener layout_change; diff --git a/include/wlr/types/wlr_relative_pointer_v1.h b/include/wlr/types/wlr_relative_pointer_v1.h new file mode 100644 index 000000000..815dcaca7 --- /dev/null +++ b/include/wlr/types/wlr_relative_pointer_v1.h @@ -0,0 +1,45 @@ +/* + * This an unstable interface of wlroots. No guarantees are made regarding the + * future consistency of this API. + */ +#ifndef WLR_USE_UNSTABLE +#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features" +#endif + +#ifndef WLR_TYPES_WLR_RELATIVE_POINTER_V1_H +#define WLR_TYPES_WLR_RELATIVE_POINTER_V1_H + +#include + + +/* 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). + */ + +struct wlr_relative_pointer_manager_v1 { + struct wl_list resources; + struct wl_global *global; + + struct { + struct wl_signal destroy; + struct wl_signal get_relative_pointer; + } requests; + + void *data; +}; + +struct wlr_relative_pointer_v1 { + struct wl_resource *resource; + + struct { + struct wl_signal destroy; + } destroy; + + void *data; +}; + +struct wlr_relative_pointer_manager_v1 *wlr_relative_pointer_v1_create(struct wl_display *display); +void wlr_relative_pointer_v1_destroy(struct wlr_relative_pointer_manager_v1 *relative_pointer_manager); + +#endif diff --git a/protocol/meson.build b/protocol/meson.build index 58f570465..6d5acf377 100644 --- a/protocol/meson.build +++ b/protocol/meson.build @@ -20,6 +20,7 @@ protocols = [ [wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'], [wl_protocol_dir, 'unstable/xdg-shell/xdg-shell-unstable-v6.xml'], [wl_protocol_dir, 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml'], + [wl_protocol_dir, 'unstable/relative-pointer/relative-pointer-unstable-v1.xml'], 'gamma-control.xml', 'gtk-primary-selection.xml', 'idle.xml', @@ -42,6 +43,7 @@ client_protocols = [ [wl_protocol_dir, 'unstable/xdg-decoration/xdg-decoration-unstable-v1.xml'], [wl_protocol_dir, 'unstable/xdg-shell/xdg-shell-unstable-v6.xml'], [wl_protocol_dir, 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml'], + [wl_protocol_dir, 'unstable/relative-pointer/relative-pointer-unstable-v1.xml'], 'idle.xml', 'input-method-unstable-v2.xml', 'screenshooter.xml', diff --git a/rootston/desktop.c b/rootston/desktop.c index 48e2635c9..e4affe3b2 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -1081,6 +1081,8 @@ struct roots_desktop *desktop_create(struct roots_server *server, wlr_presentation_create(server->wl_display, server->backend); desktop->foreign_toplevel_manager_v1 = wlr_foreign_toplevel_manager_v1_create(server->wl_display); + desktop->relative_pointer_manager = + wlr_relative_pointer_v1_create(server->wl_display); return desktop; } diff --git a/types/meson.build b/types/meson.build index 1813b1449..982f607de 100644 --- a/types/meson.build +++ b/types/meson.build @@ -51,6 +51,7 @@ lib_wlr_types = static_library( 'wlr_primary_selection.c', 'wlr_region.c', 'wlr_screencopy_v1.c', + 'wlr_relative_pointer_v1.c', 'wlr_screenshooter.c', 'wlr_server_decoration.c', 'wlr_surface.c', diff --git a/types/wlr_relative_pointer_v1.c b/types/wlr_relative_pointer_v1.c new file mode 100644 index 000000000..54bd41a7e --- /dev/null +++ b/types/wlr_relative_pointer_v1.c @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include "wayland-util.h" +#include "wayland-server.h" +#include "relative-pointer-unstable-v1-protocol.h" + +static const struct zwp_relative_pointer_manager_v1_interface relative_pointer_manager_v1_impl; +static const struct zwp_relative_pointer_v1_interface relative_pointer_v1_impl; + + +/* Callback functions + */ + +static void relative_pointer_manager_v1_handle_destroy(struct wl_client *client, + struct wl_resource *resource) +{ + wlr_log(WLR_DEBUG, "relative_pointer_manager_v1_handle_destroy called"); +} + + +static void relative_pointer_manager_v1_handle_get_relative_pointer(struct wl_client *client, + struct wl_resource *resource, uint32_t id, struct wl_resource *pointer) +{ + wlr_log(WLR_DEBUG, "relative_pointer_manager_v1_handle_get_relative_pointer called"); +} + + +static void relative_pointer_v1_handle_destroy(struct wl_client *client, + struct wl_resource *resource) +{ + wlr_log(WLR_DEBUG, "relative_pointer_v1_handle_destroy called"); +} + + +static void relative_pointer_manager_v1_handle_resource_destroy(struct wl_resource *resource) +{ + wl_list_remove(wl_resource_get_link(resource)); + wlr_log(WLR_DEBUG, "relative_pointer_manager_v1_handle_resource_destroy called"); +} + + +static void relative_pointer_manager_bind(struct wl_client *wl_client, void *data, + uint32_t version, uint32_t id) +{ + struct wlr_relative_pointer_manager_v1 *relative_pointer_manager = data; + + struct wl_resource *wl_resource = wl_resource_create(wl_client, + &zwp_relative_pointer_manager_v1_interface, version, id); + + if (wl_resource == NULL) { + wl_client_post_no_memory(wl_client); + return; + } + + wl_list_insert(&relative_pointer_manager->resources, wl_resource_get_link(wl_resource)); + + wl_resource_set_implementation(wl_resource, &relative_pointer_manager_v1_impl, + relative_pointer_manager, relative_pointer_manager_v1_handle_resource_destroy); + + wlr_log(WLR_DEBUG, "relative_pointer_manager bound"); +} + + +/* Implementations + */ + +static const struct zwp_relative_pointer_manager_v1_interface relative_pointer_manager_v1_impl = { + .destroy = relative_pointer_manager_v1_handle_destroy, + .get_relative_pointer = relative_pointer_manager_v1_handle_get_relative_pointer, +}; + + +static const struct zwp_relative_pointer_v1_interface relative_pointer_v1_impl = { + .destroy = relative_pointer_v1_handle_destroy, +}; + + +/* Public functions + */ + +struct wlr_relative_pointer_manager_v1 *wlr_relative_pointer_v1_create(struct wl_display *display) +{ + struct wlr_relative_pointer_manager_v1 *relative_pointer_manager = + calloc(1, sizeof(struct wlr_relative_pointer_manager_v1)); + + if (relative_pointer_manager == NULL) { + return NULL; + } + + wl_list_init(&relative_pointer_manager->resources); + + wl_signal_init(&relative_pointer_manager->requests.destroy); + wl_signal_init(&relative_pointer_manager->requests.get_relative_pointer); + + relative_pointer_manager->global = wl_global_create(display, + &zwp_relative_pointer_manager_v1_interface, 1, + relative_pointer_manager, relative_pointer_manager_bind); + + if (relative_pointer_manager->global == NULL) { + free(relative_pointer_manager); + return NULL; + } + + wlr_log(WLR_DEBUG, "relative_pointer_v1 manager created"); + + return relative_pointer_manager; +} + + +void wlr_relative_pointer_v1_destroy(struct wlr_relative_pointer_manager_v1 *relative_pointer_manager) +{ + if (relative_pointer_manager == NULL) { + return; + } + + struct wl_resource *resource; + struct wl_resource *tmp_resource; + wl_resource_for_each_safe(resource, tmp_resource, &relative_pointer_manager->resources) { + wl_resource_destroy(resource); + } + + wl_global_destroy(relative_pointer_manager->global); + free(relative_pointer_manager); +}