GFXprim
2D bitmap graphics library with emphasis on speed and correctness
Loading...
Searching...
No Matches
gp_backend.h
1// SPDX-License-Identifier: LGPL-2.1-or-later
2/*
3 * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos
4 * <jiri.bluebear.dluhos@gmail.com>
5 *
6 * Copyright (C) 2009-2024 Cyril Hrubis <metan@ucw.cz>
7 */
8
9/*
10
11 The gp_backend is overall structure for API for managing
12 connection/mmaped memory/... to xserver window/framebuffer/... .
13
14 In contrast to other graphics libraries we do not try to create unified
15 initalization interface that would match specialities for every possible
16 backend. Rather than that we are trying to create API that is the same
17 for all backends, once initalization is done.
18
19 So once you initalize, for example, framebuffer driver, the gp_backend
20 structure is returned, which then could be used with generic code for
21 backend drawing.
22
23 */
24
25#ifndef BACKENDS_GP_BACKEND_H
26#define BACKENDS_GP_BACKEND_H
27
28#include <core/gp_types.h>
29
30#include <utils/gp_timer.h>
31#include <utils/gp_list.h>
32#include <utils/gp_poll.h>
33
34#include <input/gp_ev_queue.h>
35#include <input/gp_task.h>
36
37#include <backends/gp_types.h>
38
39enum gp_backend_attrs {
40 /* window size */
41 GP_BACKEND_SIZE,
42 /* window title */
43 GP_BACKEND_TITLE,
44 /* fullscreen mode */
45 GP_BACKEND_FULLSCREEN,
46};
47
48enum gp_backend_cursors {
49 /* Arrow default cursor type */
50 GP_BACKEND_CURSOR_ARROW,
51 /* Text edit cursor */
52 GP_BACKEND_CURSOR_TEXT_EDIT,
53 /* Crosshair */
54 GP_BACKEND_CURSOR_CROSSHAIR,
55 /* Used typicaly while howering over links */
56 GP_BACKEND_CURSOR_HAND,
57 /* Last cursor + 1 */
58 GP_BACKEND_CURSOR_MAX,
59
60 /* Shows cursor */
61 GP_BACKEND_CURSOR_SHOW = 0xc000,
62 /* Hides cursor */
63 GP_BACKEND_CURSOR_HIDE = 0x8000,
64};
65
66struct gp_backend {
67 /*
68 * Pointer to pixmap app should draw to.
69 *
70 * This MAY change upon a flip operation.
71 */
72 gp_pixmap *pixmap;
73
74 /* Backend name */
75 const char *name;
76
77 /*
78 * If display is buffered, this copies content
79 * of pixmap into display.
80 *
81 * If display is not buffered, this is no-op (set to NULL).
82 */
83 void (*flip)(gp_backend *self);
84
85 /*
86 * Updates display rectangle.
87 *
88 * In contrast to flip operation, the pixmap
89 * must not change (this is intended for updating very small areas).
90 *
91 * If display is not buffered, this is no-op (set to NULL).
92 */
93 void (*update_rect)(gp_backend *self,
94 gp_coord x0, gp_coord y0,
95 gp_coord x1, gp_coord y1);
96
97 /*
98 * Attribute change callback.
99 *
100 * The vals is supposed to be:
101 *
102 * GP_BACKEND_SIZE uint32_t vals[2];
103 * GP_BACKEND_TITLE const char *title
104 * GP_BACKEND_FULLSCREEN int *fs
105 */
106 int (*set_attr)(gp_backend *self, enum gp_backend_attrs attr,
107 const void *vals);
108
112 int (*set_cursor)(gp_backend *self, enum gp_backend_cursors cursor);
113
114 /*
115 * Resize acknowledge callback. This must be called
116 * after you got resize event in order to resize
117 * backend buffers.
118 */
119 int (*resize_ack)(gp_backend *self);
120
121 /*
122 * Exits the backend.
123 */
124 void (*exit)(gp_backend *self);
125
126 /*
127 * Non-blocking event loop.
128 *
129 * Backends that have a file descriptor does not set this function and
130 * rather insert a file descriptor into the fds array.
131 */
132 void (*poll)(gp_backend *self);
133
134 /*
135 * Clipboard handler.
136 */
137 int (*clipboard)(gp_backend *self, gp_clipboard *op);
138
139 /*
140 * Blocking event loop. Blocks until events are ready.
141 *
142 * Note that events received by a backend are not necessarily
143 * translated to input events. So input queue may be empty
144 * after Wait has returned.
145 *
146 * Backends that have a file descriptor does not set this function and
147 * rather insert a file descriptor into the fds array.
148 */
149 void (*wait)(gp_backend *self);
150
151 /* File descriptors to poll for */
152 gp_poll fds;
153
154 /*
155 * Queue to store input events.
156 */
157 gp_ev_queue *event_queue;
158
159 /* Priority queue for timers. */
160 gp_timer *timers;
161
162 /* Task queue */
163 gp_task_queue *task_queue;
164
170 gp_dlist input_drivers;
171
172 void *clipboard_data;
173
177 unsigned int dpi;
178
179 /* Backed private data */
180 char priv[];
181};
182
183#define GP_BACKEND_PRIV(backend) ((void*)(backend)->priv)
184
185static inline void gp_backend_flip(gp_backend *self)
186{
187 if (self->flip)
188 self->flip(self);
189}
190
191void gp_backend_update_rect_xyxy(gp_backend *self,
192 gp_coord x0, gp_coord y0,
193 gp_coord x1, gp_coord y1);
194
195static inline void gp_backend_update_rect(gp_backend *self,
196 gp_coord x0, gp_coord y0,
197 gp_coord x1, gp_coord y1)
198{
199 return gp_backend_update_rect_xyxy(self, x0, y0, x1, y1);
200}
201
202static inline void gp_backend_update_rect_xywh(gp_backend *self,
203 gp_coord x, gp_coord y,
204 gp_size w, gp_size h)
205{
206 gp_backend_update_rect_xyxy(self, x, y, x + w - 1, y + h - 1);
207}
208
209static inline void gp_backend_poll_add(gp_backend *self, gp_fd *fd)
210{
211 gp_poll_add(&self->fds, fd);
212}
213
214static inline void gp_backend_poll_rem(gp_backend *self, gp_fd *fd)
215{
216 gp_poll_rem(&self->fds, fd);
217}
218
219static inline gp_fd *gp_backend_poll_rem_by_fd(gp_backend *self, int fd)
220{
221 return gp_poll_rem_by_fd(&self->fds, fd);
222}
223
224static inline int gp_backend_cursor_set(gp_backend *self, enum gp_backend_cursors cursor)
225{
226 if (self->set_cursor)
227 return self->set_cursor(self, cursor);
228
229 return 1;
230}
231
232void gp_backend_exit(gp_backend *self);
233
234/*
235 * Polls backend, the events are filled into event queue.
236 */
237void gp_backend_poll(gp_backend *self);
238
239/*
240 * Poll and GetEvent combined.
241 */
242gp_event *gp_backend_poll_event(gp_backend *self);
243
244/*
245 * Waits for backend events.
246 */
247void gp_backend_wait(gp_backend *self);
248
249/*
250 * Wait and GetEvent combined.
251 */
252gp_event *gp_backend_wait_event(gp_backend *self);
253
254/*
255 * Adds timer to backend.
256 *
257 * If timer Callback is NULL a timer event is pushed into
258 * the backend event queue once timer expires.
259 *
260 * See input/GP_Timer.h for more information about timers.
261 */
262void gp_backend_add_timer(gp_backend *self, gp_timer *timer);
263
264/*
265 * Removes timer from backend timer queue.
266 */
267void gp_backend_rem_timer(gp_backend *self, gp_timer *timer);
268
269/*
270 * Returns number of timers scheduled in backend.
271 */
272static inline unsigned int gp_backend_timers_in_queue(gp_backend *self)
273{
274 return gp_timer_queue_size(self->timers);
275}
276
277/*
278 * Returns a timeout to a closest timer in ms or -1. Can be passed directly to
279 * poll(2).
280 */
281int gp_backend_timer_timeout(gp_backend *self);
282
283/*
284 * Sets backend caption, if supported.
285 *
286 * When setting caption is not possible/implemented non zero is returned.
287 */
288static inline int gp_backend_set_caption(gp_backend *backend,
289 const char *caption)
290{
291 if (!backend->set_attr)
292 return 1;
293
294 return backend->set_attr(backend, GP_BACKEND_TITLE, caption);
295}
296
297/*
298 * Resize backend, if supported.
299 *
300 * When resizing is not possible/implemented non zero is returned.
301 *
302 * When the backend size matches the passed width and height,
303 * no action is done.
304 *
305 * Note that after calling this, the backend->pixmap pointer may change.
306 */
307int gp_backend_resize(gp_backend *backend, uint32_t w, uint32_t h);
308
309/*
310 * Changes fullscreen mode.
311 *
312 * val 0 - turn off
313 * 1 - turn on
314 * 2 - toggle
315 * 3 - query
316 */
317static inline int gp_backend_fullscreen(gp_backend *backend, int val)
318{
319 if (!backend->set_attr)
320 return 0;
321
322 return backend->set_attr(backend, GP_BACKEND_FULLSCREEN, &val);
323}
324
325/*
326 * Resize acknowledge. You must call this right after you application has
327 * received resize event.
328 *
329 * This will resize backend buffers. After this call returns the backend width
330 * height and pixmap pointer are most likely different.
331 *
332 * This function returns zero on succes. Non zero on failure. If it fails the
333 * best action to take is to save application data and exit (as the backend
334 * may be in undefined state).
335 */
336int gp_backend_resize_ack(gp_backend *self);
337
347void gp_backend_task_ins(gp_backend *self, gp_task *task);
348
355void gp_backend_task_rem(gp_backend *self, gp_task *task);
356
367void gp_backend_task_queue_set(gp_backend *self, gp_task_queue *task_queue);
368
369/*
370 * Event Queue functions.
371 */
372static inline unsigned int gp_backend_events(gp_backend *self)
373{
374 return gp_ev_queue_events(self->event_queue);
375}
376
377static inline gp_event *gp_backend_get_event(gp_backend *self)
378{
379 return gp_ev_queue_get(self->event_queue);
380}
381
382static inline gp_event *gp_backend_peek_event(gp_backend *self)
383{
384 return gp_ev_queue_peek(self->event_queue);
385}
386
387static inline void gp_backend_put_event_back(gp_backend *self, gp_event *ev)
388{
389 gp_ev_queue_put_back(self->event_queue, ev);
390}
391
392#endif /* BACKENDS_GP_BACKEND_H */
A common types.
int gp_coord
Integer type for coordinates i.e. x, y, ...
Definition gp_types.h:19
unsigned int gp_size
Integer type for sizes i.e. w, h, ...
Definition gp_types.h:24
A linked list implementation.
A simple epoll wrapper.
int gp_poll_add(gp_poll *self, gp_fd *fd)
Adds a file descriptor.
gp_fd * gp_poll_rem_by_fd(gp_poll *self, int fd)
Looks up and removes a gp_fd by a fd.
int gp_poll_rem(gp_poll *self, gp_fd *fd)
Removes a file descriptor.
Timers and timer queue implementation.
static unsigned int gp_timer_queue_size(gp_timer *queue)
Returns size of the queue, i.e. number of timers.
Definition gp_timer.h:139
An epoll file descriptor.
Definition gp_poll.h:70
A pixmap buffer.
Definition gp_pixmap.h:33
An epoll instance.
Definition gp_poll.h:46
A timer.
Definition gp_timer.h:26