aboutsummaryrefslogtreecommitdiff
path: root/include/rootston
diff options
context:
space:
mode:
Diffstat (limited to 'include/rootston')
-rw-r--r--include/rootston/bindings.h9
-rw-r--r--include/rootston/config.h133
-rw-r--r--include/rootston/cursor.h105
-rw-r--r--include/rootston/desktop.h119
-rw-r--r--include/rootston/ini.h93
-rw-r--r--include/rootston/input.h37
-rw-r--r--include/rootston/keyboard.h34
-rw-r--r--include/rootston/layers.h35
-rw-r--r--include/rootston/output.h52
-rw-r--r--include/rootston/seat.h181
-rw-r--r--include/rootston/server.h37
-rw-r--r--include/rootston/switch.h18
-rw-r--r--include/rootston/text_input.h63
-rw-r--r--include/rootston/view.h260
-rw-r--r--include/rootston/virtual_keyboard.h7
-rw-r--r--include/rootston/xcursor.h12
16 files changed, 1195 insertions, 0 deletions
diff --git a/include/rootston/bindings.h b/include/rootston/bindings.h
new file mode 100644
index 00000000..db38130b
--- /dev/null
+++ b/include/rootston/bindings.h
@@ -0,0 +1,9 @@
+#ifndef ROOTSTON_BINDINGS_H
+#define ROOTSTON_BINDINGS_H
+
+#include "rootston/seat.h"
+#include "rootston/input.h"
+
+void execute_binding_command(struct roots_seat *seat, struct roots_input *input, const char *command);
+
+#endif //ROOTSTON_BINDINGS_H
diff --git a/include/rootston/config.h b/include/rootston/config.h
new file mode 100644
index 00000000..f8132269
--- /dev/null
+++ b/include/rootston/config.h
@@ -0,0 +1,133 @@
+#ifndef ROOTSTON_CONFIG_H
+#define ROOTSTON_CONFIG_H
+
+#include <xf86drmMode.h>
+#include <wlr/types/wlr_input_device.h>
+#include <wlr/types/wlr_switch.h>
+#include <wlr/types/wlr_output_layout.h>
+
+#define ROOTS_CONFIG_DEFAULT_SEAT_NAME "seat0"
+
+struct roots_output_mode_config {
+ drmModeModeInfo info;
+ struct wl_list link;
+};
+
+struct roots_output_config {
+ char *name;
+ bool enable;
+ enum wl_output_transform transform;
+ int x, y;
+ float scale;
+ struct wl_list link;
+ struct {
+ int width, height;
+ float refresh_rate;
+ } mode;
+ struct wl_list modes;
+};
+
+struct roots_device_config {
+ char *name;
+ char *seat;
+ char *mapped_output;
+ bool tap_enabled;
+ struct wlr_box *mapped_box;
+ struct wl_list link;
+};
+
+struct roots_binding_config {
+ uint32_t modifiers;
+ xkb_keysym_t *keysyms;
+ size_t keysyms_len;
+ char *command;
+ struct wl_list link;
+};
+
+struct roots_keyboard_config {
+ char *name;
+ char *seat;
+ uint32_t meta_key;
+ char *rules;
+ char *model;
+ char *layout;
+ char *variant;
+ char *options;
+ int repeat_rate, repeat_delay;
+ struct wl_list link;
+};
+
+struct roots_cursor_config {
+ char *seat;
+ char *mapped_output;
+ struct wlr_box *mapped_box;
+ char *theme;
+ char *default_image;
+ struct wl_list link;
+};
+
+struct roots_switch_config {
+ char *name;
+ enum wlr_switch_type switch_type;
+ enum wlr_switch_state switch_state;
+ char *command;
+ struct wl_list link;
+};
+
+struct roots_config {
+ bool xwayland;
+ bool xwayland_lazy;
+
+ struct wl_list outputs;
+ struct wl_list devices;
+ struct wl_list bindings;
+ struct wl_list keyboards;
+ struct wl_list cursors;
+ struct wl_list switches;
+
+ char *config_path;
+ char *startup_cmd;
+ bool debug_damage_tracking;
+};
+
+/**
+ * Create a roots config from the given command line arguments. Command line
+ * arguments can specify the location of the config file. If it is not
+ * specified, the default location will be used.
+ */
+struct roots_config *roots_config_create_from_args(int argc, char *argv[]);
+
+/**
+ * Destroy the config and free its resources.
+ */
+void roots_config_destroy(struct roots_config *config);
+
+/**
+ * Get configuration for the output. If the output is not configured, returns
+ * NULL.
+ */
+struct roots_output_config *roots_config_get_output(struct roots_config *config,
+ struct wlr_output *output);
+
+/**
+ * Get configuration for the device. If the device is not configured, returns
+ * NULL.
+ */
+struct roots_device_config *roots_config_get_device(struct roots_config *config,
+ struct wlr_input_device *device);
+
+/**
+ * Get configuration for the keyboard. If the keyboard is not configured,
+ * returns NULL. A NULL device returns the default config for keyboards.
+ */
+struct roots_keyboard_config *roots_config_get_keyboard(
+ struct roots_config *config, struct wlr_input_device *device);
+
+/**
+ * Get configuration for the cursor. If the cursor is not configured, returns
+ * NULL. A NULL seat_name returns the default config for cursors.
+ */
+struct roots_cursor_config *roots_config_get_cursor(struct roots_config *config,
+ const char *seat_name);
+
+#endif
diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h
new file mode 100644
index 00000000..b5bb682f
--- /dev/null
+++ b/include/rootston/cursor.h
@@ -0,0 +1,105 @@
+#ifndef ROOTSTON_CURSOR_H
+#define ROOTSTON_CURSOR_H
+
+#include <wlr/types/wlr_pointer_constraints_v1.h>
+#include "rootston/seat.h"
+
+enum roots_cursor_mode {
+ ROOTS_CURSOR_PASSTHROUGH = 0,
+ ROOTS_CURSOR_MOVE = 1,
+ ROOTS_CURSOR_RESIZE = 2,
+ ROOTS_CURSOR_ROTATE = 3,
+};
+
+struct roots_cursor {
+ struct roots_seat *seat;
+ struct wlr_cursor *cursor;
+
+ struct wlr_pointer_constraint_v1 *active_constraint;
+ pixman_region32_t confine; // invalid if active_constraint == NULL
+
+ const char *default_xcursor;
+
+ enum roots_cursor_mode mode;
+
+ // state from input (review if this is necessary)
+ struct wlr_xcursor_manager *xcursor_manager;
+ struct wlr_seat *wl_seat;
+ struct wl_client *cursor_client;
+ int offs_x, offs_y;
+ int view_x, view_y, view_width, view_height;
+ float view_rotation;
+ uint32_t resize_edges;
+
+ struct roots_seat_view *pointer_view;
+ struct wlr_surface *wlr_surface;
+
+ struct wl_listener motion;
+ struct wl_listener motion_absolute;
+ struct wl_listener button;
+ struct wl_listener axis;
+
+ struct wl_listener touch_down;
+ struct wl_listener touch_up;
+ struct wl_listener touch_motion;
+
+ struct wl_listener tool_axis;
+ struct wl_listener tool_tip;
+ struct wl_listener tool_proximity;
+ struct wl_listener tool_button;
+
+ struct wl_listener request_set_cursor;
+
+ struct wl_listener focus_change;
+
+ struct wl_listener constraint_commit;
+};
+
+struct roots_cursor *roots_cursor_create(struct roots_seat *seat);
+
+void roots_cursor_destroy(struct roots_cursor *cursor);
+
+void roots_cursor_handle_motion(struct roots_cursor *cursor,
+ struct wlr_event_pointer_motion *event);
+
+void roots_cursor_handle_motion_absolute(struct roots_cursor *cursor,
+ struct wlr_event_pointer_motion_absolute *event);
+
+void roots_cursor_handle_button(struct roots_cursor *cursor,
+ struct wlr_event_pointer_button *event);
+
+void roots_cursor_handle_axis(struct roots_cursor *cursor,
+ struct wlr_event_pointer_axis *event);
+
+void roots_cursor_handle_touch_down(struct roots_cursor *cursor,
+ struct wlr_event_touch_down *event);
+
+void roots_cursor_handle_touch_up(struct roots_cursor *cursor,
+ struct wlr_event_touch_up *event);
+
+void roots_cursor_handle_touch_motion(struct roots_cursor *cursor,
+ struct wlr_event_touch_motion *event);
+
+void roots_cursor_handle_tool_axis(struct roots_cursor *cursor,
+ struct wlr_event_tablet_tool_axis *event);
+
+void roots_cursor_handle_tool_tip(struct roots_cursor *cursor,
+ struct wlr_event_tablet_tool_tip *event);
+
+void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor,
+ struct wlr_seat_pointer_request_set_cursor_event *event);
+
+void roots_cursor_handle_focus_change(struct roots_cursor *cursor,
+ struct wlr_seat_pointer_focus_change_event *event);
+
+void roots_cursor_handle_constraint_commit(struct roots_cursor *cursor);
+
+void roots_cursor_update_position(struct roots_cursor *cursor,
+ uint32_t time);
+
+void roots_cursor_update_focus(struct roots_cursor *cursor);
+
+void roots_cursor_constrain(struct roots_cursor *cursor,
+ struct wlr_pointer_constraint_v1 *constraint, double sx, double sy);
+
+#endif
diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h
new file mode 100644
index 00000000..b1fcaca0
--- /dev/null
+++ b/include/rootston/desktop.h
@@ -0,0 +1,119 @@
+#ifndef ROOTSTON_DESKTOP_H
+#define ROOTSTON_DESKTOP_H
+#include <time.h>
+#include <wayland-server.h>
+#include <wlr/config.h>
+#include <wlr/types/wlr_compositor.h>
+#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
+#include <wlr/types/wlr_gamma_control_v1.h>
+#include <wlr/types/wlr_gamma_control.h>
+#include <wlr/types/wlr_idle_inhibit_v1.h>
+#include <wlr/types/wlr_idle.h>
+#include <wlr/types/wlr_input_inhibitor.h>
+#include <wlr/types/wlr_input_method_v2.h>
+#include <wlr/types/wlr_layer_shell_v1.h>
+#include <wlr/types/wlr_list.h>
+#include <wlr/types/wlr_output_layout.h>
+#include <wlr/types/wlr_output.h>
+#include <wlr/types/wlr_presentation_time.h>
+#include <wlr/types/wlr_gtk_primary_selection.h>
+#include <wlr/types/wlr_screencopy_v1.h>
+#include <wlr/types/wlr_screenshooter.h>
+#include <wlr/types/wlr_text_input_v3.h>
+#include <wlr/types/wlr_virtual_keyboard_v1.h>
+#include <wlr/types/wlr_wl_shell.h>
+#include <wlr/types/wlr_xcursor_manager.h>
+#include <wlr/types/wlr_xdg_decoration_v1.h>
+#include <wlr/types/wlr_xdg_shell_v6.h>
+#include <wlr/types/wlr_xdg_shell.h>
+#include "rootston/config.h"
+#include "rootston/output.h"
+#include "rootston/view.h"
+
+struct roots_desktop {
+ struct wl_list views; // roots_view::link
+
+ struct wl_list outputs; // roots_output::link
+ struct timespec last_frame;
+
+ struct roots_server *server;
+ struct roots_config *config;
+
+ struct wlr_output_layout *layout;
+ struct wlr_xcursor_manager *xcursor_manager;
+
+ struct wlr_compositor *compositor;
+ struct wlr_wl_shell *wl_shell;
+ struct wlr_xdg_shell_v6 *xdg_shell_v6;
+ struct wlr_xdg_shell *xdg_shell;
+ struct wlr_gamma_control_manager *gamma_control_manager;
+ struct wlr_gamma_control_manager_v1 *gamma_control_manager_v1;
+ struct wlr_screenshooter *screenshooter;
+ struct wlr_export_dmabuf_manager_v1 *export_dmabuf_manager_v1;
+ struct wlr_server_decoration_manager *server_decoration_manager;
+ struct wlr_xdg_decoration_manager_v1 *xdg_decoration_manager;
+ struct wlr_gtk_primary_selection_device_manager *primary_selection_device_manager;
+ struct wlr_idle *idle;
+ struct wlr_idle_inhibit_manager_v1 *idle_inhibit;
+ struct wlr_input_inhibit_manager *input_inhibit;
+ struct wlr_layer_shell_v1 *layer_shell;
+ struct wlr_input_method_manager_v2 *input_method;
+ struct wlr_text_input_manager_v3 *text_input;
+ struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard;
+ struct wlr_screencopy_manager_v1 *screencopy;
+ struct wlr_tablet_manager_v2 *tablet_v2;
+ struct wlr_pointer_constraints_v1 *pointer_constraints;
+ struct wlr_presentation *presentation;
+ struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager_v1;
+
+ struct wl_listener new_output;
+ struct wl_listener layout_change;
+ struct wl_listener xdg_shell_v6_surface;
+ struct wl_listener xdg_shell_surface;
+ struct wl_listener wl_shell_surface;
+ struct wl_listener layer_shell_surface;
+ struct wl_listener xdg_toplevel_decoration;
+ struct wl_listener input_inhibit_activate;
+ struct wl_listener input_inhibit_deactivate;
+ struct wl_listener virtual_keyboard_new;
+ struct wl_listener pointer_constraint;
+
+#if WLR_HAS_XWAYLAND
+ struct wlr_xwayland *xwayland;
+ struct wl_listener xwayland_surface;
+#endif
+};
+
+struct roots_server;
+
+struct roots_desktop *desktop_create(struct roots_server *server,
+ struct roots_config *config);
+void desktop_destroy(struct roots_desktop *desktop);
+struct roots_output *desktop_output_from_wlr_output(
+ struct roots_desktop *desktop, struct wlr_output *output);
+
+struct wlr_surface *desktop_surface_at(struct roots_desktop *desktop,
+ double lx, double ly, double *sx, double *sy,
+ struct roots_view **view);
+
+struct roots_view *view_create(struct roots_desktop *desktop);
+void view_destroy(struct roots_view *view);
+void view_activate(struct roots_view *view, bool activate);
+void view_apply_damage(struct roots_view *view);
+void view_damage_whole(struct roots_view *view);
+void view_update_position(struct roots_view *view, int x, int y);
+void view_update_size(struct roots_view *view, int width, int height);
+void view_update_decorated(struct roots_view *view, bool decorated);
+void view_initial_focus(struct roots_view *view);
+void view_map(struct roots_view *view, struct wlr_surface *surface);
+void view_unmap(struct roots_view *view);
+void view_arrange_maximized(struct roots_view *view);
+
+void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data);
+void handle_xdg_shell_surface(struct wl_listener *listener, void *data);
+void handle_xdg_toplevel_decoration(struct wl_listener *listener, void *data);
+void handle_wl_shell_surface(struct wl_listener *listener, void *data);
+void handle_layer_shell_surface(struct wl_listener *listener, void *data);
+void handle_xwayland_surface(struct wl_listener *listener, void *data);
+
+#endif
diff --git a/include/rootston/ini.h b/include/rootston/ini.h
new file mode 100644
index 00000000..2804255b
--- /dev/null
+++ b/include/rootston/ini.h
@@ -0,0 +1,93 @@
+/* inih -- simple .INI file parser
+
+inih is released under the New BSD license (see LICENSE.txt). Go to the project
+home page for more info:
+
+https://github.com/benhoyt/inih
+
+*/
+
+#ifndef __INI_H__
+#define __INI_H__
+
+/* Make this header file easier to include in C++ code */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+
+/* Typedef for prototype of handler function. */
+typedef int (*ini_handler)(void* user, const char* section,
+ const char* name, const char* value);
+
+/* Typedef for prototype of fgets-style reader function. */
+typedef char* (*ini_reader)(char* str, int num, void* stream);
+
+/* Parse given INI-style file. May have [section]s, name=value pairs
+ (whitespace stripped), and comments starting with ';' (semicolon). Section
+ is "" if name=value pair parsed before any section heading. name:value
+ pairs are also supported as a concession to Python's configparser.
+
+ For each name=value pair parsed, call handler function with given user
+ pointer as well as section, name, and value (data only valid for duration
+ of handler call). Handler should return nonzero on success, zero on error.
+
+ Returns 0 on success, line number of first error on parse error (doesn't
+ stop on first error), -1 on file open error, or -2 on memory allocation
+ error (only when INI_USE_STACK is zero).
+*/
+int ini_parse(const char* filename, ini_handler handler, void* user);
+
+/* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't
+ close the file when it's finished -- the caller must do that. */
+int ini_parse_file(FILE* file, ini_handler handler, void* user);
+
+/* Same as ini_parse(), but takes an ini_reader function pointer instead of
+ filename. Used for implementing custom or string-based I/O. */
+int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
+ void* user);
+
+/* Nonzero to allow multi-line value parsing, in the style of Python's
+ configparser. If allowed, ini_parse() will call the handler with the same
+ name for each subsequent line parsed. */
+#ifndef INI_ALLOW_MULTILINE
+#define INI_ALLOW_MULTILINE 1
+#endif
+
+/* Nonzero to allow a UTF-8 BOM sequence (0xEF 0xBB 0xBF) at the start of
+ the file. See http://code.google.com/p/inih/issues/detail?id=21 */
+#ifndef INI_ALLOW_BOM
+#define INI_ALLOW_BOM 1
+#endif
+
+/* Nonzero to allow inline comments (with valid inline comment characters
+ specified by INI_INLINE_COMMENT_PREFIXES). Set to 0 to turn off and match
+ Python 3.2+ configparser behaviour. */
+#ifndef INI_ALLOW_INLINE_COMMENTS
+#define INI_ALLOW_INLINE_COMMENTS 1
+#endif
+#ifndef INI_INLINE_COMMENT_PREFIXES
+#define INI_INLINE_COMMENT_PREFIXES ";"
+#endif
+
+/* Nonzero to use stack, zero to use heap (malloc/free). */
+#ifndef INI_USE_STACK
+#define INI_USE_STACK 1
+#endif
+
+/* Stop parsing on first error (default is to keep parsing). */
+#ifndef INI_STOP_ON_FIRST_ERROR
+#define INI_STOP_ON_FIRST_ERROR 0
+#endif
+
+/* Maximum line length for any line in INI file. */
+#ifndef INI_MAX_LINE
+#define INI_MAX_LINE 2000
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INI_H__ */
diff --git a/include/rootston/input.h b/include/rootston/input.h
new file mode 100644
index 00000000..31810b4d
--- /dev/null
+++ b/include/rootston/input.h
@@ -0,0 +1,37 @@
+#ifndef ROOTSTON_INPUT_H
+#define ROOTSTON_INPUT_H
+
+#include <wayland-server.h>
+#include <wlr/types/wlr_cursor.h>
+#include <wlr/types/wlr_input_device.h>
+#include <wlr/types/wlr_seat.h>
+#include "rootston/config.h"
+#include "rootston/cursor.h"
+#include "rootston/server.h"
+#include "rootston/view.h"
+
+struct roots_input {
+ struct roots_config *config;
+ struct roots_server *server;
+
+ struct wl_listener new_input;
+
+ struct wl_list seats; // roots_seat::link
+};
+
+struct roots_input *input_create(struct roots_server *server,
+ struct roots_config *config);
+void input_destroy(struct roots_input *input);
+
+struct roots_seat *input_seat_from_wlr_seat(struct roots_input *input,
+ struct wlr_seat *seat);
+
+bool input_view_has_focus(struct roots_input *input, struct roots_view *view);
+
+struct roots_seat *input_get_seat(struct roots_input *input, char *name);
+
+struct roots_seat *input_last_active_seat(struct roots_input *input);
+
+void input_update_cursor_focus(struct roots_input *input);
+
+#endif
diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h
new file mode 100644
index 00000000..0140389a
--- /dev/null
+++ b/include/rootston/keyboard.h
@@ -0,0 +1,34 @@
+#ifndef ROOTSTON_KEYBOARD_H
+#define ROOTSTON_KEYBOARD_H
+
+#include <xkbcommon/xkbcommon.h>
+#include "rootston/input.h"
+
+#define ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP 32
+
+struct roots_keyboard {
+ struct roots_input *input;
+ struct roots_seat *seat;
+ struct wlr_input_device *device;
+ struct roots_keyboard_config *config;
+ struct wl_list link;
+
+ struct wl_listener device_destroy;
+ struct wl_listener keyboard_key;
+ struct wl_listener keyboard_modifiers;
+
+ xkb_keysym_t pressed_keysyms_translated[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP];
+ xkb_keysym_t pressed_keysyms_raw[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP];
+};
+
+struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device,
+ struct roots_input *input);
+
+void roots_keyboard_destroy(struct roots_keyboard *keyboard);
+
+void roots_keyboard_handle_key(struct roots_keyboard *keyboard,
+ struct wlr_event_keyboard_key *event);
+
+void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard);
+
+#endif
diff --git a/include/rootston/layers.h b/include/rootston/layers.h
new file mode 100644
index 00000000..0dacf20f
--- /dev/null
+++ b/include/rootston/layers.h
@@ -0,0 +1,35 @@
+#ifndef ROOTSTON_LAYERS_H
+#define ROOTSTON_LAYERS_H
+#include <stdbool.h>
+#include <wlr/types/wlr_box.h>
+#include <wlr/types/wlr_surface.h>
+#include <wlr/types/wlr_layer_shell_v1.h>
+
+struct roots_layer_surface {
+ struct wlr_layer_surface_v1 *layer_surface;
+ struct wl_list link;
+
+ struct wl_listener destroy;
+ struct wl_listener map;
+ struct wl_listener unmap;
+ struct wl_listener surface_commit;
+ struct wl_listener output_destroy;
+ struct wl_listener new_popup;
+
+ bool configured;
+ struct wlr_box geo;
+};
+
+struct roots_layer_popup {
+ struct roots_layer_surface *parent;
+ struct wlr_xdg_popup *wlr_popup;
+ struct wl_listener map;
+ struct wl_listener unmap;
+ struct wl_listener destroy;
+ struct wl_listener commit;
+};
+
+struct roots_output;
+void arrange_layers(struct roots_output *output);
+
+#endif
diff --git a/include/rootston/output.h b/include/rootston/output.h
new file mode 100644
index 00000000..3f07ab6f
--- /dev/null
+++ b/include/rootston/output.h
@@ -0,0 +1,52 @@
+#ifndef ROOTSTON_OUTPUT_H
+#define ROOTSTON_OUTPUT_H
+#include <pixman.h>
+#include <time.h>
+#include <wayland-server.h>
+#include <wlr/types/wlr_box.h>
+#include <wlr/types/wlr_output_damage.h>
+
+struct roots_desktop;
+
+struct roots_output {
+ struct roots_desktop *desktop;
+ struct wlr_output *wlr_output;
+ struct wl_list link; // roots_desktop:outputs
+
+ struct roots_view *fullscreen_view;
+ struct wl_list layers[4]; // layer_surface::link
+
+ struct timespec last_frame;
+ struct wlr_output_damage *damage;
+
+ struct wlr_box usable_area;
+
+ struct wl_listener destroy;
+ struct wl_listener mode;
+ struct wl_listener transform;
+ struct wl_listener present;
+ struct wl_listener damage_frame;
+ struct wl_listener damage_destroy;
+};
+
+void rotate_child_position(double *sx, double *sy, double sw, double sh,
+ double pw, double ph, float rotation);
+
+void handle_new_output(struct wl_listener *listener, void *data);
+
+struct roots_view;
+struct roots_drag_icon;
+
+void output_damage_whole(struct roots_output *output);
+void output_damage_whole_view(struct roots_output *output,
+ struct roots_view *view);
+void output_damage_from_view(struct roots_output *output,
+ struct roots_view *view);
+void output_damage_whole_drag_icon(struct roots_output *output,
+ struct roots_drag_icon *icon);
+void output_damage_from_local_surface(struct roots_output *output,
+ struct wlr_surface *surface, double ox, double oy, float rotation);
+void output_damage_whole_local_surface(struct roots_output *output,
+ struct wlr_surface *surface, double ox, double oy, float rotation);
+
+#endif
diff --git a/include/rootston/seat.h b/include/rootston/seat.h
new file mode 100644
index 00000000..105ba3aa
--- /dev/null
+++ b/include/rootston/seat.h
@@ -0,0 +1,181 @@
+#ifndef ROOTSTON_SEAT_H
+#define ROOTSTON_SEAT_H
+
+#include <wayland-server.h>
+#include "rootston/input.h"
+#include "rootston/keyboard.h"
+#include "rootston/layers.h"
+#include "rootston/switch.h"
+#include "rootston/text_input.h"
+
+struct roots_seat {
+ struct roots_input *input;
+ struct wlr_seat *seat;
+ struct roots_cursor *cursor;
+ struct wl_list link; // roots_input::seats
+
+ // coordinates of the first touch point if it exists
+ int32_t touch_id;
+ double touch_x, touch_y;
+
+ // If the focused layer is set, views cannot receive keyboard focus
+ struct wlr_layer_surface_v1 *focused_layer;
+
+ struct roots_input_method_relay im_relay;
+
+ // If non-null, only this client can receive input events
+ struct wl_client *exclusive_client;
+
+ struct wl_list views; // roots_seat_view::link
+ bool has_focus;
+
+ struct wl_list drag_icons; // roots_drag_icon::link
+
+ struct wl_list keyboards;
+ struct wl_list pointers;
+ struct wl_list switches;
+ struct wl_list touch;
+ struct wl_list tablets;
+ struct wl_list tablet_pads;
+
+ struct wl_listener new_drag_icon;
+ struct wl_listener destroy;
+};
+
+struct roots_seat_view {
+ struct roots_seat *seat;
+ struct roots_view *view;
+
+ bool has_button_grab;
+ double grab_sx;
+ double grab_sy;
+
+ struct wl_list link; // roots_seat::views
+
+ struct wl_listener view_unmap;
+ struct wl_listener view_destroy;
+};
+
+struct roots_drag_icon {
+ struct roots_seat *seat;
+ struct wlr_drag_icon *wlr_drag_icon;
+ struct wl_list link;
+
+ double x, y;
+
+ struct wl_listener surface_commit;
+ struct wl_listener map;
+ struct wl_listener unmap;
+ struct wl_listener destroy;
+};
+
+struct roots_pointer {
+ struct roots_seat *seat;
+ struct wlr_input_device *device;
+ struct wl_listener device_destroy;
+ struct wl_list link;
+};
+
+struct roots_touch {
+ struct roots_seat *seat;
+ struct wlr_input_device *device;
+ struct wl_listener device_destroy;
+ struct wl_list link;
+};
+
+struct roots_tablet {
+ struct roots_seat *seat;
+ struct wlr_input_device *device;
+ struct wlr_tablet_v2_tablet *tablet_v2;
+
+ struct wl_listener device_destroy;
+ struct wl_listener axis;
+ struct wl_listener proximity;
+ struct wl_listener tip;
+ struct wl_listener button;
+ struct wl_list link;
+};
+
+struct roots_tablet_pad {
+ struct wl_list link;
+ struct wlr_tablet_v2_tablet_pad *tablet_v2_pad;
+
+ struct roots_seat *seat;
+ struct wlr_input_device *device;
+
+ struct wl_listener device_destroy;
+ struct wl_listener attach;
+ struct wl_listener button;
+ struct wl_listener ring;
+ struct wl_listener strip;
+
+ struct roots_tablet *tablet;
+ struct wl_listener tablet_destroy;
+};
+
+struct roots_tablet_tool {
+ struct wl_list link;
+ struct wl_list tool_link;
+ struct wlr_tablet_v2_tablet_tool *tablet_v2_tool;
+
+ struct roots_seat *seat;
+ double tilt_x, tilt_y;
+
+ struct wl_listener set_cursor;
+ struct wl_listener tool_destroy;
+
+ struct roots_tablet *current_tablet;
+ struct wl_listener tablet_destroy;
+};
+
+struct roots_pointer_constraint {
+ struct wlr_pointer_constraint_v1 *constraint;
+
+ struct wl_listener destroy;
+};
+
+struct roots_seat *roots_seat_create(struct roots_input *input, char *name);
+
+void roots_seat_destroy(struct roots_seat *seat);
+
+void roots_seat_add_device(struct roots_seat *seat,
+ struct wlr_input_device *device);
+
+void roots_seat_configure_cursor(struct roots_seat *seat);
+
+void roots_seat_configure_xcursor(struct roots_seat *seat);
+
+bool roots_seat_has_meta_pressed(struct roots_seat *seat);
+
+struct roots_view *roots_seat_get_focus(struct roots_seat *seat);
+
+void roots_seat_set_focus(struct roots_seat *seat, struct roots_view *view);
+
+void roots_seat_set_focus_layer(struct roots_seat *seat,
+ struct wlr_layer_surface_v1 *layer);
+
+void roots_seat_cycle_focus(struct roots_seat *seat);
+
+void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view);
+
+void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view,
+ uint32_t edges);
+
+void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view);
+
+void roots_seat_end_compositor_grab(struct roots_seat *seat);
+
+struct roots_seat_view *roots_seat_view_from_view( struct roots_seat *seat,
+ struct roots_view *view);
+
+void roots_drag_icon_update_position(struct roots_drag_icon *icon);
+
+void roots_drag_icon_damage_whole(struct roots_drag_icon *icon);
+
+void roots_seat_set_exclusive_client(struct roots_seat *seat,
+ struct wl_client *client);
+
+bool roots_seat_allow_input(struct roots_seat *seat,
+ struct wl_resource *resource);
+
+#endif
diff --git a/include/rootston/server.h b/include/rootston/server.h
new file mode 100644
index 00000000..1836a374
--- /dev/null
+++ b/include/rootston/server.h
@@ -0,0 +1,37 @@
+#ifndef _ROOTSTON_SERVER_H
+#define _ROOTSTON_SERVER_H
+
+#include <wayland-server.h>
+#include <wlr/backend.h>
+#include <wlr/backend/session.h>
+#include <wlr/config.h>
+#include <wlr/render/wlr_renderer.h>
+#include <wlr/types/wlr_data_device.h>
+#if WLR_HAS_XWAYLAND
+#include <wlr/xwayland.h>
+#endif
+#include "rootston/config.h"
+#include "rootston/desktop.h"
+#include "rootston/input.h"
+
+struct roots_server {
+ /* Rootston resources */
+ struct roots_config *config;
+ struct roots_desktop *desktop;
+ struct roots_input *input;
+
+ /* Wayland resources */
+ struct wl_display *wl_display;
+ struct wl_event_loop *wl_event_loop;
+
+ /* WLR tools */
+ struct wlr_backend *backend;
+ struct wlr_renderer *renderer;
+
+ /* Global resources */
+ struct wlr_data_device_manager *data_device_manager;
+};
+
+extern struct roots_server server;
+
+#endif
diff --git a/include/rootston/switch.h b/include/rootston/switch.h
new file mode 100644
index 00000000..28197774
--- /dev/null
+++ b/include/rootston/switch.h
@@ -0,0 +1,18 @@
+#ifndef ROOTSTON_SWITCH_H
+#define ROOTSTON_SWITCH_H
+
+#include "rootston/input.h"
+
+struct roots_switch {
+ struct roots_seat *seat;
+ struct wlr_input_device *device;
+ struct wl_listener device_destroy;
+
+ struct wl_listener toggle;
+ struct wl_list link;
+};
+
+void roots_switch_handle_toggle(struct roots_switch *lid_switch,
+ struct wlr_event_switch_toggle *event);
+
+#endif // ROOTSTON_SWITCH_H
diff --git a/include/rootston/text_input.h b/include/rootston/text_input.h
new file mode 100644
index 00000000..82e45e3e
--- /dev/null
+++ b/include/rootston/text_input.h
@@ -0,0 +1,63 @@
+#ifndef ROOTSTON_TEXT_INPUT_H
+#define ROOTSTON_TEXT_INPUT_H
+
+#include <wlr/types/wlr_text_input_v3.h>
+#include <wlr/types/wlr_input_method_v2.h>
+#include <wlr/types/wlr_surface.h>
+#include "rootston/seat.h"
+
+/**
+ * The relay structure manages the relationship between text-input and
+ * input_method interfaces on a given seat. Multiple text-input interfaces may
+ * be bound to a relay, but at most one will be focused (reveiving events) at
+ * a time. At most one input-method interface may be bound to the seat. The
+ * relay manages life cycle of both sides. When both sides are present and
+ * focused, the relay passes messages between them.
+ *
+ * Text input focus is a subset of keyboard focus - if the text-input is
+ * in the focused state, wl_keyboard sent an enter as well. However, having
+ * wl_keyboard focused doesn't mean that text-input will be focused.
+ */
+struct roots_input_method_relay {
+ struct roots_seat *seat;
+
+ struct wl_list text_inputs; // roots_text_input::link
+ struct wlr_input_method_v2 *input_method; // doesn't have to be present
+
+ struct wl_listener text_input_new;
+ struct wl_listener text_input_enable;
+ struct wl_listener text_input_commit;
+ struct wl_listener text_input_disable;
+ struct wl_listener text_input_destroy;
+
+ struct wl_listener input_method_new;
+ struct wl_listener input_method_commit;
+ struct wl_listener input_method_destroy;
+};
+
+struct roots_text_input {
+ struct roots_input_method_relay *relay;
+
+ struct wlr_text_input_v3 *input;
+ // The surface getting seat's focus. Stored for when text-input cannot
+ // be sent an enter event immediately after getting focus, e.g. when
+ // there's no input method available. Cleared once text-input is entered.
+ struct wlr_surface *pending_focused_surface;
+
+ struct wl_list link;
+
+ struct wl_listener pending_focused_surface_destroy;
+};
+
+void roots_input_method_relay_init(struct roots_seat *seat,
+ struct roots_input_method_relay *relay);
+
+// Updates currently focused surface. Surface must belong to the same seat.
+void roots_input_method_relay_set_focus(struct roots_input_method_relay *relay,
+ struct wlr_surface *surface);
+
+struct roots_text_input *roots_text_input_create(
+ struct roots_input_method_relay *relay,
+ struct wlr_text_input_v3 *text_input);
+
+#endif
diff --git a/include/rootston/view.h b/include/rootston/view.h
new file mode 100644
index 00000000..b1feb5ce
--- /dev/null
+++ b/include/rootston/view.h
@@ -0,0 +1,260 @@
+#ifndef ROOTSTON_VIEW_H
+#define ROOTSTON_VIEW_H
+#include <stdbool.h>
+#include <wlr/config.h>
+#include <wlr/types/wlr_box.h>
+#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
+#include <wlr/types/wlr_surface.h>
+#include <wlr/types/wlr_xdg_decoration_v1.h>
+#include <wlr/types/wlr_xdg_shell_v6.h>
+#include <wlr/types/wlr_xdg_shell.h>
+
+struct roots_wl_shell_surface {
+ struct roots_view *view;
+
+ struct wl_listener destroy;
+ struct wl_listener new_popup;
+ struct wl_listener request_move;
+ struct wl_listener request_resize;
+ struct wl_listener request_maximize;
+ struct wl_listener request_fullscreen;
+ struct wl_listener set_state;
+ struct wl_listener set_title;
+ struct wl_listener set_class;
+
+ struct wl_listener surface_commit;
+};
+
+struct roots_xdg_surface_v6 {
+ struct roots_view *view;
+
+ struct wl_listener destroy;
+ struct wl_listener new_popup;
+ struct wl_listener map;
+ struct wl_listener unmap;
+ struct wl_listener request_move;
+ struct wl_listener request_resize;
+ struct wl_listener request_maximize;
+ struct wl_listener request_fullscreen;
+ struct wl_listener set_title;
+ struct wl_listener set_app_id;
+
+ struct wl_listener surface_commit;
+
+ uint32_t pending_move_resize_configure_serial;
+};
+
+struct roots_xdg_toplevel_decoration;
+
+struct roots_xdg_surface {
+ struct roots_view *view;
+
+ struct wl_listener destroy;
+ struct wl_listener new_popup;
+ struct wl_listener map;
+ struct wl_listener unmap;
+ struct wl_listener request_move;
+ struct wl_listener request_resize;
+ struct wl_listener request_maximize;
+ struct wl_listener request_fullscreen;
+ struct wl_listener set_title;
+ struct wl_listener set_app_id;
+
+
+ struct wl_listener surface_commit;
+
+ uint32_t pending_move_resize_configure_serial;
+
+ struct roots_xdg_toplevel_decoration *xdg_toplevel_decoration;
+};
+
+struct roots_xwayland_surface {
+ struct roots_view *view;
+
+ struct wl_listener destroy;
+ struct wl_listener request_configure;
+ struct wl_listener request_move;
+ struct wl_listener request_resize;
+ struct wl_listener request_maximize;
+ struct wl_listener request_fullscreen;
+ struct wl_listener map;
+ struct wl_listener unmap;
+ struct wl_listener set_title;
+ struct wl_listener set_class;
+
+ struct wl_listener surface_commit;
+};
+
+enum roots_view_type {
+ ROOTS_WL_SHELL_VIEW,
+ ROOTS_XDG_SHELL_V6_VIEW,
+ ROOTS_XDG_SHELL_VIEW,
+#if WLR_HAS_XWAYLAND
+ ROOTS_XWAYLAND_VIEW,
+#endif
+};
+
+struct roots_view {
+ struct roots_desktop *desktop;
+ struct wl_list link; // roots_desktop::views
+
+ struct wlr_box box;
+ float rotation;
+ float alpha;
+
+ bool decorated;
+ int border_width;
+ int titlebar_height;
+
+ bool maximized;
+ struct roots_output *fullscreen_output;
+ struct {
+ double x, y;
+ uint32_t width, height;
+ float rotation;
+ } saved;
+
+ struct {
+ bool update_x, update_y;
+ double x, y;
+ uint32_t width, height;
+ } pending_move_resize;
+
+ // TODO: Something for roots-enforced width/height
+ enum roots_view_type type;
+ union {
+ struct wlr_wl_shell_surface *wl_shell_surface;
+ struct wlr_xdg_surface_v6 *xdg_surface_v6;
+ struct wlr_xdg_surface *xdg_surface;
+#if WLR_HAS_XWAYLAND
+ struct wlr_xwayland_surface *xwayland_surface;
+#endif
+ };
+ union {
+ struct roots_wl_shell_surface *roots_wl_shell_surface;
+ struct roots_xdg_surface_v6 *roots_xdg_surface_v6;
+ struct roots_xdg_surface *roots_xdg_surface;
+#if WLR_HAS_XWAYLAND
+ struct roots_xwayland_surface *roots_xwayland_surface;
+#endif
+ };
+
+ struct wlr_surface *wlr_surface;
+ struct wl_list children; // roots_view_child::link
+
+ struct wlr_foreign_toplevel_handle_v1 *toplevel_handle;
+ struct wl_listener toplevel_handle_request_maximize;
+ struct wl_listener toplevel_handle_request_activate;
+ struct wl_listener toplevel_handle_request_close;
+
+ struct wl_listener new_subsurface;
+
+ struct {
+ struct wl_signal unmap;
+ struct wl_signal destroy;
+ } events;
+
+ // TODO: this should follow the typical type/impl pattern we use elsewhere
+ void (*activate)(struct roots_view *view, bool active);
+ void (*move)(struct roots_view *view, double x, double y);
+ void (*resize)(struct roots_view *view, uint32_t width, uint32_t height);
+ void (*move_resize)(struct roots_view *view, double x, double y,
+ uint32_t width, uint32_t height);
+ void (*maximize)(struct roots_view *view, bool maximized);
+ void (*set_fullscreen)(struct roots_view *view, bool fullscreen);
+ void (*close)(struct roots_view *view);
+ void (*destroy)(struct roots_view *view);
+};
+
+struct roots_view_child {
+ struct roots_view *view;
+ struct wlr_surface *wlr_surface;
+ struct wl_list link;
+
+ struct wl_listener commit;
+ struct wl_listener new_subsurface;
+
+ void (*destroy)(struct roots_view_child *child);
+};
+
+struct roots_subsurface {
+ struct roots_view_child view_child;
+ struct wlr_subsurface *wlr_subsurface;
+ struct wl_listener destroy;
+};
+
+struct roots_wl_shell_popup {
+ struct roots_view_child view_child;
+ struct wlr_wl_shell_surface *wlr_wl_shell_surface;
+ struct wl_listener destroy;
+ struct wl_listener set_state;
+ struct wl_listener new_popup;
+};
+
+struct roots_xdg_popup_v6 {
+ struct roots_view_child view_child;
+ struct wlr_xdg_popup_v6 *wlr_popup;
+ struct wl_listener destroy;
+ struct wl_listener map;
+ struct wl_listener unmap;
+ struct wl_listener new_popup;
+};
+
+struct roots_xdg_popup {
+ struct roots_view_child view_child;
+ struct wlr_xdg_popup *wlr_popup;
+ struct wl_listener destroy;
+ struct wl_listener map;
+ struct wl_listener unmap;
+ struct wl_listener new_popup;
+};
+
+struct roots_xdg_toplevel_decoration {
+ struct wlr_xdg_toplevel_decoration_v1 *wlr_decoration;
+ struct roots_xdg_surface *surface;
+ struct wl_listener destroy;
+ struct wl_listener request_mode;
+ struct wl_listener surface_commit;
+};
+
+void view_get_box(const struct roots_view *view, struct wlr_box *box);
+void view_activate(struct roots_view *view, bool active);
+void view_move(struct roots_view *view, double x, double y);
+void view_resize(struct roots_view *view, uint32_t width, uint32_t height);
+void view_move_resize(struct roots_view *view, double x, double y,
+ uint32_t width, uint32_t height);
+void view_maximize(struct roots_view *view, bool maximized);
+void view_set_fullscreen(struct roots_view *view, bool fullscreen,
+ struct wlr_output *output);
+void view_rotate(struct roots_view *view, float rotation);
+void view_cycle_alpha(struct roots_view *view);
+void view_close(struct roots_view *view);
+bool view_center(struct roots_view *view);
+void view_setup(struct roots_view *view);
+void view_teardown(struct roots_view *view);
+
+void view_set_title(struct roots_view *view, const char *title);
+void view_set_app_id(struct roots_view *view, const char *app_id);
+void view_create_foreign_toplevel_handle(struct roots_view *view);
+
+void view_get_deco_box(const struct roots_view *view, struct wlr_box *box);
+
+enum roots_deco_part {
+ ROOTS_DECO_PART_NONE = 0,
+ ROOTS_DECO_PART_TOP_BORDER = (1 << 0),
+ ROOTS_DECO_PART_BOTTOM_BORDER = (1 << 1),
+ ROOTS_DECO_PART_LEFT_BORDER = (1 << 2),
+ ROOTS_DECO_PART_RIGHT_BORDER = (1 << 3),
+ ROOTS_DECO_PART_TITLEBAR = (1 << 4),
+};
+
+enum roots_deco_part view_get_deco_part(struct roots_view *view, double sx, double sy);
+
+void view_child_init(struct roots_view_child *child, struct roots_view *view,
+ struct wlr_surface *wlr_surface);
+void view_child_finish(struct roots_view_child *child);
+
+struct roots_subsurface *subsurface_create(struct roots_view *view,
+ struct wlr_subsurface *wlr_subsurface);
+
+#endif
diff --git a/include/rootston/virtual_keyboard.h b/include/rootston/virtual_keyboard.h
new file mode 100644
index 00000000..613e5595
--- /dev/null
+++ b/include/rootston/virtual_keyboard.h
@@ -0,0 +1,7 @@
+#ifndef ROOTSTON_VIRTUAL_KEYBOARD_H
+#define ROOTSTON_VIRTUAL_KEYBOARD_H
+
+#include <wayland-server-core.h>
+
+void handle_virtual_keyboard(struct wl_listener *listener, void *data);
+#endif
diff --git a/include/rootston/xcursor.h b/include/rootston/xcursor.h
new file mode 100644
index 00000000..f78489a4
--- /dev/null
+++ b/include/rootston/xcursor.h
@@ -0,0 +1,12 @@
+#ifndef ROOTSTON_XCURSOR_H
+#define ROOTSTON_XCURSOR_H
+
+#include <stdint.h>
+
+#define ROOTS_XCURSOR_SIZE 24
+
+#define ROOTS_XCURSOR_DEFAULT "left_ptr"
+#define ROOTS_XCURSOR_MOVE "grabbing"
+#define ROOTS_XCURSOR_ROTATE "grabbing"
+
+#endif