/* * Copyright © 2012 Collabora, Ltd. * Copyright © 2012 Intel Corporation * Copyright © 2017-2018 Red Hat Inc. * Copyright © 2018 Jonas Ådahl * Copyright © 2021 Christian Rauch * Copyright © 2024 Colin Kinloch * * 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. */ #ifndef DIGESTING_LIBDECOR_H #define DIGESTING_LIBDECOR_H // config.h /* Version number of package */ #define VERSION "0.2.2" /* Plugin directiory path */ #define LIBDECOR_PLUGIN_DIR "/usr/local/lib/x86_64-linux-gnu/libdecor/plugins-1" /* Plugin API version */ #define LIBDECOR_PLUGIN_API_VERSION 1 #define HAS_DBUS /* #undef HAVE_MKOSTEMP */ #define HAVE_POSIX_FALLOCATE #define HAVE_MEMFD_CREATE #define HAVE_GETTID // utils.h #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) // libdecor.h struct libdecor_frame; struct libdecor_configuration; struct libdecor_state; enum libdecor_error { LIBDECOR_ERROR_COMPOSITOR_INCOMPATIBLE, LIBDECOR_ERROR_INVALID_FRAME_CONFIGURATION, }; enum libdecor_window_state { LIBDECOR_WINDOW_STATE_NONE = 0, LIBDECOR_WINDOW_STATE_ACTIVE = 1 << 0, LIBDECOR_WINDOW_STATE_MAXIMIZED = 1 << 1, LIBDECOR_WINDOW_STATE_FULLSCREEN = 1 << 2, LIBDECOR_WINDOW_STATE_TILED_LEFT = 1 << 3, LIBDECOR_WINDOW_STATE_TILED_RIGHT = 1 << 4, LIBDECOR_WINDOW_STATE_TILED_TOP = 1 << 5, LIBDECOR_WINDOW_STATE_TILED_BOTTOM = 1 << 6, LIBDECOR_WINDOW_STATE_SUSPENDED = 1 << 7, LIBDECOR_WINDOW_STATE_RESIZING = 1 << 8, LIBDECOR_WINDOW_STATE_CONSTRAINED_LEFT = 1 << 9, LIBDECOR_WINDOW_STATE_CONSTRAINED_RIGHT = 1 << 10, LIBDECOR_WINDOW_STATE_CONSTRAINED_TOP = 1 << 11, LIBDECOR_WINDOW_STATE_CONSTRAINED_BOTTOM = 1 << 12, }; enum libdecor_resize_edge { LIBDECOR_RESIZE_EDGE_NONE, LIBDECOR_RESIZE_EDGE_TOP, LIBDECOR_RESIZE_EDGE_BOTTOM, LIBDECOR_RESIZE_EDGE_LEFT, LIBDECOR_RESIZE_EDGE_TOP_LEFT, LIBDECOR_RESIZE_EDGE_BOTTOM_LEFT, LIBDECOR_RESIZE_EDGE_RIGHT, LIBDECOR_RESIZE_EDGE_TOP_RIGHT, LIBDECOR_RESIZE_EDGE_BOTTOM_RIGHT, }; enum libdecor_capabilities { LIBDECOR_ACTION_MOVE = 1 << 0, LIBDECOR_ACTION_RESIZE = 1 << 1, LIBDECOR_ACTION_MINIMIZE = 1 << 2, LIBDECOR_ACTION_FULLSCREEN = 1 << 3, LIBDECOR_ACTION_CLOSE = 1 << 4, }; enum libdecor_wm_capabilities { LIBDECOR_WM_CAPABILITIES_WINDOW_MENU = 1 << 0, LIBDECOR_WM_CAPABILITIES_MAXIMIZE = 1 << 1, LIBDECOR_WM_CAPABILITIES_FULLSCREEN = 1 << 2, LIBDECOR_WM_CAPABILITIES_MINIMIZE = 1 << 3 }; // libdecor-plugin.h struct libdecor_frame_private; struct libdecor_frame { struct libdecor_frame_private *priv; struct wl_list link; }; struct libdecor_plugin_private; struct libdecor_plugin { struct libdecor_plugin_private *priv; }; #define LIBDECOR_PLUGIN_PRIORITY_HIGH 1000 #define LIBDECOR_PLUGIN_PRIORITY_MEDIUM 100 #define LIBDECOR_PLUGIN_PRIORITY_LOW 0 struct libdecor_plugin_priority { const char *desktop; int priority; }; struct libdecor_plugin_interface { void (* destroy)(struct libdecor_plugin *plugin); int (* get_fd)(struct libdecor_plugin *plugin); int (* dispatch)(struct libdecor_plugin *plugin, int timeout); void (* set_handle_application_cursor)(struct libdecor_plugin *plugin, bool handle_cursor); struct libdecor_frame * (* frame_new)(struct libdecor_plugin *plugin); void (* frame_free)(struct libdecor_plugin *plugin, struct libdecor_frame *frame); void (* frame_commit)(struct libdecor_plugin *plugin, struct libdecor_frame *frame, struct libdecor_state *state, struct libdecor_configuration *configuration); void (*frame_property_changed)(struct libdecor_plugin *plugin, struct libdecor_frame *frame); void (* frame_popup_grab)(struct libdecor_plugin *plugin, struct libdecor_frame *frame, const char *seat_name); void (* frame_popup_ungrab)(struct libdecor_plugin *plugin, struct libdecor_frame *frame, const char *seat_name); bool (* frame_get_border_size)(struct libdecor_plugin *plugin, struct libdecor_frame *frame, struct libdecor_configuration *configuration, int *left, int *right, int *top, int *bottom); }; // #include "libdecor.c" struct libdecor_state { enum libdecor_window_state window_state; int content_width; int content_height; }; struct libdecor_limits { int min_width; int min_height; int max_width; int max_height; }; struct libdecor_configuration { uint32_t serial; bool has_window_state; enum libdecor_window_state window_state; bool has_size; int window_width; int window_height; }; struct libdecor_frame_private { int ref_count; struct wl_surface *wl_surface; void *user_data; struct xdg_surface *xdg_surface; struct xdg_toplevel *xdg_toplevel; struct zxdg_toplevel_decoration_v1 *toplevel_decoration; bool pending_map; struct { char *app_id; char *title; struct libdecor_limits content_limits; struct xdg_toplevel *parent; } state; struct libdecor_configuration *pending_configuration; int content_width; int content_height; enum libdecor_window_state window_state; bool has_decoration_mode; enum zxdg_toplevel_decoration_v1_mode decoration_mode; enum libdecor_capabilities capabilities; enum libdecor_wm_capabilities wm_capabilities; /* original limits for interactive resize */ struct libdecor_limits interactive_limits; bool visible; }; struct libdecor_plugin_private { struct libdecor_plugin_interface *iface; }; // #include "libdecor-fallback.c" struct libdecor_plugin_fallback { struct libdecor_plugin plugin; struct libdecor *context; }; // #include "desktop-settings.h" enum libdecor_color_scheme { LIBDECOR_COLOR_SCHEME_DEFAULT, LIBDECOR_COLOR_SCHEME_PREFER_DARK, LIBDECOR_COLOR_SCHEME_PREFER_LIGHT, }; // #include "plugins/gtk/libdecor-gtk.c" static const size_t SHADOW_MARGIN = 24; static const char *cursor_names[] = { "top_side", "bottom_side", "left_side", "top_left_corner", "bottom_left_corner", "right_side", "top_right_corner", "bottom_right_corner" }; enum header_element { HEADER_NONE, HEADER_FULL, /* entire header bar */ HEADER_TITLE, /* label */ HEADER_MIN, HEADER_MAX, HEADER_CLOSE, }; enum titlebar_gesture_state { TITLEBAR_GESTURE_STATE_INIT, TITLEBAR_GESTURE_STATE_BUTTON_PRESSED, TITLEBAR_GESTURE_STATE_CONSUMED, TITLEBAR_GESTURE_STATE_DISCARDED, }; struct header_element_data { const char *name; enum header_element type; /* pointer to button or NULL if not found*/ GtkWidget *widget; GtkStateFlags state; }; enum decoration_type { DECORATION_TYPE_NONE, DECORATION_TYPE_ALL, DECORATION_TYPE_TITLE_ONLY }; enum component { NONE = 0, SHADOW, HEADER, }; struct seat { struct libdecor_plugin_gtk *plugin_gtk; char *name; struct wl_seat *wl_seat; struct wl_pointer *wl_pointer; struct wl_touch *wl_touch; struct wl_surface *cursor_surface; struct wl_cursor *current_cursor; int cursor_scale; struct wl_list cursor_outputs; struct wl_cursor_theme *cursor_theme; /* cursors for resize edges and corners */ struct wl_cursor *cursors[ARRAY_LENGTH(cursor_names)]; struct wl_cursor *cursor_left_ptr; struct wl_surface *pointer_focus; struct wl_surface *touch_focus; int pointer_x, pointer_y; uint32_t touch_down_time_stamp; uint32_t serial; bool grabbed; struct wl_list link; }; struct output { struct libdecor_plugin_gtk *plugin_gtk; struct wl_output *wl_output; uint32_t id; int scale; struct wl_list link; }; struct buffer { struct wl_buffer *wl_buffer; bool in_use; bool is_detached; void *data; size_t data_size; int width; int height; int scale; int buffer_width; int buffer_height; }; struct border_component { enum component type; struct wl_surface *wl_surface; struct wl_subsurface *wl_subsurface; struct buffer *buffer; bool opaque; struct wl_list output_list; int scale; struct wl_list child_components; /* border_component::link */ struct wl_list link; /* border_component::child_components */ }; struct surface_output { struct output *output; struct wl_list link; }; struct cursor_output { struct output *output; struct wl_list link; }; struct libdecor_frame_gtk { struct libdecor_frame frame; struct libdecor_plugin_gtk *plugin_gtk; int content_width; int content_height; enum libdecor_window_state window_state; enum decoration_type decoration_type; char *title; enum libdecor_capabilities capabilities; struct border_component *active; struct border_component *touch_active; struct border_component *focus; struct border_component *grab; bool shadow_showing; struct border_component shadow; GtkWidget *window; /* offscreen window for rendering */ GtkWidget *header; /* header bar with widgets */ struct border_component headerbar; struct header_element_data hdr_focus; /* store pre-processed shadow tile */ cairo_surface_t *shadow_blur; struct wl_list link; struct { enum titlebar_gesture_state state; int button_pressed_count; uint32_t first_pressed_button; uint32_t first_pressed_time; double pressed_x; double pressed_y; uint32_t pressed_serial; } titlebar_gesture; }; struct libdecor_plugin_gtk { struct libdecor_plugin plugin; struct wl_callback *globals_callback; struct wl_callback *globals_callback_shm; struct wl_registry *wl_registry; struct wl_subcompositor *wl_subcompositor; struct wl_compositor *wl_compositor; struct wl_shm *wl_shm; struct wl_callback *shm_callback; bool has_argb; struct wl_list visible_frame_list; struct wl_list seat_list; struct wl_list output_list; char *cursor_theme_name; int cursor_size; int double_click_time_ms; int drag_threshold; bool handle_cursor; }; enum titlebar_gesture { TITLEBAR_GESTURE_DOUBLE_CLICK, TITLEBAR_GESTURE_MIDDLE_CLICK, TITLEBAR_GESTURE_RIGHT_CLICK, }; // libdecor.h void libdecor_frame_ref(struct libdecor_frame *frame); void libdecor_frame_unref(struct libdecor_frame *frame); void *libdecor_frame_get_user_data(struct libdecor_frame *frame); void libdecor_frame_set_user_data(struct libdecor_frame *frame, void *user_data); void libdecor_frame_set_visibility(struct libdecor_frame *frame, bool visible); bool libdecor_frame_is_visible(struct libdecor_frame *frame); void libdecor_frame_set_parent(struct libdecor_frame *frame, struct libdecor_frame *parent); void libdecor_frame_set_title(struct libdecor_frame *frame, const char *title); const char * libdecor_frame_get_title(struct libdecor_frame *frame); void libdecor_frame_set_app_id(struct libdecor_frame *frame, const char *app_id); void libdecor_frame_set_capabilities(struct libdecor_frame *frame, enum libdecor_capabilities capabilities); void libdecor_frame_unset_capabilities(struct libdecor_frame *frame, enum libdecor_capabilities capabilities); bool libdecor_frame_has_capability(struct libdecor_frame *frame, enum libdecor_capabilities capability); void libdecor_frame_show_window_menu(struct libdecor_frame *frame, struct wl_seat *wl_seat, uint32_t serial, int x, int y); void libdecor_frame_popup_grab(struct libdecor_frame *frame, const char *seat_name); void libdecor_frame_popup_ungrab(struct libdecor_frame *frame, const char *seat_name); void libdecor_frame_translate_coordinate(struct libdecor_frame *frame, int surface_x, int surface_y, int *frame_x, int *frame_y); void libdecor_frame_set_min_content_size(struct libdecor_frame *frame, int content_width, int content_height); void libdecor_frame_set_max_content_size(struct libdecor_frame *frame, int content_width, int content_height); void libdecor_frame_get_min_content_size(const struct libdecor_frame *frame, int *content_width, int *content_height); void libdecor_frame_get_max_content_size(const struct libdecor_frame *frame, int *content_width, int *content_height); void libdecor_frame_resize(struct libdecor_frame *frame, struct wl_seat *wl_seat, uint32_t serial, enum libdecor_resize_edge edge); void libdecor_frame_move(struct libdecor_frame *frame, struct wl_seat *wl_seat, uint32_t serial); void libdecor_frame_commit(struct libdecor_frame *frame, struct libdecor_state *state, struct libdecor_configuration *configuration); void libdecor_frame_set_minimized(struct libdecor_frame *frame); void libdecor_frame_set_maximized(struct libdecor_frame *frame); void libdecor_frame_unset_maximized(struct libdecor_frame *frame); void libdecor_frame_set_fullscreen(struct libdecor_frame *frame, struct wl_output *output); void libdecor_frame_unset_fullscreen(struct libdecor_frame *frame); bool libdecor_frame_is_floating(struct libdecor_frame *frame); void libdecor_frame_close(struct libdecor_frame *frame); void libdecor_frame_map(struct libdecor_frame *frame); struct xdg_surface * libdecor_frame_get_xdg_surface(struct libdecor_frame *frame); struct xdg_toplevel * libdecor_frame_get_xdg_toplevel(struct libdecor_frame *frame); enum libdecor_wm_capabilities libdecor_frame_get_wm_capabilities(struct libdecor_frame *frame); struct libdecor_state * libdecor_state_new(int width, int height); void libdecor_state_free(struct libdecor_state *state); bool libdecor_configuration_get_content_size(struct libdecor_configuration *configuration, struct libdecor_frame *frame, int *width, int *height); bool libdecor_configuration_get_window_state(struct libdecor_configuration *configuration, enum libdecor_window_state *window_state); struct libdecor_frame* libdecor_decorate(struct wl_surface *wl_surface, void *user_data); int libdecor_dispatch(int timeout); // libdecor-plugin.h struct wl_surface * libdecor_frame_get_wl_surface(struct libdecor_frame *frame); int libdecor_frame_get_content_width(struct libdecor_frame *frame); int libdecor_frame_get_content_height(struct libdecor_frame *frame); enum libdecor_window_state libdecor_frame_get_window_state(struct libdecor_frame *frame); enum libdecor_capabilities libdecor_frame_get_capabilities(const struct libdecor_frame *frame); void libdecor_frame_dismiss_popup(struct libdecor_frame *frame, const char *seat_name); void libdecor_frame_toplevel_commit(struct libdecor_frame *frame); void libdecor_notify_plugin_ready(void); void libdecor_notify_plugin_error(enum libdecor_error error, const char *__restrict fmt, ...); int libdecor_state_get_content_width(struct libdecor_state *state); int libdecor_state_get_content_height(struct libdecor_state *state); enum libdecor_window_state libdecor_state_get_window_state(struct libdecor_state *state); int libdecor_plugin_init(struct libdecor_plugin *plugin, struct libdecor_plugin_interface *iface); void libdecor_plugin_release(struct libdecor_plugin *plugin); // #include "libdecor-fallback.h" struct libdecor_plugin * libdecor_fallback_plugin_new(void); // #include "libdecor-cairo-blur.h" int blur_surface(cairo_surface_t *surface, int margin); void render_shadow(cairo_t *cr, cairo_surface_t *surface, int x, int y, int width, int height, int margin, int top_margin); // #include "desktop-settings.h" bool libdecor_get_cursor_settings(char **theme, int *size); enum libdecor_color_scheme libdecor_get_color_scheme(); // #include "os-compatibility.h" int libdecor_os_create_anonymous_file(off_t size); // #include "libdecor.c" static void init_xdg_wm_base(uint32_t id, uint32_t version); //#include "plugins/gtk/libdecor-gtk.c" static void libdecor_plugin_gtk_destroy(struct libdecor_plugin *plugin); static void init_wl_compositor(struct libdecor_plugin_gtk *plugin_gtk, uint32_t id, uint32_t version); static void init_wl_subcompositor(struct libdecor_plugin_gtk *plugin_gtk, uint32_t id, uint32_t version); static void init_wl_shm(struct libdecor_plugin_gtk *plugin_gtk, uint32_t id, uint32_t version); static void init_wl_seat(struct libdecor_plugin_gtk *plugin_gtk, uint32_t id, uint32_t version); static void init_wl_output(struct libdecor_plugin_gtk *plugin_gtk, uint32_t id, uint32_t version); static void output_removed(struct libdecor_plugin_gtk *plugin_gtk, struct output *output); // digesting_libdecor typedef struct Ctx{ /* globals */ struct wl_display *wl_display; struct wl_registry *wl_registry; struct wl_compositor *wl_compositor; struct xdg_wm_base *xdg_wm_base; struct zxdg_decoration_manager_v1 *decoration_manager; struct wl_list frames; struct wl_callback *wl_callback; struct libdecor_plugin *plugin; bool plugin_ready; bool init_done; bool has_error; /* window */ struct wl_surface *wl_surface; struct libdecor_frame *libdecor_frame; struct wl_egl_window *wl_egl_window; int configured; int w; int h; int close_signal; //struct xdg_surface *xdg_surface; //struct xdg_toplevel *xdg_toplevel; //struct wl_region *wl_region; EGLDisplay egl_display; EGLContext egl_context; EGLSurface egl_surface; } Ctx; #endif //DIGESTING_LIBDECOR_H