1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
#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"
#include <string.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;
/* Backend's copy of yasl_display_spec.app_id, or NULL; for desktop services. */
const char *app_id;
};
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);
/* Report a presented CPU frame's extent, and copy it when out can hold it. */
static inline bool yasl_copy_frame(const uint32_t *pixels, struct yasl_vector2i extent,
uint32_t *out, size_t cap, struct yasl_vector2i *size)
{
*size = extent;
size_t count = (size_t)extent.x * (size_t)extent.y;
if (!count || count > cap) return false;
memcpy(out, pixels, count * sizeof(*pixels));
return true;
}
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);
/* Optional; returns zero or less when the system reports no interval. */
int (*display_double_click_ms)(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);
/* Optional; NULL means the bell is unsupported. */
bool (*surface_bell)(struct yasl_surface *s);
/* Optional; NULL means no readback. Fills size only for an available frame. */
bool (*surface_read_pixels)(struct yasl_surface *s, uint32_t *out, size_t cap,
struct yasl_vector2i *size);
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
|