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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
#ifndef YASL_PRIVATE_BACKEND_H
#define YASL_PRIVATE_BACKEND_H
#include "common/types.h"
#include "common/private_loop.h"
#include "common/private_native.h"
#include "common/input.h"
#include "common/gl_options.h"
#include "common/timing.h"
#include <string.h>
struct yasl_private_backend_ops;
struct yasl_private_event_state;
struct yasl_private_display {
const struct yasl_private_backend_ops *ops;
void *native_handle;
bool offline; /* Connection lost; native handles are unusable until it is restored. */
struct yasl_private_loop *loop;
/* Backend's copy of yasl_private_display_spec.app_id, or NULL; for desktop services. */
const char *app_id;
struct yasl_private_event_state *events;
struct yasl_surface *surfaces;
};
struct yasl_surface {
struct yasl_vulkan_binding *vulkan;
unsigned creation_flags;
enum yasl_private_presenter presenter;
struct yasl_surface *parent;
uint32_t *cpu_pixels;
int cpu_width, cpu_height;
uint64_t cpu_token;
bool cpu_acquired;
uint32_t *committed_pixels;
int committed_width, committed_height;
/* Window values last reported through public WINDOW events. */
struct yasl_private_vector2i reported_size;
uint32_t reported_scale_120, reported_state;
bool refresh_owed;
bool refresh_active;
void (*refresh_callback)(struct yasl_surface *, void *);
void *refresh_userdata;
bool text_input_active;
unsigned text_purpose;
char *text_surrounding;
size_t text_length, text_begin, text_end;
uint64_t text_revision, text_generation;
struct yasl_private_display *display;
void *native_handle;
struct yasl_private_vector2i size;
uint32_t scale_120;
uint32_t state; /* Authoritative YASL_PRIVATE_STATE_* bitmask, maintained by the backend. */
uint32_t bg_color;
struct yasl_private_window_cbs callbacks;
void *ud;
uint64_t frame_generation;
struct input_queue input;
enum yasl_private_pointer_mode pointer_mode;
struct yasl_private_frame_clock clock;
uint64_t frames_skipped;
yasl_private_timer_id *timers;
int timer_count;
int timer_capacity;
struct yasl_surface *event_next;
uint64_t id;
void *userdata;
bool popup;
bool drawing;
bool frame_presented;
uint32_t reported_scale;
uint64_t draw_index;
struct yasl_private_frame *active_frame;
yasl_private_pacing_mode pacing;
yasl_private_timer_id pacing_timer;
};
bool yasl_private_events_open(struct yasl_private_display *d);
void yasl_private_events_close(struct yasl_private_display *d);
int yasl_private_events_error(struct yasl_private_display *d);
bool yasl_private_events_pending(struct yasl_private_display *d);
struct yasl_surface *yasl_private_events_find(struct yasl_private_display *d, uint64_t id);
bool yasl_private_events_register(struct yasl_surface *s);
void yasl_private_events_unregister(struct yasl_surface *s);
bool yasl_private_events_push(struct yasl_private_display *d, struct yasl_surface *queue_owner,
const struct yasl_private_event *event);
void yasl_private_surface_notify_configure(struct yasl_surface *s, struct yasl_private_geometry geometry);
void yasl_private_surface_notify_refresh(struct yasl_surface *s);
void yasl_private_surface_notify_close(struct yasl_surface *s);
void yasl_private_surface_notify_state(struct yasl_surface *s, uint32_t state);
void yasl_private_surface_notify_drag(struct yasl_surface *s, enum yasl_private_drag_event ev, struct yasl_private_vector2i pos);
void yasl_private_surface_notify_drop(struct yasl_surface *s, enum yasl_private_drop_event ev, struct yasl_private_vector2i pos);
void yasl_private_surface_notify_composition(struct yasl_surface *s, const char *text, int begin, int end);
void yasl_private_surface_draw(struct yasl_surface *s, struct yasl_private_frame *frame);
void yasl_private_display_notify_event(struct yasl_private_display *d, enum yasl_private_event_type type);
void yasl_private_surface_complete_paste(struct yasl_surface *s, uint64_t request_id,
enum yasl_private_transfer_status status, const char *text, size_t len);
uint64_t yasl_private_events_request_id(struct yasl_private_display *d);
void yasl_private_surface_clear_timers(struct yasl_surface *s);
struct yasl_surface *yasl_private_create_toplevel(struct yasl_private_display *d,
const struct yasl_private_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_private_copy_frame(const uint32_t *pixels, struct yasl_private_vector2i extent,
uint32_t *out, size_t cap, struct yasl_private_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_private_frame_begin(struct yasl_surface *s)
{
if (++s->frame_generation == 0) ++s->frame_generation;
return s->frame_generation;
}
typedef void (*yasl_private_gl_proc)(void);
struct yasl_private_backend_ops {
struct yasl_surface *(*surface_create_gl)(struct yasl_private_display *, const struct yasl_private_window_spec *, const int *, struct yasl_surface *share);
bool (*gl_make_current)(struct yasl_private_display *, struct yasl_surface *);
yasl_private_gl_proc (*gl_get_proc_address)(struct yasl_private_display *, const char *);
bool (*gl_swap_interval)(struct yasl_private_display *, struct yasl_surface *, int);
bool (*gl_swap_buffers)(struct yasl_private_display *, struct yasl_surface *);
void *(*surface_get_metal_layer)(struct yasl_surface *);
bool (*surface_update_text_input)(struct yasl_surface *);
enum yasl_private_backend type;
struct yasl_private_display *(*display_open)(struct yasl_private_loop *loop, const struct yasl_private_display_spec *spec);
void (*display_close)(struct yasl_private_display *d);
uint32_t (*display_caps)(const struct yasl_private_display *d);
int (*display_dispatch_timeout)(struct yasl_private_display *d, int timeout_ms);
void (*display_flush)(struct yasl_private_display *d);
int (*display_modifiers)(const struct yasl_private_display *d);
/* Optional; returns zero or less when the system reports no interval. */
int (*display_double_click_ms)(const struct yasl_private_display *d);
bool (*display_copy_text)(struct yasl_private_display *d, enum yasl_private_selection sel, const char *text);
bool (*display_request_paste)(struct yasl_private_display *d, enum yasl_private_selection sel,
struct yasl_surface *target, uint64_t request_id);
bool (*display_drag_start)(struct yasl_private_display *d, struct yasl_surface *origin, const struct yasl_private_drag_image *image, const struct yasl_private_drag_listener *l, void *ud);
void (*display_drag_cancel)(struct yasl_private_display *d);
/* Create with callbacks disabled; common code installs them after return. */
struct yasl_surface *(*surface_create_toplevel)(struct yasl_private_display *d,
const struct yasl_private_window_spec *spec, void *graphics_device);
struct yasl_surface *(*surface_create_popup)(struct yasl_surface *parent, const struct yasl_private_popup_spec *spec);
bool (*surface_popup_reposition)(struct yasl_surface *popup, const struct yasl_private_popup_spec *spec);
void (*surface_destroy)(struct yasl_surface *s);
struct input_queue *(*surface_input_queue)(struct yasl_surface *s);
bool (*surface_set_size)(struct yasl_surface *s, struct yasl_private_vector2i size);
bool (*surface_set_fullscreen)(struct yasl_surface *s, bool enabled);
bool (*surface_set_maximized)(struct yasl_surface *s, bool enabled);
bool (*surface_minimize)(struct yasl_surface *s);
struct yasl_private_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_private_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_private_framebuffer *fb, const struct yasl_private_damage_list *damage);
/* Optional; NULL means only YASL_PRIVATE_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_private_pointer_mode mode);
struct yasl_private_geometry (*surface_geometry)(const struct yasl_surface *s);
struct yasl_private_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_private_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_private_rect2i caret);
bool (*surface_start_interactive_move)(struct yasl_surface *s);
bool (*surface_start_interactive_resize)(struct yasl_surface *s, enum yasl_private_resize_edge edge);
bool (*surface_show_window_menu)(struct yasl_surface *s, struct yasl_private_vector2i pos);
bool (*surface_drag_carry)(struct yasl_surface *s, struct yasl_private_vector2i offset);
bool (*surface_place_under_pointer)(struct yasl_surface *s, struct yasl_private_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_private_vector2i *size);
void *(*display_get_native_handle)(struct yasl_private_display *d);
void *(*surface_get_native_handle)(struct yasl_surface *s);
bool (*surface_get_native_frame)(struct yasl_surface *s,
const struct yasl_private_framebuffer *target, struct yasl_private_native_frame *out);
};
#if YASL_HAS_WAYLAND
extern const struct yasl_private_backend_ops yasl_private_wayland_backend;
#endif
#if YASL_HAS_X11
extern const struct yasl_private_backend_ops yasl_private_x11_backend;
#endif
#if YASL_HAS_COCOA
extern const struct yasl_private_backend_ops yasl_private_cocoa_backend;
#endif
#endif
|