aboutsummaryrefslogtreecommitdiff
path: root/include/wlr
diff options
context:
space:
mode:
Diffstat (limited to 'include/wlr')
-rw-r--r--include/wlr/backend.h70
-rw-r--r--include/wlr/backend/drm.h37
-rw-r--r--include/wlr/backend/headless.h40
-rw-r--r--include/wlr/backend/interface.h32
-rw-r--r--include/wlr/backend/libinput.h27
-rw-r--r--include/wlr/backend/meson.build16
-rw-r--r--include/wlr/backend/multi.h36
-rw-r--r--include/wlr/backend/session.h94
-rw-r--r--include/wlr/backend/session/interface.h22
-rw-r--r--include/wlr/backend/session/meson.build1
-rw-r--r--include/wlr/backend/wayland.h45
-rw-r--r--include/wlr/backend/x11.h20
-rw-r--r--include/wlr/config.h.in16
-rw-r--r--include/wlr/interfaces/meson.build11
-rw-r--r--include/wlr/interfaces/wlr_input_device.h25
-rw-r--r--include/wlr/interfaces/wlr_keyboard.h29
-rw-r--r--include/wlr/interfaces/wlr_output.h52
-rw-r--r--include/wlr/interfaces/wlr_pointer.h22
-rw-r--r--include/wlr/interfaces/wlr_switch.h22
-rw-r--r--include/wlr/interfaces/wlr_tablet_pad.h22
-rw-r--r--include/wlr/interfaces/wlr_tablet_tool.h22
-rw-r--r--include/wlr/interfaces/wlr_touch.h22
-rw-r--r--include/wlr/meson.build26
-rw-r--r--include/wlr/render/dmabuf.h48
-rw-r--r--include/wlr/render/egl.h118
-rw-r--r--include/wlr/render/gles2.h27
-rw-r--r--include/wlr/render/interface.h87
-rw-r--r--include/wlr/render/meson.build9
-rw-r--r--include/wlr/render/wlr_renderer.h121
-rw-r--r--include/wlr/render/wlr_texture.h73
-rw-r--r--include/wlr/types/meson.build49
-rw-r--r--include/wlr/types/wlr_box.h44
-rw-r--r--include/wlr/types/wlr_buffer.h71
-rw-r--r--include/wlr/types/wlr_compositor.h53
-rw-r--r--include/wlr/types/wlr_cursor.h194
-rw-r--r--include/wlr/types/wlr_data_device.h231
-rw-r--r--include/wlr/types/wlr_export_dmabuf_v1.h46
-rw-r--r--include/wlr/types/wlr_foreign_toplevel_management_v1.h120
-rw-r--r--include/wlr/types/wlr_gamma_control.h46
-rw-r--r--include/wlr/types/wlr_gamma_control_v1.h35
-rw-r--r--include/wlr/types/wlr_gtk_primary_selection.h53
-rw-r--r--include/wlr/types/wlr_idle.h71
-rw-r--r--include/wlr/types/wlr_idle_inhibit_v1.h58
-rw-r--r--include/wlr/types/wlr_input_device.h66
-rw-r--r--include/wlr/types/wlr_input_inhibitor.h34
-rw-r--r--include/wlr/types/wlr_input_method_v2.h87
-rw-r--r--include/wlr/types/wlr_keyboard.h115
-rw-r--r--include/wlr/types/wlr_layer_shell_v1.h134
-rw-r--r--include/wlr/types/wlr_linux_dmabuf_v1.h75
-rw-r--r--include/wlr/types/wlr_list.h83
-rw-r--r--include/wlr/types/wlr_matrix.h59
-rw-r--r--include/wlr/types/wlr_output.h278
-rw-r--r--include/wlr/types/wlr_output_damage.h87
-rw-r--r--include/wlr/types/wlr_output_layout.h133
-rw-r--r--include/wlr/types/wlr_pointer.h72
-rw-r--r--include/wlr/types/wlr_pointer_constraints_v1.h102
-rw-r--r--include/wlr/types/wlr_presentation_time.h59
-rw-r--r--include/wlr/types/wlr_primary_selection.h54
-rw-r--r--include/wlr/types/wlr_region.h24
-rw-r--r--include/wlr/types/wlr_screencopy_v1.h55
-rw-r--r--include/wlr/types/wlr_screenshooter.h41
-rw-r--r--include/wlr/types/wlr_seat.h573
-rw-r--r--include/wlr/types/wlr_server_decoration.h78
-rw-r--r--include/wlr/types/wlr_surface.h246
-rw-r--r--include/wlr/types/wlr_switch.h47
-rw-r--r--include/wlr/types/wlr_tablet_pad.h94
-rw-r--r--include/wlr/types/wlr_tablet_tool.h136
-rw-r--r--include/wlr/types/wlr_tablet_v2.h330
-rw-r--r--include/wlr/types/wlr_text_input_v3.h93
-rw-r--r--include/wlr/types/wlr_touch.h58
-rw-r--r--include/wlr/types/wlr_virtual_keyboard_v1.h46
-rw-r--r--include/wlr/types/wlr_wl_shell.h175
-rw-r--r--include/wlr/types/wlr_xcursor_manager.h69
-rw-r--r--include/wlr/types/wlr_xdg_decoration_v1.h69
-rw-r--r--include/wlr/types/wlr_xdg_output_v1.h47
-rw-r--r--include/wlr/types/wlr_xdg_shell.h389
-rw-r--r--include/wlr/types/wlr_xdg_shell_v6.h359
-rw-r--r--include/wlr/util/edges.h28
-rw-r--r--include/wlr/util/log.h64
-rw-r--r--include/wlr/util/meson.build6
-rw-r--r--include/wlr/util/region.h56
-rw-r--r--include/wlr/version.h.in16
-rw-r--r--include/wlr/xcursor.h102
-rw-r--r--include/wlr/xwayland.h260
84 files changed, 7162 insertions, 0 deletions
diff --git a/include/wlr/backend.h b/include/wlr/backend.h
new file mode 100644
index 00000000..54f2b5e8
--- /dev/null
+++ b/include/wlr/backend.h
@@ -0,0 +1,70 @@
+/*
+ * 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_BACKEND_H
+#define WLR_BACKEND_H
+
+#include <wayland-server.h>
+#include <wlr/backend/session.h>
+#include <wlr/render/egl.h>
+
+struct wlr_backend_impl;
+
+struct wlr_backend {
+ const struct wlr_backend_impl *impl;
+
+ struct {
+ /** Raised when destroyed, passed the wlr_backend reference */
+ struct wl_signal destroy;
+ /** Raised when new inputs are added, passed the wlr_input_device */
+ struct wl_signal new_input;
+ /** Raised when new outputs are added, passed the wlr_output */
+ struct wl_signal new_output;
+ } events;
+};
+
+typedef struct wlr_renderer *(*wlr_renderer_create_func_t)(struct wlr_egl *egl, EGLenum platform,
+ void *remote_display, EGLint *config_attribs, EGLint visual_id);
+/**
+ * Automatically initializes the most suitable backend given the environment.
+ * Will always return a multibackend. The backend is created but not started.
+ * Returns NULL on failure.
+ *
+ * The compositor can request to initialize the backend's renderer by setting
+ * the create_render_func. The callback must initialize the given wlr_egl and
+ * return a valid wlr_renderer, or NULL if it has failed to initiaze it.
+ * Pass NULL as create_renderer_func to use the backend's default renderer.
+ */
+struct wlr_backend *wlr_backend_autocreate(struct wl_display *display,
+ wlr_renderer_create_func_t create_renderer_func);
+/**
+ * Start the backend. This may signal new_input or new_output immediately, but
+ * may also wait until the display's event loop begins. Returns false on
+ * failure.
+ */
+bool wlr_backend_start(struct wlr_backend *backend);
+/**
+ * Destroy the backend and clean up all of its resources. Normally called
+ * automatically when the wl_display is destroyed.
+ */
+void wlr_backend_destroy(struct wlr_backend *backend);
+/**
+ * Obtains the wlr_renderer reference this backend is using.
+ */
+struct wlr_renderer *wlr_backend_get_renderer(struct wlr_backend *backend);
+/**
+ * Obtains the wlr_session reference from this backend if there is any.
+ * Might return NULL for backends that don't use a session.
+ */
+struct wlr_session *wlr_backend_get_session(struct wlr_backend *backend);
+/**
+ * Returns the clock used by the backend for presentation feedback.
+ */
+clockid_t wlr_backend_get_presentation_clock(struct wlr_backend *backend);
+
+#endif
diff --git a/include/wlr/backend/drm.h b/include/wlr/backend/drm.h
new file mode 100644
index 00000000..3724adfb
--- /dev/null
+++ b/include/wlr/backend/drm.h
@@ -0,0 +1,37 @@
+/*
+ * 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_BACKEND_DRM_H
+#define WLR_BACKEND_DRM_H
+
+#include <wayland-server.h>
+#include <wlr/backend.h>
+#include <wlr/backend/session.h>
+#include <wlr/types/wlr_output.h>
+
+/**
+ * Creates a DRM backend using the specified GPU file descriptor (typically from
+ * a device node in /dev/dri).
+ *
+ * To slave this to another DRM backend, pass it as the parent (which _must_ be
+ * a DRM backend, other kinds of backends raise SIGABRT).
+ */
+struct wlr_backend *wlr_drm_backend_create(struct wl_display *display,
+ struct wlr_session *session, int gpu_fd, struct wlr_backend *parent,
+ wlr_renderer_create_func_t create_renderer_func);
+
+bool wlr_backend_is_drm(struct wlr_backend *backend);
+bool wlr_output_is_drm(struct wlr_output *output);
+
+/**
+ * Add mode to the list of available modes
+ */
+typedef struct _drmModeModeInfo drmModeModeInfo;
+bool wlr_drm_connector_add_mode(struct wlr_output *output, const drmModeModeInfo *mode);
+
+#endif
diff --git a/include/wlr/backend/headless.h b/include/wlr/backend/headless.h
new file mode 100644
index 00000000..eab102e2
--- /dev/null
+++ b/include/wlr/backend/headless.h
@@ -0,0 +1,40 @@
+/*
+ * 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_BACKEND_HEADLESS_H
+#define WLR_BACKEND_HEADLESS_H
+
+#include <wlr/backend.h>
+#include <wlr/types/wlr_input_device.h>
+#include <wlr/types/wlr_output.h>
+
+/**
+ * Creates a headless backend. A headless backend has no outputs or inputs by
+ * default.
+ */
+struct wlr_backend *wlr_headless_backend_create(struct wl_display *display,
+ wlr_renderer_create_func_t create_renderer_func);
+/**
+ * Create a new headless output backed by an in-memory EGL framebuffer. You can
+ * read pixels from this framebuffer via wlr_renderer_read_pixels but it is
+ * otherwise not displayed.
+ */
+struct wlr_output *wlr_headless_add_output(struct wlr_backend *backend,
+ unsigned int width, unsigned int height);
+/**
+ * Creates a new input device. The caller is responsible for manually raising
+ * any event signals on the new input device if it wants to simulate input
+ * events.
+ */
+struct wlr_input_device *wlr_headless_add_input_device(
+ struct wlr_backend *backend, enum wlr_input_device_type type);
+bool wlr_backend_is_headless(struct wlr_backend *backend);
+bool wlr_input_device_is_headless(struct wlr_input_device *device);
+bool wlr_output_is_headless(struct wlr_output *output);
+
+#endif
diff --git a/include/wlr/backend/interface.h b/include/wlr/backend/interface.h
new file mode 100644
index 00000000..4a6a5cbb
--- /dev/null
+++ b/include/wlr/backend/interface.h
@@ -0,0 +1,32 @@
+/*
+ * 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_BACKEND_INTERFACE_H
+#define WLR_BACKEND_INTERFACE_H
+
+#include <stdbool.h>
+#include <time.h>
+#include <wlr/backend.h>
+#include <wlr/render/egl.h>
+
+struct wlr_backend_impl {
+ bool (*start)(struct wlr_backend *backend);
+ void (*destroy)(struct wlr_backend *backend);
+ struct wlr_renderer *(*get_renderer)(struct wlr_backend *backend);
+ struct wlr_session *(*get_session)(struct wlr_backend *backend);
+ clockid_t (*get_presentation_clock)(struct wlr_backend *backend);
+};
+
+/**
+ * Initializes common state on a wlr_backend and sets the implementation to the
+ * provided wlr_backend_impl reference.
+ */
+void wlr_backend_init(struct wlr_backend *backend,
+ const struct wlr_backend_impl *impl);
+
+#endif
diff --git a/include/wlr/backend/libinput.h b/include/wlr/backend/libinput.h
new file mode 100644
index 00000000..1a2ab294
--- /dev/null
+++ b/include/wlr/backend/libinput.h
@@ -0,0 +1,27 @@
+/*
+ * 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_BACKEND_LIBINPUT_H
+#define WLR_BACKEND_LIBINPUT_H
+
+#include <libinput.h>
+#include <wayland-server.h>
+#include <wlr/backend.h>
+#include <wlr/backend/session.h>
+#include <wlr/types/wlr_input_device.h>
+
+struct wlr_backend *wlr_libinput_backend_create(struct wl_display *display,
+ struct wlr_session *session);
+/** Gets the underlying libinput_device handle for the given wlr_input_device */
+struct libinput_device *wlr_libinput_get_device_handle(
+ struct wlr_input_device *dev);
+
+bool wlr_backend_is_libinput(struct wlr_backend *backend);
+bool wlr_input_device_is_libinput(struct wlr_input_device *device);
+
+#endif
diff --git a/include/wlr/backend/meson.build b/include/wlr/backend/meson.build
new file mode 100644
index 00000000..3d6f0e40
--- /dev/null
+++ b/include/wlr/backend/meson.build
@@ -0,0 +1,16 @@
+install_headers(
+ 'drm.h',
+ 'headless.h',
+ 'interface.h',
+ 'libinput.h',
+ 'multi.h',
+ 'session.h',
+ 'wayland.h',
+ subdir: 'wlr/backend',
+)
+
+if conf_data.get('WLR_HAS_X11_BACKEND', 0) == 1
+ install_headers('x11.h', subdir: 'wlr/backend')
+endif
+
+subdir('session')
diff --git a/include/wlr/backend/multi.h b/include/wlr/backend/multi.h
new file mode 100644
index 00000000..0687f4b6
--- /dev/null
+++ b/include/wlr/backend/multi.h
@@ -0,0 +1,36 @@
+/*
+ * 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_BACKEND_MULTI_H
+#define WLR_BACKEND_MULTI_H
+
+#include <wlr/backend.h>
+#include <wlr/backend/session.h>
+
+/**
+ * Creates a multi-backend. Multi-backends wrap an arbitrary number of backends
+ * and aggregate their new_output/new_input signals.
+ */
+struct wlr_backend *wlr_multi_backend_create(struct wl_display *display);
+/**
+ * Adds the given backend to the multi backend. This should be done before the
+ * new backend is started.
+ */
+bool wlr_multi_backend_add(struct wlr_backend *multi,
+ struct wlr_backend *backend);
+
+void wlr_multi_backend_remove(struct wlr_backend *multi,
+ struct wlr_backend *backend);
+
+bool wlr_backend_is_multi(struct wlr_backend *backend);
+bool wlr_multi_is_empty(struct wlr_backend *backend);
+
+void wlr_multi_for_each_backend(struct wlr_backend *backend,
+ void (*callback)(struct wlr_backend *backend, void *data), void *data);
+
+#endif
diff --git a/include/wlr/backend/session.h b/include/wlr/backend/session.h
new file mode 100644
index 00000000..7b26f34c
--- /dev/null
+++ b/include/wlr/backend/session.h
@@ -0,0 +1,94 @@
+#ifndef WLR_BACKEND_SESSION_H
+#define WLR_BACKEND_SESSION_H
+
+#include <libudev.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <wayland-server.h>
+
+struct session_impl;
+
+struct wlr_device {
+ int fd;
+ dev_t dev;
+ struct wl_signal signal;
+
+ struct wl_list link;
+};
+
+struct wlr_session {
+ const struct session_impl *impl;
+ /*
+ * Signal for when the session becomes active/inactive.
+ * It's called when we swap virtual terminal.
+ */
+ struct wl_signal session_signal;
+ bool active;
+
+ /*
+ * 0 if virtual terminals are not supported
+ * i.e. seat != "seat0"
+ */
+ unsigned vtnr;
+ char seat[256];
+
+ struct udev *udev;
+ struct udev_monitor *mon;
+ struct wl_event_source *udev_event;
+
+ struct wl_list devices;
+
+ struct wl_listener display_destroy;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+};
+
+/*
+ * Opens a session, taking control of the current virtual terminal.
+ * This should not be called if another program is already in control
+ * of the terminal (Xorg, another Wayland compositor, etc.).
+ *
+ * If logind support is not enabled, you must have CAP_SYS_ADMIN or be root.
+ * It is safe to drop privileges after this is called.
+ *
+ * Returns NULL on error.
+ */
+struct wlr_session *wlr_session_create(struct wl_display *disp);
+
+/*
+ * Closes a previously opened session and restores the virtual terminal.
+ * You should call wlr_session_close_file on each files you opened
+ * with wlr_session_open_file before you call this.
+ */
+void wlr_session_destroy(struct wlr_session *session);
+
+/*
+ * Opens the file at path.
+ * This can only be used to open DRM or evdev (input) devices.
+ *
+ * When the session becomes inactive:
+ * - DRM files lose their DRM master status
+ * - evdev files become invalid and should be closed
+ *
+ * Returns -errno on error.
+ */
+int wlr_session_open_file(struct wlr_session *session, const char *path);
+
+/*
+ * Closes a file previously opened with wlr_session_open_file.
+ */
+void wlr_session_close_file(struct wlr_session *session, int fd);
+
+void wlr_session_signal_add(struct wlr_session *session, int fd,
+ struct wl_listener *listener);
+/*
+ * Changes the virtual terminal.
+ */
+bool wlr_session_change_vt(struct wlr_session *session, unsigned vt);
+
+size_t wlr_session_find_gpus(struct wlr_session *session,
+ size_t ret_len, int *ret);
+
+#endif
diff --git a/include/wlr/backend/session/interface.h b/include/wlr/backend/session/interface.h
new file mode 100644
index 00000000..5ccf9c8a
--- /dev/null
+++ b/include/wlr/backend/session/interface.h
@@ -0,0 +1,22 @@
+/*
+ * 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_BACKEND_SESSION_INTERFACE_H
+#define WLR_BACKEND_SESSION_INTERFACE_H
+
+#include <wlr/backend/session.h>
+
+struct session_impl {
+ struct wlr_session *(*create)(struct wl_display *disp);
+ void (*destroy)(struct wlr_session *session);
+ int (*open)(struct wlr_session *session, const char *path);
+ void (*close)(struct wlr_session *session, int fd);
+ bool (*change_vt)(struct wlr_session *session, unsigned vt);
+};
+
+#endif
diff --git a/include/wlr/backend/session/meson.build b/include/wlr/backend/session/meson.build
new file mode 100644
index 00000000..21b5a96b
--- /dev/null
+++ b/include/wlr/backend/session/meson.build
@@ -0,0 +1 @@
+install_headers('interface.h', subdir: 'wlr/backend/session')
diff --git a/include/wlr/backend/wayland.h b/include/wlr/backend/wayland.h
new file mode 100644
index 00000000..119ea247
--- /dev/null
+++ b/include/wlr/backend/wayland.h
@@ -0,0 +1,45 @@
+#ifndef WLR_BACKEND_WAYLAND_H
+#define WLR_BACKEND_WAYLAND_H
+
+#include <stdbool.h>
+#include <wayland-client.h>
+#include <wayland-server.h>
+#include <wlr/backend.h>
+#include <wlr/types/wlr_input_device.h>
+#include <wlr/types/wlr_output.h>
+
+/**
+ * Creates a new wlr_wl_backend. This backend will be created with no outputs;
+ * you must use wlr_wl_output_create to add them.
+ *
+ * The `remote` argument is the name of the host compositor wayland socket. Set
+ * to NULL for the default behaviour (WAYLAND_DISPLAY env variable or wayland-0
+ * default)
+ */
+struct wlr_backend *wlr_wl_backend_create(struct wl_display *display, const char *remote,
+ wlr_renderer_create_func_t create_renderer_func);
+
+/**
+ * Adds a new output to this backend. You may remove outputs by destroying them.
+ * Note that if called before initializing the backend, this will return NULL
+ * and your outputs will be created during initialization (and given to you via
+ * the output_add signal).
+ */
+struct wlr_output *wlr_wl_output_create(struct wlr_backend *backend);
+
+/**
+ * True if the given backend is a wlr_wl_backend.
+ */
+bool wlr_backend_is_wl(struct wlr_backend *backend);
+
+/**
+ * True if the given input device is a wlr_wl_input_device.
+ */
+bool wlr_input_device_is_wl(struct wlr_input_device *device);
+
+/**
+ * True if the given output is a wlr_wl_output.
+ */
+bool wlr_output_is_wl(struct wlr_output *output);
+
+#endif
diff --git a/include/wlr/backend/x11.h b/include/wlr/backend/x11.h
new file mode 100644
index 00000000..5793a3b9
--- /dev/null
+++ b/include/wlr/backend/x11.h
@@ -0,0 +1,20 @@
+#ifndef WLR_BACKEND_X11_H
+#define WLR_BACKEND_X11_H
+
+#include <stdbool.h>
+
+#include <wayland-server.h>
+
+#include <wlr/backend.h>
+#include <wlr/types/wlr_input_device.h>
+#include <wlr/types/wlr_output.h>
+
+struct wlr_backend *wlr_x11_backend_create(struct wl_display *display,
+ const char *x11_display, wlr_renderer_create_func_t create_renderer_func);
+struct wlr_output *wlr_x11_output_create(struct wlr_backend *backend);
+
+bool wlr_backend_is_x11(struct wlr_backend *backend);
+bool wlr_input_device_is_x11(struct wlr_input_device *device);
+bool wlr_output_is_x11(struct wlr_output *output);
+
+#endif
diff --git a/include/wlr/config.h.in b/include/wlr/config.h.in
new file mode 100644
index 00000000..94273fac
--- /dev/null
+++ b/include/wlr/config.h.in
@@ -0,0 +1,16 @@
+#ifndef WLR_CONFIG_H
+#define WLR_CONFIG_H
+
+#mesondefine WLR_HAS_LIBCAP
+
+#mesondefine WLR_HAS_SYSTEMD
+#mesondefine WLR_HAS_ELOGIND
+
+#mesondefine WLR_HAS_X11_BACKEND
+
+#mesondefine WLR_HAS_XWAYLAND
+
+#mesondefine WLR_HAS_XCB_ERRORS
+#mesondefine WLR_HAS_XCB_ICCCM
+
+#endif
diff --git a/include/wlr/interfaces/meson.build b/include/wlr/interfaces/meson.build
new file mode 100644
index 00000000..7d4d811d
--- /dev/null
+++ b/include/wlr/interfaces/meson.build
@@ -0,0 +1,11 @@
+install_headers(
+ 'wlr_input_device.h',
+ 'wlr_keyboard.h',
+ 'wlr_output.h',
+ 'wlr_pointer.h',
+ 'wlr_switch.h',
+ 'wlr_tablet_pad.h',
+ 'wlr_tablet_tool.h',
+ 'wlr_touch.h',
+ subdir: 'wlr/interfaces',
+)
diff --git a/include/wlr/interfaces/wlr_input_device.h b/include/wlr/interfaces/wlr_input_device.h
new file mode 100644
index 00000000..05248bf6
--- /dev/null
+++ b/include/wlr/interfaces/wlr_input_device.h
@@ -0,0 +1,25 @@
+/*
+ * 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_INTERFACES_WLR_INPUT_DEVICE_H
+#define WLR_INTERFACES_WLR_INPUT_DEVICE_H
+
+#include <wlr/types/wlr_input_device.h>
+
+struct wlr_input_device_impl {
+ void (*destroy)(struct wlr_input_device *wlr_device);
+};
+
+void wlr_input_device_init(
+ struct wlr_input_device *wlr_device,
+ enum wlr_input_device_type type,
+ const struct wlr_input_device_impl *impl,
+ const char *name, int vendor, int product);
+void wlr_input_device_destroy(struct wlr_input_device *dev);
+
+#endif
diff --git a/include/wlr/interfaces/wlr_keyboard.h b/include/wlr/interfaces/wlr_keyboard.h
new file mode 100644
index 00000000..5d537827
--- /dev/null
+++ b/include/wlr/interfaces/wlr_keyboard.h
@@ -0,0 +1,29 @@
+/*
+ * 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_INTERFACES_WLR_KEYBOARD_H
+#define WLR_INTERFACES_WLR_KEYBOARD_H
+
+#include <stdint.h>
+#include <wlr/types/wlr_keyboard.h>
+
+struct wlr_keyboard_impl {
+ void (*destroy)(struct wlr_keyboard *keyboard);
+ void (*led_update)(struct wlr_keyboard *keyboard, uint32_t leds);
+};
+
+void wlr_keyboard_init(struct wlr_keyboard *keyboard,
+ const struct wlr_keyboard_impl *impl);
+void wlr_keyboard_destroy(struct wlr_keyboard *keyboard);
+void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard,
+ struct wlr_event_keyboard_key *event);
+void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard,
+ uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked,
+ uint32_t group);
+
+#endif
diff --git a/include/wlr/interfaces/wlr_output.h b/include/wlr/interfaces/wlr_output.h
new file mode 100644
index 00000000..f7ffe3b4
--- /dev/null
+++ b/include/wlr/interfaces/wlr_output.h
@@ -0,0 +1,52 @@
+/*
+ * 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_INTERFACES_WLR_OUTPUT_H
+#define WLR_INTERFACES_WLR_OUTPUT_H
+
+#include <stdbool.h>
+#include <wlr/backend.h>
+#include <wlr/types/wlr_box.h>
+#include <wlr/types/wlr_output.h>
+
+struct wlr_output_impl {
+ bool (*enable)(struct wlr_output *output, bool enable);
+ bool (*set_mode)(struct wlr_output *output, struct wlr_output_mode *mode);
+ bool (*set_custom_mode)(struct wlr_output *output, int32_t width,
+ int32_t height, int32_t refresh);
+ void (*transform)(struct wlr_output *output,
+ enum wl_output_transform transform);
+ bool (*set_cursor)(struct wlr_output *output, struct wlr_texture *texture,
+ int32_t scale, enum wl_output_transform transform,
+ int32_t hotspot_x, int32_t hotspot_y, bool update_texture);
+ bool (*move_cursor)(struct wlr_output *output, int x, int y);
+ void (*destroy)(struct wlr_output *output);
+ bool (*make_current)(struct wlr_output *output, int *buffer_age);
+ bool (*swap_buffers)(struct wlr_output *output, pixman_region32_t *damage);
+ bool (*set_gamma)(struct wlr_output *output, size_t size,
+ const uint16_t *r, const uint16_t *g, const uint16_t *b);
+ size_t (*get_gamma_size)(struct wlr_output *output);
+ bool (*export_dmabuf)(struct wlr_output *output,
+ struct wlr_dmabuf_attributes *attribs);
+ bool (*schedule_frame)(struct wlr_output *output);
+};
+
+void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend,
+ const struct wlr_output_impl *impl, struct wl_display *display);
+void wlr_output_update_mode(struct wlr_output *output,
+ struct wlr_output_mode *mode);
+void wlr_output_update_custom_mode(struct wlr_output *output, int32_t width,
+ int32_t height, int32_t refresh);
+void wlr_output_update_enabled(struct wlr_output *output, bool enabled);
+void wlr_output_update_needs_swap(struct wlr_output *output);
+void wlr_output_damage_whole(struct wlr_output *output);
+void wlr_output_send_frame(struct wlr_output *output);
+void wlr_output_send_present(struct wlr_output *output,
+ struct wlr_output_event_present *event);
+
+#endif
diff --git a/include/wlr/interfaces/wlr_pointer.h b/include/wlr/interfaces/wlr_pointer.h
new file mode 100644
index 00000000..fd3ab102
--- /dev/null
+++ b/include/wlr/interfaces/wlr_pointer.h
@@ -0,0 +1,22 @@
+/*
+ * 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_INTERFACES_WLR_POINTER_H
+#define WLR_INTERFACES_WLR_POINTER_H
+
+#include <wlr/types/wlr_pointer.h>
+
+struct wlr_pointer_impl {
+ void (*destroy)(struct wlr_pointer *pointer);
+};
+
+void wlr_pointer_init(struct wlr_pointer *pointer,
+ const struct wlr_pointer_impl *impl);
+void wlr_pointer_destroy(struct wlr_pointer *pointer);
+
+#endif
diff --git a/include/wlr/interfaces/wlr_switch.h b/include/wlr/interfaces/wlr_switch.h
new file mode 100644
index 00000000..0b0454f5
--- /dev/null
+++ b/include/wlr/interfaces/wlr_switch.h
@@ -0,0 +1,22 @@
+/*
+ * 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_INTERFACES_WLR_SWITCH_H
+#define WLR_INTERFACES_WLR_SWITCH_H
+
+#include <wlr/types/wlr_switch.h>
+
+struct wlr_switch_impl {
+ void (*destroy)(struct wlr_switch *lid_switch);
+};
+
+void wlr_switch_init(struct wlr_switch *lid_switch,
+ struct wlr_switch_impl *impl);
+void wlr_switch_destroy(struct wlr_switch *lid_switch);
+
+#endif
diff --git a/include/wlr/interfaces/wlr_tablet_pad.h b/include/wlr/interfaces/wlr_tablet_pad.h
new file mode 100644
index 00000000..86bbe9c3
--- /dev/null
+++ b/include/wlr/interfaces/wlr_tablet_pad.h
@@ -0,0 +1,22 @@
+/*
+ * 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_INTERFACES_WLR_TABLET_PAD_H
+#define WLR_INTERFACES_WLR_TABLET_PAD_H
+
+#include <wlr/types/wlr_tablet_pad.h>
+
+struct wlr_tablet_pad_impl {
+ void (*destroy)(struct wlr_tablet_pad *pad);
+};
+
+void wlr_tablet_pad_init(struct wlr_tablet_pad *pad,
+ struct wlr_tablet_pad_impl *impl);
+void wlr_tablet_pad_destroy(struct wlr_tablet_pad *pad);
+
+#endif
diff --git a/include/wlr/interfaces/wlr_tablet_tool.h b/include/wlr/interfaces/wlr_tablet_tool.h
new file mode 100644
index 00000000..9cfc3ca0
--- /dev/null
+++ b/include/wlr/interfaces/wlr_tablet_tool.h
@@ -0,0 +1,22 @@
+/*
+ * 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_INTERFACES_WLR_TABLET_TOOL_H
+#define WLR_INTERFACES_WLR_TABLET_TOOL_H
+
+#include <wlr/types/wlr_tablet_tool.h>
+
+struct wlr_tablet_impl {
+ void (*destroy)(struct wlr_tablet *tablet);
+};
+
+void wlr_tablet_init(struct wlr_tablet *tablet,
+ struct wlr_tablet_impl *impl);
+void wlr_tablet_destroy(struct wlr_tablet *tablet);
+
+#endif
diff --git a/include/wlr/interfaces/wlr_touch.h b/include/wlr/interfaces/wlr_touch.h
new file mode 100644
index 00000000..cc426332
--- /dev/null
+++ b/include/wlr/interfaces/wlr_touch.h
@@ -0,0 +1,22 @@
+/*
+ * 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_INTERFACES_WLR_TOUCH_H
+#define WLR_INTERFACES_WLR_TOUCH_H
+
+#include <wlr/types/wlr_touch.h>
+
+struct wlr_touch_impl {
+ void (*destroy)(struct wlr_touch *touch);
+};
+
+void wlr_touch_init(struct wlr_touch *touch,
+ struct wlr_touch_impl *impl);
+void wlr_touch_destroy(struct wlr_touch *touch);
+
+#endif
diff --git a/include/wlr/meson.build b/include/wlr/meson.build
new file mode 100644
index 00000000..8874dbc7
--- /dev/null
+++ b/include/wlr/meson.build
@@ -0,0 +1,26 @@
+version_array = meson.project_version().split('.')
+version_data = configuration_data()
+version_data.set_quoted('WLR_VERSION_STR', meson.project_version())
+version_data.set('WLR_VERSION_MAJOR', version_array[0])
+version_data.set('WLR_VERSION_MINOR', version_array[1])
+version_data.set('WLR_VERSION_MICRO', version_array[2])
+version_data.set('WLR_VERSION_API_CURRENT', so_version[0])
+version_data.set('WLR_VERSION_API_REVISION', so_version[1])
+version_data.set('WLR_VERSION_API_AGE', so_version[2])
+
+install_headers(
+ configure_file(input: 'config.h.in', output: 'config.h',configuration: conf_data),
+ configure_file(input: 'version.h.in', output: 'version.h', configuration: version_data),
+ 'backend.h',
+ 'xcursor.h',
+ subdir: 'wlr'
+)
+if conf_data.get('WLR_HAS_XWAYLAND', 0) == 1
+ install_headers('xwayland.h', subdir: 'wlr')
+endif
+
+subdir('backend')
+subdir('interfaces')
+subdir('render')
+subdir('types')
+subdir('util')
diff --git a/include/wlr/render/dmabuf.h b/include/wlr/render/dmabuf.h
new file mode 100644
index 00000000..32cfe874
--- /dev/null
+++ b/include/wlr/render/dmabuf.h
@@ -0,0 +1,48 @@
+/*
+ * 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_RENDER_DMABUF_H
+#define WLR_RENDER_DMABUF_H
+
+#include <stdint.h>
+
+// So we don't have to pull in linux specific drm headers
+#ifndef DRM_FORMAT_MOD_INVALID
+#define DRM_FORMAT_MOD_INVALID ((1ULL<<56) - 1)
+#endif
+
+#ifndef DRM_FORMAT_MOD_LINEAR
+#define DRM_FORMAT_MOD_LINEAR 0
+#endif
+
+#define WLR_DMABUF_MAX_PLANES 4
+
+enum wlr_dmabuf_attributes_flags {
+ WLR_DMABUF_ATTRIBUTES_FLAGS_Y_INVERT = 1,
+ WLR_DMABUF_ATTRIBUTES_FLAGS_INTERLACED = 2,
+ WLR_DMABUF_ATTRIBUTES_FLAGS_BOTTOM_FIRST = 4,
+};
+
+struct wlr_dmabuf_attributes {
+ int32_t width, height;
+ uint32_t format;
+ uint32_t flags; // enum wlr_dmabuf_attributes_flags
+ uint64_t modifier;
+
+ int n_planes;
+ uint32_t offset[WLR_DMABUF_MAX_PLANES];
+ uint32_t stride[WLR_DMABUF_MAX_PLANES];
+ int fd[WLR_DMABUF_MAX_PLANES];
+};
+
+/**
+ * Closes all file descriptors in the DMA-BUF attributes.
+ */
+void wlr_dmabuf_attributes_finish(struct wlr_dmabuf_attributes *attribs);
+
+#endif
diff --git a/include/wlr/render/egl.h b/include/wlr/render/egl.h
new file mode 100644
index 00000000..269af7e2
--- /dev/null
+++ b/include/wlr/render/egl.h
@@ -0,0 +1,118 @@
+/*
+ * 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_RENDER_EGL_H
+#define WLR_RENDER_EGL_H
+
+#include <wlr/config.h>
+
+#if !WLR_HAS_X11_BACKEND && !WLR_HAS_XWAYLAND && !defined MESA_EGL_NO_X11_HEADERS
+#define MESA_EGL_NO_X11_HEADERS
+#endif
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <pixman.h>
+#include <stdbool.h>
+#include <wayland-server.h>
+#include <wlr/render/dmabuf.h>
+
+struct wlr_egl {
+ EGLenum platform;
+ EGLDisplay display;
+ EGLConfig config;
+ EGLContext context;
+
+ const char *exts_str;
+
+ struct {
+ bool bind_wayland_display_wl;
+ bool buffer_age_ext;
+ bool image_base_khr;
+ bool image_dma_buf_export_mesa;
+ bool image_dmabuf_import_ext;
+ bool image_dmabuf_import_modifiers_ext;
+ bool swap_buffers_with_damage_ext;
+ bool swap_buffers_with_damage_khr;
+ } exts;
+
+ struct wl_display *wl_display;
+};
+
+// TODO: Allocate and return a wlr_egl
+/**
+ * Initializes an EGL context for the given platform and remote display.
+ * Will attempt to load all possibly required api functions.
+ */
+bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display,
+ EGLint *config_attribs, EGLint visual_id);
+
+/**
+ * Frees all related EGL resources, makes the context not-current and
+ * unbinds a bound wayland display.
+ */
+void wlr_egl_finish(struct wlr_egl *egl);
+
+/**
+ * Binds the given display to the EGL instance.
+ * This will allow clients to create EGL surfaces from wayland ones and render
+ * to it.
+ */
+bool wlr_egl_bind_display(struct wlr_egl *egl, struct wl_display *local_display);
+
+/**
+ * Returns a surface for the given native window
+ * The window must match the remote display the wlr_egl was created with.
+ */
+EGLSurface wlr_egl_create_surface(struct wlr_egl *egl, void *window);
+
+/**
+ * Creates an EGL image from the given wl_drm buffer resource.
+ */
+EGLImageKHR wlr_egl_create_image_from_wl_drm(struct wlr_egl *egl,
+ struct wl_resource *data, EGLint *fmt, int *width, int *height,
+ bool *inverted_y);
+
+/**
+ * Creates an EGL image from the given dmabuf attributes. Check usability
+ * of the dmabuf with wlr_egl_check_import_dmabuf once first.
+ */
+EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl,
+ struct wlr_dmabuf_attributes *attributes);
+
+/**
+ * Get the available dmabuf formats
+ */
+int wlr_egl_get_dmabuf_formats(struct wlr_egl *egl, int **formats);
+
+/**
+ * Get the available dmabuf modifiers for a given format
+ */
+int wlr_egl_get_dmabuf_modifiers(struct wlr_egl *egl, int format,
+ uint64_t **modifiers);
+
+bool wlr_egl_export_image_to_dmabuf(struct wlr_egl *egl, EGLImageKHR image,
+ int32_t width, int32_t height, uint32_t flags,
+ struct wlr_dmabuf_attributes *attribs);
+
+/**
+ * Destroys an EGL image created with the given wlr_egl.
+ */
+bool wlr_egl_destroy_image(struct wlr_egl *egl, EGLImageKHR image);
+
+bool wlr_egl_make_current(struct wlr_egl *egl, EGLSurface surface,
+ int *buffer_age);
+
+bool wlr_egl_is_current(struct wlr_egl *egl);
+
+bool wlr_egl_swap_buffers(struct wlr_egl *egl, EGLSurface surface,
+ pixman_region32_t *damage);
+
+bool wlr_egl_destroy_surface(struct wlr_egl *egl, EGLSurface surface);
+
+#endif
diff --git a/include/wlr/render/gles2.h b/include/wlr/render/gles2.h
new file mode 100644
index 00000000..fca11ab8
--- /dev/null
+++ b/include/wlr/render/gles2.h
@@ -0,0 +1,27 @@
+/*
+ * 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_RENDER_GLES2_H
+#define WLR_RENDER_GLES2_H
+
+#include <wlr/backend.h>
+#include <wlr/render/wlr_renderer.h>
+
+struct wlr_egl;
+
+struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl);
+
+struct wlr_texture *wlr_gles2_texture_from_pixels(struct wlr_egl *egl,
+ enum wl_shm_format wl_fmt, uint32_t stride, uint32_t width, uint32_t height,
+ const void *data);
+struct wlr_texture *wlr_gles2_texture_from_wl_drm(struct wlr_egl *egl,
+ struct wl_resource *data);
+struct wlr_texture *wlr_gles2_texture_from_dmabuf(struct wlr_egl *egl,
+ struct wlr_dmabuf_attributes *attribs);
+
+#endif
diff --git a/include/wlr/render/interface.h b/include/wlr/render/interface.h
new file mode 100644
index 00000000..c98a7cda
--- /dev/null
+++ b/include/wlr/render/interface.h
@@ -0,0 +1,87 @@
+/*
+ * 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_RENDER_INTERFACE_H
+#define WLR_RENDER_INTERFACE_H
+
+#include <wlr/config.h>
+
+#if !WLR_HAS_X11_BACKEND && !WLR_HAS_XWAYLAND && !defined MESA_EGL_NO_X11_HEADERS
+#define MESA_EGL_NO_X11_HEADERS
+#endif
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <stdbool.h>
+#include <wayland-server-protocol.h>
+#include <wlr/render/wlr_renderer.h>
+#include <wlr/render/wlr_texture.h>
+#include <wlr/types/wlr_box.h>
+#include <wlr/types/wlr_output.h>
+#include <wlr/render/dmabuf.h>
+
+struct wlr_renderer_impl {
+ void (*begin)(struct wlr_renderer *renderer, uint32_t width,
+ uint32_t height);
+ void (*end)(struct wlr_renderer *renderer);
+ void (*clear)(struct wlr_renderer *renderer, const float color[static 4]);
+ void (*scissor)(struct wlr_renderer *renderer, struct wlr_box *box);
+ bool (*render_texture_with_matrix)(struct wlr_renderer *renderer,
+ struct wlr_texture *texture, const float matrix[static 9],
+ float alpha);
+ void (*render_quad_with_matrix)(struct wlr_renderer *renderer,
+ const float color[static 4], const float matrix[static 9]);
+ void (*render_ellipse_with_matrix)(struct wlr_renderer *renderer,
+ const float color[static 4], const float matrix[static 9]);
+ const enum wl_shm_format *(*formats)(
+ struct wlr_renderer *renderer, size_t *len);
+ bool (*format_supported)(struct wlr_renderer *renderer,
+ enum wl_shm_format fmt);
+ bool (*resource_is_wl_drm_buffer)(struct wlr_renderer *renderer,
+ struct wl_resource *resource);
+ void (*wl_drm_buffer_get_size)(struct wlr_renderer *renderer,
+ struct wl_resource *buffer, int *width, int *height);
+ int (*get_dmabuf_formats)(struct wlr_renderer *renderer, int **formats);
+ int (*get_dmabuf_modifiers)(struct wlr_renderer *renderer, int format,
+ uint64_t **modifiers);
+ enum wl_shm_format (*preferred_read_format)(struct wlr_renderer *renderer);
+ bool (*read_pixels)(struct wlr_renderer *renderer, enum wl_shm_format fmt,
+ uint32_t *flags, uint32_t stride, uint32_t width, uint32_t height,
+ uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
+ void *data);
+ struct wlr_texture *(*texture_from_pixels)(struct wlr_renderer *renderer,
+ enum wl_shm_format fmt, uint32_t stride, uint32_t width,
+ uint32_t height, const void *data);
+ struct wlr_texture *(*texture_from_wl_drm)(struct wlr_renderer *renderer,
+ struct wl_resource *data);
+ struct wlr_texture *(*texture_from_dmabuf)(struct wlr_renderer *renderer,
+ struct wlr_dmabuf_attributes *attribs);
+ void (*destroy)(struct wlr_renderer *renderer);
+ void (*init_wl_display)(struct wlr_renderer *renderer,
+ struct wl_display *wl_display);
+};
+
+void wlr_renderer_init(struct wlr_renderer *renderer,
+ const struct wlr_renderer_impl *impl);
+
+struct wlr_texture_impl {
+ void (*get_size)(struct wlr_texture *texture, int *width, int *height);
+ bool (*is_opaque)(struct wlr_texture *texture);
+ bool (*write_pixels)(struct wlr_texture *texture,
+ uint32_t stride, uint32_t width, uint32_t height,
+ uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
+ const void *data);
+ bool (*to_dmabuf)(struct wlr_texture *texture,
+ struct wlr_dmabuf_attributes *attribs);
+ void (*destroy)(struct wlr_texture *texture);
+};
+
+void wlr_texture_init(struct wlr_texture *texture,
+ const struct wlr_texture_impl *impl);
+
+#endif
diff --git a/include/wlr/render/meson.build b/include/wlr/render/meson.build
new file mode 100644
index 00000000..05127bb7
--- /dev/null
+++ b/include/wlr/render/meson.build
@@ -0,0 +1,9 @@
+install_headers(
+ 'dmabuf.h',
+ 'egl.h',
+ 'gles2.h',
+ 'interface.h',
+ 'wlr_renderer.h',
+ 'wlr_texture.h',
+ subdir: 'wlr/render'
+)
diff --git a/include/wlr/render/wlr_renderer.h b/include/wlr/render/wlr_renderer.h
new file mode 100644
index 00000000..9c031b7f
--- /dev/null
+++ b/include/wlr/render/wlr_renderer.h
@@ -0,0 +1,121 @@
+/*
+ * 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_RENDER_WLR_RENDERER_H
+#define WLR_RENDER_WLR_RENDERER_H
+
+#include <stdint.h>
+#include <wayland-server-protocol.h>
+#include <wlr/render/egl.h>
+#include <wlr/render/wlr_texture.h>
+#include <wlr/types/wlr_box.h>
+
+enum wlr_renderer_read_pixels_flags {
+ WLR_RENDERER_READ_PIXELS_Y_INVERT = 1,
+};
+
+struct wlr_renderer_impl;
+
+struct wlr_renderer {
+ const struct wlr_renderer_impl *impl;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+};
+
+struct wlr_renderer *wlr_renderer_autocreate(struct wlr_egl *egl, EGLenum platform,
+ void *remote_display, EGLint *config_attribs, EGLint visual_id);
+
+void wlr_renderer_begin(struct wlr_renderer *r, int width, int height);
+void wlr_renderer_end(struct wlr_renderer *r);
+void wlr_renderer_clear(struct wlr_renderer *r, const float color[static 4]);
+/**
+ * Defines a scissor box. Only pixels that lie within the scissor box can be
+ * modified by drawing functions. Providing a NULL `box` disables the scissor
+ * box.
+ */
+void wlr_renderer_scissor(struct wlr_renderer *r, struct wlr_box *box);
+/**
+ * Renders the requested texture.
+ */
+bool wlr_render_texture(struct wlr_renderer *r, struct wlr_texture *texture,
+ const float projection[static 9], int x, int y, float alpha);
+/**
+ * Renders the requested texture using the provided matrix.
+ */
+bool wlr_render_texture_with_matrix(struct wlr_renderer *r,
+ struct wlr_texture *texture, const float matrix[static 9], float alpha);
+/**
+ * Renders a solid rectangle in the specified color.
+ */
+void wlr_render_rect(struct wlr_renderer *r, const struct wlr_box *box,
+ const float color[static 4], const float projection[static 9]);
+/**
+ * Renders a solid quadrangle in the specified color with the specified matrix.
+ */
+void wlr_render_quad_with_matrix(struct wlr_renderer *r,
+ const float color[static 4], const float matrix[static 9]);
+/**
+ * Renders a solid ellipse in the specified color.
+ */
+void wlr_render_ellipse(struct wlr_renderer *r, const struct wlr_box *box,
+ const float color[static 4], const float projection[static 9]);
+/**
+ * Renders a solid ellipse in the specified color with the specified matrix.
+ */
+void wlr_render_ellipse_with_matrix(struct wlr_renderer *r,
+ const float color[static 4], const float matrix[static 9]);
+/**
+ * Returns a list of pixel formats supported by this renderer.
+ */
+const enum wl_shm_format *wlr_renderer_get_formats(struct wlr_renderer *r,
+ size_t *len);
+/**
+ * Returns true if this wl_buffer is a wl_drm buffer.
+ */
+bool wlr_renderer_resource_is_wl_drm_buffer(struct wlr_renderer *renderer,
+ struct wl_resource *buffer);
+/**
+ * Gets the width and height of a wl_drm buffer.
+ */
+void wlr_renderer_wl_drm_buffer_get_size(struct wlr_renderer *renderer,
+ struct wl_resource *buffer, int *width, int *height);
+/**
+ * Get the available dmabuf formats
+ */
+int wlr_renderer_get_dmabuf_formats(struct wlr_renderer *renderer,
+ int **formats);
+/**
+ * Get the available dmabuf modifiers for a given format
+ */
+int wlr_renderer_get_dmabuf_modifiers(struct wlr_renderer *renderer, int format,
+ uint64_t **modifiers);
+/**
+ * Reads out of pixels of the currently bound surface into data. `stride` is in
+ * bytes.
+ *
+ * If `flags` is not NULl, the caller indicates that it accepts frame flags
+ * defined in `enum wlr_renderer_read_pixels_flags`.
+ */
+bool wlr_renderer_read_pixels(struct wlr_renderer *r, enum wl_shm_format fmt,
+ uint32_t *flags, uint32_t stride, uint32_t width, uint32_t height,
+ uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y, void *data);
+/**
+ * Checks if a format is supported.
+ */
+bool wlr_renderer_format_supported(struct wlr_renderer *r,
+ enum wl_shm_format fmt);
+void wlr_renderer_init_wl_display(struct wlr_renderer *r,
+ struct wl_display *wl_display);
+/**
+ * Destroys this wlr_renderer. Textures must be destroyed separately.
+ */
+void wlr_renderer_destroy(struct wlr_renderer *renderer);
+
+#endif
diff --git a/include/wlr/render/wlr_texture.h b/include/wlr/render/wlr_texture.h
new file mode 100644
index 00000000..f210717a
--- /dev/null
+++ b/include/wlr/render/wlr_texture.h
@@ -0,0 +1,73 @@
+/*
+ * 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_RENDER_WLR_TEXTURE_H
+#define WLR_RENDER_WLR_TEXTURE_H
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <stdint.h>
+#include <wayland-server-protocol.h>
+#include <wlr/render/dmabuf.h>
+
+struct wlr_renderer;
+struct wlr_texture_impl;
+
+struct wlr_texture {
+ const struct wlr_texture_impl *impl;
+};
+
+/**
+ * Create a new texture from raw pixel data. `stride` is in bytes. The returned
+ * texture is mutable.
+ */
+struct wlr_texture *wlr_texture_from_pixels(struct wlr_renderer *renderer,
+ enum wl_shm_format wl_fmt, uint32_t stride, uint32_t width, uint32_t height,
+ const void *data);
+
+/**
+ * Create a new texture from a wl_drm resource. The returned texture is
+ * immutable.
+ */
+struct wlr_texture *wlr_texture_from_wl_drm(struct wlr_renderer *renderer,
+ struct wl_resource *data);
+
+/**
+ * Create a new texture from a DMA-BUF. The returned texture is immutable.
+ */
+struct wlr_texture *wlr_texture_from_dmabuf(struct wlr_renderer *renderer,
+ struct wlr_dmabuf_attributes *attribs);
+
+/**
+ * Get the texture width and height.
+ */
+void wlr_texture_get_size(struct wlr_texture *texture, int *width, int *height);
+
+/**
+ * Returns true if this texture is using a fully opaque format.
+ */
+bool wlr_texture_is_opaque(struct wlr_texture *texture);
+
+/**
+ * Update a texture with raw pixels. The texture must be mutable, and the input
+ * data must have the same pixel format that the texture was created with.
+ */
+bool wlr_texture_write_pixels(struct wlr_texture *texture,
+ uint32_t stride, uint32_t width, uint32_t height,
+ uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
+ const void *data);
+
+bool wlr_texture_to_dmabuf(struct wlr_texture *texture,
+ struct wlr_dmabuf_attributes *attribs);
+
+/**
+ * Destroys this wlr_texture.
+ */
+void wlr_texture_destroy(struct wlr_texture *texture);
+
+#endif
diff --git a/include/wlr/types/meson.build b/include/wlr/types/meson.build
new file mode 100644
index 00000000..752c0dea
--- /dev/null
+++ b/include/wlr/types/meson.build
@@ -0,0 +1,49 @@
+install_headers(
+ 'wlr_box.h',
+ 'wlr_buffer.h',
+ 'wlr_compositor.h',
+ 'wlr_cursor.h',
+ 'wlr_data_device.h',
+ 'wlr_export_dmabuf_v1.h',
+ 'wlr_foreign_toplevel_management_v1.h',
+ 'wlr_gamma_control_v1.h',
+ 'wlr_gamma_control.h',
+ 'wlr_gtk_primary_selection.h',
+ 'wlr_idle_inhibit_v1.h',
+ 'wlr_idle.h',
+ 'wlr_input_device.h',
+ 'wlr_input_inhibitor.h',
+ 'wlr_input_method_v2.h',
+ 'wlr_keyboard.h',
+ 'wlr_layer_shell_v1.h',
+ 'wlr_linux_dmabuf_v1.h',
+ 'wlr_list.h',
+ 'wlr_matrix.h',
+ 'wlr_output_damage.h',
+ 'wlr_output_layout.h',
+ 'wlr_output.h',
+ 'wlr_pointer.h',
+ 'wlr_pointer_constraints_v1.h',
+ 'wlr_presentation_time.h',
+ 'wlr_primary_selection.h',
+ 'wlr_region.h',
+ 'wlr_screencopy_v1.h',
+ 'wlr_screenshooter.h',
+ 'wlr_seat.h',
+ 'wlr_server_decoration.h',
+ 'wlr_surface.h',
+ 'wlr_switch.h',
+ 'wlr_tablet_pad.h',
+ 'wlr_tablet_tool.h',
+ 'wlr_tablet_v2.h',
+ 'wlr_text_input_v3.h',
+ 'wlr_touch.h',
+ 'wlr_virtual_keyboard_v1.h',
+ 'wlr_wl_shell.h',
+ 'wlr_xcursor_manager.h',
+ 'wlr_xdg_decoration_v1.h',
+ 'wlr_xdg_output_v1.h',
+ 'wlr_xdg_shell_v6.h',
+ 'wlr_xdg_shell.h',
+ subdir: 'wlr/types',
+)
diff --git a/include/wlr/types/wlr_box.h b/include/wlr/types/wlr_box.h
new file mode 100644
index 00000000..40fd69bd
--- /dev/null
+++ b/include/wlr/types/wlr_box.h
@@ -0,0 +1,44 @@
+/*
+ * 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_BOX_H
+#define WLR_TYPES_WLR_BOX_H
+
+#include <pixman.h>
+#include <stdbool.h>
+#include <wayland-server.h>
+
+struct wlr_box {
+ int x, y;
+ int width, height;
+};
+
+void wlr_box_closest_point(const struct wlr_box *box, double x, double y,
+ double *dest_x, double *dest_y);
+
+bool wlr_box_intersection(struct wlr_box *dest, const struct wlr_box *box_a,
+ const struct wlr_box *box_b);
+
+bool wlr_box_contains_point(const struct wlr_box *box, double x, double y);
+
+bool wlr_box_empty(const struct wlr_box *box);
+
+/**
+ * Transforms a box inside a `width` x `height` box.
+ */
+void wlr_box_transform(struct wlr_box *dest, const struct wlr_box *box,
+ enum wl_output_transform transform, int width, int height);
+
+/**
+ * Creates the smallest box that contains the box rotated about its center.
+ */
+void wlr_box_rotated_bounds(struct wlr_box *dest, const struct wlr_box *box, float rotation);
+
+void wlr_box_from_pixman_box32(struct wlr_box *dest, const pixman_box32_t box);
+
+#endif
diff --git a/include/wlr/types/wlr_buffer.h b/include/wlr/types/wlr_buffer.h
new file mode 100644
index 00000000..0c987b17
--- /dev/null
+++ b/include/wlr/types/wlr_buffer.h
@@ -0,0 +1,71 @@
+/*
+ * 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_BUFFER_H
+#define WLR_TYPES_WLR_BUFFER_H
+
+#include <pixman.h>
+#include <wayland-server.h>
+
+/**
+ * A client buffer.
+ */
+struct wlr_buffer {
+ /**
+ * The buffer resource, if any. Will be NULL if the client destroys it.
+ */
+ struct wl_resource *resource;
+ /**
+ * The buffer's texture, if any. A buffer will not have a texture if the
+ * client destroys the buffer before it has been released.
+ */
+ struct wlr_texture *texture;
+ bool released;
+ size_t n_refs;
+
+ struct wl_listener resource_destroy;
+};
+
+struct wlr_renderer;
+
+/**
+ * Check if a resource is a wl_buffer resource.
+ */
+bool wlr_resource_is_buffer(struct wl_resource *resource);
+/**
+ * Get the size of a wl_buffer resource.
+ */
+bool wlr_buffer_get_resource_size(struct wl_resource *resource,
+ struct wlr_renderer *renderer, int *width, int *height);
+
+/**
+ * Upload a buffer to the GPU and reference it.
+ */
+struct wlr_buffer *wlr_buffer_create(struct wlr_renderer *renderer,
+ struct wl_resource *resource);
+/**
+ * Reference the buffer.
+ */
+struct wlr_buffer *wlr_buffer_ref(struct wlr_buffer *buffer);
+/**
+ * Unreference the buffer. After this call, `buffer` may not be accessed
+ * anymore.
+ */
+void wlr_buffer_unref(struct wlr_buffer *buffer);
+/**
+ * Try to update the buffer's content. On success, returns the updated buffer
+ * and destroys the provided `buffer`. On error, `buffer` is intact and NULL is
+ * returned.
+ *
+ * Fails if there's more than one reference to the buffer or if the texture
+ * isn't mutable.
+ */
+struct wlr_buffer *wlr_buffer_apply_damage(struct wlr_buffer *buffer,
+ struct wl_resource *resource, pixman_region32_t *damage);
+
+#endif
diff --git a/include/wlr/types/wlr_compositor.h b/include/wlr/types/wlr_compositor.h
new file mode 100644
index 00000000..36b9e83f
--- /dev/null
+++ b/include/wlr/types/wlr_compositor.h
@@ -0,0 +1,53 @@
+/*
+ * 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_COMPOSITOR_H
+#define WLR_TYPES_WLR_COMPOSITOR_H
+
+#include <wayland-server.h>
+#include <wlr/render/wlr_renderer.h>
+
+struct wlr_surface;
+
+struct wlr_subcompositor {
+ struct wl_global *global;
+ struct wl_list resources;
+ struct wl_list subsurface_resources;
+};
+
+struct wlr_compositor {
+ struct wl_global *global;
+ struct wl_list resources;
+ struct wlr_renderer *renderer;
+ struct wl_list surface_resources;
+ struct wl_list region_resources;
+
+ struct wlr_subcompositor subcompositor;
+
+ struct wl_listener display_destroy;
+
+ struct {
+ struct wl_signal new_surface;
+ struct wl_signal destroy;
+ } events;
+};
+
+void wlr_compositor_destroy(struct wlr_compositor *wlr_compositor);
+struct wlr_compositor *wlr_compositor_create(struct wl_display *display,
+ struct wlr_renderer *renderer);
+
+bool wlr_surface_is_subsurface(struct wlr_surface *surface);
+
+/**
+ * Get a subsurface from a surface. Can return NULL if the subsurface has been
+ * destroyed.
+ */
+struct wlr_subsurface *wlr_subsurface_from_wlr_surface(
+ struct wlr_surface *surface);
+
+#endif
diff --git a/include/wlr/types/wlr_cursor.h b/include/wlr/types/wlr_cursor.h
new file mode 100644
index 00000000..44ced1f0
--- /dev/null
+++ b/include/wlr/types/wlr_cursor.h
@@ -0,0 +1,194 @@
+/*
+ * 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_CURSOR_H
+#define WLR_TYPES_WLR_CURSOR_H
+
+#include <wayland-server.h>
+#include <wlr/types/wlr_box.h>
+#include <wlr/types/wlr_input_device.h>
+#include <wlr/types/wlr_output_layout.h>
+#include <wlr/types/wlr_output.h>
+
+/**
+ * wlr_cursor implements the behavior of the "cursor", that is, the image on the
+ * screen typically moved about with a mouse or so. It provides tracking for
+ * this in global coordinates, and integrates with wlr_output,
+ * wlr_output_layout, and wlr_input_device. You can use it to abstract multiple
+ * input devices over a single cursor, constrain cursor movement to the usable
+ * area of a wlr_output_layout and communicate position updates to the hardware
+ * cursor, constrain specific input devices to specific outputs or regions of
+ * the screen, and so on.
+ */
+
+struct wlr_cursor_state;
+
+struct wlr_cursor {
+ struct wlr_cursor_state *state;
+ double x, y;
+
+ /**
+ * The interpretation of these signals is the responsibility of the
+ * compositor, but some helpers are provided for your benefit. If you
+ * receive a relative motion event, for example, you may want to call
+ * wlr_cursor_move. If you receive an absolute event, call
+ * wlr_cursor_warp_absolute. If you pass an input device into these
+ * functions, it will apply the region/output constraints associated with
+ * that device to the resulting cursor motion. If an output layout is
+ * attached, these functions will constrain the resulting cursor motion to
+ * within the usable space of the output layout.
+ *
+ * Re-broadcasting these signals to, for example, a wlr_seat, is also your
+ * responsibility.
+ */
+ struct {
+ struct wl_signal motion;
+ struct wl_signal motion_absolute;
+ struct wl_signal button;
+ struct wl_signal axis;
+
+ struct wl_signal touch_up;
+ struct wl_signal touch_down;
+ struct wl_signal touch_motion;
+ struct wl_signal touch_cancel;
+
+ struct wl_signal tablet_tool_axis;
+ struct wl_signal tablet_tool_proximity;
+ struct wl_signal tablet_tool_tip;
+ struct wl_signal tablet_tool_button;
+ } events;
+
+ void *data;
+};
+
+struct wlr_cursor *wlr_cursor_create();
+
+void wlr_cursor_destroy(struct wlr_cursor *cur);
+
+/**
+ * Warp the cursor to the given x and y in layout coordinates. If x and y are
+ * out of the layout boundaries or constraints, no warp will happen.
+ *
+ * `dev` may be passed to respect device mapping constraints. If `dev` is NULL,
+ * device mapping constraints will be ignored.
+ *
+ * Returns true when the cursor warp was successful.
+ */
+bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev,
+ double lx, double ly);
+
+/**
+ * Convert absolute 0..1 coordinates to layout coordinates.
+ *
+ * `dev` may be passed to respect device mapping constraints. If `dev` is NULL,
+ * device mapping constraints will be ignored.
+ */
+void wlr_cursor_absolute_to_layout_coords(struct wlr_cursor *cur,
+ struct wlr_input_device *dev, double x, double y, double *lx, double *ly);
+
+
+/**
+ * Warp the cursor to the given x and y coordinates. If the given point is out
+ * of the layout boundaries or constraints, the closest point will be used.
+ * If one coordinate is NAN, it will be ignored.
+ *
+ * `dev` may be passed to respect device mapping constraints. If `dev` is NULL,
+ * device mapping constraints will be ignored.
+ */
+void wlr_cursor_warp_closest(struct wlr_cursor *cur,
+ struct wlr_input_device *dev, double x, double y);
+
+/**
+ * Warp the cursor to the given x and y in absolute 0..1 coordinates. If the
+ * given point is out of the layout boundaries or constraints, the closest point
+ * will be used. If one coordinate is NAN, it will be ignored.
+ *
+ * `dev` may be passed to respect device mapping constraints. If `dev` is NULL,
+ * device mapping constraints will be ignored.
+ */
+void wlr_cursor_warp_absolute(struct wlr_cursor *cur,
+ struct wlr_input_device *dev, double x, double y);
+
+/**
+ * Move the cursor in the direction of the given x and y layout coordinates. If
+ * one coordinate is NAN, it will be ignored.
+ *
+ * `dev` may be passed to respect device mapping constraints. If `dev` is NULL,
+ * device mapping constraints will be ignored.
+ */
+void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev,
+ double delta_x, double delta_y);
+
+/**
+ * Set the cursor image. stride is given in bytes. If pixels is NULL, hides the
+ * cursor.
+ *
+ * If scale isn't zero, the image is only set on outputs having the provided
+ * scale.
+ */
+void wlr_cursor_set_image(struct wlr_cursor *cur, const uint8_t *pixels,
+ int32_t stride, uint32_t width, uint32_t height, int32_t hotspot_x,
+ int32_t hotspot_y, float scale);
+
+/**
+ * Set the cursor surface. The surface can be committed to update the cursor
+ * image. The surface position is subtracted from the hotspot. A NULL surface
+ * commit hides the cursor.
+ */
+void wlr_cursor_set_surface(struct wlr_cursor *cur, struct wlr_surface *surface,
+ int32_t hotspot_x, int32_t hotspot_y);
+
+/**
+ * Attaches this input device to this cursor. The input device must be one of:
+ *
+ * - WLR_INPUT_DEVICE_POINTER
+ * - WLR_INPUT_DEVICE_TOUCH
+ * - WLR_INPUT_DEVICE_TABLET_TOOL
+ */
+void wlr_cursor_attach_input_device(struct wlr_cursor *cur,
+ struct wlr_input_device *dev);
+
+void wlr_cursor_detach_input_device(struct wlr_cursor *cur,
+ struct wlr_input_device *dev);
+/**
+ * Uses the given layout to establish the boundaries and movement semantics of
+ * this cursor. Cursors without an output layout allow infinite movement in any
+ * direction and do not support absolute input events.
+ */
+void wlr_cursor_attach_output_layout(struct wlr_cursor *cur,
+ struct wlr_output_layout *l);
+
+/**
+ * Attaches this cursor to the given output, which must be among the outputs in
+ * the current output_layout for this cursor. This call is invalid for a cursor
+ * without an associated output layout.
+ */
+void wlr_cursor_map_to_output(struct wlr_cursor *cur,
+ struct wlr_output *output);
+
+/**
+ * Maps all input from a specific input device to a given output. The input
+ * device must be attached to this cursor and the output must be among the
+ * outputs in the attached output layout.
+ */
+void wlr_cursor_map_input_to_output(struct wlr_cursor *cur,
+ struct wlr_input_device *dev, struct wlr_output *output);
+
+/**
+ * Maps this cursor to an arbitrary region on the associated wlr_output_layout.
+ */
+void wlr_cursor_map_to_region(struct wlr_cursor *cur, struct wlr_box *box);
+
+/**
+ * Maps inputs from this input device to an arbitrary region on the associated
+ * wlr_output_layout.
+ */
+void wlr_cursor_map_input_to_region(struct wlr_cursor *cur,
+ struct wlr_input_device *dev, struct wlr_box *box);
+
+#endif
diff --git a/include/wlr/types/wlr_data_device.h b/include/wlr/types/wlr_data_device.h
new file mode 100644
index 00000000..9c4ce995
--- /dev/null
+++ b/include/wlr/types/wlr_data_device.h
@@ -0,0 +1,231 @@
+/*
+ * 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_DATA_DEVICE_H
+#define WLR_TYPES_WLR_DATA_DEVICE_H
+
+#include <wayland-server.h>
+#include <wlr/types/wlr_seat.h>
+
+extern const struct wlr_pointer_grab_interface
+ wlr_data_device_pointer_drag_interface;
+
+extern const struct wlr_keyboard_grab_interface
+ wlr_data_device_keyboard_drag_interface;
+
+extern const struct wlr_touch_grab_interface
+ wlr_data_device_touch_drag_interface;
+
+struct wlr_data_device_manager {
+ struct wl_global *global;
+ struct wl_list resources;
+ struct wl_list data_sources;
+
+ struct wl_listener display_destroy;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_data_offer {
+ struct wl_resource *resource;
+ struct wlr_data_source *source;
+
+ uint32_t actions;
+ enum wl_data_device_manager_dnd_action preferred_action;
+ bool in_ask;
+
+ struct wl_listener source_destroy;
+};
+
+/**
+ * A data source implementation. Only the `send` function is mandatory. Refer to
+ * the matching wl_data_source_* functions documentation to know what they do.
+ */
+struct wlr_data_source_impl {
+ void (*send)(struct wlr_data_source *source, const char *mime_type,
+ int32_t fd);
+ void (*accept)(struct wlr_data_source *source, uint32_t serial,
+ const char *mime_type);
+ void (*cancel)(struct wlr_data_source *source);
+
+ void (*dnd_drop)(struct wlr_data_source *source);
+ void (*dnd_finish)(struct wlr_data_source *source);
+ void (*dnd_action)(struct wlr_data_source *source,
+ enum wl_data_device_manager_dnd_action action);
+};
+
+struct wlr_data_source {
+ const struct wlr_data_source_impl *impl;
+
+ // source metadata
+ struct wl_array mime_types;
+ int32_t actions;
+
+ // source status
+ bool accepted;
+
+ // drag'n'drop status
+ enum wl_data_device_manager_dnd_action current_dnd_action;
+ uint32_t compositor_action;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+};
+
+struct wlr_drag_icon {
+ struct wlr_surface *surface;
+ struct wlr_seat_client *client;
+ struct wl_list link; // wlr_seat::drag_icons
+ bool mapped;
+
+ bool is_pointer;
+ int32_t touch_id;
+
+ struct {
+ struct wl_signal map;
+ struct wl_signal unmap;
+ struct wl_signal destroy;
+ } events;
+
+ struct wl_listener surface_destroy;
+ struct wl_listener seat_client_destroy;
+
+ void *data;
+};
+
+struct wlr_drag {
+ struct wlr_seat_pointer_grab pointer_grab;
+ struct wlr_seat_keyboard_grab keyboard_grab;
+ struct wlr_seat_touch_grab touch_grab;
+
+ struct wlr_seat *seat;
+ struct wlr_seat_client *seat_client;
+ struct wlr_seat_client *focus_client;
+
+ bool is_pointer_grab;
+
+ struct wlr_drag_icon *icon;
+ struct wlr_surface *focus;
+ struct wlr_data_source *source;
+
+ bool cancelling;
+ int32_t grab_touch_id;
+
+ struct wl_listener point_destroy;
+ struct wl_listener source_destroy;
+ struct wl_listener seat_client_destroy;
+ struct wl_listener icon_destroy;
+
+ struct {
+ struct wl_signal focus;
+ struct wl_signal motion;
+ struct wl_signal drop;
+ struct wl_signal destroy;
+ } events;
+};
+
+struct wlr_drag_motion_event {
+ struct wlr_drag *drag;
+ uint32_t time;
+ double sx, sy;
+};
+
+struct wlr_drag_drop_event {
+ struct wlr_drag *drag;
+ uint32_t time;
+};
+
+/**
+ * Create a wl data device manager global for this display.
+ */
+struct wlr_data_device_manager *wlr_data_device_manager_create(
+ struct wl_display *display);
+
+/**
+ * Destroys a wlr_data_device_manager and removes its wl_data_device_manager global.
+ */
+void wlr_data_device_manager_destroy(struct wlr_data_device_manager *manager);
+
+/**
+ * Creates a new wl_data_offer if there is a wl_data_source currently set as
+ * the seat selection and sends it to the seat client, followed by the
+ * wl_data_device.selection() event. If there is no current selection, the
+ * wl_data_device.selection() event will carry a NULL wl_data_offer. If the
+ * client does not have a wl_data_device for the seat nothing * will be done.
+ */
+void wlr_seat_client_send_selection(struct wlr_seat_client *seat_client);
+
+/**
+ * Sets the current selection for the seat. This removes the previous one if
+ * there was any.
+ */
+void wlr_seat_set_selection(struct wlr_seat *seat,
+ struct wlr_data_source *source, uint32_t serial);
+
+/**
+ * Initializes the data source with the provided implementation.
+ */
+void wlr_data_source_init(struct wlr_data_source *source,
+ const struct wlr_data_source_impl *impl);
+
+/**
+ * Finishes the data source.
+ */
+void wlr_data_source_finish(struct wlr_data_source *source);
+
+/**
+ * Sends the data as the specified MIME type over the passed file descriptor,
+ * then close it.
+ */
+void wlr_data_source_send(struct wlr_data_source *source, const char *mime_type,
+ int32_t fd);
+
+/**
+ * Notifies the data source that a target accepts one of the offered MIME types.
+ * If a target doesn't accept any of the offered types, `mime_type` is NULL.
+ */
+void wlr_data_source_accept(struct wlr_data_source *source, uint32_t serial,
+ const char *mime_type);
+
+/**
+ * Notifies the data source it is no longer valid and should be destroyed. That
+ * potentially destroys immediately the data source.
+ */
+void wlr_data_source_cancel(struct wlr_data_source *source);
+
+/**
+ * Notifies the data source that the drop operation was performed. This does not
+ * indicate acceptance.
+ *
+ * The data source may still be used in the future and should not be destroyed
+ * here.
+ */
+void wlr_data_source_dnd_drop(struct wlr_data_source *source);
+
+/**
+ * Notifies the data source that the drag-and-drop operation concluded. That
+ * potentially destroys immediately the data source.
+ */
+void wlr_data_source_dnd_finish(struct wlr_data_source *source);
+
+/**
+ * Notifies the data source that a target accepts the drag with the specified
+ * action.
+ *
+ * This shouldn't be called after `wlr_data_source_dnd_drop` unless the
+ * drag-and-drop operation ended in an "ask" action.
+ */
+void wlr_data_source_dnd_action(struct wlr_data_source *source,
+ enum wl_data_device_manager_dnd_action action);
+
+#endif
diff --git a/include/wlr/types/wlr_export_dmabuf_v1.h b/include/wlr/types/wlr_export_dmabuf_v1.h
new file mode 100644
index 00000000..204da985
--- /dev/null
+++ b/include/wlr/types/wlr_export_dmabuf_v1.h
@@ -0,0 +1,46 @@
+/*
+ * 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_EXPORT_DMABUF_V1_H
+#define WLR_TYPES_WLR_EXPORT_DMABUF_V1_H
+
+#include <stdbool.h>
+#include <wayland-server.h>
+#include <wlr/render/dmabuf.h>
+
+struct wlr_export_dmabuf_manager_v1 {
+ struct wl_global *global;
+ struct wl_list resources; // wl_resource_get_link
+ struct wl_list frames; // wlr_export_dmabuf_frame_v1::link
+
+ struct wl_listener display_destroy;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+};
+
+struct wlr_export_dmabuf_frame_v1 {
+ struct wl_resource *resource;
+ struct wlr_export_dmabuf_manager_v1 *manager;
+ struct wl_list link; // wlr_export_dmabuf_manager_v1::frames
+
+ struct wlr_dmabuf_attributes attribs;
+ struct wlr_output *output;
+
+ bool cursor_locked;
+
+ struct wl_listener output_swap_buffers;
+};
+
+struct wlr_export_dmabuf_manager_v1 *wlr_export_dmabuf_manager_v1_create(
+ struct wl_display *display);
+void wlr_export_dmabuf_manager_v1_destroy(
+ struct wlr_export_dmabuf_manager_v1 *manager);
+
+#endif
diff --git a/include/wlr/types/wlr_foreign_toplevel_management_v1.h b/include/wlr/types/wlr_foreign_toplevel_management_v1.h
new file mode 100644
index 00000000..75ae0e64
--- /dev/null
+++ b/include/wlr/types/wlr_foreign_toplevel_management_v1.h
@@ -0,0 +1,120 @@
+/*
+ * 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_FOREIGN_TOPLEVEL_MANAGEMENT_V1_H
+#define WLR_TYPES_WLR_FOREIGN_TOPLEVEL_MANAGEMENT_V1_H
+
+#include <wayland-server.h>
+#include <wlr/types/wlr_output.h>
+
+struct wlr_foreign_toplevel_manager_v1 {
+ struct wl_event_loop *event_loop;
+ struct wl_global *global;
+ struct wl_list resources;
+ struct wl_list toplevels; // wlr_foreign_toplevel_handle_v1::link
+
+ struct wl_listener display_destroy;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+enum wlr_foreign_toplevel_handle_v1_state {
+ WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MAXIMIZED = 1,
+ WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MINIMIZED = 2,
+ WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED = 4,
+};
+
+struct wlr_foreign_toplevel_handle_v1_output {
+ struct wl_list link; // wlr_foreign_toplevel_handle_v1::outputs
+ struct wl_listener output_destroy;
+ struct wlr_output *output;
+
+ struct wlr_foreign_toplevel_handle_v1 *toplevel;
+};
+
+struct wlr_foreign_toplevel_handle_v1 {
+ struct wlr_foreign_toplevel_manager_v1 *manager;
+ struct wl_list resources;
+ struct wl_list link;
+ struct wl_event_source *idle_source;
+
+ char *title;
+ char *app_id;
+ struct wl_list outputs; // wlr_foreign_toplevel_v1_output
+ uint32_t state; // wlr_foreign_toplevel_v1_state
+
+ struct {
+ // wlr_foreign_toplevel_handle_v1_maximized_event
+ struct wl_signal request_maximize;
+ //wlr_foreign_toplevel_handle_v1_minimized_event
+ struct wl_signal request_minimize;
+ //wlr_foreign_toplevel_handle_v1_activated_event
+ struct wl_signal request_activate;
+ struct wl_signal request_close;
+
+ //wlr_foreign_toplevel_handle_v1_set_rectangle_event
+ struct wl_signal set_rectangle;
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_foreign_toplevel_handle_v1_maximized_event {
+ struct wlr_foreign_toplevel_handle_v1 *toplevel;
+ bool maximized;
+};
+
+struct wlr_foreign_toplevel_handle_v1_minimized_event {
+ struct wlr_foreign_toplevel_handle_v1 *toplevel;
+ bool minimized;
+};
+
+struct wlr_foreign_toplevel_handle_v1_activated_event {
+ struct wlr_foreign_toplevel_handle_v1 *toplevel;
+ struct wlr_seat *seat;
+};
+
+struct wlr_foreign_toplevel_handle_v1_set_rectangle_event {
+ struct wlr_foreign_toplevel_handle_v1 *toplevel;
+ struct wlr_surface *surface;
+ int32_t x, y, width, height;
+};
+
+struct wlr_foreign_toplevel_manager_v1 *wlr_foreign_toplevel_manager_v1_create(
+ struct wl_display *display);
+void wlr_foreign_toplevel_manager_v1_destroy(
+ struct wlr_foreign_toplevel_manager_v1 *manager);
+
+struct wlr_foreign_toplevel_handle_v1 *wlr_foreign_toplevel_handle_v1_create(
+ struct wlr_foreign_toplevel_manager_v1 *manager);
+void wlr_foreign_toplevel_handle_v1_destroy(
+ struct wlr_foreign_toplevel_handle_v1 *toplevel);
+
+void wlr_foreign_toplevel_handle_v1_set_title(
+ struct wlr_foreign_toplevel_handle_v1 *toplevel, const char *title);
+void wlr_foreign_toplevel_handle_v1_set_app_id(
+ struct wlr_foreign_toplevel_handle_v1 *toplevel, const char *app_id);
+
+void wlr_foreign_toplevel_handle_v1_output_enter(
+ struct wlr_foreign_toplevel_handle_v1 *toplevel, struct wlr_output *output);
+void wlr_foreign_toplevel_handle_v1_output_leave(
+ struct wlr_foreign_toplevel_handle_v1 *toplevel, struct wlr_output *output);
+
+void wlr_foreign_toplevel_handle_v1_set_maximized(
+ struct wlr_foreign_toplevel_handle_v1 *toplevel, bool maximized);
+void wlr_foreign_toplevel_handle_v1_set_minimized(
+ struct wlr_foreign_toplevel_handle_v1 *toplevel, bool minimized);
+void wlr_foreign_toplevel_handle_v1_set_activated(
+ struct wlr_foreign_toplevel_handle_v1 *toplevel, bool activated);
+
+#endif
diff --git a/include/wlr/types/wlr_gamma_control.h b/include/wlr/types/wlr_gamma_control.h
new file mode 100644
index 00000000..912a413c
--- /dev/null
+++ b/include/wlr/types/wlr_gamma_control.h
@@ -0,0 +1,46 @@
+/*
+ * 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_GAMMA_CONTROL_H
+#define WLR_TYPES_WLR_GAMMA_CONTROL_H
+
+#include <wayland-server.h>
+
+struct wlr_gamma_control_manager {
+ struct wl_global *global;
+ struct wl_list controls; // wlr_gamma_control::link
+
+ struct wl_listener display_destroy;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_gamma_control {
+ struct wl_resource *resource;
+ struct wlr_output *output;
+ struct wl_list link;
+
+ struct wl_listener output_destroy_listener;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+
+ void* data;
+};
+
+struct wlr_gamma_control_manager *wlr_gamma_control_manager_create(
+ struct wl_display *display);
+void wlr_gamma_control_manager_destroy(
+ struct wlr_gamma_control_manager *gamma_control_manager);
+
+#endif
diff --git a/include/wlr/types/wlr_gamma_control_v1.h b/include/wlr/types/wlr_gamma_control_v1.h
new file mode 100644
index 00000000..f186aa81
--- /dev/null
+++ b/include/wlr/types/wlr_gamma_control_v1.h
@@ -0,0 +1,35 @@
+#ifndef WLR_TYPES_WLR_GAMMA_CONTROL_V1_H
+#define WLR_TYPES_WLR_GAMMA_CONTROL_V1_H
+
+#include <wayland-server.h>
+
+struct wlr_gamma_control_manager_v1 {
+ struct wl_global *global;
+ struct wl_list resources;
+ struct wl_list controls; // wlr_gamma_control_v1::link
+
+ struct wl_listener display_destroy;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_gamma_control_v1 {
+ struct wl_resource *resource;
+ struct wlr_output *output;
+ struct wl_list link;
+
+ struct wl_listener output_destroy_listener;
+
+ void *data;
+};
+
+struct wlr_gamma_control_manager_v1 *wlr_gamma_control_manager_v1_create(
+ struct wl_display *display);
+void wlr_gamma_control_manager_v1_destroy(
+ struct wlr_gamma_control_manager_v1 *manager);
+
+#endif
diff --git a/include/wlr/types/wlr_gtk_primary_selection.h b/include/wlr/types/wlr_gtk_primary_selection.h
new file mode 100644
index 00000000..436a50d2
--- /dev/null
+++ b/include/wlr/types/wlr_gtk_primary_selection.h
@@ -0,0 +1,53 @@
+/*
+ * 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_GTK_PRIMARY_SELECTION_H
+#define WLR_TYPES_WLR_GTK_PRIMARY_SELECTION_H
+
+#include <wayland-server.h>
+#include <wlr/types/wlr_seat.h>
+
+struct wlr_gtk_primary_selection_device_manager {
+ struct wl_global *global;
+ struct wl_list resources; // wl_resource_get_link
+ struct wl_list devices; // wlr_gtk_primary_selection_device::link
+
+ struct wl_listener display_destroy;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+/**
+ * A device is a per-seat object used to set and get the current selection.
+ */
+struct wlr_gtk_primary_selection_device {
+ struct wlr_gtk_primary_selection_device_manager *manager;
+ struct wlr_seat *seat;
+ struct wl_list link; // wlr_gtk_primary_selection_device_manager::devices
+ struct wl_list resources; // wl_resource_get_link
+
+ struct wl_list offers; // wl_resource_get_link
+ uint32_t selection_serial;
+
+ struct wl_listener seat_destroy;
+ struct wl_listener seat_focus_change;
+ struct wl_listener seat_primary_selection;
+
+ void *data;
+};
+
+struct wlr_gtk_primary_selection_device_manager *
+ wlr_gtk_primary_selection_device_manager_create(struct wl_display *display);
+void wlr_gtk_primary_selection_device_manager_destroy(
+ struct wlr_gtk_primary_selection_device_manager *manager);
+
+#endif
diff --git a/include/wlr/types/wlr_idle.h b/include/wlr/types/wlr_idle.h
new file mode 100644
index 00000000..d8c81a60
--- /dev/null
+++ b/include/wlr/types/wlr_idle.h
@@ -0,0 +1,71 @@
+/*
+ * 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_IDLE_H
+#define WLR_TYPES_WLR_IDLE_H
+
+#include <wayland-server.h>
+#include <wlr/types/wlr_seat.h>
+
+/**
+ * Idle protocol is used to create timers which will notify the client when the
+ * compositor does not receive any input for a given time(in milliseconds). Also
+ * the client will be notified when the timer receives an activity notify and already
+ * was in idle state. Besides this, the client is able to simulate user activity
+ * which will reset the timers and at any time can destroy the timer.
+ */
+
+
+struct wlr_idle {
+ struct wl_global *global;
+ struct wl_list idle_timers; // wlr_idle_timeout::link
+ struct wl_event_loop *event_loop;
+ bool enabled;
+
+ struct wl_listener display_destroy;
+ struct {
+ struct wl_signal activity_notify;
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_idle_timeout {
+ struct wl_resource *resource;
+ struct wl_list link;
+ struct wlr_seat *seat;
+
+ struct wl_event_source *idle_source;
+ bool idle_state;
+ bool enabled;
+ uint32_t timeout; // milliseconds
+
+ struct wl_listener input_listener;
+ struct wl_listener seat_destroy;
+
+ void *data;
+};
+
+struct wlr_idle *wlr_idle_create(struct wl_display *display);
+
+void wlr_idle_destroy(struct wlr_idle *idle);
+
+/**
+ * Send notification to restart all timers for the given seat. Called by
+ * compositor when there is an user activity event on that seat.
+ */
+void wlr_idle_notify_activity(struct wlr_idle *idle, struct wlr_seat *seat);
+
+/**
+ * Enable or disable timers for a given idle resource by seat.
+ * Passing a NULL seat means update timers for all seats.
+ */
+void wlr_idle_set_enabled(struct wlr_idle *idle, struct wlr_seat *seat,
+ bool enabled);
+#endif
diff --git a/include/wlr/types/wlr_idle_inhibit_v1.h b/include/wlr/types/wlr_idle_inhibit_v1.h
new file mode 100644
index 00000000..2093eafe
--- /dev/null
+++ b/include/wlr/types/wlr_idle_inhibit_v1.h
@@ -0,0 +1,58 @@
+/*
+ * 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_IDLE_INHIBIT_V1_H
+#define WLR_TYPES_WLR_IDLE_INHIBIT_V1_H
+
+#include <wayland-server.h>
+
+/* This interface permits clients to inhibit the idle behavior such as
+ * screenblanking, locking, and screensaving.
+ *
+ * This allows clients to ensure they stay visible instead of being hidden by
+ * power-saving.
+ *
+ * Inhibitors are created for surfaces. They should only be in effect, while
+ * this surface is visible.
+ * The effect could also be limited to outputs it is displayed on (e.g.
+ * dimm/dpms off outputs, except the one a video is displayed on).
+ */
+
+struct wlr_idle_inhibit_manager_v1 {
+ struct wl_list resources; // wl_resource_get_link
+ struct wl_list inhibitors; // wlr_idle_inhibit_inhibitor_v1::link
+ struct wl_global *global;
+
+ struct wl_listener display_destroy;
+
+ struct {
+ struct wl_signal new_inhibitor;
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_idle_inhibitor_v1 {
+ struct wlr_surface *surface;
+ struct wl_resource *resource;
+ struct wl_listener surface_destroy;
+
+ struct wl_list link; // wlr_idle_inhibit_manager_v1::inhibitors;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_idle_inhibit_manager_v1 *wlr_idle_inhibit_v1_create(struct wl_display *display);
+void wlr_idle_inhibit_v1_destroy(struct wlr_idle_inhibit_manager_v1 *idle_inhibit);
+
+#endif
diff --git a/include/wlr/types/wlr_input_device.h b/include/wlr/types/wlr_input_device.h
new file mode 100644
index 00000000..f948d55b
--- /dev/null
+++ b/include/wlr/types/wlr_input_device.h
@@ -0,0 +1,66 @@
+/*
+ * 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_INPUT_DEVICE_H
+#define WLR_TYPES_WLR_INPUT_DEVICE_H
+
+enum wlr_button_state {
+ WLR_BUTTON_RELEASED,
+ WLR_BUTTON_PRESSED,
+};
+
+enum wlr_input_device_type {
+ WLR_INPUT_DEVICE_KEYBOARD,
+ WLR_INPUT_DEVICE_POINTER,
+ WLR_INPUT_DEVICE_TOUCH,
+ WLR_INPUT_DEVICE_TABLET_TOOL,
+ WLR_INPUT_DEVICE_TABLET_PAD,
+ WLR_INPUT_DEVICE_SWITCH,
+};
+
+/* Note: these are circular dependencies */
+#include <wlr/types/wlr_keyboard.h>
+#include <wlr/types/wlr_pointer.h>
+#include <wlr/types/wlr_touch.h>
+#include <wlr/types/wlr_tablet_tool.h>
+#include <wlr/types/wlr_tablet_pad.h>
+#include <wlr/types/wlr_switch.h>
+
+struct wlr_input_device_impl;
+
+struct wlr_input_device {
+ const struct wlr_input_device_impl *impl;
+
+ enum wlr_input_device_type type;
+ unsigned int vendor, product;
+ char *name;
+ // Or 0 if not applicable to this device
+ double width_mm, height_mm;
+ char *output_name;
+
+ /* wlr_input_device.type determines which of these is valid */
+ union {
+ void *_device;
+ struct wlr_keyboard *keyboard;
+ struct wlr_pointer *pointer;
+ struct wlr_switch *lid_switch;
+ struct wlr_touch *touch;
+ struct wlr_tablet *tablet;
+ struct wlr_tablet_pad *tablet_pad;
+ };
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+
+ struct wl_list link;
+};
+
+#endif
diff --git a/include/wlr/types/wlr_input_inhibitor.h b/include/wlr/types/wlr_input_inhibitor.h
new file mode 100644
index 00000000..f3187540
--- /dev/null
+++ b/include/wlr/types/wlr_input_inhibitor.h
@@ -0,0 +1,34 @@
+/*
+ * 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_INPUT_INHIBITOR_H
+#define WLR_TYPES_INPUT_INHIBITOR_H
+#include <wayland-server.h>
+
+struct wlr_input_inhibit_manager {
+ struct wl_global *global;
+ struct wl_client *active_client;
+ struct wl_resource *active_inhibitor;
+
+ struct wl_listener display_destroy;
+
+ struct {
+ struct wl_signal activate; // struct wlr_input_inhibit_manager *
+ struct wl_signal deactivate; // struct wlr_input_inhibit_manager *
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_input_inhibit_manager *wlr_input_inhibit_manager_create(
+ struct wl_display *display);
+void wlr_input_inhibit_manager_destroy(
+ struct wlr_input_inhibit_manager *manager);
+
+#endif
diff --git a/include/wlr/types/wlr_input_method_v2.h b/include/wlr/types/wlr_input_method_v2.h
new file mode 100644
index 00000000..d22d54d1
--- /dev/null
+++ b/include/wlr/types/wlr_input_method_v2.h
@@ -0,0 +1,87 @@
+/*
+ * 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_INPUT_METHOD_V2_H
+#define WLR_TYPES_WLR_INPUT_METHOD_V2_H
+#include <stdint.h>
+#include <stdlib.h>
+#include <wayland-server.h>
+#include <wlr/types/wlr_seat.h>
+
+struct wlr_input_method_v2_preedit_string {
+ char *text;
+ int32_t cursor_begin;
+ int32_t cursor_end;
+};
+
+struct wlr_input_method_v2_delete_surrounding_text {
+ uint32_t before_length;
+ uint32_t after_length;
+};
+
+struct wlr_input_method_v2_state {
+ struct wlr_input_method_v2_preedit_string preedit;
+ char *commit_text;
+ struct wlr_input_method_v2_delete_surrounding_text delete;
+};
+
+struct wlr_input_method_v2 {
+ struct wl_resource *resource;
+
+ struct wlr_seat *seat;
+
+ struct wlr_input_method_v2_state pending;
+ struct wlr_input_method_v2_state current;
+ bool active; // pending compositor-side state
+ bool client_active; // state known to the client
+ uint32_t current_serial; // received in last commit call
+
+ struct wl_list link;
+
+ struct wl_listener seat_destroy;
+
+ struct {
+ struct wl_signal commit; // (struct wlr_input_method_v2*)
+ struct wl_signal destroy; // (struct wlr_input_method_v2*)
+ } events;
+};
+
+struct wlr_input_method_manager_v2 {
+ struct wl_global *global;
+ struct wl_list bound_resources; // struct wl_resource*::link
+ struct wl_list input_methods; // struct wlr_input_method_v2*::link
+
+ struct wl_listener display_destroy;
+
+ struct {
+ struct wl_signal input_method; // (struct wlr_input_method_v2*)
+ struct wl_signal destroy; // (struct wlr_input_method_manager_v2*)
+ } events;
+};
+
+struct wlr_input_method_manager_v2 *wlr_input_method_manager_v2_create(
+ struct wl_display *display);
+void wlr_input_method_manager_v2_destroy(
+ struct wlr_input_method_manager_v2 *manager);
+
+void wlr_input_method_v2_send_activate(
+ struct wlr_input_method_v2 *input_method);
+void wlr_input_method_v2_send_deactivate(
+ struct wlr_input_method_v2 *input_method);
+void wlr_input_method_v2_send_surrounding_text(
+ struct wlr_input_method_v2 *input_method, const char *text,
+ uint32_t cursor, uint32_t anchor);
+void wlr_input_method_v2_send_content_type(
+ struct wlr_input_method_v2 *input_method, uint32_t hint,
+ uint32_t purpose);
+void wlr_input_method_v2_send_text_change_cause(
+ struct wlr_input_method_v2 *input_method, uint32_t cause);
+void wlr_input_method_v2_send_done(struct wlr_input_method_v2 *input_method);
+void wlr_input_method_v2_send_unavailable(
+ struct wlr_input_method_v2 *input_method);
+#endif
diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h
new file mode 100644
index 00000000..ae279541
--- /dev/null
+++ b/include/wlr/types/wlr_keyboard.h
@@ -0,0 +1,115 @@
+/*
+ * 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_KEYBOARD_H
+#define WLR_TYPES_WLR_KEYBOARD_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <wayland-server.h>
+#include <wayland-server.h>
+#include <xkbcommon/xkbcommon.h>
+
+#define WLR_LED_COUNT 3
+
+enum wlr_keyboard_led {
+ WLR_LED_NUM_LOCK = 1,
+ WLR_LED_CAPS_LOCK = 2,
+ WLR_LED_SCROLL_LOCK = 4,
+};
+
+#define WLR_MODIFIER_COUNT 8
+
+enum wlr_keyboard_modifier {
+ WLR_MODIFIER_SHIFT = 1,
+ WLR_MODIFIER_CAPS = 2,
+ WLR_MODIFIER_CTRL = 4,
+ WLR_MODIFIER_ALT = 8,
+ WLR_MODIFIER_MOD2 = 16,
+ WLR_MODIFIER_MOD3 = 32,
+ WLR_MODIFIER_LOGO = 64,
+ WLR_MODIFIER_MOD5 = 128,
+};
+
+#define WLR_KEYBOARD_KEYS_CAP 32
+
+struct wlr_keyboard_impl;
+
+struct wlr_keyboard_modifiers {
+ xkb_mod_mask_t depressed;
+ xkb_mod_mask_t latched;
+ xkb_mod_mask_t locked;
+ xkb_mod_mask_t group;
+};
+
+struct wlr_keyboard {
+ const struct wlr_keyboard_impl *impl;
+
+ char *keymap_string;
+ size_t keymap_size;
+ struct xkb_keymap *keymap;
+ struct xkb_state *xkb_state;
+ xkb_led_index_t led_indexes[WLR_LED_COUNT];
+ xkb_mod_index_t mod_indexes[WLR_MODIFIER_COUNT];
+
+ uint32_t keycodes[WLR_KEYBOARD_KEYS_CAP];
+ size_t num_keycodes;
+ struct wlr_keyboard_modifiers modifiers;
+
+ struct {
+ int32_t rate;
+ int32_t delay;
+ } repeat_info;
+
+ struct {
+ /**
+ * The `key` event signals with a `wlr_event_keyboard_key` event that a
+ * key has been pressed or released on the keyboard. This event is
+ * emitted before the xkb state of the keyboard has been updated
+ * (including modifiers).
+ */
+ struct wl_signal key;
+
+ /**
+ * The `modifiers` event signals that the modifier state of the
+ * `wlr_keyboard` has been updated. At this time, you can read the
+ * modifier state of the `wlr_keyboard` and handle the updated state by
+ * sending it to clients.
+ */
+ struct wl_signal modifiers;
+ struct wl_signal keymap;
+ struct wl_signal repeat_info;
+ } events;
+
+ void *data;
+};
+
+enum wlr_key_state {
+ WLR_KEY_RELEASED,
+ WLR_KEY_PRESSED,
+};
+
+struct wlr_event_keyboard_key {
+ uint32_t time_msec;
+ uint32_t keycode;
+ bool update_state; // if backend doesn't update modifiers on its own
+ enum wlr_key_state state;
+};
+
+void wlr_keyboard_set_keymap(struct wlr_keyboard *kb,
+ struct xkb_keymap *keymap);
+/**
+ * Sets the keyboard repeat info. `rate` is in key repeats/second and delay is
+ * in milliseconds.
+ */
+void wlr_keyboard_set_repeat_info(struct wlr_keyboard *kb, int32_t rate,
+ int32_t delay);
+void wlr_keyboard_led_update(struct wlr_keyboard *keyboard, uint32_t leds);
+uint32_t wlr_keyboard_get_modifiers(struct wlr_keyboard *keyboard);
+
+#endif
diff --git a/include/wlr/types/wlr_layer_shell_v1.h b/include/wlr/types/wlr_layer_shell_v1.h
new file mode 100644
index 00000000..838b2e83
--- /dev/null
+++ b/include/wlr/types/wlr_layer_shell_v1.h
@@ -0,0 +1,134 @@
+/*
+ * 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_LAYER_SHELL_V1_H
+#define WLR_TYPES_WLR_LAYER_SHELL_V1_H
+#include <stdbool.h>
+#include <stdint.h>
+#include <wayland-server.h>
+#include <wlr/types/wlr_box.h>
+#include <wlr/types/wlr_surface.h>
+#include "wlr-layer-shell-unstable-v1-protocol.h"
+
+/**
+ * wlr_layer_shell_v1 allows clients to arrange themselves in "layers" on the
+ * desktop in accordance with the wlr-layer-shell protocol. When a client is
+ * added, the new_surface signal will be raised and passed a reference to our
+ * wlr_layer_surface_v1. At this time, the client will have configured the
+ * surface as it desires, including information like desired anchors and
+ * margins. The compositor should use this information to decide how to arrange
+ * the layer on-screen, then determine the dimensions of the layer and call
+ * wlr_layer_surface_v1_configure. The client will then attach a buffer and
+ * commit the surface, at which point the wlr_layer_surface_v1 map signal is
+ * raised and the compositor should begin rendering the surface.
+ */
+struct wlr_layer_shell_v1 {
+ struct wl_global *global;
+ struct wl_list resources; // wl_resource
+ struct wl_list surfaces; // wl_layer_surface
+
+ struct wl_listener display_destroy;
+
+ struct {
+ // struct wlr_layer_surface_v1 *
+ // Note: the output may be NULL. In this case, it is your
+ // responsibility to assign an output before returning.
+ struct wl_signal new_surface;
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_layer_surface_v1_state {
+ uint32_t anchor;
+ int32_t exclusive_zone;
+ struct {
+ uint32_t top, right, bottom, left;
+ } margin;
+ bool keyboard_interactive;
+ uint32_t desired_width, desired_height;
+ uint32_t actual_width, actual_height;
+};
+
+struct wlr_layer_surface_v1_configure {
+ struct wl_list link; // wlr_layer_surface_v1::configure_list
+ uint32_t serial;
+ struct wlr_layer_surface_v1_state state;
+};
+
+struct wlr_layer_surface_v1 {
+ struct wl_list link; // wlr_layer_shell_v1::surfaces
+ struct wlr_surface *surface;
+ struct wlr_output *output;
+ struct wl_resource *resource;
+ struct wlr_layer_shell_v1 *shell;
+ struct wl_list popups; // wlr_xdg_popup::link
+
+ char *namespace;
+ enum zwlr_layer_shell_v1_layer layer;
+
+ bool added, configured, mapped, closed;
+ uint32_t configure_serial;
+ struct wl_event_source *configure_idle;
+ uint32_t configure_next_serial;
+ struct wl_list configure_list;
+
+ struct wlr_layer_surface_v1_configure *acked_configure;
+
+ struct wlr_layer_surface_v1_state client_pending;
+ struct wlr_layer_surface_v1_state server_pending;
+ struct wlr_layer_surface_v1_state current;
+
+ struct wl_listener surface_destroy;
+
+ struct {
+ struct wl_signal destroy;
+ struct wl_signal map;
+ struct wl_signal unmap;
+ struct wl_signal new_popup;
+ } events;
+
+ void *data;
+};
+
+struct wlr_layer_shell_v1 *wlr_layer_shell_v1_create(struct wl_display *display);
+void wlr_layer_shell_v1_destroy(struct wlr_layer_shell_v1 *layer_shell);
+
+/**
+ * Notifies the layer surface to configure itself with this width/height. The
+ * layer_surface will signal its map event when the surface is ready to assume
+ * this size.
+ */
+void wlr_layer_surface_v1_configure(struct wlr_layer_surface_v1 *surface,
+ uint32_t width, uint32_t height);
+
+/**
+ * Unmaps this layer surface and notifies the client that it has been closed.
+ */
+void wlr_layer_surface_v1_close(struct wlr_layer_surface_v1 *surface);
+
+bool wlr_surface_is_layer_surface(struct wlr_surface *surface);
+
+struct wlr_layer_surface_v1 *wlr_layer_surface_v1_from_wlr_surface(
+ struct wlr_surface *surface);
+
+/* Calls the iterator function for each sub-surface and popup of this surface */
+void wlr_layer_surface_v1_for_each_surface(struct wlr_layer_surface_v1 *surface,
+ wlr_surface_iterator_func_t iterator, void *user_data);
+
+/**
+ * Find a surface within this layer-surface tree at the given surface-local
+ * coordinates. Returns the surface and coordinates in the leaf surface
+ * coordinate system or NULL if no surface is found at that location.
+ */
+struct wlr_surface *wlr_layer_surface_v1_surface_at(
+ struct wlr_layer_surface_v1 *surface, double sx, double sy,
+ double *sub_x, double *sub_y);
+
+#endif
diff --git a/include/wlr/types/wlr_linux_dmabuf_v1.h b/include/wlr/types/wlr_linux_dmabuf_v1.h
new file mode 100644
index 00000000..f21b0b3a
--- /dev/null
+++ b/include/wlr/types/wlr_linux_dmabuf_v1.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_LINUX_DMABUF_H
+#define WLR_TYPES_WLR_LINUX_DMABUF_H
+
+#include <stdint.h>
+#include <wayland-server-protocol.h>
+#include <wlr/render/dmabuf.h>
+
+struct wlr_dmabuf_v1_buffer {
+ struct wlr_renderer *renderer;
+ struct wl_resource *buffer_resource;
+ struct wl_resource *params_resource;
+ struct wlr_dmabuf_attributes attributes;
+ bool has_modifier;
+};
+
+/**
+ * Returns true if the given resource was created via the linux-dmabuf
+ * buffer protocol, false otherwise
+ */
+bool wlr_dmabuf_v1_resource_is_buffer(struct wl_resource *buffer_resource);
+
+/**
+ * Returns the wlr_dmabuf_buffer if the given resource was created
+ * via the linux-dmabuf buffer protocol
+ */
+struct wlr_dmabuf_v1_buffer *wlr_dmabuf_v1_buffer_from_buffer_resource(
+ struct wl_resource *buffer_resource);
+
+/**
+ * Returns the wlr_dmabuf_buffer if the given resource was created
+ * via the linux-dmabuf params protocol
+ */
+struct wlr_dmabuf_v1_buffer *wlr_dmabuf_v1_buffer_from_params_resource(
+ struct wl_resource *params_resource);
+
+/* the protocol interface */
+struct wlr_linux_dmabuf_v1 {
+ struct wl_global *global;
+ struct wlr_renderer *renderer;
+ struct wl_list resources;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+
+ struct wl_listener display_destroy;
+ struct wl_listener renderer_destroy;
+};
+
+/**
+ * Create linux-dmabuf interface
+ */
+struct wlr_linux_dmabuf_v1 *wlr_linux_dmabuf_v1_create(struct wl_display *display,
+ struct wlr_renderer *renderer);
+/**
+ * Destroy the linux-dmabuf interface
+ */
+void wlr_linux_dmabuf_v1_destroy(struct wlr_linux_dmabuf_v1 *linux_dmabuf);
+
+/**
+ * Returns the wlr_linux_dmabuf if the given resource was created
+ * via the linux_dmabuf protocol
+ */
+struct wlr_linux_dmabuf_v1 *wlr_linux_dmabuf_v1_from_resource(
+ struct wl_resource *resource);
+
+#endif
diff --git a/include/wlr/types/wlr_list.h b/include/wlr/types/wlr_list.h
new file mode 100644
index 00000000..60f388f9
--- /dev/null
+++ b/include/wlr/types/wlr_list.h
@@ -0,0 +1,83 @@
+/*
+ * 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_LIST_H
+#define WLR_TYPES_WLR_LIST_H
+
+#include <stdbool.h>
+#include <stddef.h>
+
+struct wlr_list {
+ size_t capacity;
+ size_t length;
+ void **items;
+};
+
+/**
+ * Initialize a list. Returns true on success, false on failure.
+ */
+bool wlr_list_init(struct wlr_list *list);
+
+/**
+ * Deinitialize a list.
+ */
+void wlr_list_finish(struct wlr_list *list);
+
+/**
+ * Executes `callback` on each element in the list.
+ */
+void wlr_list_for_each(struct wlr_list *list, void (*callback)(void *item));
+
+/**
+ * Add `item` to the end of a list.
+ * Returns: new list length or `-1` on failure.
+ */
+ssize_t wlr_list_push(struct wlr_list *list, void *item);
+
+/**
+ * Place `item` into index `index` in the list.
+ * Returns: new list length or `-1` on failure.
+ */
+ssize_t wlr_list_insert(struct wlr_list *list, size_t index, void *item);
+
+/**
+ * Remove an item from the list.
+ */
+void wlr_list_del(struct wlr_list *list, size_t index);
+
+/**
+ * Remove and return an item from the end of the list.
+ */
+void *wlr_list_pop(struct wlr_list *list);
+
+/**
+ * Get a reference to the last item of a list without removal.
+ */
+void *wlr_list_peek(struct wlr_list *list);
+
+/**
+ * Append each item in `source` to `list`.
+ * Does not modify `source`.
+ * Returns: new list length or `-1` on failure.
+ */
+ssize_t wlr_list_cat(struct wlr_list *list, const struct wlr_list *source);
+
+/**
+ * Sort a list using `qsort`.
+ */
+void wlr_list_qsort(struct wlr_list *list,
+ int compare(const void *left, const void *right));
+
+/**
+ * Return the index of the first item in the list that returns 0 for the given
+ * `compare` function, or -1 if none matches.
+ */
+ssize_t wlr_list_find(struct wlr_list *list,
+ int compare(const void *item, const void *cmp_to), const void *cmp_to);
+
+#endif
diff --git a/include/wlr/types/wlr_matrix.h b/include/wlr/types/wlr_matrix.h
new file mode 100644
index 00000000..a3961c35
--- /dev/null
+++ b/include/wlr/types/wlr_matrix.h
@@ -0,0 +1,59 @@
+/*
+ * This is a stable interface of wlroots. Future changes will be limited to:
+ *
+ * - New functions
+ * - New struct members
+ * - New enum members
+ *
+ * Note that wlroots does not make an ABI compatibility promise - in the future,
+ * the layout and size of structs used by wlroots may change, requiring code
+ * depending on this header to be recompiled (but not edited).
+ *
+ * Breaking changes are announced by email and follow a 1-year deprecation
+ * schedule. Send an email to ~sircmpwn/wlroots-announce+subscribe@lists.sr.ht
+ * to receive these announcements.
+ */
+
+#ifndef WLR_TYPES_WLR_MATRIX_H
+#define WLR_TYPES_WLR_MATRIX_H
+
+#include <wayland-server.h>
+#include <wlr/types/wlr_box.h>
+
+/** Writes the identity matrix into mat */
+void wlr_matrix_identity(float mat[static 9]);
+
+/** mat ← a × b */
+void wlr_matrix_multiply(float mat[static 9], const float a[static 9],
+ const float b[static 9]);
+
+void wlr_matrix_transpose(float mat[static 9], const float a[static 9]);
+
+/** Writes a 2D translation matrix to mat of magnitude (x, y) */
+void wlr_matrix_translate(float mat[static 9], float x, float y);
+
+/** Writes a 2D scale matrix to mat of magnitude (x, y) */
+void wlr_matrix_scale(float mat[static 9], float x, float y);
+
+/** Writes a 2D rotation matrix to mat at an angle of rad radians */
+void wlr_matrix_rotate(float mat[static 9], float rad);
+
+/** Writes a transformation matrix which applies the specified
+ * wl_output_transform to mat */
+void wlr_matrix_transform(float mat[static 9],
+ enum wl_output_transform transform);
+
+/** Writes a 2D orthographic projection matrix to mat of (width, height) with a
+ * specified wl_output_transform*/
+void wlr_matrix_projection(float mat[static 9], int width, int height,
+ enum wl_output_transform transform);
+
+/** Shortcut for the various matrix operations involved in projecting the
+ * specified wlr_box onto a given orthographic projection with a given
+ * rotation. The result is written to mat, which can be applied to each
+ * coordinate of the box to get a new coordinate from [-1,1]. */
+void wlr_matrix_project_box(float mat[static 9], const struct wlr_box *box,
+ enum wl_output_transform transform, float rotation,
+ const float projection[static 9]);
+
+#endif
diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h
new file mode 100644
index 00000000..22822b11
--- /dev/null
+++ b/include/wlr/types/wlr_output.h
@@ -0,0 +1,278 @@
+/*
+ * 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_OUTPUT_H
+#define WLR_TYPES_WLR_OUTPUT_H
+
+#include <pixman.h>
+#include <stdbool.h>
+#include <time.h>
+#include <wayland-server.h>
+#include <wayland-util.h>
+#include <wlr/render/dmabuf.h>
+
+struct wlr_output_mode {
+ uint32_t flags; // enum wl_output_mode
+ int32_t width, height;
+ int32_t refresh; // mHz
+ struct wl_list link;
+};
+
+struct wlr_output_cursor {
+ struct wlr_output *output;
+ double x, y;
+ bool enabled;
+ bool visible;
+ uint32_t width, height;
+ int32_t hotspot_x, hotspot_y;
+ struct wl_list link;
+
+ // only when using a software cursor without a surface
+ struct wlr_texture *texture;
+
+ // only when using a cursor surface
+ struct wlr_surface *surface;
+ struct wl_listener surface_commit;
+ struct wl_listener surface_destroy;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+};
+
+struct wlr_output_impl;
+
+/**
+ * A compositor output region. This typically corresponds to a monitor that
+ * displays part of the compositor space.
+ *
+ * Compositors should listen to the `frame` event to render an output. They
+ * should call `wlr_output_make_current`, render and then call
+ * `wlr_output_swap_buffers`. No rendering should happen outside a `frame` event
+ * handler.
+ */
+struct wlr_output {
+ const struct wlr_output_impl *impl;
+ struct wlr_backend *backend;
+ struct wl_display *display;
+
+ struct wl_global *global;
+ struct wl_list resources;
+
+ char name[24];
+ char make[56];
+ char model[16];
+ char serial[16];
+ int32_t phys_width, phys_height; // mm
+
+ // Note: some backends may have zero modes
+ struct wl_list modes;
+ struct wlr_output_mode *current_mode;
+ int32_t width, height;
+ int32_t refresh; // mHz, may be zero
+
+ bool enabled;
+ float scale;
+ enum wl_output_subpixel subpixel;
+ enum wl_output_transform transform;
+
+ bool needs_swap;
+ // damage for cursors and fullscreen surface, in output-local coordinates
+ pixman_region32_t damage;
+ bool frame_pending;
+ float transform_matrix[9];
+
+ struct {
+ // Request to render a frame
+ struct wl_signal frame;
+ // Emitted when buffers need to be swapped (because software cursors or
+ // fullscreen damage or because of backend-specific logic)
+ struct wl_signal needs_swap;
+ // Emitted right before buffer swap
+ struct wl_signal swap_buffers; // wlr_output_event_swap_buffers
+ // Emitted right after the buffer has been presented to the user
+ struct wl_signal present; // wlr_output_event_present
+ struct wl_signal enable;
+ struct wl_signal mode;
+ struct wl_signal scale;
+ struct wl_signal transform;
+ struct wl_signal destroy;
+ } events;
+
+ struct wl_event_source *idle_frame;
+
+ struct wl_list cursors; // wlr_output_cursor::link
+ struct wlr_output_cursor *hardware_cursor;
+ int software_cursor_locks; // number of locks forcing software cursors
+
+ // the output position in layout space reported to clients
+ int32_t lx, ly;
+
+ struct wl_listener display_destroy;
+
+ void *data;
+};
+
+struct wlr_output_event_swap_buffers {
+ struct wlr_output *output;
+ struct timespec *when;
+ pixman_region32_t *damage; // output-buffer-local coordinates
+};
+
+enum wlr_output_present_flag {
+ // The presentation was synchronized to the "vertical retrace" by the
+ // display hardware such that tearing does not happen.
+ WLR_OUTPUT_PRESENT_VSYNC = 0x1,
+ // The display hardware provided measurements that the hardware driver
+ // converted into a presentation timestamp.
+ WLR_OUTPUT_PRESENT_HW_CLOCK = 0x2,
+ // The display hardware signalled that it started using the new image
+ // content.
+ WLR_OUTPUT_PRESENT_HW_COMPLETION = 0x4,
+ // The presentation of this update was done zero-copy.
+ WLR_OUTPUT_PRESENT_ZERO_COPY = 0x8,
+};
+
+struct wlr_output_event_present {
+ struct wlr_output *output;
+ // Time when the content update turned into light the first time.
+ struct timespec *when;
+ // Vertical retrace counter. Zero if unavailable.
+ unsigned seq;
+ // Prediction of how many nanoseconds after `when` the very next output
+ // refresh may occur. Zero if unknown.
+ int refresh; // nsec
+ uint32_t flags; // enum wlr_output_present_flag
+};
+
+struct wlr_surface;
+
+/**
+ * Enables or disables the output. A disabled output is turned off and doesn't
+ * emit `frame` events.
+ */
+bool wlr_output_enable(struct wlr_output *output, bool enable);
+void wlr_output_create_global(struct wlr_output *output);
+void wlr_output_destroy_global(struct wlr_output *output);
+/**
+ * Sets the output mode. Enables the output if it's currently disabled.
+ */
+bool wlr_output_set_mode(struct wlr_output *output,
+ struct wlr_output_mode *mode);
+/**
+ * Sets a custom mode on the output. If modes are available, they are preferred.
+ * Setting `refresh` to zero lets the backend pick a preferred value.
+ */
+bool wlr_output_set_custom_mode(struct wlr_output *output, int32_t width,
+ int32_t height, int32_t refresh);
+void wlr_output_set_transform(struct wlr_output *output,
+ enum wl_output_transform transform);
+void wlr_output_set_position(struct wlr_output *output, int32_t lx, int32_t ly);
+void wlr_output_set_scale(struct wlr_output *output, float scale);
+void wlr_output_destroy(struct wlr_output *output);
+/**
+ * Computes the transformed output resolution.
+ */
+void wlr_output_transformed_resolution(struct wlr_output *output,
+ int *width, int *height);
+/**
+ * Computes the transformed and scaled output resolution.
+ */
+void wlr_output_effective_resolution(struct wlr_output *output,
+ int *width, int *height);
+/**
+ * Makes the output rendering context current.
+ *
+ * `buffer_age` is set to the drawing buffer age in number of frames or -1 if
+ * unknown. This is useful for damage tracking.
+ */
+bool wlr_output_make_current(struct wlr_output *output, int *buffer_age);
+/**
+ * Get the preferred format for reading pixels.
+ * This function might change the current rendering context.
+ */
+bool wlr_output_preferred_read_format(struct wlr_output *output,
+ enum wl_shm_format *fmt);
+/**
+ * Swaps the output buffers. If the time of the frame isn't known, set `when` to
+ * NULL. If the compositor doesn't support damage tracking, set `damage` to
+ * NULL.
+ *
+ * Damage is given in output-buffer-local coordinates (ie. scaled and
+ * transformed).
+ *
+ * Swapping buffers schedules a `frame` event.
+ */
+bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when,
+ pixman_region32_t *damage);
+/**
+ * Manually schedules a `frame` event. If a `frame` event is already pending,
+ * it is a no-op.
+ */
+void wlr_output_schedule_frame(struct wlr_output *output);
+/**
+ * Returns the maximum length of each gamma ramp, or 0 if unsupported.
+ */
+size_t wlr_output_get_gamma_size(struct wlr_output *output);
+/**
+ * Sets the gamma table for this output. `r`, `g` and `b` are gamma ramps for
+ * red, green and blue. `size` is the length of the ramps and must not exceed
+ * the value returned by `wlr_output_get_gamma_size`.
+ *
+ * Providing zero-sized ramps resets the gamma table.
+ */
+bool wlr_output_set_gamma(struct wlr_output *output, size_t size,
+ const uint16_t *r, const uint16_t *g, const uint16_t *b);
+bool wlr_output_export_dmabuf(struct wlr_output *output,
+ struct wlr_dmabuf_attributes *attribs);
+struct wlr_output *wlr_output_from_resource(struct wl_resource *resource);
+/**
+ * Locks the output to only use software cursors instead of hardware cursors.
+ * This is useful if hardware cursors need to be temporarily disabled (e.g.
+ * during screen capture). There must be as many unlocks as there have been
+ * locks to restore the original state. There should never be an unlock before
+ * a lock.
+ */
+void wlr_output_lock_software_cursors(struct wlr_output *output, bool lock);
+/**
+ * Renders software cursors. This is a utility function that can be called when
+ * compositors render.
+ */
+void wlr_output_render_software_cursors(struct wlr_output *output,
+ pixman_region32_t *damage);
+
+
+struct wlr_output_cursor *wlr_output_cursor_create(struct wlr_output *output);
+/**
+ * Sets the cursor image. The image must be already scaled for the output.
+ */
+bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor,
+ const uint8_t *pixels, int32_t stride, uint32_t width, uint32_t height,
+ int32_t hotspot_x, int32_t hotspot_y);
+void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor,
+ struct wlr_surface *surface, int32_t hotspot_x, int32_t hotspot_y);
+bool wlr_output_cursor_move(struct wlr_output_cursor *cursor,
+ double x, double y);
+void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor);
+
+
+/**
+ * Returns the transform that, when composed with `tr`, gives
+ * `WL_OUTPUT_TRANSFORM_NORMAL`.
+ */
+enum wl_output_transform wlr_output_transform_invert(
+ enum wl_output_transform tr);
+
+/**
+ * Returns a transform that, when applied, has the same effect as applying
+ * sequentially `tr_a` and `tr_b`.
+ */
+enum wl_output_transform wlr_output_transform_compose(
+ enum wl_output_transform tr_a, enum wl_output_transform tr_b);
+
+#endif
diff --git a/include/wlr/types/wlr_output_damage.h b/include/wlr/types/wlr_output_damage.h
new file mode 100644
index 00000000..d614e6d6
--- /dev/null
+++ b/include/wlr/types/wlr_output_damage.h
@@ -0,0 +1,87 @@
+/*
+ * 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_OUTPUT_DAMAGE_H
+#define WLR_TYPES_WLR_OUTPUT_DAMAGE_H
+
+#include <pixman.h>
+#include <time.h>
+#include <wlr/types/wlr_box.h>
+#include <wlr/types/wlr_output.h>
+
+/**
+ * Damage tracking requires to keep track of previous frames' damage. To allow
+ * damage tracking to work with triple buffering, a history of two frames is
+ * required.
+ */
+#define WLR_OUTPUT_DAMAGE_PREVIOUS_LEN 2
+
+/**
+ * Tracks damage for an output.
+ *
+ * When a `frame` event is emitted, `wlr_output_damage_make_current` should be
+ * called. If necessary, the output should be repainted and
+ * `wlr_output_damage_swap_buffers` should be called. No rendering should happen
+ * outside a `frame` event handler.
+ */
+struct wlr_output_damage {
+ struct wlr_output *output;
+ int max_rects; // max number of damaged rectangles
+
+ pixman_region32_t current; // in output-local coordinates
+
+ // circular queue for previous damage
+ pixman_region32_t previous[WLR_OUTPUT_DAMAGE_PREVIOUS_LEN];
+ size_t previous_idx;
+
+ struct {
+ struct wl_signal frame;
+ struct wl_signal destroy;
+ } events;
+
+ struct wl_listener output_destroy;
+ struct wl_listener output_mode;
+ struct wl_listener output_transform;
+ struct wl_listener output_scale;
+ struct wl_listener output_needs_swap;
+ struct wl_listener output_frame;
+};
+
+struct wlr_output_damage *wlr_output_damage_create(struct wlr_output *output);
+void wlr_output_damage_destroy(struct wlr_output_damage *output_damage);
+/**
+ * Makes the output rendering context current. `needs_swap` is set to true if
+ * `wlr_output_damage_swap_buffers` needs to be called. The region of the output
+ * that needs to be repainted is added to `damage`.
+ */
+bool wlr_output_damage_make_current(struct wlr_output_damage *output_damage,
+ bool *needs_swap, pixman_region32_t *damage);
+/**
+ * Swaps the output buffers. If the time of the frame isn't known, set `when` to
+ * NULL.
+ *
+ * Swapping buffers schedules a `frame` event.
+ */
+bool wlr_output_damage_swap_buffers(struct wlr_output_damage *output_damage,
+ struct timespec *when, pixman_region32_t *damage);
+/**
+ * Accumulates damage and schedules a `frame` event.
+ */
+void wlr_output_damage_add(struct wlr_output_damage *output_damage,
+ pixman_region32_t *damage);
+/**
+ * Damages the whole output and schedules a `frame` event.
+ */
+void wlr_output_damage_add_whole(struct wlr_output_damage *output_damage);
+/**
+ * Accumulates damage from a box and schedules a `frame` event.
+ */
+void wlr_output_damage_add_box(struct wlr_output_damage *output_damage,
+ struct wlr_box *box);
+
+#endif
diff --git a/include/wlr/types/wlr_output_layout.h b/include/wlr/types/wlr_output_layout.h
new file mode 100644
index 00000000..cc9d2328
--- /dev/null
+++ b/include/wlr/types/wlr_output_layout.h
@@ -0,0 +1,133 @@
+/*
+ * 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_OUTPUT_LAYOUT_H
+#define WLR_TYPES_WLR_OUTPUT_LAYOUT_H
+
+#include <stdbool.h>
+#include <wayland-util.h>
+#include <wlr/types/wlr_box.h>
+#include <wlr/types/wlr_output.h>
+
+struct wlr_output_layout_state;
+
+struct wlr_output_layout {
+ struct wl_list outputs;
+ struct wlr_output_layout_state *state;
+
+ struct {
+ struct wl_signal add;
+ struct wl_signal change;
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_output_layout_output_state;
+
+struct wlr_output_layout_output {
+ struct wlr_output *output;
+ int x, y;
+ struct wl_list link;
+ struct wlr_output_layout_output_state *state;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+};
+
+/**
+ * Creates a wlr_output_layout, which can be used to describing outputs in
+ * physical space relative to one another, and perform various useful operations
+ * on that state.
+ */
+struct wlr_output_layout *wlr_output_layout_create();
+
+void wlr_output_layout_destroy(struct wlr_output_layout *layout);
+
+struct wlr_output_layout_output *wlr_output_layout_get(
+ struct wlr_output_layout *layout, struct wlr_output *reference);
+
+struct wlr_output *wlr_output_layout_output_at(struct wlr_output_layout *layout,
+ double lx, double ly);
+
+void wlr_output_layout_add(struct wlr_output_layout *layout,
+ struct wlr_output *output, int lx, int ly);
+
+void wlr_output_layout_move(struct wlr_output_layout *layout,
+ struct wlr_output *output, int lx, int ly);
+
+void wlr_output_layout_remove(struct wlr_output_layout *layout,
+ struct wlr_output *output);
+
+/**
+ * Given x and y in layout coordinates, adjusts them to local output
+ * coordinates relative to the given reference output.
+ */
+void wlr_output_layout_output_coords(struct wlr_output_layout *layout,
+ struct wlr_output *reference, double *lx, double *ly);
+
+bool wlr_output_layout_contains_point(struct wlr_output_layout *layout,
+ struct wlr_output *reference, int lx, int ly);
+
+bool wlr_output_layout_intersects(struct wlr_output_layout *layout,
+ struct wlr_output *reference, const struct wlr_box *target_lbox);
+
+/**
+ * Get the closest point on this layout from the given point from the reference
+ * output. If reference is NULL, gets the closest point from the entire layout.
+ */
+void wlr_output_layout_closest_point(struct wlr_output_layout *layout,
+ struct wlr_output *reference, double lx, double ly, double *dest_lx,
+ double *dest_ly);
+
+/**
+ * Get the box of the layout for the given reference output in layout
+ * coordinates. If `reference` is NULL, the box will be for the extents of the
+ * entire layout.
+ */
+struct wlr_box *wlr_output_layout_get_box(
+ struct wlr_output_layout *layout, struct wlr_output *reference);
+
+/**
+* Add an auto configured output to the layout. This will place the output in a
+* sensible location in the layout. The coordinates of the output in the layout
+* may adjust dynamically when the layout changes. If the output is already in
+* the layout, it will become auto configured. If the position of the output is
+* set such as with `wlr_output_layout_move()`, the output will become manually
+* configured.
+*/
+void wlr_output_layout_add_auto(struct wlr_output_layout *layout,
+ struct wlr_output *output);
+
+/**
+ * Get the output closest to the center of the layout extents.
+ */
+struct wlr_output *wlr_output_layout_get_center_output(
+ struct wlr_output_layout *layout);
+
+enum wlr_direction {
+ WLR_DIRECTION_UP = 1,
+ WLR_DIRECTION_DOWN = 2,
+ WLR_DIRECTION_LEFT = 4,
+ WLR_DIRECTION_RIGHT = 8,
+};
+
+/**
+ * Get the closest adjacent output to the reference output from the reference
+ * point in the given direction.
+ */
+struct wlr_output *wlr_output_layout_adjacent_output(
+ struct wlr_output_layout *layout, enum wlr_direction direction,
+ struct wlr_output *reference, double ref_lx, double ref_ly);
+struct wlr_output *wlr_output_layout_farthest_output(
+ struct wlr_output_layout *layout, enum wlr_direction direction,
+ struct wlr_output *reference, double ref_lx, double ref_ly);
+
+#endif
diff --git a/include/wlr/types/wlr_pointer.h b/include/wlr/types/wlr_pointer.h
new file mode 100644
index 00000000..7dc643ae
--- /dev/null
+++ b/include/wlr/types/wlr_pointer.h
@@ -0,0 +1,72 @@
+/*
+ * 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_POINTER_H
+#define WLR_TYPES_WLR_POINTER_H
+
+#include <stdint.h>
+#include <wayland-server.h>
+#include <wlr/types/wlr_input_device.h>
+
+struct wlr_pointer_impl;
+
+struct wlr_pointer {
+ const struct wlr_pointer_impl *impl;
+
+ struct {
+ struct wl_signal motion;
+ struct wl_signal motion_absolute;
+ struct wl_signal button;
+ struct wl_signal axis;
+ } events;
+
+ void *data;
+};
+
+struct wlr_event_pointer_motion {
+ struct wlr_input_device *device;
+ uint32_t time_msec;
+ double delta_x, delta_y;
+};
+
+struct wlr_event_pointer_motion_absolute {
+ struct wlr_input_device *device;
+ uint32_t time_msec;
+ // From 0..1
+ double x, y;
+};
+
+struct wlr_event_pointer_button {
+ struct wlr_input_device *device;
+ uint32_t time_msec;
+ uint32_t button;
+ enum wlr_button_state state;
+};
+
+enum wlr_axis_source {
+ WLR_AXIS_SOURCE_WHEEL,
+ WLR_AXIS_SOURCE_FINGER,
+ WLR_AXIS_SOURCE_CONTINUOUS,
+ WLR_AXIS_SOURCE_WHEEL_TILT,
+};
+
+enum wlr_axis_orientation {
+ WLR_AXIS_ORIENTATION_VERTICAL,
+ WLR_AXIS_ORIENTATION_HORIZONTAL,
+};
+
+struct wlr_event_pointer_axis {
+ struct wlr_input_device *device;
+ uint32_t time_msec;
+ enum wlr_axis_source source;
+ enum wlr_axis_orientation orientation;
+ double delta;
+ int32_t delta_discrete;
+};
+
+#endif
diff --git a/include/wlr/types/wlr_pointer_constraints_v1.h b/include/wlr/types/wlr_pointer_constraints_v1.h
new file mode 100644
index 00000000..fef8c2e9
--- /dev/null
+++ b/include/wlr/types/wlr_pointer_constraints_v1.h
@@ -0,0 +1,102 @@
+/*
+ * 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_POINTER_CONSTRAINTS_V1_H
+#define WLR_TYPES_WLR_POINTER_CONSTRAINTS_V1_H
+
+#include <stdint.h>
+#include <wayland-server.h>
+#include <pixman.h>
+#include <wlr/types/wlr_box.h>
+#include <wlr/types/wlr_seat.h>
+#include "pointer-constraints-unstable-v1-protocol.h"
+
+struct wlr_seat;
+
+enum wlr_pointer_constraint_v1_type {
+ WLR_POINTER_CONSTRAINT_V1_LOCKED,
+ WLR_POINTER_CONSTRAINT_V1_CONFINED,
+};
+
+enum wlr_pointer_constraint_v1_state_field {
+ WLR_POINTER_CONSTRAINT_V1_STATE_REGION = 1 << 0,
+ WLR_POINTER_CONSTRAINT_V1_STATE_CURSOR_HINT = 1 << 1,
+};
+
+struct wlr_pointer_constraint_v1_state {
+ uint32_t committed; // enum wlr_pointer_constraint_v1_state_field
+ pixman_region32_t region;
+
+ // only valid for locked_pointer
+ struct {
+ double x, y;
+ } cursor_hint;
+};
+
+struct wlr_pointer_constraint_v1 {
+ struct wlr_pointer_constraints_v1 *pointer_constraints;
+
+ struct wl_resource *resource;
+ struct wlr_surface *surface;
+ struct wlr_seat *seat;
+ enum zwp_pointer_constraints_v1_lifetime lifetime;
+ enum wlr_pointer_constraint_v1_type type;
+ pixman_region32_t region;
+
+ struct wlr_pointer_constraint_v1_state current, pending;
+
+ struct wl_listener surface_commit;
+ struct wl_listener surface_destroy;
+ struct wl_listener seat_destroy;
+
+ struct wl_list link; // wlr_pointer_constraints_v1::constraints
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_pointer_constraints_v1 {
+ struct wl_list resources; // wl_resource_get_link
+ struct wl_global *global;
+
+ struct {
+ /**
+ * Called when a new pointer constraint is created.
+ *
+ * data: struct wlr_pointer_constraint_v1 *
+ */
+ struct wl_signal new_constraint;
+ } events;
+
+ struct wl_list constraints; // wlr_pointer_constraint_v1::link
+
+ void *data;
+};
+
+struct wlr_pointer_constraints_v1 *wlr_pointer_constraints_v1_create(
+ struct wl_display *display);
+void wlr_pointer_constraints_v1_destroy(
+ struct wlr_pointer_constraints_v1 *pointer_constraints);
+
+struct wlr_pointer_constraint_v1 *
+ wlr_pointer_constraints_v1_constraint_for_surface(
+ struct wlr_pointer_constraints_v1 *pointer_constraints,
+ struct wlr_surface *surface, struct wlr_seat *seat);
+
+void wlr_pointer_constraint_v1_send_activated(
+ struct wlr_pointer_constraint_v1 *constraint);
+/**
+ * Deactivate the constraint. May destroy the constraint.
+ */
+void wlr_pointer_constraint_v1_send_deactivated(
+ struct wlr_pointer_constraint_v1 *constraint);
+
+#endif
diff --git a/include/wlr/types/wlr_presentation_time.h b/include/wlr/types/wlr_presentation_time.h
new file mode 100644
index 00000000..9f9f0e87
--- /dev/null
+++ b/include/wlr/types/wlr_presentation_time.h
@@ -0,0 +1,59 @@
+/*
+ * 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_PRESENTATION_TIME_H
+#define WLR_TYPES_WLR_PRESENTATION_TIME_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <time.h>
+#include <wayland-server.h>
+
+struct wlr_presentation {
+ struct wl_global *global;
+ struct wl_list resources; // wl_resource_get_link
+ struct wl_list feedbacks; // wlr_presentation_feedback::link
+ clockid_t clock;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+
+ struct wl_listener display_destroy;
+};
+
+struct wlr_presentation_feedback {
+ struct wl_resource *resource;
+ struct wlr_presentation *presentation;
+ struct wlr_surface *surface;
+ bool committed;
+ struct wl_list link; // wlr_presentation::feedbacks
+
+ struct wl_listener surface_commit;
+ struct wl_listener surface_destroy;
+};
+
+struct wlr_presentation_event {
+ struct wlr_output *output;
+ uint64_t tv_sec;
+ uint32_t tv_nsec;
+ uint32_t refresh;
+ uint64_t seq;
+ uint32_t flags; // wp_presentation_feedback_kind
+};
+
+struct wlr_backend;
+
+struct wlr_presentation *wlr_presentation_create(struct wl_display *display,
+ struct wlr_backend *backend);
+void wlr_presentation_destroy(struct wlr_presentation *presentation);
+void wlr_presentation_send_surface_presented(
+ struct wlr_presentation *presentation, struct wlr_surface *surface,
+ struct wlr_presentation_event *event);
+
+#endif
diff --git a/include/wlr/types/wlr_primary_selection.h b/include/wlr/types/wlr_primary_selection.h
new file mode 100644
index 00000000..9be61acc
--- /dev/null
+++ b/include/wlr/types/wlr_primary_selection.h
@@ -0,0 +1,54 @@
+/*
+ * 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_PRIMARY_SELECTION_H
+#define WLR_TYPES_WLR_PRIMARY_SELECTION_H
+
+#include <wayland-server.h>
+#include <wlr/types/wlr_seat.h>
+
+struct wlr_primary_selection_source;
+
+/**
+ * A data source implementation. Only the `send` function is mandatory.
+ */
+struct wlr_primary_selection_source_impl {
+ void (*send)(struct wlr_primary_selection_source *source,
+ const char *mime_type, int fd);
+ void (*destroy)(struct wlr_primary_selection_source *source);
+};
+
+/**
+ * A source is the sending side of a selection.
+ */
+struct wlr_primary_selection_source {
+ const struct wlr_primary_selection_source_impl *impl;
+
+ // source metadata
+ struct wl_array mime_types;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+void wlr_primary_selection_source_init(
+ struct wlr_primary_selection_source *source,
+ const struct wlr_primary_selection_source_impl *impl);
+void wlr_primary_selection_source_destroy(
+ struct wlr_primary_selection_source *source);
+void wlr_primary_selection_source_send(
+ struct wlr_primary_selection_source *source, const char *mime_type,
+ int fd);
+
+void wlr_seat_set_primary_selection(struct wlr_seat *seat,
+ struct wlr_primary_selection_source *source);
+
+#endif
diff --git a/include/wlr/types/wlr_region.h b/include/wlr/types/wlr_region.h
new file mode 100644
index 00000000..ec7f73aa
--- /dev/null
+++ b/include/wlr/types/wlr_region.h
@@ -0,0 +1,24 @@
+/*
+ * 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_REGION_H
+#define WLR_TYPES_WLR_REGION_H
+
+#include <pixman.h>
+#include <wayland-server-protocol.h>
+
+/*
+ * Creates a new region resource with the provided new ID. If `resource_list` is
+ * non-NULL, adds the region's resource to the list.
+ */
+struct wl_resource *wlr_region_create(struct wl_client *client,
+ uint32_t version, uint32_t id, struct wl_list *resource_list);
+
+pixman_region32_t *wlr_region_from_resource(struct wl_resource *resource);
+
+#endif
diff --git a/include/wlr/types/wlr_screencopy_v1.h b/include/wlr/types/wlr_screencopy_v1.h
new file mode 100644
index 00000000..c7197bab
--- /dev/null
+++ b/include/wlr/types/wlr_screencopy_v1.h
@@ -0,0 +1,55 @@
+/*
+ * 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_SCREENCOPY_V1_H
+#define WLR_TYPES_WLR_SCREENCOPY_V1_H
+
+#include <stdbool.h>
+#include <wayland-server.h>
+#include <wlr/types/wlr_box.h>
+
+struct wlr_screencopy_manager_v1 {
+ struct wl_global *global;
+ struct wl_list resources; // wl_resource
+ struct wl_list frames; // wlr_screencopy_frame_v1::link
+
+ struct wl_listener display_destroy;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_screencopy_frame_v1 {
+ struct wl_resource *resource;
+ struct wlr_screencopy_manager_v1 *manager;
+ struct wl_list link;
+
+ enum wl_shm_format format;
+ struct wlr_box box;
+ int stride;
+
+ bool overlay_cursor, cursor_locked;
+
+ struct wl_shm_buffer *buffer;
+ struct wl_listener buffer_destroy;
+
+ struct wlr_output *output;
+ struct wl_listener output_swap_buffers;
+
+ void *data;
+};
+
+struct wlr_screencopy_manager_v1 *wlr_screencopy_manager_v1_create(
+ struct wl_display *display);
+void wlr_screencopy_manager_v1_destroy(
+ struct wlr_screencopy_manager_v1 *screencopy);
+
+#endif
diff --git a/include/wlr/types/wlr_screenshooter.h b/include/wlr/types/wlr_screenshooter.h
new file mode 100644
index 00000000..b7b87b39
--- /dev/null
+++ b/include/wlr/types/wlr_screenshooter.h
@@ -0,0 +1,41 @@
+/*
+ * 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_SCREENSHOOTER_H
+#define WLR_TYPES_WLR_SCREENSHOOTER_H
+
+#include <wayland-server.h>
+
+struct wlr_screenshooter {
+ struct wl_global *global;
+ struct wl_list screenshots; // wlr_screenshot::link
+
+ struct wl_listener display_destroy;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_screenshot {
+ struct wl_resource *resource;
+ struct wl_resource *output_resource;
+ struct wl_list link;
+
+ struct wlr_output *output;
+ struct wlr_screenshooter *screenshooter;
+
+ void* data;
+};
+
+struct wlr_screenshooter *wlr_screenshooter_create(struct wl_display *display);
+void wlr_screenshooter_destroy(struct wlr_screenshooter *screenshooter);
+
+#endif
diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h
new file mode 100644
index 00000000..942a3420
--- /dev/null
+++ b/include/wlr/types/wlr_seat.h
@@ -0,0 +1,573 @@
+/*
+ * 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_SEAT_H
+#define WLR_TYPES_WLR_SEAT_H
+
+#include <time.h>
+#include <wayland-server.h>
+#include <wlr/types/wlr_input_device.h>
+#include <wlr/types/wlr_keyboard.h>
+#include <wlr/types/wlr_surface.h>
+
+/**
+ * Contains state for a single client's bound wl_seat resource and can be used
+ * to issue input events to that client. The lifetime of these objects is
+ * managed by wlr_seat; some may be NULL.
+ */
+struct wlr_seat_client {
+ struct wl_client *client;
+ struct wlr_seat *seat;
+
+ // lists of wl_resource
+ struct wl_list resources;
+ struct wl_list pointers;
+ struct wl_list keyboards;
+ struct wl_list touches;
+ struct wl_list data_devices;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+
+ struct wl_list link;
+};
+
+struct wlr_touch_point {
+ int32_t touch_id;
+ struct wlr_surface *surface;
+ struct wlr_seat_client *client;
+
+ struct wlr_surface *focus_surface;
+ struct wlr_seat_client *focus_client;
+ double sx, sy;
+
+ struct wl_listener surface_destroy;
+ struct wl_listener focus_surface_destroy;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+
+ struct wl_list link;
+};
+
+struct wlr_seat_pointer_grab;
+
+struct wlr_pointer_grab_interface {
+ void (*enter)(struct wlr_seat_pointer_grab *grab,
+ struct wlr_surface *surface, double sx, double sy);
+ void (*motion)(struct wlr_seat_pointer_grab *grab, uint32_t time,
+ double sx, double sy);
+ uint32_t (*button)(struct wlr_seat_pointer_grab *grab, uint32_t time,
+ uint32_t button, uint32_t state);
+ void (*axis)(struct wlr_seat_pointer_grab *grab, uint32_t time,
+ enum wlr_axis_orientation orientation, double value,
+ int32_t value_discrete, enum wlr_axis_source source);
+ void (*cancel)(struct wlr_seat_pointer_grab *grab);
+};
+
+struct wlr_seat_keyboard_grab;
+
+struct wlr_keyboard_grab_interface {
+ void (*enter)(struct wlr_seat_keyboard_grab *grab,
+ struct wlr_surface *surface, uint32_t keycodes[],
+ size_t num_keycodes, struct wlr_keyboard_modifiers *modifiers);
+ void (*key)(struct wlr_seat_keyboard_grab *grab, uint32_t time,
+ uint32_t key, uint32_t state);
+ void (*modifiers)(struct wlr_seat_keyboard_grab *grab,
+ struct wlr_keyboard_modifiers *modifiers);
+ void (*cancel)(struct wlr_seat_keyboard_grab *grab);
+};
+
+struct wlr_seat_touch_grab;
+
+struct wlr_touch_grab_interface {
+ uint32_t (*down)(struct wlr_seat_touch_grab *grab, uint32_t time,
+ struct wlr_touch_point *point);
+ void (*up)(struct wlr_seat_touch_grab *grab, uint32_t time,
+ struct wlr_touch_point *point);
+ void (*motion)(struct wlr_seat_touch_grab *grab, uint32_t time,
+ struct wlr_touch_point *point);
+ void (*enter)(struct wlr_seat_touch_grab *grab, uint32_t time,
+ struct wlr_touch_point *point);
+ // XXX this will conflict with the actual touch cancel which is different so
+ // we need to rename this
+ void (*cancel)(struct wlr_seat_touch_grab *grab);
+};
+
+/**
+ * Passed to `wlr_seat_touch_start_grab()` to start a grab of the touch device.
+ * The grabber is responsible for handling touch events for the seat.
+ */
+struct wlr_seat_touch_grab {
+ const struct wlr_touch_grab_interface *interface;
+ struct wlr_seat *seat;
+ void *data;
+};
+
+/**
+ * Passed to `wlr_seat_keyboard_start_grab()` to start a grab of the keyboard.
+ * The grabber is responsible for handling keyboard events for the seat.
+ */
+struct wlr_seat_keyboard_grab {
+ const struct wlr_keyboard_grab_interface *interface;
+ struct wlr_seat *seat;
+ void *data;
+};
+
+/**
+ * Passed to `wlr_seat_pointer_start_grab()` to start a grab of the pointer. The
+ * grabber is responsible for handling pointer events for the seat.
+ */
+struct wlr_seat_pointer_grab {
+ const struct wlr_pointer_grab_interface *interface;
+ struct wlr_seat *seat;
+ void *data;
+};
+
+struct wlr_seat_pointer_state {
+ struct wlr_seat *seat;
+ struct wlr_seat_client *focused_client;
+ struct wlr_surface *focused_surface;
+
+ struct wlr_seat_pointer_grab *grab;
+ struct wlr_seat_pointer_grab *default_grab;
+
+ uint32_t button_count;
+ uint32_t grab_button;
+ uint32_t grab_serial;
+ uint32_t grab_time;
+
+ struct wl_listener surface_destroy;
+
+ struct {
+ struct wl_signal focus_change; // wlr_seat_pointer_focus_change_event
+ } events;
+};
+
+// TODO: May be useful to be able to simulate keyboard input events
+struct wlr_seat_keyboard_state {
+ struct wlr_seat *seat;
+ struct wlr_keyboard *keyboard;
+
+ struct wlr_seat_client *focused_client;
+ struct wlr_surface *focused_surface;
+
+ struct wl_listener keyboard_destroy;
+ struct wl_listener keyboard_keymap;
+ struct wl_listener keyboard_repeat_info;
+
+ struct wl_listener surface_destroy;
+
+ struct wlr_seat_keyboard_grab *grab;
+ struct wlr_seat_keyboard_grab *default_grab;
+
+ struct {
+ struct wl_signal focus_change; // wlr_seat_keyboard_focus_change_event
+ } events;
+};
+
+struct wlr_seat_touch_state {
+ struct wlr_seat *seat;
+ struct wl_list touch_points; // wlr_touch_point::link
+
+ uint32_t grab_serial;
+ uint32_t grab_id;
+
+ struct wlr_seat_touch_grab *grab;
+ struct wlr_seat_touch_grab *default_grab;
+};
+
+struct wlr_primary_selection_source;
+
+struct wlr_seat {
+ struct wl_global *global;
+ struct wl_display *display;
+ struct wl_list clients;
+ struct wl_list drag_icons; // wlr_drag_icon::link
+
+ char *name;
+ uint32_t capabilities;
+ struct timespec last_event;
+
+ struct wlr_data_source *selection_source;
+ uint32_t selection_serial;
+
+ struct wlr_primary_selection_source *primary_selection_source;
+
+ // `drag` goes away before `drag_source`, when the implicit grab ends
+ struct wlr_drag *drag;
+ struct wlr_data_source *drag_source;
+ uint32_t drag_serial;
+
+ struct wlr_seat_pointer_state pointer_state;
+ struct wlr_seat_keyboard_state keyboard_state;
+ struct wlr_seat_touch_state touch_state;
+
+ struct wl_listener display_destroy;
+ struct wl_listener selection_source_destroy;
+ struct wl_listener primary_selection_source_destroy;
+ struct wl_listener drag_source_destroy;
+
+ struct {
+ struct wl_signal pointer_grab_begin;
+ struct wl_signal pointer_grab_end;
+
+ struct wl_signal keyboard_grab_begin;
+ struct wl_signal keyboard_grab_end;
+
+ struct wl_signal touch_grab_begin;
+ struct wl_signal touch_grab_end;
+
+ struct wl_signal request_set_cursor;
+
+ struct wl_signal selection;
+ struct wl_signal primary_selection;
+
+ struct wl_signal start_drag;
+ struct wl_signal new_drag_icon;
+
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_seat_pointer_request_set_cursor_event {
+ struct wlr_seat_client *seat_client;
+ struct wlr_surface *surface;
+ uint32_t serial;
+ int32_t hotspot_x, hotspot_y;
+};
+
+struct wlr_seat_pointer_focus_change_event {
+ struct wlr_seat *seat;
+ struct wlr_surface *old_surface, *new_surface;
+ double sx, sy;
+};
+
+struct wlr_seat_keyboard_focus_change_event {
+ struct wlr_seat *seat;
+ struct wlr_surface *old_surface, *new_surface;
+};
+
+/**
+ * Allocates a new wlr_seat and adds a wl_seat global to the display.
+ */
+struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name);
+/**
+ * Destroys a wlr_seat and removes its wl_seat global.
+ */
+void wlr_seat_destroy(struct wlr_seat *wlr_seat);
+/**
+ * Gets a wlr_seat_client for the specified client, or returns NULL if no
+ * client is bound for that client.
+ */
+struct wlr_seat_client *wlr_seat_client_for_wl_client(struct wlr_seat *wlr_seat,
+ struct wl_client *wl_client);
+/**
+ * Updates the capabilities available on this seat.
+ * Will automatically send them to all clients.
+ */
+void wlr_seat_set_capabilities(struct wlr_seat *wlr_seat,
+ uint32_t capabilities);
+/**
+ * Updates the name of this seat.
+ * Will automatically send it to all clients.
+ */
+void wlr_seat_set_name(struct wlr_seat *wlr_seat, const char *name);
+
+/**
+ * Whether or not the surface has pointer focus
+ */
+bool wlr_seat_pointer_surface_has_focus(struct wlr_seat *wlr_seat,
+ struct wlr_surface *surface);
+
+/**
+ * Send a pointer enter event to the given surface and consider it to be the
+ * focused surface for the pointer. This will send a leave event to the last
+ * surface that was entered. Coordinates for the enter event are surface-local.
+ * Compositor should use `wlr_seat_pointer_notify_enter()` to change pointer
+ * focus to respect pointer grabs.
+ */
+void wlr_seat_pointer_enter(struct wlr_seat *wlr_seat,
+ struct wlr_surface *surface, double sx, double sy);
+
+/**
+ * Clear the focused surface for the pointer and leave all entered surfaces.
+ */
+void wlr_seat_pointer_clear_focus(struct wlr_seat *wlr_seat);
+
+/**
+ * Send a motion event to the surface with pointer focus. Coordinates for the
+ * motion event are surface-local. Compositors should use
+ * `wlr_seat_pointer_notify_motion()` to send motion events to respect pointer
+ * grabs.
+ */
+void wlr_seat_pointer_send_motion(struct wlr_seat *wlr_seat, uint32_t time,
+ double sx, double sy);
+
+/**
+ * Send a button event to the surface with pointer focus. Coordinates for the
+ * button event are surface-local. Returns the serial. Compositors should use
+ * `wlr_seat_pointer_notify_button()` to send button events to respect pointer
+ * grabs.
+ */
+uint32_t wlr_seat_pointer_send_button(struct wlr_seat *wlr_seat, uint32_t time,
+ uint32_t button, uint32_t state);
+
+/**
+ * Send an axis event to the surface with pointer focus. Compositors should use
+ * `wlr_seat_pointer_notify_axis()` to send axis events to respect pointer
+ * grabs.
+ **/
+void wlr_seat_pointer_send_axis(struct wlr_seat *wlr_seat, uint32_t time,
+ enum wlr_axis_orientation orientation, double value,
+ int32_t value_discrete, enum wlr_axis_source source);
+
+/**
+ * Start a grab of the pointer of this seat. The grabber is responsible for
+ * handling all pointer events until the grab ends.
+ */
+void wlr_seat_pointer_start_grab(struct wlr_seat *wlr_seat,
+ struct wlr_seat_pointer_grab *grab);
+
+/**
+ * End the grab of the pointer of this seat. This reverts the grab back to the
+ * default grab for the pointer.
+ */
+void wlr_seat_pointer_end_grab(struct wlr_seat *wlr_seat);
+
+/**
+ * Notify the seat of a pointer enter event to the given surface and request it
+ * to be the focused surface for the pointer. Pass surface-local coordinates
+ * where the enter occurred.
+ */
+void wlr_seat_pointer_notify_enter(struct wlr_seat *wlr_seat,
+ struct wlr_surface *surface, double sx, double sy);
+
+/**
+ * Notify the seat of motion over the given surface. Pass surface-local
+ * coordinates where the pointer motion occurred.
+ */
+void wlr_seat_pointer_notify_motion(struct wlr_seat *wlr_seat, uint32_t time,
+ double sx, double sy);
+
+/**
+ * Notify the seat that a button has been pressed. Returns the serial of the
+ * button press or zero if no button press was sent.
+ */
+uint32_t wlr_seat_pointer_notify_button(struct wlr_seat *wlr_seat,
+ uint32_t time, uint32_t button, uint32_t state);
+
+/**
+ * Notify the seat of an axis event.
+ */
+void wlr_seat_pointer_notify_axis(struct wlr_seat *wlr_seat, uint32_t time,
+ enum wlr_axis_orientation orientation, double value,
+ int32_t value_discrete, enum wlr_axis_source source);
+
+/**
+ * Whether or not the pointer has a grab other than the default grab.
+ */
+bool wlr_seat_pointer_has_grab(struct wlr_seat *seat);
+
+/**
+ * Set this keyboard as the active keyboard for the seat.
+ */
+void wlr_seat_set_keyboard(struct wlr_seat *seat, struct wlr_input_device *dev);
+
+/**
+ * Get the active keyboard for the seat.
+ */
+struct wlr_keyboard *wlr_seat_get_keyboard(struct wlr_seat *seat);
+
+/**
+ * Start a grab of the keyboard of this seat. The grabber is responsible for
+ * handling all keyboard events until the grab ends.
+ */
+void wlr_seat_keyboard_start_grab(struct wlr_seat *wlr_seat,
+ struct wlr_seat_keyboard_grab *grab);
+
+/**
+ * End the grab of the keyboard of this seat. This reverts the grab back to the
+ * default grab for the keyboard.
+ */
+void wlr_seat_keyboard_end_grab(struct wlr_seat *wlr_seat);
+
+/**
+ * Send the keyboard key to focused keyboard resources. Compositors should use
+ * `wlr_seat_notify_key()` to respect keyboard grabs.
+ */
+void wlr_seat_keyboard_send_key(struct wlr_seat *seat, uint32_t time,
+ uint32_t key, uint32_t state);
+
+/**
+ * Notify the seat that a key has been pressed on the keyboard. Defers to any
+ * keyboard grabs.
+ */
+void wlr_seat_keyboard_notify_key(struct wlr_seat *seat, uint32_t time,
+ uint32_t key, uint32_t state);
+
+/**
+ * Send the modifier state to focused keyboard resources. Compositors should use
+ * `wlr_seat_keyboard_notify_modifiers()` to respect any keyboard grabs.
+ */
+void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat,
+ struct wlr_keyboard_modifiers *modifiers);
+
+/**
+ * Notify the seat that the modifiers for the keyboard have changed. Defers to
+ * any keyboard grabs.
+ */
+void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat,
+ struct wlr_keyboard_modifiers *modifiers);
+
+/**
+ * Notify the seat that the keyboard focus has changed and request it to be the
+ * focused surface for this keyboard. Defers to any current grab of the seat's
+ * keyboard.
+ */
+void wlr_seat_keyboard_notify_enter(struct wlr_seat *seat,
+ struct wlr_surface *surface, uint32_t keycodes[], size_t num_keycodes,
+ struct wlr_keyboard_modifiers *modifiers);
+
+/**
+ * Send a keyboard enter event to the given surface and consider it to be the
+ * focused surface for the keyboard. This will send a leave event to the last
+ * surface that was entered. Compositors should use
+ * `wlr_seat_keyboard_notify_enter()` to change keyboard focus to respect
+ * keyboard grabs.
+ */
+void wlr_seat_keyboard_enter(struct wlr_seat *seat,
+ struct wlr_surface *surface, uint32_t keycodes[], size_t num_keycodes,
+ struct wlr_keyboard_modifiers *modifiers);
+
+/**
+ * Clear the focused surface for the keyboard and leave all entered surfaces.
+ */
+void wlr_seat_keyboard_clear_focus(struct wlr_seat *wlr_seat);
+
+/**
+ * Whether or not the keyboard has a grab other than the default grab
+ */
+bool wlr_seat_keyboard_has_grab(struct wlr_seat *seat);
+
+/**
+ * Start a grab of the touch device of this seat. The grabber is responsible for
+ * handling all touch events until the grab ends.
+ */
+void wlr_seat_touch_start_grab(struct wlr_seat *wlr_seat,
+ struct wlr_seat_touch_grab *grab);
+
+/**
+ * End the grab of the touch device of this seat. This reverts the grab back to
+ * the default grab for the touch device.
+ */
+void wlr_seat_touch_end_grab(struct wlr_seat *wlr_seat);
+
+/**
+ * Get the active touch point with the given `touch_id`. If the touch point does
+ * not exist or is no longer active, returns NULL.
+ */
+struct wlr_touch_point *wlr_seat_touch_get_point(struct wlr_seat *seat,
+ int32_t touch_id);
+
+/**
+ * Notify the seat of a touch down on the given surface. Defers to any grab of
+ * the touch device.
+ */
+uint32_t wlr_seat_touch_notify_down(struct wlr_seat *seat,
+ struct wlr_surface *surface, uint32_t time, int32_t touch_id, double sx,
+ double sy);
+
+/**
+ * Notify the seat that the touch point given by `touch_id` is up. Defers to any
+ * grab of the touch device.
+ */
+void wlr_seat_touch_notify_up(struct wlr_seat *seat, uint32_t time,
+ int32_t touch_id);
+
+/**
+ * Notify the seat that the touch point given by `touch_id` has moved. Defers to
+ * any grab of the touch device. The seat should be notified of touch motion
+ * even if the surface is not the owner of the touch point for processing by
+ * grabs.
+ */
+void wlr_seat_touch_notify_motion(struct wlr_seat *seat, uint32_t time,
+ int32_t touch_id, double sx, double sy);
+
+/**
+ * Notify the seat that the touch point given by `touch_id` has entered a new
+ * surface. The surface is required. To clear focus, use
+ * `wlr_seat_touch_point_clear_focus()`.
+ */
+void wlr_seat_touch_point_focus(struct wlr_seat *seat,
+ struct wlr_surface *surface, uint32_t time, int32_t touch_id, double sx,
+ double sy);
+
+/**
+ * Clear the focused surface for the touch point given by `touch_id`.
+ */
+void wlr_seat_touch_point_clear_focus(struct wlr_seat *seat, uint32_t time,
+ int32_t touch_id);
+
+/**
+ * Send a touch down event to the client of the given surface. All future touch
+ * events for this point will go to this surface. If the touch down is valid,
+ * this will add a new touch point with the given `touch_id`. The touch down may
+ * not be valid if the surface seat client does not accept touch input.
+ * Coordinates are surface-local. Compositors should use
+ * `wlr_seat_touch_notify_down()` to respect any grabs of the touch device.
+ */
+uint32_t wlr_seat_touch_send_down(struct wlr_seat *seat,
+ struct wlr_surface *surface, uint32_t time, int32_t touch_id, double sx,
+ double sy);
+
+/**
+ * Send a touch up event for the touch point given by the `touch_id`. The event
+ * will go to the client for the surface given in the cooresponding touch down
+ * event. This will remove the touch point. Compositors should use
+ * `wlr_seat_touch_notify_up()` to respect any grabs of the touch device.
+ */
+void wlr_seat_touch_send_up(struct wlr_seat *seat, uint32_t time,
+ int32_t touch_id);
+
+/**
+ * Send a touch motion event for the touch point given by the `touch_id`. The
+ * event will go to the client for the surface given in the corresponding touch
+ * down event. Compositors should use `wlr_seat_touch_notify_motion()` to
+ * respect any grabs of the touch device.
+ */
+void wlr_seat_touch_send_motion(struct wlr_seat *seat, uint32_t time,
+ int32_t touch_id, double sx, double sy);
+
+/**
+ * How many touch points are currently down for the seat.
+ */
+int wlr_seat_touch_num_points(struct wlr_seat *seat);
+
+/**
+ * Whether or not the seat has a touch grab other than the default grab.
+ */
+bool wlr_seat_touch_has_grab(struct wlr_seat *seat);
+
+/**
+ * Check whether this serial is valid to start a grab action such as an
+ * interactive move or resize.
+ */
+bool wlr_seat_validate_grab_serial(struct wlr_seat *seat, uint32_t serial);
+
+struct wlr_seat_client *wlr_seat_client_from_resource(
+ struct wl_resource *resource);
+
+struct wlr_seat_client *wlr_seat_client_from_pointer_resource(
+ struct wl_resource *resource);
+
+#endif
diff --git a/include/wlr/types/wlr_server_decoration.h b/include/wlr/types/wlr_server_decoration.h
new file mode 100644
index 00000000..ff8d1369
--- /dev/null
+++ b/include/wlr/types/wlr_server_decoration.h
@@ -0,0 +1,78 @@
+/*
+ * 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_SERVER_DECORATION_H
+#define WLR_TYPES_WLR_SERVER_DECORATION_H
+
+#include <wayland-server.h>
+
+/**
+ * Possible values to use in request_mode and the event mode. Same as
+ * org_kde_kwin_server_decoration_manager_mode.
+ */
+enum wlr_server_decoration_manager_mode {
+ /**
+ * Undecorated: The surface is not decorated at all, neither server nor
+ * client-side. An example is a popup surface which should not be
+ * decorated.
+ */
+ WLR_SERVER_DECORATION_MANAGER_MODE_NONE = 0,
+ /**
+ * Client-side decoration: The decoration is part of the surface and the
+ * client.
+ */
+ WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT = 1,
+ /**
+ * Server-side decoration: The server embeds the surface into a decoration
+ * frame.
+ */
+ WLR_SERVER_DECORATION_MANAGER_MODE_SERVER = 2,
+};
+
+struct wlr_server_decoration_manager {
+ struct wl_global *global;
+ struct wl_list resources;
+ struct wl_list decorations; // wlr_server_decoration::link
+
+ uint32_t default_mode; // enum wlr_server_decoration_manager_mode
+
+ struct wl_listener display_destroy;
+
+ struct {
+ struct wl_signal new_decoration;
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_server_decoration {
+ struct wl_resource *resource;
+ struct wlr_surface *surface;
+ struct wl_list link;
+
+ uint32_t mode; // enum wlr_server_decoration_manager_mode
+
+ struct {
+ struct wl_signal destroy;
+ struct wl_signal mode;
+ } events;
+
+ struct wl_listener surface_destroy_listener;
+
+ void *data;
+};
+
+struct wlr_server_decoration_manager *wlr_server_decoration_manager_create(
+ struct wl_display *display);
+void wlr_server_decoration_manager_set_default_mode(
+ struct wlr_server_decoration_manager *manager, uint32_t default_mode);
+void wlr_server_decoration_manager_destroy(
+ struct wlr_server_decoration_manager *manager);
+
+#endif
diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h
new file mode 100644
index 00000000..b8f8c02a
--- /dev/null
+++ b/include/wlr/types/wlr_surface.h
@@ -0,0 +1,246 @@
+/*
+ * 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_SURFACE_H
+#define WLR_TYPES_WLR_SURFACE_H
+
+#include <pixman.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <time.h>
+#include <wayland-server.h>
+#include <wlr/types/wlr_output.h>
+
+enum wlr_surface_state_field {
+ WLR_SURFACE_STATE_BUFFER = 1 << 0,
+ WLR_SURFACE_STATE_SURFACE_DAMAGE = 1 << 1,
+ WLR_SURFACE_STATE_BUFFER_DAMAGE = 1 << 2,
+ WLR_SURFACE_STATE_OPAQUE_REGION = 1 << 3,
+ WLR_SURFACE_STATE_INPUT_REGION = 1 << 4,
+ WLR_SURFACE_STATE_TRANSFORM = 1 << 5,
+ WLR_SURFACE_STATE_SCALE = 1 << 6,
+ WLR_SURFACE_STATE_FRAME_CALLBACK_LIST = 1 << 7,
+};
+
+struct wlr_surface_state {
+ uint32_t committed; // enum wlr_surface_state_field
+
+ struct wl_resource *buffer_resource;
+ int32_t dx, dy; // relative to previous position
+ pixman_region32_t surface_damage, buffer_damage; // clipped to bounds
+ pixman_region32_t opaque, input;
+ enum wl_output_transform transform;
+ int32_t scale;
+ struct wl_list frame_callback_list; // wl_resource
+
+ int width, height; // in surface-local coordinates
+ int buffer_width, buffer_height;
+
+ struct wl_listener buffer_destroy;
+};
+
+struct wlr_surface_role {
+ const char *name;
+ void (*commit)(struct wlr_surface *surface);
+ void (*precommit)(struct wlr_surface *surface);
+};
+
+struct wlr_surface {
+ struct wl_resource *resource;
+ struct wlr_renderer *renderer;
+ /**
+ * The surface's buffer, if any. A surface has an attached buffer when it
+ * commits with a non-null buffer in its pending state. A surface will not
+ * have a buffer if it has never committed one, has committed a null buffer,
+ * or something went wrong with uploading the buffer.
+ */
+ struct wlr_buffer *buffer;
+ /**
+ * The buffer position, in surface-local units.
+ */
+ int sx, sy;
+ /**
+ * The last commit's buffer damage, in buffer-local coordinates. This
+ * contains both the damage accumulated by the client via
+ * `wlr_surface_state.surface_damage` and `wlr_surface_state.buffer_damage`.
+ * If the buffer has been resized, the whole buffer is damaged.
+ *
+ * This region needs to be scaled and transformed into output coordinates,
+ * just like the buffer's texture. In addition, if the buffer has shrunk the
+ * old size needs to be damaged and if the buffer has moved the old and new
+ * positions need to be damaged.
+ */
+ pixman_region32_t buffer_damage;
+ /**
+ * The current opaque region, in surface-local coordinates. It is clipped to
+ * the surface bounds. If the surface's buffer is using a fully opaque
+ * format, this is set to the whole surface.
+ */
+ pixman_region32_t opaque_region;
+ /**
+ * The current input region, in surface-local coordinates. It is clipped to
+ * the surface bounds.
+ */
+ pixman_region32_t input_region;
+ /**
+ * `current` contains the current, committed surface state. `pending`
+ * accumulates state changes from the client between commits and shouldn't
+ * be accessed by the compositor directly. `previous` contains the state of
+ * the previous commit.
+ */
+ struct wlr_surface_state current, pending, previous;
+
+ const struct wlr_surface_role *role; // the lifetime-bound role or NULL
+ void *role_data; // role-specific data
+
+ struct {
+ struct wl_signal commit;
+ struct wl_signal new_subsurface;
+ struct wl_signal destroy;
+ } events;
+
+ struct wl_list subsurfaces; // wlr_subsurface::parent_link
+
+ // wlr_subsurface::parent_pending_link
+ struct wl_list subsurface_pending_list;
+
+ struct wl_listener renderer_destroy;
+
+ void *data;
+};
+
+struct wlr_subsurface_state {
+ int32_t x, y;
+};
+
+struct wlr_subsurface {
+ struct wl_resource *resource;
+ struct wlr_surface *surface;
+ struct wlr_surface *parent;
+
+ struct wlr_subsurface_state current, pending;
+
+ struct wlr_surface_state cached;
+ bool has_cache;
+
+ bool synchronized;
+ bool reordered;
+
+ struct wl_list parent_link;
+ struct wl_list parent_pending_link;
+
+ struct wl_listener surface_destroy;
+ struct wl_listener parent_destroy;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+typedef void (*wlr_surface_iterator_func_t)(struct wlr_surface *surface,
+ int sx, int sy, void *data);
+
+struct wlr_renderer;
+
+/**
+ * Create a new surface resource with the provided new ID. If `resource_list`
+ * is non-NULL, adds the surface's resource to the list.
+ */
+struct wlr_surface *wlr_surface_create(struct wl_client *client,
+ uint32_t version, uint32_t id, struct wlr_renderer *renderer,
+ struct wl_list *resource_list);
+
+/**
+ * Set the lifetime role for this surface. Returns 0 on success or -1 if the
+ * role cannot be set.
+ */
+bool wlr_surface_set_role(struct wlr_surface *surface,
+ const struct wlr_surface_role *role, void *role_data,
+ struct wl_resource *error_resource, uint32_t error_code);
+
+/**
+ * Whether or not this surface currently has an attached buffer. A surface has
+ * an attached buffer when it commits with a non-null buffer in its pending
+ * state. A surface will not have a buffer if it has never committed one, has
+ * committed a null buffer, or something went wrong with uploading the buffer.
+ */
+bool wlr_surface_has_buffer(struct wlr_surface *surface);
+
+/**
+ * Get the texture of the buffer currently attached to this surface. Returns
+ * NULL if no buffer is currently attached or if something went wrong with
+ * uploading the buffer.
+ */
+struct wlr_texture *wlr_surface_get_texture(struct wlr_surface *surface);
+
+/**
+ * Create a new subsurface resource with the provided new ID. If `resource_list`
+ * is non-NULL, adds the subsurface's resource to the list.
+ */
+struct wlr_subsurface *wlr_subsurface_create(struct wlr_surface *surface,
+ struct wlr_surface *parent, uint32_t version, uint32_t id,
+ struct wl_list *resource_list);
+
+/**
+ * Get the root of the subsurface tree for this surface.
+ */
+struct wlr_surface *wlr_surface_get_root_surface(struct wlr_surface *surface);
+
+/**
+ * Check if the surface accepts input events at the given surface-local
+ * coordinates. Does not check the surface's subsurfaces.
+ */
+bool wlr_surface_point_accepts_input(struct wlr_surface *surface,
+ double sx, double sy);
+
+/**
+ * Find a surface in this surface's tree that accepts input events at the given
+ * surface-local coordinates. Returns the surface and coordinates in the leaf
+ * surface coordinate system or NULL if no surface is found at that location.
+ */
+struct wlr_surface *wlr_surface_surface_at(struct wlr_surface *surface,
+ double sx, double sy, double *sub_x, double *sub_y);
+
+void wlr_surface_send_enter(struct wlr_surface *surface,
+ struct wlr_output *output);
+
+void wlr_surface_send_leave(struct wlr_surface *surface,
+ struct wlr_output *output);
+
+void wlr_surface_send_frame_done(struct wlr_surface *surface,
+ const struct timespec *when);
+
+struct wlr_box;
+/**
+ * Get the bounding box that contains the surface and all subsurfaces in
+ * surface coordinates.
+ * X and y may be negative, if there are subsurfaces with negative position.
+ */
+void wlr_surface_get_extends(struct wlr_surface *surface, struct wlr_box *box);
+
+struct wlr_surface *wlr_surface_from_resource(struct wl_resource *resource);
+
+/**
+ * Call `iterator` on each surface in the surface tree, with the surface's
+ * position relative to the root surface. The function is called from root to
+ * leaves (in rendering order).
+ */
+void wlr_surface_for_each_surface(struct wlr_surface *surface,
+ wlr_surface_iterator_func_t iterator, void *user_data);
+
+/**
+ * Get the effective damage to the surface in terms of surface local
+ * coordinates. This includes damage induced by resizing and moving the
+ * surface. The damage is not expected to be bounded by the surface itself.
+ */
+void wlr_surface_get_effective_damage(struct wlr_surface *surface,
+ pixman_region32_t *damage);
+
+#endif
diff --git a/include/wlr/types/wlr_switch.h b/include/wlr/types/wlr_switch.h
new file mode 100644
index 00000000..df1c8579
--- /dev/null
+++ b/include/wlr/types/wlr_switch.h
@@ -0,0 +1,47 @@
+/*
+ * 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_SWITCH_H
+#define WLR_TYPES_WLR_SWITCH_H
+
+#include <stdint.h>
+#include <wayland-server.h>
+#include <wlr/types/wlr_input_device.h>
+#include <wlr/types/wlr_list.h>
+
+struct wlr_switch_impl;
+
+struct wlr_switch {
+ struct wlr_switch_impl *impl;
+
+ struct {
+ struct wl_signal toggle;
+ } events;
+
+ void *data;
+};
+
+enum wlr_switch_type {
+ WLR_SWITCH_TYPE_LID = 1,
+ WLR_SWITCH_TYPE_TABLET_MODE,
+};
+
+enum wlr_switch_state {
+ WLR_SWITCH_STATE_OFF = 0,
+ WLR_SWITCH_STATE_ON,
+ WLR_SWITCH_STATE_TOGGLE
+};
+
+struct wlr_event_switch_toggle {
+ struct wlr_input_device *device;
+ uint32_t time_msec;
+ enum wlr_switch_type switch_type;
+ enum wlr_switch_state switch_state;
+};
+
+#endif
diff --git a/include/wlr/types/wlr_tablet_pad.h b/include/wlr/types/wlr_tablet_pad.h
new file mode 100644
index 00000000..d9bb284f
--- /dev/null
+++ b/include/wlr/types/wlr_tablet_pad.h
@@ -0,0 +1,94 @@
+/*
+ * 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_TABLET_PAD_H
+#define WLR_TYPES_WLR_TABLET_PAD_H
+
+#include <stdint.h>
+#include <wayland-server.h>
+#include <wlr/types/wlr_input_device.h>
+#include <wlr/types/wlr_list.h>
+
+/*
+ * NOTE: the wlr tablet pad implementation does not currently support tablets
+ * with more than one mode. I don't own any such hardware so I cannot test it
+ * and it is too complicated to make a meaningful implementation of blindly.
+ */
+
+struct wlr_tablet_pad_impl;
+
+struct wlr_tablet_pad {
+ struct wlr_tablet_pad_impl *impl;
+
+ struct {
+ struct wl_signal button;
+ struct wl_signal ring;
+ struct wl_signal strip;
+ struct wl_signal attach_tablet; //struct wlr_tablet_tool
+ } events;
+
+ size_t button_count;
+ size_t ring_count;
+ size_t strip_count;
+
+ struct wl_list groups; // wlr_tablet_pad_group::link
+ struct wlr_list paths; // char *
+
+ void *data;
+};
+
+struct wlr_tablet_pad_group {
+ struct wl_list link;
+
+ size_t button_count;
+ unsigned int *buttons;
+
+ size_t strip_count;
+ unsigned int *strips;
+
+ size_t ring_count;
+ unsigned int *rings;
+
+ unsigned int mode_count;
+};
+
+struct wlr_event_tablet_pad_button {
+ uint32_t time_msec;
+ uint32_t button;
+ enum wlr_button_state state;
+ unsigned int mode;
+ unsigned int group;
+};
+
+enum wlr_tablet_pad_ring_source {
+ WLR_TABLET_PAD_RING_SOURCE_UNKNOWN,
+ WLR_TABLET_PAD_RING_SOURCE_FINGER,
+};
+
+struct wlr_event_tablet_pad_ring {
+ uint32_t time_msec;
+ enum wlr_tablet_pad_ring_source source;
+ uint32_t ring;
+ double position;
+ unsigned int mode;
+};
+
+enum wlr_tablet_pad_strip_source {
+ WLR_TABLET_PAD_STRIP_SOURCE_UNKNOWN,
+ WLR_TABLET_PAD_STRIP_SOURCE_FINGER,
+};
+
+struct wlr_event_tablet_pad_strip {
+ uint32_t time_msec;
+ enum wlr_tablet_pad_strip_source source;
+ uint32_t strip;
+ double position;
+ unsigned int mode;
+};
+
+#endif
diff --git a/include/wlr/types/wlr_tablet_tool.h b/include/wlr/types/wlr_tablet_tool.h
new file mode 100644
index 00000000..cb516ed9
--- /dev/null
+++ b/include/wlr/types/wlr_tablet_tool.h
@@ -0,0 +1,136 @@
+/*
+ * 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_TABLET_TOOL_H
+#define WLR_TYPES_TABLET_TOOL_H
+
+#include <stdint.h>
+#include <wayland-server.h>
+#include <wlr/types/wlr_input_device.h>
+#include <wlr/types/wlr_list.h>
+
+/*
+ * Copy+Paste from libinput, but this should neither use libinput, nor
+ * tablet-unstable-v2 headers, so we can't include them
+ */
+enum wlr_tablet_tool_type {
+ WLR_TABLET_TOOL_TYPE_PEN = 1, /**< A generic pen */
+ WLR_TABLET_TOOL_TYPE_ERASER, /**< Eraser */
+ WLR_TABLET_TOOL_TYPE_BRUSH, /**< A paintbrush-like tool */
+ WLR_TABLET_TOOL_TYPE_PENCIL, /**< Physical drawing tool, e.g.
+ Wacom Inking Pen */
+ WLR_TABLET_TOOL_TYPE_AIRBRUSH, /**< An airbrush-like tool */
+ WLR_TABLET_TOOL_TYPE_MOUSE, /**< A mouse bound to the tablet */
+ WLR_TABLET_TOOL_TYPE_LENS, /**< A mouse tool with a lens */
+};
+
+struct wlr_tablet_tool {
+ enum wlr_tablet_tool_type type;
+ uint64_t hardware_serial;
+ uint64_t hardware_wacom;
+
+ // Capabilities
+ bool tilt;
+ bool pressure;
+ bool distance;
+ bool rotation;
+ bool slider;
+ bool wheel;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_tablet_impl;
+
+struct wlr_tablet {
+ struct wlr_tablet_impl *impl;
+
+ struct {
+ struct wl_signal axis;
+ struct wl_signal proximity;
+ struct wl_signal tip;
+ struct wl_signal button;
+ } events;
+
+ const char *name;
+ struct wlr_list paths; // char *
+
+ void *data;
+};
+
+enum wlr_tablet_tool_axes {
+ WLR_TABLET_TOOL_AXIS_X = 1,
+ WLR_TABLET_TOOL_AXIS_Y = 2,
+ WLR_TABLET_TOOL_AXIS_DISTANCE = 4,
+ WLR_TABLET_TOOL_AXIS_PRESSURE = 8,
+ WLR_TABLET_TOOL_AXIS_TILT_X = 16,
+ WLR_TABLET_TOOL_AXIS_TILT_Y = 32,
+ WLR_TABLET_TOOL_AXIS_ROTATION = 64,
+ WLR_TABLET_TOOL_AXIS_SLIDER = 128,
+ WLR_TABLET_TOOL_AXIS_WHEEL = 256,
+};
+
+struct wlr_event_tablet_tool_axis {
+ struct wlr_input_device *device;
+ struct wlr_tablet_tool *tool;
+
+ uint32_t time_msec;
+ uint32_t updated_axes;
+ // From 0..1
+ double x, y;
+ // Relative to last event
+ double dx, dy;
+ double pressure;
+ double distance;
+ double tilt_x, tilt_y;
+ double rotation;
+ double slider;
+ double wheel_delta;
+};
+
+enum wlr_tablet_tool_proximity_state {
+ WLR_TABLET_TOOL_PROXIMITY_OUT,
+ WLR_TABLET_TOOL_PROXIMITY_IN,
+};
+
+struct wlr_event_tablet_tool_proximity {
+ struct wlr_input_device *device;
+ struct wlr_tablet_tool *tool;
+ uint32_t time_msec;
+ // From 0..1
+ double x, y;
+ enum wlr_tablet_tool_proximity_state state;
+};
+
+enum wlr_tablet_tool_tip_state {
+ WLR_TABLET_TOOL_TIP_UP,
+ WLR_TABLET_TOOL_TIP_DOWN,
+};
+
+struct wlr_event_tablet_tool_tip {
+ struct wlr_input_device *device;
+ struct wlr_tablet_tool *tool;
+ uint32_t time_msec;
+ // From 0..1
+ double x, y;
+ enum wlr_tablet_tool_tip_state state;
+};
+
+struct wlr_event_tablet_tool_button {
+ struct wlr_input_device *device;
+ struct wlr_tablet_tool *tool;
+ uint32_t time_msec;
+ uint32_t button;
+ enum wlr_button_state state;
+};
+
+#endif
diff --git a/include/wlr/types/wlr_tablet_v2.h b/include/wlr/types/wlr_tablet_v2.h
new file mode 100644
index 00000000..d6fd646d
--- /dev/null
+++ b/include/wlr/types/wlr_tablet_v2.h
@@ -0,0 +1,330 @@
+/*
+ * 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_TABLET_V2_H
+#define WLR_TYPES_WLR_TABLET_V2_H
+
+#include <wayland-server.h>
+#include <wlr/types/wlr_seat.h>
+#include <wlr/types/wlr_input_device.h>
+
+#include "tablet-unstable-v2-protocol.h"
+
+/* This can probably be even lower,the tools don't have a lot of buttons */
+#define WLR_TABLET_V2_TOOL_BUTTONS_CAP 16
+
+struct wlr_tablet_pad_v2_grab_interface;
+
+struct wlr_tablet_pad_v2_grab {
+ const struct wlr_tablet_pad_v2_grab_interface *interface;
+ struct wlr_tablet_v2_tablet_pad *pad;
+ void *data;
+};
+
+struct wlr_tablet_tool_v2_grab_interface;
+
+struct wlr_tablet_tool_v2_grab {
+ const struct wlr_tablet_tool_v2_grab_interface *interface;
+ struct wlr_tablet_v2_tablet_tool *tool;
+ void *data;
+};
+
+struct wlr_tablet_client_v2;
+struct wlr_tablet_tool_client_v2;
+struct wlr_tablet_pad_client_v2;
+
+struct wlr_tablet_manager_v2 {
+ struct wl_global *wl_global;
+ struct wl_list clients; // wlr_tablet_manager_client_v2::link
+ struct wl_list seats; // wlr_tablet_seat_v2::link
+
+ struct wl_listener display_destroy;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_tablet_v2_tablet {
+ struct wl_list link; // wlr_tablet_seat_v2::tablets
+ struct wlr_tablet *wlr_tablet;
+ struct wlr_input_device *wlr_device;
+ struct wl_list clients; // wlr_tablet_client_v2::tablet_link
+
+ struct wl_listener tool_destroy;
+
+ struct wlr_tablet_client_v2 *current_client;
+};
+
+struct wlr_tablet_v2_tablet_tool {
+ struct wl_list link; // wlr_tablet_seat_v2::tablets
+ struct wlr_tablet_tool *wlr_tool;
+ struct wl_list clients; // wlr_tablet_tool_client_v2::tool_link
+
+ struct wl_listener tool_destroy;
+
+ struct wlr_tablet_tool_client_v2 *current_client;
+ struct wlr_surface *focused_surface;
+ struct wl_listener surface_destroy;
+
+ struct wlr_tablet_tool_v2_grab *grab;
+ struct wlr_tablet_tool_v2_grab default_grab;
+
+ uint32_t proximity_serial;
+ bool is_down;
+ uint32_t down_serial;
+ size_t num_buttons;
+ uint32_t pressed_buttons[WLR_TABLET_V2_TOOL_BUTTONS_CAP];
+ uint32_t pressed_serials[WLR_TABLET_V2_TOOL_BUTTONS_CAP];
+
+ struct {
+ struct wl_signal set_cursor; // struct wlr_tablet_v2_event_cursor
+ } events;
+};
+
+struct wlr_tablet_v2_tablet_pad {
+ struct wl_list link; // wlr_tablet_seat_v2::pads
+ struct wlr_tablet_pad *wlr_pad;
+ struct wlr_input_device *wlr_device;
+ struct wl_list clients; // wlr_tablet_pad_client_v2::pad_link
+
+ size_t group_count;
+ uint32_t *groups;
+
+ struct wl_listener pad_destroy;
+
+ struct wlr_tablet_pad_client_v2 *current_client;
+ struct wlr_tablet_pad_v2_grab *grab;
+ struct wlr_tablet_pad_v2_grab default_grab;
+
+ struct {
+ struct wl_signal button_feedback; // struct wlr_tablet_v2_event_feedback
+ struct wl_signal strip_feedback; // struct wlr_tablet_v2_event_feedback
+ struct wl_signal ring_feedback; // struct wlr_tablet_v2_event_feedback
+ } events;
+};
+
+struct wlr_tablet_v2_event_cursor {
+ struct wlr_surface *surface;
+ uint32_t serial;
+ int32_t hotspot_x;
+ int32_t hotspot_y;
+ struct wlr_seat_client *seat_client;
+};
+
+struct wlr_tablet_v2_event_feedback {
+ const char *description;
+ size_t index;
+ uint32_t serial;
+};
+
+struct wlr_tablet_v2_tablet *wlr_tablet_create(
+ struct wlr_tablet_manager_v2 *manager,
+ struct wlr_seat *wlr_seat,
+ struct wlr_input_device *wlr_device);
+
+struct wlr_tablet_v2_tablet_pad *wlr_tablet_pad_create(
+ struct wlr_tablet_manager_v2 *manager,
+ struct wlr_seat *wlr_seat,
+ struct wlr_input_device *wlr_device);
+
+struct wlr_tablet_v2_tablet_tool *wlr_tablet_tool_create(
+ struct wlr_tablet_manager_v2 *manager,
+ struct wlr_seat *wlr_seat,
+ struct wlr_tablet_tool *wlr_tool);
+
+struct wlr_tablet_manager_v2 *wlr_tablet_v2_create(struct wl_display *display);
+void wlr_tablet_v2_destroy(struct wlr_tablet_manager_v2 *manager);
+
+void wlr_send_tablet_v2_tablet_tool_proximity_in(
+ struct wlr_tablet_v2_tablet_tool *tool,
+ struct wlr_tablet_v2_tablet *tablet,
+ struct wlr_surface *surface);
+
+void wlr_send_tablet_v2_tablet_tool_down(struct wlr_tablet_v2_tablet_tool *tool);
+void wlr_send_tablet_v2_tablet_tool_up(struct wlr_tablet_v2_tablet_tool *tool);
+
+void wlr_send_tablet_v2_tablet_tool_motion(
+ struct wlr_tablet_v2_tablet_tool *tool, double x, double y);
+
+void wlr_send_tablet_v2_tablet_tool_pressure(
+ struct wlr_tablet_v2_tablet_tool *tool, double pressure);
+
+void wlr_send_tablet_v2_tablet_tool_distance(
+ struct wlr_tablet_v2_tablet_tool *tool, double distance);
+
+void wlr_send_tablet_v2_tablet_tool_tilt(
+ struct wlr_tablet_v2_tablet_tool *tool, double x, double y);
+
+void wlr_send_tablet_v2_tablet_tool_rotation(
+ struct wlr_tablet_v2_tablet_tool *tool, double degrees);
+
+void wlr_send_tablet_v2_tablet_tool_slider(
+ struct wlr_tablet_v2_tablet_tool *tool, double position);
+
+void wlr_send_tablet_v2_tablet_tool_wheel(
+ struct wlr_tablet_v2_tablet_tool *tool, double degrees, int32_t clicks);
+
+void wlr_send_tablet_v2_tablet_tool_proximity_out(
+ struct wlr_tablet_v2_tablet_tool *tool);
+
+void wlr_send_tablet_v2_tablet_tool_button(
+ struct wlr_tablet_v2_tablet_tool *tool, uint32_t button,
+ enum zwp_tablet_pad_v2_button_state state);
+
+
+
+void wlr_tablet_v2_tablet_tool_notify_proximity_in(
+ struct wlr_tablet_v2_tablet_tool *tool,
+ struct wlr_tablet_v2_tablet *tablet,
+ struct wlr_surface *surface);
+
+void wlr_tablet_v2_tablet_tool_notify_down(struct wlr_tablet_v2_tablet_tool *tool);
+void wlr_tablet_v2_tablet_tool_notify_up(struct wlr_tablet_v2_tablet_tool *tool);
+
+void wlr_tablet_v2_tablet_tool_notify_motion(
+ struct wlr_tablet_v2_tablet_tool *tool, double x, double y);
+
+void wlr_tablet_v2_tablet_tool_notify_pressure(
+ struct wlr_tablet_v2_tablet_tool *tool, double pressure);
+
+void wlr_tablet_v2_tablet_tool_notify_distance(
+ struct wlr_tablet_v2_tablet_tool *tool, double distance);
+
+void wlr_tablet_v2_tablet_tool_notify_tilt(
+ struct wlr_tablet_v2_tablet_tool *tool, double x, double y);
+
+void wlr_tablet_v2_tablet_tool_notify_rotation(
+ struct wlr_tablet_v2_tablet_tool *tool, double degrees);
+
+void wlr_tablet_v2_tablet_tool_notify_slider(
+ struct wlr_tablet_v2_tablet_tool *tool, double position);
+
+void wlr_tablet_v2_tablet_tool_notify_wheel(
+ struct wlr_tablet_v2_tablet_tool *tool, double degrees, int32_t clicks);
+
+void wlr_tablet_v2_tablet_tool_notify_proximity_out(
+ struct wlr_tablet_v2_tablet_tool *tool);
+
+void wlr_tablet_v2_tablet_tool_notify_button(
+ struct wlr_tablet_v2_tablet_tool *tool, uint32_t button,
+ enum zwp_tablet_pad_v2_button_state state);
+
+
+struct wlr_tablet_tool_v2_grab_interface {
+ void (*proximity_in)(
+ struct wlr_tablet_tool_v2_grab *grab,
+ struct wlr_tablet_v2_tablet *tablet,
+ struct wlr_surface *surface);
+
+ void (*down)(struct wlr_tablet_tool_v2_grab *grab);
+ void (*up)(struct wlr_tablet_tool_v2_grab *grab);
+
+ void (*motion)(struct wlr_tablet_tool_v2_grab *grab, double x, double y);
+
+ void (*pressure)(struct wlr_tablet_tool_v2_grab *grab, double pressure);
+
+ void (*distance)(struct wlr_tablet_tool_v2_grab *grab, double distance);
+
+ void (*tilt)(struct wlr_tablet_tool_v2_grab *grab, double x, double y);
+
+ void (*rotation)(struct wlr_tablet_tool_v2_grab *grab, double degrees);
+
+ void (*slider)(struct wlr_tablet_tool_v2_grab *grab, double position);
+
+ void (*wheel)(struct wlr_tablet_tool_v2_grab *grab, double degrees, int32_t clicks);
+
+ void (*proximity_out)(struct wlr_tablet_tool_v2_grab *grab);
+
+ void (*button)(
+ struct wlr_tablet_tool_v2_grab *grab, uint32_t button,
+ enum zwp_tablet_pad_v2_button_state state);
+ void (*cancel)(struct wlr_tablet_tool_v2_grab *grab);
+};
+
+void wlr_tablet_tool_v2_start_grab(struct wlr_tablet_v2_tablet_tool *tool, struct wlr_tablet_tool_v2_grab *grab);
+void wlr_tablet_tool_v2_end_grab(struct wlr_tablet_v2_tablet_tool *tool);
+
+void wlr_tablet_tool_v2_start_implicit_grab(struct wlr_tablet_v2_tablet_tool *tool);
+
+
+uint32_t wlr_send_tablet_v2_tablet_pad_enter(
+ struct wlr_tablet_v2_tablet_pad *pad,
+ struct wlr_tablet_v2_tablet *tablet,
+ struct wlr_surface *surface);
+
+void wlr_send_tablet_v2_tablet_pad_button(
+ struct wlr_tablet_v2_tablet_pad *pad, size_t button,
+ uint32_t time, enum zwp_tablet_pad_v2_button_state state);
+
+void wlr_send_tablet_v2_tablet_pad_strip(struct wlr_tablet_v2_tablet_pad *pad,
+ uint32_t strip, double position, bool finger, uint32_t time);
+void wlr_send_tablet_v2_tablet_pad_ring(struct wlr_tablet_v2_tablet_pad *pad,
+ uint32_t ring, double position, bool finger, uint32_t time);
+
+uint32_t wlr_send_tablet_v2_tablet_pad_leave(struct wlr_tablet_v2_tablet_pad *pad,
+ struct wlr_surface *surface);
+
+uint32_t wlr_send_tablet_v2_tablet_pad_mode(struct wlr_tablet_v2_tablet_pad *pad,
+ size_t group, uint32_t mode, uint32_t time);
+
+
+uint32_t wlr_tablet_v2_tablet_pad_notify_enter(
+ struct wlr_tablet_v2_tablet_pad *pad,
+ struct wlr_tablet_v2_tablet *tablet,
+ struct wlr_surface *surface);
+
+void wlr_tablet_v2_tablet_pad_notify_button(
+ struct wlr_tablet_v2_tablet_pad *pad, size_t button,
+ uint32_t time, enum zwp_tablet_pad_v2_button_state state);
+
+void wlr_tablet_v2_tablet_pad_notify_strip(
+ struct wlr_tablet_v2_tablet_pad *pad,
+ uint32_t strip, double position, bool finger, uint32_t time);
+void wlr_tablet_v2_tablet_pad_notify_ring(
+ struct wlr_tablet_v2_tablet_pad *pad,
+ uint32_t ring, double position, bool finger, uint32_t time);
+
+uint32_t wlr_tablet_v2_tablet_pad_notify_leave(
+ struct wlr_tablet_v2_tablet_pad *pad, struct wlr_surface *surface);
+
+uint32_t wlr_tablet_v2_tablet_pad_notify_mode(
+ struct wlr_tablet_v2_tablet_pad *pad,
+ size_t group, uint32_t mode, uint32_t time);
+
+struct wlr_tablet_pad_v2_grab_interface {
+ uint32_t (*enter)(
+ struct wlr_tablet_pad_v2_grab *grab,
+ struct wlr_tablet_v2_tablet *tablet,
+ struct wlr_surface *surface);
+
+ void (*button)(struct wlr_tablet_pad_v2_grab *grab,size_t button,
+ uint32_t time, enum zwp_tablet_pad_v2_button_state state);
+
+ void (*strip)(struct wlr_tablet_pad_v2_grab *grab,
+ uint32_t strip, double position, bool finger, uint32_t time);
+ void (*ring)(struct wlr_tablet_pad_v2_grab *grab,
+ uint32_t ring, double position, bool finger, uint32_t time);
+
+ uint32_t (*leave)(struct wlr_tablet_pad_v2_grab *grab,
+ struct wlr_surface *surface);
+
+ uint32_t (*mode)(struct wlr_tablet_pad_v2_grab *grab,
+ size_t group, uint32_t mode, uint32_t time);
+
+ void (*cancel)(struct wlr_tablet_pad_v2_grab *grab);
+};
+
+void wlr_tablet_v2_end_grab(struct wlr_tablet_v2_tablet_pad *pad);
+void wlr_tablet_v2_start_grab(struct wlr_tablet_v2_tablet_pad *pad, struct wlr_tablet_pad_v2_grab *grab);
+
+bool wlr_surface_accepts_tablet_v2(struct wlr_tablet_v2_tablet *tablet,
+ struct wlr_surface *surface);
+#endif /* WLR_TYPES_WLR_TABLET_V2_H */
diff --git a/include/wlr/types/wlr_text_input_v3.h b/include/wlr/types/wlr_text_input_v3.h
new file mode 100644
index 00000000..0db0cf47
--- /dev/null
+++ b/include/wlr/types/wlr_text_input_v3.h
@@ -0,0 +1,93 @@
+/*
+ * 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_TEXT_INPUT_V3_H
+#define WLR_TYPES_WLR_TEXT_INPUT_V3_H
+
+#include <wayland-server.h>
+#include <wlr/types/wlr_seat.h>
+#include <wlr/types/wlr_surface.h>
+
+struct wlr_text_input_v3_state {
+ struct {
+ char *text; // NULL is allowed and equivalent to empty string
+ uint32_t cursor;
+ uint32_t anchor;
+ } surrounding;
+
+ uint32_t text_change_cause;
+
+ struct {
+ uint32_t hint;
+ uint32_t purpose;
+ } content_type;
+
+ struct {
+ int32_t x;
+ int32_t y;
+ int32_t width;
+ int32_t height;
+ } cursor_rectangle;
+};
+
+struct wlr_text_input_v3 {
+ struct wlr_seat *seat; // becomes null when seat destroyed
+ struct wl_resource *resource;
+ struct wlr_surface *focused_surface;
+ struct wlr_text_input_v3_state pending;
+ struct wlr_text_input_v3_state current;
+ uint32_t current_serial; // next in line to send
+ bool pending_enabled;
+ bool current_enabled;
+
+ struct wl_list link;
+
+ struct wl_listener surface_destroy;
+ struct wl_listener seat_destroy;
+
+ struct {
+ struct wl_signal enable; // (struct wlr_text_input_v3*)
+ struct wl_signal commit; // (struct wlr_text_input_v3*)
+ struct wl_signal disable; // (struct wlr_text_input_v3*)
+ struct wl_signal destroy; // (struct wlr_text_input_v3*)
+ } events;
+};
+
+struct wlr_text_input_manager_v3 {
+ struct wl_global *global;
+
+ struct wl_list bound_resources; // struct wl_resource*::link
+ struct wl_list text_inputs; // struct wlr_text_input_v3::resource::link
+
+ struct wl_listener display_destroy;
+
+ struct {
+ struct wl_signal text_input; // (struct wlr_text_input_v3*)
+ struct wl_signal destroy; // (struct wlr_input_method_manager_v3*)
+ } events;
+};
+
+struct wlr_text_input_manager_v3 *wlr_text_input_manager_v3_create(
+ struct wl_display *wl_display);
+void wlr_text_input_manager_v3_destroy(
+ struct wlr_text_input_manager_v3 *manager);
+
+// Sends enter to the surface and saves it
+void wlr_text_input_v3_send_enter(struct wlr_text_input_v3 *text_input,
+ struct wlr_surface *wlr_surface);
+// Sends leave to the currently focused surface and clears it
+void wlr_text_input_v3_send_leave(struct wlr_text_input_v3 *text_input);
+void wlr_text_input_v3_send_preedit_string(struct wlr_text_input_v3 *text_input,
+ const char *text, uint32_t cursor_begin, uint32_t cursor_end);
+void wlr_text_input_v3_send_commit_string(struct wlr_text_input_v3 *text_input,
+ const char *text);
+void wlr_text_input_v3_send_delete_surrounding_text(
+ struct wlr_text_input_v3 *text_input, uint32_t before_length,
+ uint32_t after_length);
+void wlr_text_input_v3_send_done(struct wlr_text_input_v3 *text_input);
+#endif
diff --git a/include/wlr/types/wlr_touch.h b/include/wlr/types/wlr_touch.h
new file mode 100644
index 00000000..99316ae0
--- /dev/null
+++ b/include/wlr/types/wlr_touch.h
@@ -0,0 +1,58 @@
+/*
+ * 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_TOUCH_H
+#define WLR_TYPES_WLR_TOUCH_H
+
+#include <stdint.h>
+#include <wayland-server.h>
+
+struct wlr_touch_impl;
+
+struct wlr_touch {
+ struct wlr_touch_impl *impl;
+
+ struct {
+ struct wl_signal down;
+ struct wl_signal up;
+ struct wl_signal motion;
+ struct wl_signal cancel;
+ } events;
+
+ void *data;
+};
+
+struct wlr_event_touch_down {
+ struct wlr_input_device *device;
+ uint32_t time_msec;
+ int32_t touch_id;
+ // From 0..1
+ double x, y;
+};
+
+struct wlr_event_touch_up {
+ struct wlr_input_device *device;
+ uint32_t time_msec;
+ int32_t touch_id;
+};
+
+struct wlr_event_touch_motion {
+ struct wlr_input_device *device;
+ uint32_t time_msec;
+ int32_t touch_id;
+ // From 0..1
+ double x, y;
+};
+
+struct wlr_event_touch_cancel {
+ struct wlr_input_device *device;
+ uint32_t time_msec;
+ int32_t touch_id;
+};
+
+#endif
diff --git a/include/wlr/types/wlr_virtual_keyboard_v1.h b/include/wlr/types/wlr_virtual_keyboard_v1.h
new file mode 100644
index 00000000..e75ed8ec
--- /dev/null
+++ b/include/wlr/types/wlr_virtual_keyboard_v1.h
@@ -0,0 +1,46 @@
+/*
+ * 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_VIRTUAL_KEYBOARD_V1_H
+#define WLR_TYPES_WLR_VIRTUAL_KEYBOARD_V1_H
+
+#include <wayland-server.h>
+#include <wlr/interfaces/wlr_input_device.h>
+#include <wlr/interfaces/wlr_keyboard.h>
+
+struct wlr_virtual_keyboard_manager_v1 {
+ struct wl_global *global;
+ struct wl_list resources; // struct wl_resource*
+ struct wl_list virtual_keyboards; // struct wlr_virtual_keyboard_v1*
+
+ struct wl_listener display_destroy;
+
+ struct {
+ struct wl_signal new_virtual_keyboard; // struct wlr_virtual_keyboard_v1*
+ struct wl_signal destroy;
+ } events;
+};
+
+struct wlr_virtual_keyboard_v1 {
+ struct wl_resource *resource;
+ struct wlr_input_device input_device;
+ struct wlr_seat *seat;
+
+ struct wl_list link;
+
+ struct {
+ struct wl_signal destroy; // struct wlr_virtual_keyboard_v1*
+ } events;
+};
+
+struct wlr_virtual_keyboard_manager_v1* wlr_virtual_keyboard_manager_v1_create(
+ struct wl_display *display);
+void wlr_virtual_keyboard_manager_v1_destroy(
+ struct wlr_virtual_keyboard_manager_v1 *manager);
+
+#endif
diff --git a/include/wlr/types/wlr_wl_shell.h b/include/wlr/types/wlr_wl_shell.h
new file mode 100644
index 00000000..dffbb4d7
--- /dev/null
+++ b/include/wlr/types/wlr_wl_shell.h
@@ -0,0 +1,175 @@
+/*
+ * 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_WL_SHELL_H
+#define WLR_TYPES_WLR_WL_SHELL_H
+
+#include <stdbool.h>
+#include <wayland-server.h>
+#include <wlr/types/wlr_seat.h>
+
+struct wlr_wl_shell {
+ struct wl_global *global;
+ struct wl_list resources;
+ struct wl_list surfaces;
+ struct wl_list popup_grabs;
+ uint32_t ping_timeout;
+
+ struct wl_listener display_destroy;
+
+ struct {
+ struct wl_signal new_surface;
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_wl_shell_surface_transient_state {
+ int32_t x;
+ int32_t y;
+ enum wl_shell_surface_transient flags;
+};
+
+struct wlr_wl_shell_surface_popup_state {
+ struct wlr_seat *seat;
+ uint32_t serial;
+};
+
+// each seat gets a popup grab
+struct wlr_wl_shell_popup_grab {
+ struct wl_client *client;
+ struct wlr_seat_pointer_grab pointer_grab;
+ struct wlr_seat *seat;
+ struct wl_list popups;
+ struct wl_list link; // wlr_wl_shell::popup_grabs
+};
+
+enum wlr_wl_shell_surface_state {
+ WLR_WL_SHELL_SURFACE_STATE_NONE,
+ WLR_WL_SHELL_SURFACE_STATE_TOPLEVEL,
+ WLR_WL_SHELL_SURFACE_STATE_MAXIMIZED,
+ WLR_WL_SHELL_SURFACE_STATE_FULLSCREEN,
+ WLR_WL_SHELL_SURFACE_STATE_TRANSIENT,
+ WLR_WL_SHELL_SURFACE_STATE_POPUP,
+};
+
+struct wlr_wl_shell_surface {
+ struct wlr_wl_shell *shell;
+ struct wl_client *client;
+ struct wl_resource *resource;
+ struct wlr_surface *surface;
+ bool configured;
+ struct wl_list link; // wlr_wl_shell::surfaces
+
+ uint32_t ping_serial;
+ struct wl_event_source *ping_timer;
+
+ enum wlr_wl_shell_surface_state state;
+ struct wlr_wl_shell_surface_transient_state *transient_state;
+ struct wlr_wl_shell_surface_popup_state *popup_state;
+ struct wl_list grab_link; // wlr_wl_shell_popup_grab::popups
+
+ char *title;
+ char *class;
+
+ struct wl_listener surface_destroy;
+
+ struct wlr_wl_shell_surface *parent;
+ struct wl_list popup_link;
+ struct wl_list popups;
+ bool popup_mapped;
+
+ struct {
+ struct wl_signal destroy;
+ struct wl_signal ping_timeout;
+ struct wl_signal new_popup;
+
+ struct wl_signal request_move;
+ struct wl_signal request_resize;
+ struct wl_signal request_fullscreen;
+ struct wl_signal request_maximize;
+
+ struct wl_signal set_state;
+ struct wl_signal set_title;
+ struct wl_signal set_class;
+ } events;
+
+ void *data;
+};
+
+struct wlr_wl_shell_surface_move_event {
+ struct wlr_wl_shell_surface *surface;
+ struct wlr_seat_client *seat;
+ uint32_t serial;
+};
+
+struct wlr_wl_shell_surface_resize_event {
+ struct wlr_wl_shell_surface *surface;
+ struct wlr_seat_client *seat;
+ uint32_t serial;
+ enum wl_shell_surface_resize edges;
+};
+
+struct wlr_wl_shell_surface_set_fullscreen_event {
+ struct wlr_wl_shell_surface *surface;
+ enum wl_shell_surface_fullscreen_method method;
+ uint32_t framerate;
+ struct wlr_output *output;
+};
+
+struct wlr_wl_shell_surface_maximize_event {
+ struct wlr_wl_shell_surface *surface;
+ struct wlr_output *output;
+};
+
+/**
+ * Create a wl_shell for this display.
+ */
+struct wlr_wl_shell *wlr_wl_shell_create(struct wl_display *display);
+
+/**
+ * Destroy this surface.
+ */
+void wlr_wl_shell_destroy(struct wlr_wl_shell *wlr_wl_shell);
+
+/**
+ * Send a ping to the surface. If the surface does not respond with a pong
+ * within a reasonable amount of time, the ping timeout event will be emitted.
+ */
+void wlr_wl_shell_surface_ping(struct wlr_wl_shell_surface *surface);
+
+/**
+ * Request that the surface configure itself to be the given size.
+ */
+void wlr_wl_shell_surface_configure(struct wlr_wl_shell_surface *surface,
+ enum wl_shell_surface_resize edges, int32_t width, int32_t height);
+
+/**
+ * Find a surface within this wl-shell surface tree at the given surface-local
+ * coordinates. Returns the surface and coordinates in the leaf surface
+ * coordinate system or NULL if no surface is found at that location.
+ */
+struct wlr_surface *wlr_wl_shell_surface_surface_at(
+ struct wlr_wl_shell_surface *surface, double sx, double sy,
+ double *sub_sx, double *sub_sy);
+
+bool wlr_surface_is_wl_shell_surface(struct wlr_surface *surface);
+
+struct wlr_wl_shell_surface *wlr_wl_shell_surface_from_wlr_surface(
+ struct wlr_surface *surface);
+
+/**
+ * Call `iterator` on each surface in the shell surface tree, with the surface's
+ * position relative to the root xdg-surface. The function is called from root to
+ * leaves (in rendering order).
+ */
+void wlr_wl_shell_surface_for_each_surface(struct wlr_wl_shell_surface *surface,
+ wlr_surface_iterator_func_t iterator, void *user_data);
+
+#endif
diff --git a/include/wlr/types/wlr_xcursor_manager.h b/include/wlr/types/wlr_xcursor_manager.h
new file mode 100644
index 00000000..285006bf
--- /dev/null
+++ b/include/wlr/types/wlr_xcursor_manager.h
@@ -0,0 +1,69 @@
+/*
+ * 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_XCURSOR_MANAGER_H
+#define WLR_TYPES_WLR_XCURSOR_MANAGER_H
+
+#include <wayland-server.h>
+#include <wlr/types/wlr_cursor.h>
+#include <wlr/xcursor.h>
+
+/**
+ * An XCursor theme at a particular scale factor of the base size.
+ */
+struct wlr_xcursor_manager_theme {
+ float scale;
+ struct wlr_xcursor_theme *theme;
+ struct wl_list link;
+};
+
+/**
+ * wlr_xcursor_manager dynamically loads xcursor themes at sizes necessary for
+ * use on outputs at arbitrary scale factors. You should call
+ * wlr_xcursor_manager_load for each output you will show your cursor on, with
+ * the scale factor parameter set to that output's scale factor.
+ */
+struct wlr_xcursor_manager {
+ char *name;
+ uint32_t size;
+ struct wl_list scaled_themes; // wlr_xcursor_manager_theme::link
+};
+
+/**
+ * Creates a new XCursor manager with the given xcursor theme name and base size
+ * (for use when scale=1).
+ */
+struct wlr_xcursor_manager *wlr_xcursor_manager_create(const char *name,
+ uint32_t size);
+
+void wlr_xcursor_manager_destroy(struct wlr_xcursor_manager *manager);
+
+/**
+ * Ensures an xcursor theme at the given scale factor is loaded in the manager.
+ */
+int wlr_xcursor_manager_load(struct wlr_xcursor_manager *manager,
+ float scale);
+
+/**
+ * Retrieves a wlr_xcursor reference for the given cursor name at the given
+ * scale factor, or NULL if this wlr_xcursor_manager has not loaded a cursor
+ * theme at the requested scale.
+ */
+struct wlr_xcursor *wlr_xcursor_manager_get_xcursor(
+ struct wlr_xcursor_manager *manager, const char *name, float scale);
+
+/**
+ * Set a wlr_cursor's cursor image to the specified cursor name for all scale
+ * factors. wlr_cursor will take over from this point and ensure the correct
+ * cursor is used on each output, assuming a wlr_output_layout is attached to
+ * it.
+ */
+void wlr_xcursor_manager_set_cursor_image(struct wlr_xcursor_manager *manager,
+ const char *name, struct wlr_cursor *cursor);
+
+#endif
diff --git a/include/wlr/types/wlr_xdg_decoration_v1.h b/include/wlr/types/wlr_xdg_decoration_v1.h
new file mode 100644
index 00000000..ba1ad84b
--- /dev/null
+++ b/include/wlr/types/wlr_xdg_decoration_v1.h
@@ -0,0 +1,69 @@
+#ifndef WLR_TYPES_WLR_XDG_DECORATION_V1
+#define WLR_TYPES_WLR_XDG_DECORATION_V1
+
+#include <wayland-server.h>
+#include <wlr/types/wlr_xdg_shell.h>
+
+enum wlr_xdg_toplevel_decoration_v1_mode {
+ WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_NONE = 0,
+ WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE = 1,
+ WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE = 2,
+};
+
+struct wlr_xdg_decoration_manager_v1 {
+ struct wl_global *global;
+ struct wl_list resources;
+ struct wl_list decorations; // wlr_xdg_toplevel_decoration::link
+
+ struct wl_listener display_destroy;
+
+ struct {
+ struct wl_signal new_toplevel_decoration; // struct wlr_xdg_toplevel_decoration *
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_xdg_toplevel_decoration_v1_configure {
+ struct wl_list link; // wlr_xdg_toplevel_decoration::configure_list
+ struct wlr_xdg_surface_configure *surface_configure;
+ enum wlr_xdg_toplevel_decoration_v1_mode mode;
+};
+
+struct wlr_xdg_toplevel_decoration_v1 {
+ struct wl_resource *resource;
+ struct wlr_xdg_surface *surface;
+ struct wlr_xdg_decoration_manager_v1 *manager;
+ struct wl_list link; // wlr_xdg_decoration_manager_v1::link
+
+ bool added;
+ enum wlr_xdg_toplevel_decoration_v1_mode current_mode;
+ enum wlr_xdg_toplevel_decoration_v1_mode client_pending_mode;
+ enum wlr_xdg_toplevel_decoration_v1_mode server_pending_mode;
+
+ struct wl_list configure_list; // wlr_xdg_toplevel_decoration_v1_configure::link
+
+ struct {
+ struct wl_signal destroy;
+ struct wl_signal request_mode;
+ } events;
+
+ struct wl_listener surface_destroy;
+ struct wl_listener surface_configure;
+ struct wl_listener surface_ack_configure;
+ struct wl_listener surface_commit;
+
+ void *data;
+};
+
+struct wlr_xdg_decoration_manager_v1 *
+ wlr_xdg_decoration_manager_v1_create(struct wl_display *display);
+void wlr_xdg_decoration_manager_v1_destroy(
+ struct wlr_xdg_decoration_manager_v1 *manager);
+
+uint32_t wlr_xdg_toplevel_decoration_v1_set_mode(
+ struct wlr_xdg_toplevel_decoration_v1 *decoration,
+ enum wlr_xdg_toplevel_decoration_v1_mode mode);
+
+#endif
diff --git a/include/wlr/types/wlr_xdg_output_v1.h b/include/wlr/types/wlr_xdg_output_v1.h
new file mode 100644
index 00000000..d4279fb9
--- /dev/null
+++ b/include/wlr/types/wlr_xdg_output_v1.h
@@ -0,0 +1,47 @@
+/*
+ * 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_OUTPUT_V1_H
+#define WLR_TYPES_WLR_XDG_OUTPUT_V1_H
+#include <wayland-server.h>
+#include <wlr/types/wlr_output_layout.h>
+
+struct wlr_xdg_output_v1 {
+ struct wlr_xdg_output_manager_v1 *manager;
+ struct wl_list resources;
+ struct wl_list link;
+
+ struct wlr_output_layout_output *layout_output;
+
+ int32_t x, y;
+ int32_t width, height;
+
+ struct wl_listener destroy;
+};
+
+struct wlr_xdg_output_manager_v1 {
+ struct wl_global *global;
+ struct wl_list resources;
+ struct wlr_output_layout *layout;
+
+ struct wl_list outputs;
+
+ struct wl_listener layout_add;
+ struct wl_listener layout_change;
+ struct wl_listener layout_destroy;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+};
+
+struct wlr_xdg_output_manager_v1 *wlr_xdg_output_manager_v1_create(
+ struct wl_display *display, struct wlr_output_layout *layout);
+void wlr_xdg_output_manager_v1_destroy(struct wlr_xdg_output_manager_v1 *manager);
+
+#endif
diff --git a/include/wlr/types/wlr_xdg_shell.h b/include/wlr/types/wlr_xdg_shell.h
new file mode 100644
index 00000000..1bca9ef3
--- /dev/null
+++ b/include/wlr/types/wlr_xdg_shell.h
@@ -0,0 +1,389 @@
+/*
+ * 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_SHELL_H
+#define WLR_TYPES_WLR_XDG_SHELL_H
+#include <wlr/types/wlr_box.h>
+#include <wlr/types/wlr_seat.h>
+#include <wayland-server.h>
+#include "xdg-shell-protocol.h"
+
+struct wlr_xdg_shell {
+ struct wl_global *global;
+ struct wl_list clients;
+ struct wl_list popup_grabs;
+ uint32_t ping_timeout;
+
+ struct wl_listener display_destroy;
+
+ struct {
+ /**
+ * The `new_surface` event signals that a client has requested to
+ * create a new shell surface. At this point, the surface is ready to
+ * be configured but is not mapped or ready receive input events. The
+ * surface will be ready to be managed on the `map` event.
+ */
+ struct wl_signal new_surface;
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_xdg_client {
+ struct wlr_xdg_shell *shell;
+ struct wl_resource *resource;
+ struct wl_client *client;
+ struct wl_list surfaces;
+
+ struct wl_list link; // wlr_xdg_shell::clients
+
+ uint32_t ping_serial;
+ struct wl_event_source *ping_timer;
+};
+
+struct wlr_xdg_positioner {
+ struct wl_resource *resource;
+
+ struct wlr_box anchor_rect;
+ enum xdg_positioner_anchor anchor;
+ enum xdg_positioner_gravity gravity;
+ enum xdg_positioner_constraint_adjustment constraint_adjustment;
+
+ struct {
+ int32_t width, height;
+ } size;
+
+ struct {
+ int32_t x, y;
+ } offset;
+};
+
+struct wlr_xdg_popup {
+ struct wlr_xdg_surface *base;
+ struct wl_list link;
+
+ struct wl_resource *resource;
+ bool committed;
+ struct wlr_surface *parent;
+ struct wlr_seat *seat;
+
+ // Position of the popup relative to the upper left corner of the window
+ // geometry of the parent surface
+ struct wlr_box geometry;
+
+ struct wlr_xdg_positioner positioner;
+
+ struct wl_list grab_link; // wlr_xdg_popup_grab::popups
+};
+
+// each seat gets a popup grab
+struct wlr_xdg_popup_grab {
+ struct wl_client *client;
+ struct wlr_seat_pointer_grab pointer_grab;
+ struct wlr_seat_keyboard_grab keyboard_grab;
+ struct wlr_seat *seat;
+ struct wl_list popups;
+ struct wl_list link; // wlr_xdg_shell::popup_grabs
+ struct wl_listener seat_destroy;
+};
+
+enum wlr_xdg_surface_role {
+ WLR_XDG_SURFACE_ROLE_NONE,
+ WLR_XDG_SURFACE_ROLE_TOPLEVEL,
+ WLR_XDG_SURFACE_ROLE_POPUP,
+};
+
+struct wlr_xdg_toplevel_state {
+ bool maximized, fullscreen, resizing, activated;
+ uint32_t tiled; // enum wlr_edges
+ uint32_t width, height;
+ uint32_t max_width, max_height;
+ uint32_t min_width, min_height;
+};
+
+struct wlr_xdg_toplevel {
+ struct wl_resource *resource;
+ struct wlr_xdg_surface *base;
+ struct wlr_xdg_surface *parent;
+ bool added;
+
+ struct wlr_xdg_toplevel_state client_pending;
+ struct wlr_xdg_toplevel_state server_pending;
+ struct wlr_xdg_toplevel_state current;
+
+ char *title;
+ char *app_id;
+
+ struct {
+ struct wl_signal request_maximize;
+ struct wl_signal request_fullscreen;
+ struct wl_signal request_minimize;
+ struct wl_signal request_move;
+ struct wl_signal request_resize;
+ struct wl_signal request_show_window_menu;
+ struct wl_signal set_parent;
+ struct wl_signal set_title;
+ struct wl_signal set_app_id;
+ } events;
+};
+
+struct wlr_xdg_surface_configure {
+ struct wlr_xdg_surface *surface;
+ struct wl_list link; // wlr_xdg_surface::configure_list
+ uint32_t serial;
+
+ struct wlr_xdg_toplevel_state *toplevel_state;
+};
+
+/**
+ * An xdg-surface is a user interface element requiring management by the
+ * compositor. An xdg-surface alone isn't useful, a role should be assigned to
+ * it in order to map it.
+ *
+ * When a surface has a role and is ready to be displayed, the `map` event is
+ * emitted. When a surface should no longer be displayed, the `unmap` event is
+ * emitted. The `unmap` event is guaranteed to be emitted before the `destroy`
+ * event if the view is destroyed when mapped.
+ */
+struct wlr_xdg_surface {
+ struct wlr_xdg_client *client;
+ struct wl_resource *resource;
+ struct wlr_surface *surface;
+ struct wl_list link; // wlr_xdg_client::surfaces
+ enum wlr_xdg_surface_role role;
+
+ union {
+ struct wlr_xdg_toplevel *toplevel;
+ struct wlr_xdg_popup *popup;
+ };
+
+ struct wl_list popups; // wlr_xdg_popup::link
+
+ bool added, configured, mapped;
+ uint32_t configure_serial;
+ struct wl_event_source *configure_idle;
+ uint32_t configure_next_serial;
+ struct wl_list configure_list;
+
+ bool has_next_geometry;
+ struct wlr_box next_geometry;
+ struct wlr_box geometry;
+
+ struct wl_listener surface_destroy;
+ struct wl_listener surface_commit;
+
+ struct {
+ struct wl_signal destroy;
+ struct wl_signal ping_timeout;
+ struct wl_signal new_popup;
+ /**
+ * The `map` event signals that the shell surface is ready to be
+ * managed by the compositor and rendered on the screen. At this point,
+ * the surface has configured its properties, has had the opportunity
+ * to bind to the seat to receive input events, and has a buffer that
+ * is ready to be rendered. You can now safely add this surface to a
+ * list of views.
+ */
+ struct wl_signal map;
+ /**
+ * The `unmap` event signals that the surface is no longer in a state
+ * where it should be shown on the screen. This might happen if the
+ * surface no longer has a displayable buffer because either the
+ * surface has been hidden or is about to be destroyed.
+ */
+ struct wl_signal unmap;
+
+ // for protocol extensions
+ struct wl_signal configure; // wlr_xdg_surface_configure
+ struct wl_signal ack_configure; // wlr_xdg_surface_configure
+ } events;
+
+ void *data;
+};
+
+struct wlr_xdg_toplevel_move_event {
+ struct wlr_xdg_surface *surface;
+ struct wlr_seat_client *seat;
+ uint32_t serial;
+};
+
+struct wlr_xdg_toplevel_resize_event {
+ struct wlr_xdg_surface *surface;
+ struct wlr_seat_client *seat;
+ uint32_t serial;
+ uint32_t edges;
+};
+
+struct wlr_xdg_toplevel_set_fullscreen_event {
+ struct wlr_xdg_surface *surface;
+ bool fullscreen;
+ struct wlr_output *output;
+};
+
+struct wlr_xdg_toplevel_show_window_menu_event {
+ struct wlr_xdg_surface *surface;
+ struct wlr_seat_client *seat;
+ uint32_t serial;
+ uint32_t x, y;
+};
+
+struct wlr_xdg_shell *wlr_xdg_shell_create(struct wl_display *display);
+void wlr_xdg_shell_destroy(struct wlr_xdg_shell *xdg_shell);
+
+struct wlr_xdg_surface *wlr_xdg_surface_from_resource(
+ struct wl_resource *resource);
+struct wlr_xdg_surface *wlr_xdg_surface_from_popup_resource(
+ struct wl_resource *resource);
+struct wlr_xdg_surface *wlr_xdg_surface_from_toplevel_resource(
+ struct wl_resource *resource);
+
+struct wlr_box wlr_xdg_positioner_get_geometry(
+ struct wlr_xdg_positioner *positioner);
+
+/**
+ * Send a ping to the surface. If the surface does not respond in a reasonable
+ * amount of time, the ping_timeout event will be emitted.
+ */
+void wlr_xdg_surface_ping(struct wlr_xdg_surface *surface);
+
+/**
+ * Request that this toplevel surface be the given size. Returns the associated
+ * configure serial.
+ */
+uint32_t wlr_xdg_toplevel_set_size(struct wlr_xdg_surface *surface,
+ uint32_t width, uint32_t height);
+
+/**
+ * Request that this toplevel surface show itself in an activated or deactivated
+ * state. Returns the associated configure serial.
+ */
+uint32_t wlr_xdg_toplevel_set_activated(struct wlr_xdg_surface *surface,
+ bool activated);
+
+/**
+ * Request that this toplevel surface consider itself maximized or not
+ * maximized. Returns the associated configure serial.
+ */
+uint32_t wlr_xdg_toplevel_set_maximized(struct wlr_xdg_surface *surface,
+ bool maximized);
+
+/**
+ * Request that this toplevel surface consider itself fullscreen or not
+ * fullscreen. Returns the associated configure serial.
+ */
+uint32_t wlr_xdg_toplevel_set_fullscreen(struct wlr_xdg_surface *surface,
+ bool fullscreen);
+
+/**
+ * Request that this toplevel surface consider itself to be resizing or not
+ * resizing. Returns the associated configure serial.
+ */
+uint32_t wlr_xdg_toplevel_set_resizing(struct wlr_xdg_surface *surface,
+ bool resizing);
+
+/**
+ * Request that this toplevel surface consider itself in a tiled layout and some
+ * edges are adjacent to another part of the tiling grid. `tiled_edges` is a
+ * bitfield of `enum wlr_edges`. Returns the associated configure serial.
+ */
+uint32_t wlr_xdg_toplevel_set_tiled(struct wlr_xdg_surface *surface,
+ uint32_t tiled_edges);
+
+/**
+ * Request that this xdg surface closes.
+ */
+void wlr_xdg_surface_send_close(struct wlr_xdg_surface *surface);
+
+/**
+ * Get the geometry for this positioner based on the anchor rect, gravity, and
+ * size of this positioner.
+ */
+struct wlr_box wlr_xdg_positioner_get_geometry(
+ struct wlr_xdg_positioner *positioner);
+
+/**
+ * Get the anchor point for this popup in the toplevel parent's coordinate system.
+ */
+void wlr_xdg_popup_get_anchor_point(struct wlr_xdg_popup *popup,
+ int *toplevel_sx, int *toplevel_sy);
+
+/**
+ * Convert the given coordinates in the popup coordinate system to the toplevel
+ * surface coordinate system.
+ */
+void wlr_xdg_popup_get_toplevel_coords(struct wlr_xdg_popup *popup,
+ int popup_sx, int popup_sy, int *toplevel_sx, int *toplevel_sy);
+
+/**
+ * Set the geometry of this popup to unconstrain it according to its
+ * xdg-positioner rules. The box should be in the popup's root toplevel parent
+ * surface coordinate system.
+ */
+void wlr_xdg_popup_unconstrain_from_box(struct wlr_xdg_popup *popup,
+ struct wlr_box *toplevel_sx_box);
+
+/**
+ Invert the right/left anchor and gravity for this positioner. This can be
+ used to "flip" the positioner around the anchor rect in the x direction.
+ */
+void wlr_positioner_invert_x(struct wlr_xdg_positioner *positioner);
+
+/**
+ Invert the top/bottom anchor and gravity for this positioner. This can be
+ used to "flip" the positioner around the anchor rect in the y direction.
+ */
+void wlr_positioner_invert_y(struct wlr_xdg_positioner *positioner);
+
+/**
+ * Find a surface within this xdg-surface tree at the given surface-local
+ * coordinates. Returns the surface and coordinates in the leaf surface
+ * coordinate system or NULL if no surface is found at that location.
+ */
+struct wlr_surface *wlr_xdg_surface_surface_at(
+ struct wlr_xdg_surface *surface, double sx, double sy,
+ double *sub_x, double *sub_y);
+
+bool wlr_surface_is_xdg_surface(struct wlr_surface *surface);
+
+struct wlr_xdg_surface *wlr_xdg_surface_from_wlr_surface(
+ struct wlr_surface *surface);
+
+/**
+ * Get the surface geometry.
+ * This is either the geometry as set by the client, or defaulted to the bounds
+ * of the surface + the subsurfaces (as specified by the protocol).
+ *
+ * The x and y value can be <0
+ */
+void wlr_xdg_surface_get_geometry(struct wlr_xdg_surface *surface,
+ struct wlr_box *box);
+
+/**
+ * Call `iterator` on each surface and popup in the xdg-surface tree, with the
+ * surface's position relative to the root xdg-surface. The function is called
+ * from root to leaves (in rendering order).
+ */
+void wlr_xdg_surface_for_each_surface(struct wlr_xdg_surface *surface,
+ wlr_surface_iterator_func_t iterator, void *user_data);
+
+/**
+ * Schedule a surface configuration. This should only be called by protocols
+ * extending the shell.
+ */
+uint32_t wlr_xdg_surface_schedule_configure(struct wlr_xdg_surface *surface);
+
+/**
+ * Call `iterator` on each popup in the xdg-surface tree, with the popup's
+ * position relative to the root xdg-surface. The function is called from root
+ * to leaves (in rendering order).
+ */
+void wlr_xdg_surface_for_each_popup(struct wlr_xdg_surface *surface,
+ wlr_surface_iterator_func_t iterator, void *user_data);
+
+#endif
diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h
new file mode 100644
index 00000000..a69e488f
--- /dev/null
+++ b/include/wlr/types/wlr_xdg_shell_v6.h
@@ -0,0 +1,359 @@
+/*
+ * 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_SHELL_V6_H
+#define WLR_TYPES_WLR_XDG_SHELL_V6_H
+
+#include <wayland-server.h>
+#include <wlr/types/wlr_box.h>
+#include <wlr/types/wlr_seat.h>
+#include "xdg-shell-unstable-v6-protocol.h"
+
+struct wlr_xdg_shell_v6 {
+ struct wl_global *global;
+ struct wl_list clients;
+ struct wl_list popup_grabs;
+ uint32_t ping_timeout;
+
+ struct wl_listener display_destroy;
+
+ struct {
+ /**
+ * The `new_surface` event signals that a client has requested to
+ * create a new shell surface. At this point, the surface is ready to
+ * be configured but is not mapped or ready receive input events. The
+ * surface will be ready to be managed on the `map` event.
+ */
+ struct wl_signal new_surface;
+ struct wl_signal destroy;
+ } events;
+
+ void *data;
+};
+
+struct wlr_xdg_client_v6 {
+ struct wlr_xdg_shell_v6 *shell;
+ struct wl_resource *resource;
+ struct wl_client *client;
+ struct wl_list surfaces;
+
+ struct wl_list link; // wlr_xdg_shell_v6::clients
+
+ uint32_t ping_serial;
+ struct wl_event_source *ping_timer;
+};
+
+struct wlr_xdg_positioner_v6 {
+ struct wlr_box anchor_rect;
+ enum zxdg_positioner_v6_anchor anchor;
+ enum zxdg_positioner_v6_gravity gravity;
+ enum zxdg_positioner_v6_constraint_adjustment constraint_adjustment;
+
+ struct {
+ int32_t width, height;
+ } size;
+
+ struct {
+ int32_t x, y;
+ } offset;
+};
+
+struct wlr_xdg_popup_v6 {
+ struct wlr_xdg_surface_v6 *base;
+ struct wl_list link;
+
+ struct wl_resource *resource;
+ bool committed;
+ struct wlr_xdg_surface_v6 *parent;
+ struct wlr_seat *seat;
+
+ // Position of the popup relative to the upper left corner of the window
+ // geometry of the parent surface
+ struct wlr_box geometry;
+
+ struct wlr_xdg_positioner_v6 positioner;
+
+ struct wl_list grab_link; // wlr_xdg_popup_grab_v6::popups
+};
+
+// each seat gets a popup grab
+struct wlr_xdg_popup_grab_v6 {
+ struct wl_client *client;
+ struct wlr_seat_pointer_grab pointer_grab;
+ struct wlr_seat_keyboard_grab keyboard_grab;
+ struct wlr_seat *seat;
+ struct wl_list popups;
+ struct wl_list link; // wlr_xdg_shell_v6::popup_grabs
+ struct wl_listener seat_destroy;
+};
+
+enum wlr_xdg_surface_v6_role {
+ WLR_XDG_SURFACE_V6_ROLE_NONE,
+ WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL,
+ WLR_XDG_SURFACE_V6_ROLE_POPUP,
+};
+
+struct wlr_xdg_toplevel_v6_state {
+ bool maximized, fullscreen, resizing, activated;
+ uint32_t width, height;
+ uint32_t max_width, max_height;
+ uint32_t min_width, min_height;
+};
+
+/**
+ * An xdg-surface is a user interface element requiring management by the
+ * compositor. An xdg-surface alone isn't useful, a role should be assigned to
+ * it in order to map it.
+ *
+ * When a surface has a role and is ready to be displayed, the `map` event is
+ * emitted. When a surface should no longer be displayed, the `unmap` event is
+ * emitted. The `unmap` event is guaranteed to be emitted before the `destroy`
+ * event if the view is destroyed when mapped.
+ */
+struct wlr_xdg_toplevel_v6 {
+ struct wl_resource *resource;
+ struct wlr_xdg_surface_v6 *base;
+ struct wlr_xdg_surface_v6 *parent;
+ bool added;
+
+ struct wlr_xdg_toplevel_v6_state client_pending;
+ struct wlr_xdg_toplevel_v6_state server_pending;
+ struct wlr_xdg_toplevel_v6_state current;
+
+ char *title;
+ char *app_id;
+
+ struct {
+ struct wl_signal request_maximize;
+ struct wl_signal request_fullscreen;
+ struct wl_signal request_minimize;
+ struct wl_signal request_move;
+ struct wl_signal request_resize;
+ struct wl_signal request_show_window_menu;
+ struct wl_signal set_parent;
+ struct wl_signal set_title;
+ struct wl_signal set_app_id;
+ } events;
+};
+
+struct wlr_xdg_surface_v6_configure {
+ struct wl_list link; // wlr_xdg_surface_v6::configure_list
+ uint32_t serial;
+
+ struct wlr_xdg_toplevel_v6_state *toplevel_state;
+};
+
+struct wlr_xdg_surface_v6 {
+ struct wlr_xdg_client_v6 *client;
+ struct wl_resource *resource;
+ struct wlr_surface *surface;
+ struct wl_list link; // wlr_xdg_client_v6::surfaces
+ enum wlr_xdg_surface_v6_role role;
+
+ union {
+ struct wlr_xdg_toplevel_v6 *toplevel;
+ struct wlr_xdg_popup_v6 *popup;
+ };
+
+ struct wl_list popups; // wlr_xdg_popup_v6::link
+
+ bool added, configured, mapped;
+ uint32_t configure_serial;
+ struct wl_event_source *configure_idle;
+ uint32_t configure_next_serial;
+ struct wl_list configure_list;
+
+ bool has_next_geometry;
+ struct wlr_box next_geometry;
+ struct wlr_box geometry;
+
+ struct wl_listener surface_destroy;
+ struct wl_listener surface_commit;
+
+ struct {
+ struct wl_signal destroy;
+ struct wl_signal ping_timeout;
+ struct wl_signal new_popup;
+ /**
+ * The `map` event signals that the shell surface is ready to be
+ * managed by the compositor and rendered on the screen. At this point,
+ * the surface has configured its properties, has had the opportunity
+ * to bind to the seat to receive input events, and has a buffer that
+ * is ready to be rendered. You can now safely add this surface to a
+ * list of views.
+ */
+ struct wl_signal map;
+ /**
+ * The `unmap` event signals that the surface is no longer in a state
+ * where it should be shown on the screen. This might happen if the
+ * surface no longer has a displayable buffer because either the
+ * surface has been hidden or is about to be destroyed.
+ */
+ struct wl_signal unmap;
+ } events;
+
+ void *data;
+};
+
+struct wlr_xdg_toplevel_v6_move_event {
+ struct wlr_xdg_surface_v6 *surface;
+ struct wlr_seat_client *seat;
+ uint32_t serial;
+};
+
+struct wlr_xdg_toplevel_v6_resize_event {
+ struct wlr_xdg_surface_v6 *surface;
+ struct wlr_seat_client *seat;
+ uint32_t serial;
+ uint32_t edges;
+};
+
+struct wlr_xdg_toplevel_v6_set_fullscreen_event {
+ struct wlr_xdg_surface_v6 *surface;
+ bool fullscreen;
+ struct wlr_output *output;
+};
+
+struct wlr_xdg_toplevel_v6_show_window_menu_event {
+ struct wlr_xdg_surface_v6 *surface;
+ struct wlr_seat_client *seat;
+ uint32_t serial;
+ uint32_t x, y;
+};
+
+struct wlr_xdg_shell_v6 *wlr_xdg_shell_v6_create(struct wl_display *display);
+void wlr_xdg_shell_v6_destroy(struct wlr_xdg_shell_v6 *xdg_shell);
+
+/**
+ * Send a ping to the surface. If the surface does not respond in a reasonable
+ * amount of time, the ping_timeout event will be emitted.
+ */
+void wlr_xdg_surface_v6_ping(struct wlr_xdg_surface_v6 *surface);
+
+/**
+ * Request that this toplevel surface be the given size. Returns the associated
+ * configure serial.
+ */
+uint32_t wlr_xdg_toplevel_v6_set_size(struct wlr_xdg_surface_v6 *surface,
+ uint32_t width, uint32_t height);
+
+/**
+ * Request that this toplevel surface show itself in an activated or deactivated
+ * state. Returns the associated configure serial.
+ */
+uint32_t wlr_xdg_toplevel_v6_set_activated(struct wlr_xdg_surface_v6 *surface,
+ bool activated);
+
+/**
+ * Request that this toplevel surface consider itself maximized or not
+ * maximized. Returns the associated configure serial.
+ */
+uint32_t wlr_xdg_toplevel_v6_set_maximized(struct wlr_xdg_surface_v6 *surface,
+ bool maximized);
+
+/**
+ * Request that this toplevel surface consider itself fullscreen or not
+ * fullscreen. Returns the associated configure serial.
+ */
+uint32_t wlr_xdg_toplevel_v6_set_fullscreen(struct wlr_xdg_surface_v6 *surface,
+ bool fullscreen);
+
+/**
+ * Request that this toplevel surface consider itself to be resizing or not
+ * resizing. Returns the associated configure serial.
+ */
+uint32_t wlr_xdg_toplevel_v6_set_resizing(struct wlr_xdg_surface_v6 *surface,
+ bool resizing);
+
+/**
+ * Request that this xdg surface closes.
+ */
+void wlr_xdg_surface_v6_send_close(struct wlr_xdg_surface_v6 *surface);
+
+/**
+ * Find a surface within this xdg-surface tree at the given surface-local
+ * coordinates. Returns the surface and coordinates in the leaf surface
+ * coordinate system or NULL if no surface is found at that location.
+ */
+struct wlr_surface *wlr_xdg_surface_v6_surface_at(
+ struct wlr_xdg_surface_v6 *surface, double sx, double sy,
+ double *sub_x, double *sub_y);
+
+/**
+ * Get the geometry for this positioner based on the anchor rect, gravity, and
+ * size of this positioner.
+ */
+struct wlr_box wlr_xdg_positioner_v6_get_geometry(
+ struct wlr_xdg_positioner_v6 *positioner);
+
+/**
+ * Get the anchor point for this popup in the toplevel parent's coordinate system.
+ */
+void wlr_xdg_popup_v6_get_anchor_point(struct wlr_xdg_popup_v6 *popup,
+ int *toplevel_sx, int *toplevel_sy);
+
+/**
+ * Convert the given coordinates in the popup coordinate system to the toplevel
+ * surface coordinate system.
+ */
+void wlr_xdg_popup_v6_get_toplevel_coords(struct wlr_xdg_popup_v6 *popup,
+ int popup_sx, int popup_sy, int *toplevel_sx, int *toplevel_sy);
+
+/**
+ * Set the geometry of this popup to unconstrain it according to its
+ * xdg-positioner rules. The box should be in the popup's root toplevel parent
+ * surface coordinate system.
+ */
+void wlr_xdg_popup_v6_unconstrain_from_box(struct wlr_xdg_popup_v6 *popup,
+ struct wlr_box *toplevel_sx_box);
+
+/**
+ Invert the right/left anchor and gravity for this positioner. This can be
+ used to "flip" the positioner around the anchor rect in the x direction.
+ */
+void wlr_positioner_v6_invert_x(
+ struct wlr_xdg_positioner_v6 *positioner);
+
+/**
+ Invert the top/bottom anchor and gravity for this positioner. This can be
+ used to "flip" the positioner around the anchor rect in the y direction.
+ */
+void wlr_positioner_v6_invert_y(
+ struct wlr_xdg_positioner_v6 *positioner);
+
+bool wlr_surface_is_xdg_surface_v6(struct wlr_surface *surface);
+
+struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6_from_wlr_surface(
+ struct wlr_surface *surface);
+
+/**
+ * Get the surface geometry.
+ * This is either the geometry as set by the client, or defaulted to the bounds
+ * of the surface + the subsurfaces (as specified by the protocol).
+ *
+ * The x and y value can be <0
+ */
+void wlr_xdg_surface_v6_get_geometry(struct wlr_xdg_surface_v6 *surface, struct wlr_box *box);
+
+/**
+ * Call `iterator` on each surface and popup in the xdg-surface tree, with the
+ * surface's position relative to the root xdg-surface. The function is called
+ * from root to leaves (in rendering order).
+ */
+void wlr_xdg_surface_v6_for_each_surface(struct wlr_xdg_surface_v6 *surface,
+ wlr_surface_iterator_func_t iterator, void *user_data);
+
+/**
+ * Call `iterator` on each popup in the xdg-surface tree, with the popup's
+ * position relative to the root xdg-surface. The function is called from root
+ * to leaves (in rendering order).
+ */
+void wlr_xdg_surface_v6_for_each_popup(struct wlr_xdg_surface_v6 *surface,
+ wlr_surface_iterator_func_t iterator, void *user_data);
+
+#endif
diff --git a/include/wlr/util/edges.h b/include/wlr/util/edges.h
new file mode 100644
index 00000000..bf1eb1e7
--- /dev/null
+++ b/include/wlr/util/edges.h
@@ -0,0 +1,28 @@
+/*
+ * This is a stable interface of wlroots. Future changes will be limited to:
+ *
+ * - New functions
+ * - New struct members
+ * - New enum members
+ *
+ * Note that wlroots does not make an ABI compatibility promise - in the future,
+ * the layout and size of structs used by wlroots may change, requiring code
+ * depending on this header to be recompiled (but not edited).
+ *
+ * Breaking changes are announced by email and follow a 1-year deprecation
+ * schedule. Send an email to ~sircmpwn/wlroots-announce+subscribe@lists.sr.ht
+ * to receive these announcements.
+ */
+
+#ifndef WLR_UTIL_EDGES_H
+#define WLR_UTIL_EDGES_H
+
+enum wlr_edges {
+ WLR_EDGE_NONE = 0,
+ WLR_EDGE_TOP = 1,
+ WLR_EDGE_BOTTOM = 2,
+ WLR_EDGE_LEFT = 4,
+ WLR_EDGE_RIGHT = 8,
+};
+
+#endif
diff --git a/include/wlr/util/log.h b/include/wlr/util/log.h
new file mode 100644
index 00000000..2c441180
--- /dev/null
+++ b/include/wlr/util/log.h
@@ -0,0 +1,64 @@
+/*
+ * This is a stable interface of wlroots. Future changes will be limited to:
+ *
+ * - New functions
+ * - New struct members
+ * - New enum members
+ *
+ * Note that wlroots does not make an ABI compatibility promise - in the future,
+ * the layout and size of structs used by wlroots may change, requiring code
+ * depending on this header to be recompiled (but not edited).
+ *
+ * Breaking changes are announced by email and follow a 1-year deprecation
+ * schedule. Send an email to ~sircmpwn/wlroots-announce+subscribe@lists.sr.ht
+ * to receive these announcements.
+ */
+
+#ifndef WLR_UTIL_LOG_H
+#define WLR_UTIL_LOG_H
+
+#include <stdbool.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+
+enum wlr_log_importance {
+ WLR_SILENT = 0,
+ WLR_ERROR = 1,
+ WLR_INFO = 2,
+ WLR_DEBUG = 3,
+ WLR_LOG_IMPORTANCE_LAST,
+};
+
+typedef void (*wlr_log_func_t)(enum wlr_log_importance importance,
+ const char *fmt, va_list args);
+
+// Will log all messages less than or equal to `verbosity`
+// If `callback` is NULL, wlr will use its default logger.
+// The function can be called multiple times to update the verbosity or
+// callback function.
+void wlr_log_init(enum wlr_log_importance verbosity, wlr_log_func_t callback);
+
+// Returns the log verbosity provided to wlr_log_init
+enum wlr_log_importance wlr_log_get_verbosity(void);
+
+#ifdef __GNUC__
+#define _WLR_ATTRIB_PRINTF(start, end) __attribute__((format(printf, start, end)))
+#else
+#define _WLR_ATTRIB_PRINTF(start, end)
+#endif
+
+void _wlr_log(enum wlr_log_importance verbosity, const char *format, ...) _WLR_ATTRIB_PRINTF(2, 3);
+void _wlr_vlog(enum wlr_log_importance verbosity, const char *format, va_list args) _WLR_ATTRIB_PRINTF(2, 0);
+const char *_wlr_strip_path(const char *filepath);
+
+#define wlr_log(verb, fmt, ...) \
+ _wlr_log(verb, "[%s:%d] " fmt, _wlr_strip_path(__FILE__), __LINE__, ##__VA_ARGS__)
+
+#define wlr_vlog(verb, fmt, args) \
+ _wlr_vlog(verb, "[%s:%d] " fmt, _wlr_strip_path(__FILE__), __LINE__, args)
+
+#define wlr_log_errno(verb, fmt, ...) \
+ wlr_log(verb, fmt ": %s", ##__VA_ARGS__, strerror(errno))
+
+#endif
diff --git a/include/wlr/util/meson.build b/include/wlr/util/meson.build
new file mode 100644
index 00000000..ee72cbd6
--- /dev/null
+++ b/include/wlr/util/meson.build
@@ -0,0 +1,6 @@
+install_headers(
+ 'edges.h',
+ 'log.h',
+ 'region.h',
+ subdir: 'wlr/util',
+)
diff --git a/include/wlr/util/region.h b/include/wlr/util/region.h
new file mode 100644
index 00000000..4aca07e1
--- /dev/null
+++ b/include/wlr/util/region.h
@@ -0,0 +1,56 @@
+/*
+ * This is a stable interface of wlroots. Future changes will be limited to:
+ *
+ * - New functions
+ * - New struct members
+ * - New enum members
+ *
+ * Note that wlroots does not make an ABI compatibility promise - in the future,
+ * the layout and size of structs used by wlroots may change, requiring code
+ * depending on this header to be recompiled (but not edited).
+ *
+ * Breaking changes are announced by email and follow a 1-year deprecation
+ * schedule. Send an email to ~sircmpwn/wlroots-announce+subscribe@lists.sr.ht
+ * to receive these announcements.
+ */
+
+#ifndef WLR_UTIL_REGION_H
+#define WLR_UTIL_REGION_H
+
+#include <stdbool.h>
+#include <pixman.h>
+#include <wayland-server.h>
+
+/**
+ * Scales a region, ie. multiplies all its coordinates by `scale`.
+ *
+ * The resulting coordinates are rounded up or down so that the new region is
+ * at least as big as the original one.
+ */
+void wlr_region_scale(pixman_region32_t *dst, pixman_region32_t *src,
+ float scale);
+
+/**
+ * Applies a transform to a region inside a box of size `width` x `height`.
+ */
+void wlr_region_transform(pixman_region32_t *dst, pixman_region32_t *src,
+ enum wl_output_transform transform, int width, int height);
+
+/**
+ * Expands the region of `distance`. If `distance` is negative, it shrinks the
+ * region.
+ */
+void wlr_region_expand(pixman_region32_t *dst, pixman_region32_t *src,
+ int distance);
+
+/*
+ * Builds the smallest possible region that contains the region rotated about
+ * the point (ox, oy).
+ */
+void wlr_region_rotated_bounds(pixman_region32_t *dst, pixman_region32_t *src,
+ float rotation, int ox, int oy);
+
+bool wlr_region_confine(pixman_region32_t *region, double x1, double y1, double x2,
+ double y2, double *x2_out, double *y2_out);
+
+#endif
diff --git a/include/wlr/version.h.in b/include/wlr/version.h.in
new file mode 100644
index 00000000..cdc0fd75
--- /dev/null
+++ b/include/wlr/version.h.in
@@ -0,0 +1,16 @@
+#ifndef WLR_VERSION_H
+#define WLR_VERSION_H
+
+#mesondefine WLR_VERSION_STR
+
+#mesondefine WLR_VERSION_MAJOR
+#mesondefine WLR_VERSION_MINOR
+#mesondefine WLR_VERSION_MICRO
+
+#define WLR_VERSION_NUM ((WLR_VERSION_MAJOR << 16) | (WLR_VERSION_MINOR << 8) | WLR_VERSION_MICRO)
+
+#mesondefine WLR_VERSION_API_CURRENT
+#mesondefine WLR_VERSION_API_REVISION
+#mesondefine WLR_VERSION_API_AGE
+
+#endif
diff --git a/include/wlr/xcursor.h b/include/wlr/xcursor.h
new file mode 100644
index 00000000..39874f39
--- /dev/null
+++ b/include/wlr/xcursor.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * 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 is a stable interface of wlroots. Future changes will be limited to:
+ *
+ * - New functions
+ * - New struct members
+ * - New enum members
+ *
+ * Note that wlroots does not make an ABI compatibility promise - in the future,
+ * the layout and size of structs used by wlroots may change, requiring code
+ * depending on this header to be recompiled (but not edited).
+ *
+ * Breaking changes are announced by email and follow a 1-year deprecation
+ * schedule. Send an email to ~sircmpwn/wlroots-announce+subscribe@lists.sr.ht
+ * to receive these announcements.
+ */
+
+#ifndef WLR_XCURSOR_H
+#define WLR_XCURSOR_H
+
+#include <stdint.h>
+#include <wlr/util/edges.h>
+
+struct wlr_xcursor_image {
+ uint32_t width; /* actual width */
+ uint32_t height; /* actual height */
+ uint32_t hotspot_x; /* hot spot x (must be inside image) */
+ uint32_t hotspot_y; /* hot spot y (must be inside image) */
+ uint32_t delay; /* animation delay to next frame (ms) */
+ uint8_t *buffer;
+};
+
+struct wlr_xcursor {
+ unsigned int image_count;
+ struct wlr_xcursor_image **images;
+ char *name;
+ uint32_t total_delay; /* length of the animation in ms */
+};
+
+/**
+ * Container for an Xcursor theme.
+ */
+struct wlr_xcursor_theme {
+ unsigned int cursor_count;
+ struct wlr_xcursor **cursors;
+ char *name;
+ int size;
+};
+
+/**
+ * Loads the named xcursor theme at the given cursor size (in pixels). This is
+ * useful if you need cursor images for your compositor to use when a
+ * client-side cursors is not available or you wish to override client-side
+ * cursors for a particular UI interaction (such as using a grab cursor when
+ * moving a window around).
+ */
+struct wlr_xcursor_theme *wlr_xcursor_theme_load(const char *name, int size);
+
+void wlr_xcursor_theme_destroy(struct wlr_xcursor_theme *theme);
+
+/**
+ * Obtains a wlr_xcursor image for the specified cursor name (e.g. "left_ptr").
+ */
+struct wlr_xcursor *wlr_xcursor_theme_get_cursor(
+ struct wlr_xcursor_theme *theme, const char *name);
+
+/**
+ * Returns the current frame number for an animated cursor give a monotonic time
+ * reference.
+ */
+int wlr_xcursor_frame(struct wlr_xcursor *cursor, uint32_t time);
+
+/**
+ * Get the name of the resize cursor image for the given edges.
+ */
+const char *wlr_xcursor_get_resize_name(enum wlr_edges edges);
+
+#endif
diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h
new file mode 100644
index 00000000..40cc8848
--- /dev/null
+++ b/include/wlr/xwayland.h
@@ -0,0 +1,260 @@
+/*
+ * 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_XWAYLAND_H
+#define WLR_XWAYLAND_H
+
+#include <stdbool.h>
+#include <time.h>
+#include <wlr/config.h>
+#include <wlr/types/wlr_compositor.h>
+#include <wlr/types/wlr_seat.h>
+#include <xcb/xcb.h>
+
+struct wlr_xwm;
+struct wlr_xwayland_cursor;
+struct wlr_gtk_primary_selection_device_manager;
+
+struct wlr_xwayland {
+ pid_t pid;
+ struct wl_client *client;
+ struct wl_event_source *sigusr1_source;
+ struct wl_listener client_destroy;
+ struct wlr_xwm *xwm;
+ struct wlr_xwayland_cursor *cursor;
+ int wm_fd[2], wl_fd[2];
+
+ time_t server_start;
+
+ /* Anything above display is reset on Xwayland restart, rest is conserved */
+
+ int display;
+ int x_fd[2];
+ struct wl_event_source *x_fd_read_event[2];
+ struct wl_listener display_destroy;
+
+ bool lazy;
+
+ struct wl_display *wl_display;
+ struct wlr_compositor *compositor;
+ struct wlr_seat *seat;
+
+ struct {
+ struct wl_signal ready;
+ struct wl_signal new_surface;
+ } events;
+
+ struct wl_listener seat_destroy;
+
+ /**
+ * Add a custom event handler to xwayland. Return 1 if the event was
+ * handled or 0 to use the default wlr-xwayland handler. wlr-xwayland will
+ * free the event.
+ */
+ int (*user_event_handler)(struct wlr_xwm *xwm, xcb_generic_event_t *event);
+
+ void *data;
+};
+
+enum wlr_xwayland_surface_decorations {
+ WLR_XWAYLAND_SURFACE_DECORATIONS_ALL = 0,
+ WLR_XWAYLAND_SURFACE_DECORATIONS_NO_BORDER = 1,
+ WLR_XWAYLAND_SURFACE_DECORATIONS_NO_TITLE = 2,
+};
+
+struct wlr_xwayland_surface_hints {
+ uint32_t flags;
+ uint32_t input;
+ int32_t initial_state;
+ xcb_pixmap_t icon_pixmap;
+ xcb_window_t icon_window;
+ int32_t icon_x, icon_y;
+ xcb_pixmap_t icon_mask;
+ xcb_window_t window_group;
+};
+
+struct wlr_xwayland_surface_size_hints {
+ uint32_t flags;
+ int32_t x, y;
+ int32_t width, height;
+ int32_t min_width, min_height;
+ int32_t max_width, max_height;
+ int32_t width_inc, height_inc;
+ int32_t base_width, base_height;
+ int32_t min_aspect_num, min_aspect_den;
+ int32_t max_aspect_num, max_aspect_den;
+ uint32_t win_gravity;
+};
+
+/**
+ * An Xwayland user interface component. It has an absolute position in
+ * layout-local coordinates.
+ *
+ * When a surface is ready to be displayed, the `map` event is emitted. When a
+ * surface should no longer be displayed, the `unmap` event is emitted. The
+ * `unmap` event is guaranteed to be emitted before the `destroy` event if the
+ * view is destroyed when mapped.
+ */
+struct wlr_xwayland_surface {
+ xcb_window_t window_id;
+ struct wlr_xwm *xwm;
+ uint32_t surface_id;
+
+ struct wl_list link;
+ struct wl_list unpaired_link;
+
+ struct wlr_surface *surface;
+ int16_t x, y;
+ uint16_t width, height;
+ uint16_t saved_width, saved_height;
+ bool override_redirect;
+ bool mapped;
+
+ char *title;
+ char *class;
+ char *instance;
+ char *role;
+ pid_t pid;
+ bool has_utf8_title;
+
+ struct wl_list children; // wlr_xwayland_surface::parent_link
+ struct wlr_xwayland_surface *parent;
+ struct wl_list parent_link; // wlr_xwayland_surface::children
+
+ xcb_atom_t *window_type;
+ size_t window_type_len;
+
+ xcb_atom_t *protocols;
+ size_t protocols_len;
+
+ uint32_t decorations;
+ struct wlr_xwayland_surface_hints *hints;
+ uint32_t hints_urgency;
+ struct wlr_xwayland_surface_size_hints *size_hints;
+
+ bool pinging;
+ struct wl_event_source *ping_timer;
+
+ // _NET_WM_STATE
+ bool modal;
+ bool fullscreen;
+ bool maximized_vert, maximized_horz;
+
+ bool has_alpha;
+
+ struct {
+ struct wl_signal destroy;
+ struct wl_signal request_configure;
+ struct wl_signal request_move;
+ struct wl_signal request_resize;
+ struct wl_signal request_maximize;
+ struct wl_signal request_fullscreen;
+ struct wl_signal request_activate;
+
+ struct wl_signal map;
+ struct wl_signal unmap;
+ struct wl_signal set_title;
+ struct wl_signal set_class;
+ struct wl_signal set_role;
+ struct wl_signal set_parent;
+ struct wl_signal set_pid;
+ struct wl_signal set_window_type;
+ struct wl_signal set_hints;
+ struct wl_signal set_decorations;
+ struct wl_signal set_override_redirect;
+ struct wl_signal ping_timeout;
+ } events;
+
+ struct wl_listener surface_destroy;
+
+ void *data;
+};
+
+struct wlr_xwayland_surface_configure_event {
+ struct wlr_xwayland_surface *surface;
+ int16_t x, y;
+ uint16_t width, height;
+};
+
+// TODO: maybe add a seat to these
+struct wlr_xwayland_move_event {
+ struct wlr_xwayland_surface *surface;
+};
+
+struct wlr_xwayland_resize_event {
+ struct wlr_xwayland_surface *surface;
+ uint32_t edges;
+};
+
+/** Create an Xwayland server.
+ *
+ * The server supports a lazy mode in which Xwayland is only started when a
+ * client tries to connect.
+ *
+ * Note: wlr_xwayland will setup a global SIGUSR1 handler on the compositor
+ * process.
+ */
+struct wlr_xwayland *wlr_xwayland_create(struct wl_display *wl_display,
+ struct wlr_compositor *compositor, bool lazy);
+
+void wlr_xwayland_destroy(struct wlr_xwayland *wlr_xwayland);
+
+void wlr_xwayland_set_cursor(struct wlr_xwayland *wlr_xwayland,
+ uint8_t *pixels, uint32_t stride, uint32_t width, uint32_t height,
+ int32_t hotspot_x, int32_t hotspot_y);
+
+void wlr_xwayland_surface_activate(struct wlr_xwayland_surface *surface,
+ bool activated);
+
+void wlr_xwayland_surface_configure(struct wlr_xwayland_surface *surface,
+ int16_t x, int16_t y, uint16_t width, uint16_t height);
+
+void wlr_xwayland_surface_close(struct wlr_xwayland_surface *surface);
+
+void wlr_xwayland_surface_set_maximized(struct wlr_xwayland_surface *surface,
+ bool maximized);
+
+void wlr_xwayland_surface_set_fullscreen(struct wlr_xwayland_surface *surface,
+ bool fullscreen);
+
+void wlr_xwayland_set_seat(struct wlr_xwayland *xwayland,
+ struct wlr_seat *seat);
+
+bool wlr_surface_is_xwayland_surface(struct wlr_surface *surface);
+
+struct wlr_xwayland_surface *wlr_xwayland_surface_from_wlr_surface(
+ struct wlr_surface *surface);
+
+void wlr_xwayland_surface_ping(struct wlr_xwayland_surface *surface);
+
+/** Metric to guess if an OR window should "receive" focus
+ *
+ * In the pure X setups, window managers usually straight up ignore override
+ * redirect windows, and never touch them. (we have to handle them for mapping)
+ *
+ * When such a window wants to receive keyboard input (e.g. rofi/dzen) it will
+ * use mechanics we don't support (sniffing/grabbing input).
+ * [Sadly this is unrelated to xwayland-keyboard-grab]
+ *
+ * To still support these windows, while keeping general OR semantics as is, we
+ * need to hand a subset of windows focus.
+ * The dirty truth is, we need to hand focus to any Xwayland window, though
+ * pretending this window has focus makes it easier to handle unmap.
+ *
+ * This function provides a handy metric based on the window type to guess if
+ * the OR window wants focus.
+ * It's probably not perfect, nor exactly intended but works in practice.
+ *
+ * Returns: true if the window should receive focus
+ * false if it should be ignored
+ */
+bool wlr_xwayland_or_surface_wants_focus(
+ const struct wlr_xwayland_surface *surface);
+
+
+#endif