#ifndef YASL_BACKEND_H #define YASL_BACKEND_H #include "yasl/yasl.h" #include "yasl/loop.h" #include "yasl/native.h" #include "common/input.h" #include "common/timing.h" struct yasl_backend_ops; struct yasl_display { const struct yasl_backend_ops *ops; void *native_handle; struct yasl_display_cbs callbacks; struct yasl_loop *loop; void *app_runner; }; struct yasl_surface { struct yasl_display *display; void *native_handle; struct yasl_vector2i size; uint32_t scale_120; uint32_t state; /* Authoritative YASL_STATE_* bitmask, maintained by the backend. */ uint32_t bg_color; struct yasl_window_cbs callbacks; void *ud; uint64_t frame_generation; struct input_queue input; enum yasl_pointer_mode pointer_mode; struct yasl_frame_clock clock; uint64_t frames_skipped; yasl_timer_id *timers; int timer_count; int timer_capacity; void *app_surface; }; void yasl_surface_clear_timers(struct yasl_surface *s); struct yasl_surface *yasl_create_toplevel(struct yasl_display *d, const struct yasl_window_spec *spec, void *graphics_device); static inline uint64_t yasl_frame_begin(struct yasl_surface *s) { if (++s->frame_generation == 0) ++s->frame_generation; return s->frame_generation; } struct yasl_backend_ops { enum yasl_backend type; struct yasl_display *(*display_open)(struct yasl_loop *loop, const struct yasl_display_spec *spec); void (*display_close)(struct yasl_display *d); uint32_t (*display_caps)(const struct yasl_display *d); int (*display_dispatch_timeout)(struct yasl_display *d, int timeout_ms); void (*display_flush)(struct yasl_display *d); int (*display_modifiers)(const struct yasl_display *d); void (*display_copy)(struct yasl_display *d, enum yasl_selection sel, const char *text); void (*display_paste)(struct yasl_display *d, enum yasl_selection sel, struct yasl_surface *target); bool (*display_drag_start)(struct yasl_display *d, struct yasl_surface *origin, const struct yasl_drag_image *image, const struct yasl_drag_listener *l, void *ud); void (*display_drag_cancel)(struct yasl_display *d); /* Create with callbacks disabled; common code installs them after return. */ struct yasl_surface *(*surface_create_toplevel)(struct yasl_display *d, const struct yasl_window_spec *spec, void *graphics_device); struct yasl_surface *(*surface_create_popup)(struct yasl_surface *parent, const struct yasl_popup_spec *spec); bool (*surface_popup_reposition)(struct yasl_surface *popup, const struct yasl_popup_spec *spec); void (*surface_destroy)(struct yasl_surface *s); struct yasl_display *(*surface_display)(const struct yasl_surface *s); /* Copy only; must not invoke application callbacks. */ void (*surface_set_callbacks)(struct yasl_surface *s, const struct yasl_window_cbs *cbs, void *ud); void (*surface_set_title)(struct yasl_surface *s, const char *title); void (*surface_schedule_redraw)(struct yasl_surface *s); bool (*surface_present)(struct yasl_surface *s, const struct yasl_framebuffer *fb, const struct yasl_damage_list *damage); /* Optional; NULL means the common input queue is drained. */ bool (*surface_poll_event)(struct yasl_surface *s, struct yasl_event *ev); /* Optional; NULL means only YASL_POINTER_NORMAL is supported. Backends that * implement RELATIVE push POINTER_MOTION with delta set and pos frozen. */ bool (*surface_set_pointer_mode)(struct yasl_surface *s, enum yasl_pointer_mode mode); struct yasl_geometry (*surface_geometry)(const struct yasl_surface *s); struct yasl_timing (*surface_timing)(const struct yasl_surface *s); uint64_t (*surface_frame_time_ns)(struct yasl_surface *s, uint64_t now); void (*surface_set_cursor)(struct yasl_surface *s, enum yasl_cursor cursor); void (*surface_set_background_color)(struct yasl_surface *s, uint32_t bg); const char *(*surface_ime_preedit)(const struct yasl_surface *s); bool (*surface_ime_preedit_cursor)(const struct yasl_surface *s, int *begin, int *end); void (*surface_set_ime_caret)(struct yasl_surface *s, struct yasl_rect2i caret); bool (*surface_start_interactive_move)(struct yasl_surface *s); bool (*surface_start_interactive_resize)(struct yasl_surface *s, enum yasl_resize_edge edge); bool (*surface_show_window_menu)(struct yasl_surface *s, struct yasl_vector2i pos); bool (*surface_drag_carry)(struct yasl_surface *s, struct yasl_vector2i offset); bool (*surface_place_under_pointer)(struct yasl_surface *s, struct yasl_vector2i at); void *(*display_get_native_handle)(struct yasl_display *d); void *(*surface_get_native_handle)(struct yasl_surface *s); bool (*surface_get_native_frame)(struct yasl_surface *s, const struct yasl_framebuffer *target, struct yasl_native_frame *out); }; #if YASL_HAS_WAYLAND extern const struct yasl_backend_ops yasl_wayland_backend; #endif #if YASL_HAS_X11 extern const struct yasl_backend_ops yasl_x11_backend; #endif #if YASL_HAS_COCOA extern const struct yasl_backend_ops yasl_cocoa_backend; #endif #endif