parent
42d033e738
commit
37602e153b
@ -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
|
@ -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(®istry->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, ®istry->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(®istry->events.destroy, NULL);
|
||||
|
||||
// Implementations are supposed to remove all surfaces
|
||||
assert(wl_list_empty(®istry->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, ®istry->display_destroy);
|
||||
|
||||
wl_list_init(®istry->exported_surfaces);
|
||||
wl_signal_init(®istry->events.destroy);
|
||||
return registry;
|
||||
}
|
Loading…
Reference in new issue