demos: Fix and cleanup GP_BackendInit() + docs.
[gfxprim/pasky.git] / doc / backends.txt
blob4196c8f8d976af197c3ad67169a83501e86f4196
1 Drawing Backends
2 ----------------
4 Drawing backends provide means to draw on computer screen or into a window.
5 Instead of having one unified initialization interface each backend has it's
6 specific function and semantics but once backend is initialized the backend
7 structure provides unified API for controlling the drawing.
9 TIP: For example usage see backend link:example_backend.html[example].
11 Supported backends
12 ------------------
14 * Linux mmaped 'frame-buffer'
15 * link:http://www.libsdl.org/[SDL]
16 * 'X Window System'
17 * link:http://aa-project.sourceforge.net/aalib/[AA-lib]
20 Initialization functions
21 ------------------------
23 Linux Framebuffer
24 ~~~~~~~~~~~~~~~~~
26 [source,c]
27 -------------------------------------------------------------------------------
28 enum GP_LinuxFBFlags {
29         GP_FB_INPUT_KBD = 0x01,
30         GP_FB_SHADOW = 0x02,
31         GP_FB_ALLOC_CON = 0x04,
34 GP_Backend *GP_BackendLinuxFBInit(const char *path, int flags);
35 -------------------------------------------------------------------------------
37 Initializes mmaped frame-buffer backend. The path is path to the frame-buffer
38 device i.e. '/dev/fbX'.
40 If 'GP_FB_INPUT_KBD' flag is set console KBD driver is used to feed keystrokes
41 into the event queue, otherwise no events are generated and you are expected to
42 initialize input event driver yourself.
44 If 'GP_FB_SHADOW' flag is set shadow frame-buffer is allocated and used for
45 drawing, the memory is blitted to mmaped frame-buffer on Blit() or UpdateRect()
46 operation. Otherwise the frame-buffer mapped memory is used directly.
48 If 'GP_FB_ALLOC_CON' flag is set new console is allocated, otherwise current
49 console is used.
51 SDL
52 ~~~
54 [source,c]
55 -------------------------------------------------------------------------------
56 enum GP_BackendSDLFlags {
57         GP_SDL_FULLSCREEN = 0x01,
58         GP_SDL_RESIZABLE  = 0x02,
61 GP_Backend *GP_BackendSDLInit(GP_Size w, GP_Size h,
62                               uint8_t bpp, uint8_t flags,
63                               const char *caption);
64 -------------------------------------------------------------------------------
66 Initialize 'SDL' as a backend driver. The backend is thread safe as all the
67 operations are guarded by locks.
69 You can't initialize more than one backend at a time, which is inherited 'SDL'
70 limitation. If you call the initialization for a second time, you will get a
71 pointer to already running backend.
73 If w, h and/or bpp are zero 'SDL' tries to do a guess, most of the time wrong
74 for w and h though.
76 The caption is window caption.
78 And finally flags may change the 'SDL' to go to full-screen mode or make the
79 window resizable.
81 [source,c]
82 -------------------------------------------------------------------------------
83 #include <backends/GP_SDL_Context.h>
85 int GP_ContextFromSDLSurface(GP_Context *c, const SDL_Surface *surf);
86 -------------------------------------------------------------------------------
88 This function allows you to mix 'SDL' and 'GFXprim' code.
90 It initializes a 'GFXprim' context from the 'SDL' surface using the pixel
91 buffer from surface as pixel buffer for the context.
93 Function returns zero on success and non-zero on failure (i.e. there is no
94 'GFXprim' pixel type to match given surface).
96 For example usage see the link:example_SDL_glue.html[SDL glue example].
98 X Server
99 ~~~~~~~~
101 [source,c]
102 -------------------------------------------------------------------------------
103 #include <GP.h>
104 /* or */
105 #include <backends/GP_X11.h>
107 enum GP_BackendX11Flags {
108         /* When set, w and h is ignored and root window is used */
109         GP_X11_USE_ROOT_WIN = 0x01,
111         /* Create new borderless window above the root window */
112         GP_X11_CREATE_ROOT_WIN = 0x02,
114         /* Start fullscreen */
115         GP_X11_FULLSCREEN = 0x04,
117         /* Do not use MIT SHM even if available */
118         GP_X11_DISABLE_SHM = 0x08,
121 GP_Backend *GP_BackendX11Init(const char *display, int x, int y,
122                               unsigned int w, unsigned int h,
123                               const char *caption,
124                               enum GP_BackendX11Flags flags);
125 -------------------------------------------------------------------------------
127 Returns pointer to initialized X11 backend or in case of failure 'NULL'.
129 When display is 'NULL' default display is used (which is what you want most of the
130 time).
132 This backends supports multiple windows. Each time you call the initialization
133 routine new backend structure is returned. All backend instances share the Xlib
134 connection so you need to wait or poll only on one of them. Each backend, on
135 the other hand, has its own input queue.
137 TIP: See multiple windows link:example_x11_windows.html[example].
139 GP_BackendIsX11
140 ^^^^^^^^^^^^^^^
142 [source,c]
143 -------------------------------------------------------------------------------
144 #include <GP.h>
145 /* or */
146 #include <backends/GP_X11.h>
149  * Returns non-zero if backend is X11 backend
150  */
151 int GP_BackendIsX11(GP_Backend *self);
152 -------------------------------------------------------------------------------
154 The 'GP_BackendIsX11()' returns non-zero if backend is X11 backend, zero
155 otherwise.
158 GP_BackendX11RequestFullscreen
159 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
161 [source,c]
162 -------------------------------------------------------------------------------
163 #include <GP.h>
164 /* or */
165 #include <backends/GP_X11.h>
168  * Changes full screen mode.
170  * 0 = off
171  * 1 = on
172  * 2 = toggle
173  */
174 void GP_BackendX11RequestFullscreen(GP_Backend *self, int mode);
175 -------------------------------------------------------------------------------
177 The 'GP_BackendX11RequestFullscreen' can toggle fullscreen mode at runtime.
179 It will most likely generate resize event. See the 'GP_BackendResizeAck()' bellow.
181 AA-lib
182 ~~~~~~
184 [source,c]
185 -------------------------------------------------------------------------------
186 #include <GP.h>
187 /* or */
188 #include <backends/AALib.h>
190 GP_Backend *GP_BackendAALibInit(void);
191 -------------------------------------------------------------------------------
193 Currently the 'AA-lib' backend uses default initialization parameters.
195 Way how to pass 'AA-lib' specific parameters will be added. This interface
196 will likely change.
198 [[Backend_Init]]
199 Backend init function
200 ~~~~~~~~~~~~~~~~~~~~~
202 Although there is no unified backend initialization, there is something close to
205 [source,c]
206 -------------------------------------------------------------------------------
207 #include <GP.h>
209 GP_Backend *GP_BackendInit(const char *params, const char *caption);
210 -------------------------------------------------------------------------------
212 The 'params' string composes of backend name and backend dependend parameters.
213 The format is 'backend_name:backend_params' for example
214 'fb:new_console:/dev/fb1'.
216 The 'caption' string is used for window caption, in case of X11 backend or may
217 be ignored completly in case of framebuffer backend.
219 If 'params' is set to '"help"' help for all backends is printed into the
220 'stderr'.
222 If initialization was successful pointer to allocated and initialized backend
223 is returned otherwise 'NULL' is returned and some helpful information should
224 be printed into the 'stderr'.
227 General Backend API
228 ~~~~~~~~~~~~~~~~~~~
230 The backend API consist of a structure with callbacks. Every backend
231 initialization yields this structure. Although is possible to call these
232 pointers directly it's not recommended and everybody should rather use backend
233 (inline) functions instead as they provide more convenient API and do
234 additional sanity checks on parameters. Also functionality such as timers
235 will not work if you decide to call raw callbacks.
237 [source,c]
238 -------------------------------------------------------------------------------
239 typdef struct GP_Backend {
240         /*
241          * Backend name.
242          */
243         const char *name;
245         /*
246          * Pointer to context APP should draw to.
247          */
248         GP_Context *context;
250         ...
252         /*
253          * Connection fd. Set to -1 if not available
254          */
255         int fd;
257 -------------------------------------------------------------------------------
259 The file descriptor 'fd' is either set to -1 (in case of 'SDL' or 'AA-lib' as
260 they does not export it) or to a backend connection file descriptor usable for
261 'select()' or 'poll()'.
263 GP_BackendExit
264 ^^^^^^^^^^^^^^
266 [source,c]
267 -------------------------------------------------------------------------------
268 #include <backends/GP_Backend.h>
269 /* or */
270 #include <GP.h>
272 void GP_BackendExit(GP_Backend *backend);
273 -------------------------------------------------------------------------------
275 Calls a backend exit callback. Restores the display, keyboard, etc. state
276 back.
278 WARNING: It's important to call this functions on application exit. If you
279          doesn't do so, the state of the display, resolution etc. may not be
280          restored back to its original state. This includes program crashes and
281          interruptions. Also this function may not be signal-async-safe, it's
282          better to set signal handlers that calls it on SEGFAULT and SIGBUS
283          as this usually works and not doing so may leave non-working system
284          with black display or non-responding keyboard.
287 GP_BackendFlip
288 ^^^^^^^^^^^^^^
290 [source,c]
291 -------------------------------------------------------------------------------
292 #include <backends/GP_Backend.h>
293 /* or */
294 #include <GP.h>
296 GP_BackendFlip(GP_Backend *backend);
297 -------------------------------------------------------------------------------
299 Flips a screen. Blits backend buffer to the screen or window if the backend is
300 buffered.
303 GP_BackendUpdateRect
304 ^^^^^^^^^^^^^^^^^^^^
306 [source,c]
307 -------------------------------------------------------------------------------
308 #include <backends/GP_Backend.h>
309 /* or */
310 #include <GP.h>
312 void GP_BackendUpdateRect(GP_Backend *backend,
313                           GP_Coord x0, GP_Coord y0,
314                           GP_Coord x1, GP_Coord y1);
315 -------------------------------------------------------------------------------
317 Updates particular rectangle in case backend is buffered.
320 GP_BackendPoll
321 ^^^^^^^^^^^^^^
323 [source,c]
324 -------------------------------------------------------------------------------
325 #include <backends/GP_Backend.h>
326 /* or */
327 #include <GP.h>
329 void GP_BackendPoll(GP_Backend *backend);
330 -------------------------------------------------------------------------------
332 Polls for backend events.
334 The poll only reads events from event source (i.e. X11 socket, Linux evdev
335 file descriptor), process them and may place new event into the backend event
336 queue.
338 This call returns immediately after queued events (from X11 socket, etc.) were
339 processed.
341 For backends that do not expose file descriptor (namely SDL) this should be
342 called repeatedly. For other backends it may be called either repeatedly or
343 when data are ready on file-descriptor.
345 If the backend is the only source of events in your application, you should
346 consider using the 'GP_BackendWait()' or 'GP_BackendEventWait()' described
347 bellow.
349 GP_BackendPollEvent
350 ^^^^^^^^^^^^^^^^^^^
352 [source,c]
353 -------------------------------------------------------------------------------
354 #include <backends/GP_Backend.h>
355 /* or */
356 #include <GP.h>
358 int GP_BackendPollEvent(GP_Backend *self, GP_Event *ev);
359 -------------------------------------------------------------------------------
361 Combines the 'GP_BackendPoll()' with 'GP_BackendGetEvent()'.
363 If there are any events in the backend event queue, the top event is removed
364 from the queue and copied into the memory pointed by 'ev' and the call returns
365 immediately.
367 If backend event queue is empty 'GP_BackendPoll()' is called. Then again the
368 backend event queue is checked and if an event is found it's removed from the
369 queue and copied into the 'ev'.
371 Returns non-zero if event was copied into the memory pointed by 'ev', zero
372 otherwise.
374 .Example 'GP_BackendPollEvent()' usage.
375 [source,c]
376 -------------------------------------------------------------------------------
377         /* Called either repeatedly or when data are ready on backend fd */
379         GP_Event ev;
381         while (GP_BackendPollEvent(backend, &ev) {
383                 /* process events */
385         }
386 -------------------------------------------------------------------------------
389 GP_BackendWait
390 ^^^^^^^^^^^^^^
392 [source,c]
393 -------------------------------------------------------------------------------
394 #include <backends/GP_Backend.h>
395 /* or */
396 #include <GP.h>
398 void GP_BackendWait(GP_Backend *self);
399 -------------------------------------------------------------------------------
401 Blocks until backend event arrives.
403 [NOTE]
404 Events received by backend are not necessarily translated into the input
405 events.
407 GP_BackendWaitEvent
408 ^^^^^^^^^^^^^^^^^^^
410 [source,c]
411 -------------------------------------------------------------------------------
412 #include <backends/GP_Backend.h>
413 /* or */
414 #include <GP.h>
416 void GP_BackendWaitEvent(GP_Backend *self, GP_Event *ev);
417 -------------------------------------------------------------------------------
419 Combines the 'GP_BackendWait()' with 'GP_BackendGetEvent()'.
421 If there are any events in the backend event queue, the top event is removed
422 from the queue and copied into the memory pointed by 'ev' and the call returns
423 immediately.
425 If backend event queue is empty 'GP_BackendWait()' is called until there are
426 any events in the backend event queue. Then the top event is removed from the
427 queue and the call returns.
429 .Example 'GP_BackendWaitEvent()' usage.
430 [source,c]
431 -------------------------------------------------------------------------------
432         /* This is the main program loop */
433         GP_Event ev;
435         for (;;) {
436                 GP_BackendWaitEvent(backend, &ev);
438                 /* process events */
440         }
441 -------------------------------------------------------------------------------
443 [[Timers]]
444 GP_BackendAddTimer
445 ^^^^^^^^^^^^^^^^^^
447 [source,c]
448 -------------------------------------------------------------------------------
449 #include <backends/GP_Backend.h>
450 /* or */
451 #include <GP.h>
453 void GP_BackendAddTimer(GP_Backend *self, GP_Timer *timer);
454 -------------------------------------------------------------------------------
456 Adds a link:input.html#Timers[timer] to the backend timer queue.
458 Timers added to the backend are processed automatically while you call any of
459 backend 'Poll' or 'Wait' functions.
461 If timer callback is set to 'NULL' a timer event is pushed to the backend
462 input queue once timer has expired otherwise timer callback is called.
464 TIP: For example usage see backend timers
465      link:example_backend_timers.html[example].
467 GP_BackendRemTimer
468 ^^^^^^^^^^^^^^^^^^
470 [source,c]
471 -------------------------------------------------------------------------------
472 #include <backends/GP_Backend.h>
473 /* or */
474 #include <GP.h>
476 void GP_BackendRemTimer(GP_Backend *self, GP_Timer *timer);
477 -------------------------------------------------------------------------------
479 Removes a link:input.html#Timers[timer] from the backend timer queue.
481 GP_BackendTimersInQueue
482 ^^^^^^^^^^^^^^^^^^^^^^^
484 [source,c]
485 -------------------------------------------------------------------------------
486 #include <backends/GP_Backend.h>
487 /* or */
488 #include <GP.h>
490 void GP_BackendTimersInQueue(GP_Backend *self);
491 -------------------------------------------------------------------------------
493 Returns number of timers scheduled in backend timer queue.
495 GP_BackendEventsQueued
496 ^^^^^^^^^^^^^^^^^^^^^^
498 [source,c]
499 -------------------------------------------------------------------------------
500 #include <backends/GP_Backend.h>
501 /* or */
502 #include <GP.h>
504 unsigned int GP_BackendEventsQueued(GP_Backend *self);
505 -------------------------------------------------------------------------------
507 Returns number of events queued in the backend event queue.
511 GP_BackendGetEvent
512 ^^^^^^^^^^^^^^^^^^
514 [source,c]
515 -------------------------------------------------------------------------------
516 #include <backends/GP_Backend.h>
517 /* or */
518 #include <GP.h>
520 int GP_BackendGetEvent(GP_Backend *self, GP_Event *ev);
521 -------------------------------------------------------------------------------
523 In case there are any events queued, the top event is removed from the queue,
524 copied into the event structure that is passed as argument and non-zero is
525 returned.
527 If there are no events queued the call returns immediately with zero return
528 value.
530 TIP: For more information on events see link:input.html[input events]
531      documentation.
534 GP_BackendPeekEvent
535 ^^^^^^^^^^^^^^^^^^^
537 [source,c]
538 -------------------------------------------------------------------------------
539 #include <backends/GP_Backend.h>
540 /* or */
541 #include <GP.h>
543 int GP_BackendPeekEvent(GP_Backend *self, GP_Event *ev);
544 -------------------------------------------------------------------------------
546 Same as +GP_BackendPeekEvent()+ but the top event is not removed from the
547 queue.
549 GP_BackendPutEventBack
550 ^^^^^^^^^^^^^^^^^^^^^^
552 [source,c]
553 -------------------------------------------------------------------------------
554 #include <backends/GP_Backend.h>
555 /* or */
556 #include <GP.h>
558 void GP_BackendPutEventBack(GP_Backend *self, GP_Event *ev);
559 -------------------------------------------------------------------------------
561 Puts event to the top of the queue. May be useful for putting back events that
562 were removed from the queue.
564 GP_BackendSetCaption
565 ^^^^^^^^^^^^^^^^^^^^
567 [source,c]
568 -------------------------------------------------------------------------------
569 #include <backends/GP_Backend.h>
570 /* or */
571 #include <GP.h>
573 int GP_BackendSetCaption(GP_Backend *backend, const char *caption)
574 -------------------------------------------------------------------------------
576 Sets backend caption. On success zero is returned. On failure (backend doesn't
577 support caption, operation failed) non zero is returned.
581 GP_BackendResize
582 ^^^^^^^^^^^^^^^^
584 [source,c]
585 -------------------------------------------------------------------------------
586 #include <backends/GP_Backend.h>
587 /* or */
588 #include <GP.h>
590 int GP_BackendResize(GP_Backend *backend, uint32_t w, uint32_t h);
591 -------------------------------------------------------------------------------
593 Requests backend resize. If backend resize is supported and the resize request
594 was successful (i.e. X server allowed us to resize the window) the resize
595 event will be send and should be handled in your event loop. You must respond
596 to it by the 'GP_BackendResizeAck()' described bellow.
598 NOTE: The backend->context pointer may change upon calling this function and
599       at least backend->context->pixels pointer will change.
602 [[ResizeAck]]
603 GP_BackendResizeAck
604 ^^^^^^^^^^^^^^^^^^^
606 [source,c]
607 -------------------------------------------------------------------------------
608 #include <backends/GP_Backend.h>
609 /* or */
610 #include <GP.h>
612 int GP_BackendResizeAck(GP_Backend *self);
613 -------------------------------------------------------------------------------
615 If backend is resizable by user interaction (for example X Window) you will
616 get resize event for each change of window size, however the backend context
617 will not be resized until you call this function. This is useful in
618 multi-threaded application where one threads waits for events and others draws
619 into the buffer so you can stop the drawing threads before the backend context
620 size change.