aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/meson.build5
-rw-r--r--include/wlr/config.h.in2
-rw-r--r--include/wlr/types/wlr_xdg_foreign_registry.h75
-rw-r--r--meson.build14
-rw-r--r--meson_options.txt1
-rw-r--r--types/meson.build6
-rw-r--r--types/wlr_xdg_foreign_registry.c73
-rw-r--r--util/meson.build15
8 files changed, 183 insertions, 8 deletions
diff --git a/include/meson.build b/include/meson.build
index e2428e8d..dbd81a05 100644
--- a/include/meson.build
+++ b/include/meson.build
@@ -7,6 +7,11 @@ endif
if conf_data.get('WLR_HAS_XWAYLAND', 0) != 1
exclude_files += 'xwayland.h'
endif
+if conf_data.get('WLR_HAS_XDG_FOREIGN', 0) != 1
+ exclude_files += [
+ 'types/wlr_xdg_foreign_registry.h',
+ ]
+endif
install_subdir('wlr',
install_dir: get_option('includedir'),
diff --git a/include/wlr/config.h.in b/include/wlr/config.h.in
index c139a4d6..3cec1f1a 100644
--- a/include/wlr/config.h.in
+++ b/include/wlr/config.h.in
@@ -13,4 +13,6 @@
#mesondefine WLR_HAS_XCB_ERRORS
#mesondefine WLR_HAS_XCB_ICCCM
+#mesondefine WLR_HAS_XDG_FOREIGN
+
#endif
diff --git a/include/wlr/types/wlr_xdg_foreign_registry.h b/include/wlr/types/wlr_xdg_foreign_registry.h
new file mode 100644
index 00000000..462a9a86
--- /dev/null
+++ b/include/wlr/types/wlr_xdg_foreign_registry.h
@@ -0,0 +1,75 @@
+/*
+ * 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_XDG_FOREIGN_REGISTRY_H
+#define WLR_TYPES_WLR_XDG_FOREIGN_REGISTRY_H
+
+#include <wayland-server-core.h>
+
+#define WLR_XDG_FOREIGN_HANDLE_SIZE 37
+
+/**
+ * wlr_xdg_foreign_registry is used for storing a list of exported surfaces with
+ * the xdg-foreign family of protocols.
+ *
+ * It can be used to allow interoperability between clients using different
+ * versions of the protocol (if all versions use the same registry).
+ */
+struct wlr_xdg_foreign_registry {
+ struct wl_list exported_surfaces; // struct wlr_xdg_foreign_exported_surface
+
+ struct wl_listener display_destroy;
+ struct {
+ struct wl_signal destroy;
+ } events;
+};
+
+struct wlr_xdg_foreign_exported {
+ struct wl_list link; // wlr_xdg_foreign_registry::exported_surfaces
+ struct wlr_xdg_foreign_registry *registry;
+
+ struct wlr_surface *surface;
+
+ char handle[WLR_XDG_FOREIGN_HANDLE_SIZE];
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+};
+
+/**
+ * Create an empty wlr_xdg_foreign_registry.
+ *
+ * It will be destroyed when the associated display is destroyed.
+ */
+struct wlr_xdg_foreign_registry *wlr_xdg_foreign_registry_create(
+ struct wl_display *display);
+
+/**
+ * Add the given exported surface to the registry and assign it a unique handle.
+ * The caller is responsible for removing the exported surface from the repository
+ * if it is destroyed.
+ *
+ * Returns true if the initialization was successful.
+ */
+bool wlr_xdg_foreign_exported_init(struct wlr_xdg_foreign_exported *surface,
+ struct wlr_xdg_foreign_registry *registry);
+
+/**
+ * Find an exported surface with the given handle, or NULL if such a surface
+ * does not exist.
+ */
+struct wlr_xdg_foreign_exported *wlr_xdg_foreign_registry_find_by_handle(
+ struct wlr_xdg_foreign_registry *registry, const char *handle);
+
+/**
+ * Remove the given surface from the registry it was previously added in.
+ */
+void wlr_xdg_foreign_exported_finish(struct wlr_xdg_foreign_exported *surface);
+
+#endif
diff --git a/meson.build b/meson.build
index c6835fbe..be1b8aa9 100644
--- a/meson.build
+++ b/meson.build
@@ -87,6 +87,7 @@ conf_data.set10('WLR_HAS_X11_BACKEND', false)
conf_data.set10('WLR_HAS_XWAYLAND', false)
conf_data.set10('WLR_HAS_XCB_ERRORS', false)
conf_data.set10('WLR_HAS_XCB_ICCCM', false)
+conf_data.set10('WLR_HAS_XDG_FOREIGN', false)
# Clang complains about some zeroed initializer lists (= {0}), even though they
# are valid
@@ -109,8 +110,16 @@ pixman = dependency('pixman-1')
math = cc.find_library('m')
rt = cc.find_library('rt')
-uuid = dependency('uuid', required: false)
-uuid_create = cc.has_function('uuid_create')
+if not get_option('xdg-foreign').disabled()
+ uuid = dependency('uuid', required: false)
+ uuid_create = cc.has_function('uuid_create')
+ if uuid.found() or uuid_create
+ conf_data.set10('WLR_HAS_XDG_FOREIGN', true)
+ elif get_option('xdg-foreign').enabled()
+ error('Missing dependency uuid and uuid_create function not available ' +
+ 'cannot build with xdg-foreign support')
+ endif
+endif
wlr_files = []
wlr_deps = [
@@ -171,6 +180,7 @@ summary({
'x11_backend': conf_data.get('WLR_HAS_X11_BACKEND', 0) == 1,
'xcb-icccm': conf_data.get('WLR_HAS_XCB_ICCCM', 0) == 1,
'xcb-errors': conf_data.get('WLR_HAS_XCB_ERRORS', 0) == 1,
+ 'xdg-foreign': conf_data.get('WLR_HAS_XDG_FOREIGN', 0) == 1,
}, bool_yn: true)
if get_option('examples')
diff --git a/meson_options.txt b/meson_options.txt
index 382ef2a6..e4ff6019 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -7,3 +7,4 @@ option('xwayland', type: 'feature', value: 'auto', yield: true, description: 'En
option('x11-backend', type: 'feature', value: 'auto', description: 'Enable X11 backend')
option('examples', type: 'boolean', value: true, description: 'Build example applications')
option('icon_directory', description: 'Location used to look for cursors (default: ${datadir}/icons)', type: 'string', value: '')
+option('xdg-foreign', type: 'feature', value: 'auto', description: 'Enable xdg-foreign protocol')
diff --git a/types/meson.build b/types/meson.build
index 80978176..a2052b3a 100644
--- a/types/meson.build
+++ b/types/meson.build
@@ -66,3 +66,9 @@ wlr_files += files(
'wlr_xdg_decoration_v1.c',
'wlr_xdg_output_v1.c',
)
+
+if conf_data.get('WLR_HAS_XDG_FOREIGN', 0) == 1
+ wlr_files += files(
+ 'wlr_xdg_foreign_registry.c',
+ )
+endif
diff --git a/types/wlr_xdg_foreign_registry.c b/types/wlr_xdg_foreign_registry.c
new file mode 100644
index 00000000..7af137b5
--- /dev/null
+++ b/types/wlr_xdg_foreign_registry.c
@@ -0,0 +1,73 @@
+#include <wlr/types/wlr_xdg_foreign_registry.h>
+#include "util/signal.h"
+#include "util/uuid.h"
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+bool wlr_xdg_foreign_exported_init(
+ struct wlr_xdg_foreign_exported *exported,
+ struct wlr_xdg_foreign_registry *registry) {
+ do {
+ if (!generate_uuid(exported->handle)) {
+ return false;
+ }
+ } while (wlr_xdg_foreign_registry_find_by_handle(registry, exported->handle) != NULL);
+
+ exported->registry = registry;
+ wl_list_insert(&registry->exported_surfaces, &exported->link);
+
+ wl_signal_init(&exported->events.destroy);
+ return true;
+}
+
+struct wlr_xdg_foreign_exported *wlr_xdg_foreign_registry_find_by_handle(
+ struct wlr_xdg_foreign_registry *registry, const char *handle) {
+ if (handle == NULL || strlen(handle) >= WLR_XDG_FOREIGN_HANDLE_SIZE) {
+ return NULL;
+ }
+
+ struct wlr_xdg_foreign_exported *exported;
+ wl_list_for_each(exported, &registry->exported_surfaces, link) {
+ if (strcmp(handle, exported->handle) == 0) {
+ return exported;
+ }
+ }
+
+ return NULL;
+}
+
+void wlr_xdg_foreign_exported_finish(struct wlr_xdg_foreign_exported *surface) {
+ wlr_signal_emit_safe(&surface->events.destroy, NULL);
+ surface->registry = NULL;
+ wl_list_remove(&surface->link);
+ wl_list_init(&surface->link);
+}
+
+static void foreign_registry_handle_display_destroy(struct wl_listener *listener,
+ void *data) {
+ struct wlr_xdg_foreign_registry *registry =
+ wl_container_of(listener, registry, display_destroy);
+
+ wlr_signal_emit_safe(&registry->events.destroy, NULL);
+
+ // Implementations are supposed to remove all surfaces
+ assert(wl_list_empty(&registry->exported_surfaces));
+ free(registry);
+}
+
+
+struct wlr_xdg_foreign_registry *wlr_xdg_foreign_registry_create(
+ struct wl_display *display) {
+ struct wlr_xdg_foreign_registry *registry = calloc(1, sizeof(*registry));
+ if (!registry) {
+ return NULL;
+ }
+
+ registry->display_destroy.notify = foreign_registry_handle_display_destroy;
+ wl_display_add_destroy_listener(display, &registry->display_destroy);
+
+ wl_list_init(&registry->exported_surfaces);
+ wl_signal_init(&registry->events.destroy);
+ return registry;
+}
diff --git a/util/meson.build b/util/meson.build
index 06996a4e..6b423980 100644
--- a/util/meson.build
+++ b/util/meson.build
@@ -8,10 +8,13 @@ wlr_files += files(
'time.c',
)
-if uuid.found()
- wlr_deps += uuid
- add_project_arguments('-DHAS_LIBUUID=1', language: 'c')
-else
- add_project_arguments('-DHAS_LIBUUID=0', language: 'c')
+
+if conf_data.get('WLR_HAS_XDG_FOREIGN', 0) == 1
+ if uuid.found()
+ wlr_deps += uuid
+ add_project_arguments('-DHAS_LIBUUID=1', language: 'c')
+ else
+ add_project_arguments('-DHAS_LIBUUID=0', language: 'c')
+ endif
+ wlr_files += files('uuid.c')
endif
-wlr_files += files('uuid.c')