tests: fix HTML-gen sh script (dash compatibility)
[gfxprim.git] / doc / backends.txt
blob481a4256de28e71b9ecb9b26aabeec629266cc03
1 Drawing Backends
2 ================
4 Drawing backends provide means to draw into computer screen or into a window
5 inside of running operating system. Instead of having one unified
6 initialization interface each backend has it's specific function and semantics
7 but once backend is initialized the backend structure provides unified API for 
8 controlling the drawing.
10 So far there are backends for Linux mmaped 'frame-buffer', 'libSDL' and
11 'X Window System'.
13 TIP: For example usage see backend link:example_backend.html[example].
15 Initialization functions
16 ------------------------
18 Linux Framebuffer
19 ~~~~~~~~~~~~~~~~~
21 [source,c]
22 -------------------------------------------------------------------------------
23 GP_Backend *GP_BackendLinuxFBInit(const char *path, int flag);
24 -------------------------------------------------------------------------------
26 Initializes mmaped frame-buffer backend. The path is path to the frame-buffer
27 device i.e. '/dev/fbX'. This backend is not buffered, everything you draw
28 appears on the screen right away (an switch may be added for that purpose).
30 If flag is set console KBD driver is used to feed keystrokes into the event
31 queue, otherwise no events are generated and you are expected to initialize
32 input event driver in order to get keystrokes and/or pointer events.
35 SDL
36 ~~~
38 [source,c]
39 -------------------------------------------------------------------------------
40 enum GP_BackendSDLFlags {
41         GP_SDL_FULLSCREEN = 0x01,
42         GP_SDL_RESIZABLE  = 0x02,
45 GP_Backend *GP_BackendSDLInit(GP_Size w, GP_Size h,
46                               uint8_t bpp, uint8_t flags,
47                               const char *caption);
48 -------------------------------------------------------------------------------
50 Initialize 'SDL' as an backend driver. The backend is thread safe as all the
51 operations are guarded by locks.
53 You can't initialize more than one backend at a time, which is inherited 'SDL'
54 limitation. If you call the initialization for a second time, you will get a
55 pointer to already running backend.
57 If w, h and/or bpp are zero 'SDL' tries to do a guess, most of the time wrong
58 for w and h though.
60 The caption is window caption.
62 And finally flags may change the SDL to go to full-screen mode or make the
63 window resizable.
66 [source,c]
67 -------------------------------------------------------------------------------
68 #include <backends/GP_SDL_Context.h>
70 int GP_ContextFromSurface(GP_Context *c, const SDL_Surface *surf);
71 -------------------------------------------------------------------------------
73 This function allows you to mix 'SDL' and 'GFXprim' code.
75 It initializes a 'GFXprim' context from the 'SDL' surface using the pixel
76 buffer from surface as pixel buffer for the context.
78 Function returns zero on success and non-zero on failure (i.e. there is no
79 'GFXprim' pixel type to match given surface).
81 For example usage see the link:example_SDL_glue.html[SDL glue example].
83 X Server
84 ~~~~~~~~
86 [source,c]
87 -------------------------------------------------------------------------------
88 #include <GP.h>
89 /* or */
90 #include <backends/GP_X11.h>
92 enum GP_BackendX11Flags {
93         /* When set, w and h is ignored and root window is used */
94         GP_X11_USE_ROOT_WIN = 0x01,
95         
96         /* Create new borderless window above the root window */
97         GP_X11_CREATE_ROOT_WIN = 0x02,
99         /* Start fullscreen */
100         GP_X11_FULLSCREEN = 0x04,
102         /* Do not use MIT SHM even if available */
103         GP_X11_DISABLE_SHM = 0x08,
106 GP_Backend *GP_BackendX11Init(const char *display, int x, int y,
107                               unsigned int w, unsigned int h,
108                               const char *caption,
109                               enum GP_BackendX11Flags flags);
110 -------------------------------------------------------------------------------
112 Returns pointer to initialized X11 backend or in case of failure 'NULL'.
114 When display is 'NULL' default display is used (which is what you want most of the
115 time).
117 This backends supports multiple windows. Each time you call the initialization
118 routine new backend structure is returned. All backend instances share the Xlib
119 connection so you need to wait or poll only on one of them. Each backend, on
120 the other hand, has its own input queue.
122 TIP: See multiple windows link:example_x11_windows.html[example].
124 GP_BackendIsX11
125 ^^^^^^^^^^^^^^^
127 [source,c]
128 -------------------------------------------------------------------------------
129 #include <GP.h>
130 /* or */
131 #include <backends/GP_X11.h>
134  * Returns non-zero if backend is X11 backend
135  */
136 int GP_BackendIsX11(GP_Backend *self);
137 -------------------------------------------------------------------------------
139 The 'GP_BackendIsX11()' returns non-zero if backend is X11 backend, zero
140 otherwise.
143 GP_BackendX11RequestFullscreen
144 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
146 [source,c]
147 -------------------------------------------------------------------------------
148 #include <GP.h>
149 /* or */
150 #include <backends/GP_X11.h>
153  * Changes full screen mode.
154  * 
155  * 0 = off
156  * 1 = on
157  * 2 = toggle
158  */
159 void GP_BackendX11RequestFullscreen(GP_Backend *self, int mode);
160 -------------------------------------------------------------------------------
162 The 'GP_BackendX11RequestFullscreen' can toggle fullscreen mode at runtime.
164 It will most likely generate resize event. See the 'GP_BackendResizeAck()' bellow.
167 Overall init function
168 ~~~~~~~~~~~~~~~~~~~~~
170 Although there is no unified backend initialization, there is something close to
173 [source,c]
174 -------------------------------------------------------------------------------
175 #include <GP.h>
177 GP_Backend *GP_BackendInit(const char *params, const char *caption, FILE *help);
178 -------------------------------------------------------------------------------
180 This function takes a params string as an parameter which is used for
181 determining backend-dependent parameters. The format is
182 'backend_name:backend_parameters' where backend parameters may be window size
183 (either 'WxH' or 'FS' in case of SDL backend). The caption is window caption
184 (which is ignored in some of the cases) and the 'FILE' is file, where an error
185 is printed in case of failure, you should mostly use 'stderr' for that
186 purpose. If params is set to 'NULL' the the call only prints help into the
187 passed help 'FILE'. If initialization was successful pointer to allocated and
188 initialized backend is returned otherwise 'NULL' is returned and some helpful
189 information should be printed into the passed help 'FILE'.
192 General Backend API
193 ~~~~~~~~~~~~~~~~~~~
195 The backend API consist of a structure with callbacks. Every backend
196 initialization yields this structure. Although is possible to call these
197 pointers directly it's not recommended and everybody should rather use backend
198 inline functions instead as they provide more convenient API and do additional
199 sanity checks on parameters.
201 [source,c]
202 -------------------------------------------------------------------------------
203 typdef struct GP_Backend {
204         /*
205          * Backend name.
206          */
207         const char *name;
209         /* 
210          * Pointer to context APP should draw to.
211          */
212         GP_Context *context;
214         ...
216         /* 
217          * Connection fd. Set to -1 if not available 
218          */
219         int fd;
221 -------------------------------------------------------------------------------
223 The file descriptor 'fd' is either set to -1 (in case of SDL that does not
224 export it) or to a backend connection file descriptor usable for 'select()' or
225 'poll()'.
227 GP_BackendExit
228 ^^^^^^^^^^^^^^
230 [source,c]
231 -------------------------------------------------------------------------------
232 #include <backends/GP_Backend.h>
233 /* or */
234 #include <GP.h>
236 void GP_BackendExit(GP_Backend *backend);
237 -------------------------------------------------------------------------------
239 Calls an backend exit callback. Restores the display, keyboard, etc. state
240 back.
242 WARNING: It's important to call this functions on application exit. If you
243          doesn't do so, the state of the display, resolution etc. may not be
244          restored back to its original state. This includes program crashes and
245          interruptions. Also this function may not be signal-async-safe, it's
246          better to set signal handlers that calls it on SEGFAULT and SIGBUS
247          as this usually works and not doing so may leave non-working system
248          with black display or non-responding keyboard.
251 GP_BackendFlip
252 ^^^^^^^^^^^^^^
254 [source,c]
255 -------------------------------------------------------------------------------
256 #include <backends/GP_Backend.h>
257 /* or */
258 #include <GP.h>
260 GP_BackendFlip(GP_Backend *backend);
261 -------------------------------------------------------------------------------
263 Flips a screen. Blits backend buffer to the screen or window if the backend is
264 buffered.
267 GP_BackendUpdateRect
268 ^^^^^^^^^^^^^^^^^^^^
270 [source,c]
271 -------------------------------------------------------------------------------
272 #include <backends/GP_Backend.h>
273 /* or */
274 #include <GP.h>
276 void GP_BackendUpdateRect(GP_Backend *backend,
277                           GP_Coord x0, GP_Coord y0,
278                           GP_Coord x1, GP_Coord y1);
279 -------------------------------------------------------------------------------
281 Updates particular rectangle in case backend is buffered.
284 GP_BackendPoll
285 ^^^^^^^^^^^^^^
287 [source,c]
288 -------------------------------------------------------------------------------
289 #include <backends/GP_Backend.h>
290 /* or */
291 #include <GP.h>
293 void GP_BackendPoll(GP_Backend *backend);
294 -------------------------------------------------------------------------------
296 Polls for backend events. 
298 The poll only reads events from event source (i.e. X11 socket, Linux evdev
299 file descriptor), process them and may place new event into the backend event
300 queue.
302 This call returns immediately after queued events (from X11 socket, etc.) were
303 processed.
305 For backends that do not expose file descriptor (namely SDL) this should be
306 called repeatedly. For other backends it may be called either repeatedly or
307 when data are ready on file-descriptor.
309 If the backend is the only source of events in your application, you should
310 consider using the 'GP_BackendWait()' or 'GP_BackendEventWait()' described
311 bellow.
313 GP_BackendPollEvent
314 ^^^^^^^^^^^^^^^^^^^
316 [source,c]
317 -------------------------------------------------------------------------------
318 #include <backends/GP_Backend.h>
319 /* or */
320 #include <GP.h>
322 int GP_BackendPollEvent(GP_Backend *self, GP_Event *ev);
323 -------------------------------------------------------------------------------
325 Combines the 'GP_BackendPoll()' with 'GP_BackendGetEvent()'.
327 If there are any events in the backend event queue, the top event is removed
328 from the queue and copied into the memory pointed by 'ev' and the call returns
329 immediately.
331 If backend event queue is empty 'GP_BackendPoll()' is called. Then again the
332 backend event queue is checked and if an event is found it's removed from the
333 queue and copied into the 'ev'.
335 Returns non-zero if event was copied into the memory pointed by 'ev', zero
336 otherwise.
338 .Example 'GP_BackendPollEvent()' usage.
339 [source,c]
340 -------------------------------------------------------------------------------
341         /* Called either repeatedly or when data are ready on backend fd */
343         GP_Event ev;
345         while (GP_BackendPollEvent(backend, &ev) {
347                 /* process events */
348         
349         }
350 -------------------------------------------------------------------------------
353 GP_BackendWait
354 ^^^^^^^^^^^^^^
356 [source,c]
357 -------------------------------------------------------------------------------
358 #include <backends/GP_Backend.h>
359 /* or */
360 #include <GP.h>
362 void GP_BackendWait(GP_Backend *self);
363 -------------------------------------------------------------------------------
365 Blocks until backend event arrives.
367 [NOTE]
368 Events received by backend are not necessarily translated into the input
369 events.
371 [WARNING]
372 Using GP_BackendWait() in multi-threaded program will most likely cause
373 deadlocks. As the backend data structures and connection is guarded by a lock
374 any other backend function (called from different thread while
375 GP_BackendWait() is blocking) will lock until GP_BackendWait() returns (i.e.
376 event was received).
379 GP_BackendWaitEvent
380 ^^^^^^^^^^^^^^^^^^^
382 [source,c]
383 -------------------------------------------------------------------------------
384 #include <backends/GP_Backend.h>
385 /* or */
386 #include <GP.h>
388 void GP_BackendWaitEvent(GP_Backend *self, GP_Event *ev);
389 -------------------------------------------------------------------------------
391 Combines the 'GP_BackendWait()' with 'GP_BackendGetEvent()'.
393 If there are any events in the backend event queue, the top event is removed
394 from the queue and copied into the memory pointed by 'ev' and the call returns
395 immediately.
397 If backend event queue is empty 'GP_BackendWait()' is called until there are
398 any events in the backend event queue. Then the top event is removed from the
399 queue and the call returns.
401 .Example 'GP_BackendWaitEvent()' usage.
402 [source,c]
403 -------------------------------------------------------------------------------
404         /* This is the main program loop */
405         GP_Event ev;
407         for (;;) {
408                 GP_BackendWaitEvent(backend, &ev);
410                 /* process events */
412         }
413 -------------------------------------------------------------------------------
416 GP_BackendEventsQueued
417 ^^^^^^^^^^^^^^^^^^^^^^
419 [source,c]
420 -------------------------------------------------------------------------------
421 #include <backends/GP_Backend.h>
422 /* or */
423 #include <GP.h>
425 unsigned int GP_BackendEventsQueued(GP_Backend *self);
426 -------------------------------------------------------------------------------
428 Returns number of events queued in the backend event queue.
432 GP_BackendGetEvent
433 ^^^^^^^^^^^^^^^^^^
435 [source,c]
436 -------------------------------------------------------------------------------
437 #include <backends/GP_Backend.h>
438 /* or */
439 #include <GP.h>
441 int GP_BackendGetEvent(GP_Backend *self, GP_Event *ev);
442 -------------------------------------------------------------------------------
444 In case there are any events queued, the top event is removed from the queue,
445 copied into the event structure that is passed as argument and non-zero is
446 returned.
448 If there are no events queued the call returns immediately with zero return
449 value.
451 TIP: For more information on events see link:input.html[input events]
452      documentation.
455 GP_BackendSetCaption
456 ^^^^^^^^^^^^^^^^^^^^
458 [source,c]
459 -------------------------------------------------------------------------------
460 #include <backends/GP_Backend.h>
461 /* or */
462 #include <GP.h>
464 int GP_BackendSetCaption(GP_Backend *backend, const char *caption)
465 -------------------------------------------------------------------------------
467 Sets backend caption. On success zero is returned. On failure (backend doesn't
468 support caption, operation failed) non zero is returned.
472 GP_BackendResize
473 ^^^^^^^^^^^^^^^^
475 [source,c]
476 -------------------------------------------------------------------------------
477 #include <backends/GP_Backend.h>
478 /* or */
479 #include <GP.h>
481 int GP_BackendResize(GP_Backend *backend, uint32_t w, uint32_t h);
482 -------------------------------------------------------------------------------
484 Requests backend resize. If backend resize is supported and the resize request
485 was successful (i.e. X server allowed us to resize the window) the resize
486 event will be send and should be handled in your event loop. You must respond
487 to it by the 'GP_BackendResizeAck()' described bellow.
489 NOTE: The backend->context pointer may change upon calling this function and
490       at least backend->context->pixels pointer will change.
493 GP_BackendResizeAck
494 ^^^^^^^^^^^^^^^^^^^
496 [source,c]
497 -------------------------------------------------------------------------------
498 #include <backends/GP_Backend.h>
499 /* or */
500 #include <GP.h>
502 int GP_BackendResizeAck(GP_Backend *self);
503 -------------------------------------------------------------------------------
505 If backend is resizable by user interaction (for example X Window) you will
506 get resize event for each change of window size, however the backend context
507 will not be resized until you call this function. This is useful in
508 multi-threaded application where one threads waits for events and others draws
509 into the buffer so you can stop the drawing threads before the backend context
510 size change.