#ifndef WAYLAND_GTK_EGL_EXAMPLE_H #define WAYLAND_GTK_EGL_EXAMPLE_H /* csd */ typedef uint8_t CSD_U8; typedef uint32_t CSD_U32; typedef uint64_t CSD_U64; typedef int8_t CSD_S8; typedef int32_t CSD_S32; typedef int8_t CSD_B8; typedef int32_t CSD_B32; typedef double CSD_F64; #define CSD_Min(a, b) ((a)>(b)?(b):(a)) #define CSD_Max(a, b) ((a)<(b)?(b):(a)) #define CSD_ClampTop(x, a) CSD_Min(x, a) #define CSD_ClampBot(x, a) CSD_Max(x, a) typedef enum CSD_ColorScheme{ CSD_ColorScheme_Default, CSD_ColorScheme_Dark, CSD_ColorScheme_Light } CSD_ColorScheme; typedef struct CSD_CursorTheme{ char *name; int size; } CSD_CursorTheme; typedef uint32_t CSD_CursorShape; enum{ CSD_CursorShape_Hidden, CSD_CursorShape_Pointer, CSD_CursorShape_Resize_Top, CSD_CursorShape_Resize_Bottom, CSD_CursorShape_Resize_Left, CSD_CursorShape_Resize_Right, CSD_CursorShape_Resize_TopLeft, CSD_CursorShape_Resize_TopRight, CSD_CursorShape_Resize_BottomLeft, CSD_CursorShape_Resize_BottomRight, CSD_CursorShape_COUNT }; typedef uint32_t CSD_WindowFlags; enum{ CSD_WindowFlag_IsFullscreen = (1 << 0), CSD_WindowFlag_IsMax = (1 << 1), CSD_WindowFlag_IsActivated = (1 << 2), CSD_WindowFlag_IsTiledLeft = (1 << 3), CSD_WindowFlag_IsTiledRight = (1 << 4), CSD_WindowFlag_IsTiledTop = (1 << 5), CSD_WindowFlag_IsTiledBottom = (1 << 6), CSD_WindowFlag_IsResizing = (1 << 7), CSD_WindowFlag_IsSuspended = (1 << 8), CSD_WindowFlag_IsConstrainedLeft = (1 << 9), CSD_WindowFlag_IsConstrainedRight = (1 << 10), CSD_WindowFlag_IsConstrainedTop = (1 << 11), CSD_WindowFlag_IsConstrainedBottom = (1 << 12), }; #define CSD_WindowMask_IsAnchored \ (CSD_WindowFlag_IsFullscreen|CSD_WindowFlag_IsMax| \ CSD_WindowFlag_IsTiledLeft |CSD_WindowFlag_IsTiledRight| \ CSD_WindowFlag_IsTiledTop |CSD_WindowFlag_IsTiledBottom) typedef uint32_t CSD_WindowControlFlags; enum{ CSD_WindowControlFlag_Move = (1 << 0), CSD_WindowControlFlag_Resize = (1 << 1), CSD_WindowControlFlag_Min = (1 << 2), CSD_WindowControlFlag_Max = (1 << 3), CSD_WindowControlFlag_Close = (1 << 4), }; typedef struct CSD_Config{ CSD_U32 serial; CSD_S32 dim[2]; CSD_WindowFlags flags; CSD_U32 decoration_mode; } CSD_Config; typedef struct CSD_Frame{ CSD_S32 border[2][2]; // [0][]:x [1][]:y [][0]:min [][1]:max CSD_S32 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; CSD_U64 size; CSD_S32 dim[2]; CSD_S32 p[2]; } CSD_SubSurface; /* 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, CSD_S32 dim[2]); static void csd_subsurface_set_position(CSD_SubSurface *subsurface, CSD_S32 x, CSD_S32 y); static void csd_subsurface_commit(CSD_SubSurface *subsurface); static CSD_WindowFlags csd_window_flags_from_states_array(struct wl_array *states); /* os */ static int csd_os_resize_anonymous_file(int fd, off_t size); static int csd_os_create_anonymous_file(off_t size); /* desktop settings */ static CSD_CursorTheme csd_desktop_get_cursor_theme(void); static CSD_ColorScheme csd_desktop_get_color_scheme(void); static CSD_CursorTheme csd_desktop_get_cursor_theme_from_env(void); #if defined(HAS_DBUS) #include static DBusMessage* csd_desktop__get_setting_sync(DBusConnection *const connection, const char *k, const char *v); static int csd_desktop__parse_type(DBusMessage *const reply, const int type, void *value); #endif /* defined(HAS_DBUS) */ /* csd gtk */ typedef struct CSD_GTK_Ctx{ cairo_surface_t *shadow_blur; } CSD_GTK_Ctx; typedef struct CSD_GTK_Window{ CSD_S32 p[2]; CSD_U32 button; CSD_S32 double_click_time_ms; CSD_SubSurface titlebar; CSD_SubSurface shadow; GtkWidget *window; GtkWidget *header; CSD_U32 hover_button_code; CSD_U32 active_button_code; } GTK_Window; /* 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); /* csd gtk cairo shadow rendering */ static int csd_gtk_blur_surface(cairo_surface_t *surface, int margin); static void csd_gtk_render_shadow(cairo_t *cr, cairo_surface_t *surface, int x, int y, int width, int height, int margin, int top_margin); /* example */ typedef struct Ctx{ /* "application variables" */ CSD_B32 close_signal; /* globals: desktop settings */ CSD_ColorScheme color_scheme; CSD_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[CSD_CursorShape_COUNT]; /* globals: egl */ EGLDisplay egl_display; EGLContext egl_context; /* globals: gtk */ CSD_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; CSD_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 */ CSD_WindowControlFlags control_flags; int32_t dim[2]; int32_t mmbox[2][2]; // [0][]:x [1][]:y [][0]:min [][1]:max CSD_Config config; CSD_Config config_staged; CSD_U32 serial; CSD_B32 handled_first_size; CSD_Frame csd_frame; CSD_S32 csd_dim[2]; GTK_Window gtk_window; } Ctx; #endif /* WAYLAND_GTK_EGL_EXAMPLE_H */