diff options
Diffstat (limited to 'include/rootston')
-rw-r--r-- | include/rootston/bindings.h | 9 | ||||
-rw-r--r-- | include/rootston/config.h | 133 | ||||
-rw-r--r-- | include/rootston/cursor.h | 105 | ||||
-rw-r--r-- | include/rootston/desktop.h | 119 | ||||
-rw-r--r-- | include/rootston/ini.h | 93 | ||||
-rw-r--r-- | include/rootston/input.h | 37 | ||||
-rw-r--r-- | include/rootston/keyboard.h | 34 | ||||
-rw-r--r-- | include/rootston/layers.h | 35 | ||||
-rw-r--r-- | include/rootston/output.h | 52 | ||||
-rw-r--r-- | include/rootston/seat.h | 181 | ||||
-rw-r--r-- | include/rootston/server.h | 37 | ||||
-rw-r--r-- | include/rootston/switch.h | 18 | ||||
-rw-r--r-- | include/rootston/text_input.h | 63 | ||||
-rw-r--r-- | include/rootston/view.h | 260 | ||||
-rw-r--r-- | include/rootston/virtual_keyboard.h | 7 | ||||
-rw-r--r-- | include/rootston/xcursor.h | 12 |
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 |