#ifndef WAYLAND_GTK_EGL_EXAMPLE_H #define WAYLAND_GTK_EGL_EXAMPLE_H #define HAS_DBUS #define HAVE_MEMFD_CREATE #define HAVE_POSIX_FALLOCATE #define Min(a, b) ((a)>(b)?(b):(a)) #define Max(a, b) ((a)<(b)?(b):(a)) #define ClampTop(x, a) Min(x, a) #define ClampBot(x, a) Max(x, a) typedef enum ColorScheme{ ColorScheme_Default, ColorScheme_Dark, ColorScheme_Light } ColorScheme; typedef struct CursorTheme{ char *name; int size; } CursorTheme; typedef uint32_t CursorShape; enum{ CursorShape_Hidden, CursorShape_Pointer, CursorShape_Resize_Top, CursorShape_Resize_Bottom, CursorShape_Resize_Left, CursorShape_Resize_Right, CursorShape_Resize_TopLeft, CursorShape_Resize_TopRight, CursorShape_Resize_BottomLeft, CursorShape_Resize_BottomRight, CursorShape_COUNT }; typedef uint32_t WindowFlags; enum{ WindowFlag_IsFullscreen = (1 << 0), WindowFlag_IsMax = (1 << 1), WindowFlag_IsActivated = (1 << 2), WindowFlag_IsTiledLeft = (1 << 3), WindowFlag_IsTiledRight = (1 << 4), WindowFlag_IsTiledTop = (1 << 5), WindowFlag_IsTiledBottom = (1 << 6), WindowFlag_IsResizing = (1 << 7), WindowFlag_IsSuspended = (1 << 8), WindowFlag_IsConstrainedLeft = (1 << 9), WindowFlag_IsConstrainedRight = (1 << 10), WindowFlag_IsConstrainedTop = (1 << 11), WindowFlag_IsConstrainedBottom = (1 << 12), }; #define WindowMask_IsAnchored \ (WindowFlag_IsFullscreen|WindowFlag_IsMax| \ WindowFlag_IsTiledLeft |WindowFlag_IsTiledRight| \ WindowFlag_IsTiledTop |WindowFlag_IsTiledBottom) typedef uint32_t WindowControlFlags; enum{ WindowControlFlag_Move = (1 << 0), WindowControlFlag_Resize = (1 << 1), WindowControlFlag_Min = (1 << 2), WindowControlFlag_Max = (1 << 3), WindowControlFlag_Close = (1 << 4), }; typedef struct Config{ uint32_t serial; int32_t dim[2]; WindowFlags flags; uint32_t decoration_mode; } Config; typedef struct CSD_Frame{ int32_t border[2][2]; // [0][]:x [1][]:y [][0]:min [][1]:max int32_t minbox[2]; } CSD_Frame; typedef struct CSD_SubSurface{ struct wl_surface *wl_surface; struct wl_subsurface *wl_subsurface; struct wl_buffer *wl_buffer; void *data; uint64_t size; int32_t dim[2]; int32_t p[2]; } CSD_SubSurface; typedef struct GTK_Ctx{ cairo_surface_t *shadow_blur; } GTK_Ctx; typedef struct GTK_Window{ int32_t p[2]; uint32_t button; int double_click_time_ms; CSD_SubSurface titlebar; CSD_SubSurface shadow; GtkWidget *window; GtkWidget *header; uint32_t hover_button_code; uint32_t active_button_code; } GTK_Window; typedef struct Ctx{ /* "application variables" */ int close_signal; /* globals: desktop settings */ ColorScheme color_scheme; CursorTheme cursor_theme; /* globals: wayland */ struct wl_display *wl_display; struct wl_registry *wl_registry; struct wl_compositor *wl_compositor; struct wl_subcompositor *wl_subcompositor; struct wl_shm *wl_shm; struct xdg_wm_base *xdg_wm_base; struct zxdg_decoration_manager_v1 *zxdg_decoration_manager; struct wl_cursor_theme *wl_cursor_theme; struct wl_cursor *wl_cursors[CursorShape_COUNT]; /* globals: egl */ EGLDisplay egl_display; EGLContext egl_context; /* globals: gtk */ GTK_Ctx gtk_ctx; /* per-seat: wayland */ struct wl_seat *wl_seat; struct wl_pointer *wl_pointer; struct wl_surface *cursor_surface; struct wl_surface *hover_surface; CursorShape cursor_shape; /* per-window: wayland */ struct wl_surface *main_wl_surface; struct xdg_surface *main_xdg_surface; struct xdg_toplevel *main_xdg_toplevel; struct zxdg_toplevel_decoration_v1 *main_zxdg_toplevel_decoration; /* per-window: egl */ struct wl_egl_window *main_wl_egl_window; EGLSurface main_egl_surface; /* per-window */ WindowControlFlags control_flags; int32_t dim[2]; int32_t mmbox[2][2]; // [0][]:x [1][]:y [][0]:min [][1]:max Config config; Config config_staged; uint32_t serial; int handled_first_size; CSD_Frame csd_frame; int32_t csd_dim[2]; GTK_Window gtk_window; } Ctx; /* csd helpers */ static CSD_SubSurface csd_subsurface_new(void); static void csd_subsurface_buffer_clear(CSD_SubSurface *subsurface); static void csd_subsurface_buffer_alloc(CSD_SubSurface *subsurface, int32_t dim[2]); static void csd_subsurface_set_position(CSD_SubSurface *subsurface, int32_t x, int32_t y); static void csd_subsurface_commit(CSD_SubSurface *subsurface); static WindowFlags csd_window_flags_from_states_array(struct wl_array *states); /* os */ static int os_resize_anonymous_file(int fd, off_t size); static int os_create_anonymous_file(off_t size); /* desktop settings */ static CursorTheme ds_get_cursor_theme(void); static ColorScheme ds_get_color_scheme(void); static CursorTheme ds__get_cursor_theme_from_env(void); #if defined(HAS_DBUS) #include static DBusMessage* ds__get_setting_sync(DBusConnection *const connection, const char *k, const char *v); static int ds__parse_type(DBusMessage *const reply, const int type, void *value); #endif /* defined(HAS_DBUS) */ /* csd gtk implementation */ static void csd_gtk_init(void); static void csd_gtk_window_init(void); static CSD_Frame csd_gtk_calculate_frame(void); static void csd_gtk_update_and_render(void); static void csd_gtk_render(void); /* cairo shadow rendering */ static int cr_blur_surface(cairo_surface_t *surface, int margin); static void cr_render_shadow(cairo_t *cr, cairo_surface_t *surface, int x, int y, int width, int height, int margin, int top_margin); #endif /* WAYLAND_GTK_EGL_EXAMPLE_H */