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].
14 * Linux mmaped 'frame-buffer'
15 * link:http://www.libsdl.org/[SDL]
17 * link:http://aa-project.sourceforge.net/aalib/[AA-lib]
20 Initialization functions
21 ------------------------
27 -------------------------------------------------------------------------------
28 enum GP_LinuxFBFlags {
29 GP_FB_INPUT_KBD = 0x01,
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
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,
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
76 The caption is window caption.
78 And finally flags may change the 'SDL' to go to full-screen mode or make the
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].
102 -------------------------------------------------------------------------------
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,
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
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].
143 -------------------------------------------------------------------------------
146 #include <backends/GP_X11.h>
149 * Returns non-zero if backend is X11 backend
151 int GP_BackendIsX11(GP_Backend *self);
152 -------------------------------------------------------------------------------
154 The 'GP_BackendIsX11()' returns non-zero if backend is X11 backend, zero
158 GP_BackendX11RequestFullscreen
159 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
162 -------------------------------------------------------------------------------
165 #include <backends/GP_X11.h>
168 * Changes full screen mode.
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.
185 -------------------------------------------------------------------------------
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
199 Backend init function
200 ~~~~~~~~~~~~~~~~~~~~~
202 Although there is no unified backend initialization, there is something close to
206 -------------------------------------------------------------------------------
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
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'.
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.
238 -------------------------------------------------------------------------------
239 typdef struct GP_Backend {
246 * Pointer to context APP should draw to.
253 * Connection fd. Set to -1 if not available
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()'.
267 -------------------------------------------------------------------------------
268 #include <backends/GP_Backend.h>
272 void GP_BackendExit(GP_Backend *backend);
273 -------------------------------------------------------------------------------
275 Calls a backend exit callback. Restores the display, keyboard, etc. state
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.
291 -------------------------------------------------------------------------------
292 #include <backends/GP_Backend.h>
296 GP_BackendFlip(GP_Backend *backend);
297 -------------------------------------------------------------------------------
299 Flips a screen. Blits backend buffer to the screen or window if the backend is
307 -------------------------------------------------------------------------------
308 #include <backends/GP_Backend.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.
324 -------------------------------------------------------------------------------
325 #include <backends/GP_Backend.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
338 This call returns immediately after queued events (from X11 socket, etc.) were
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
353 -------------------------------------------------------------------------------
354 #include <backends/GP_Backend.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
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
374 .Example 'GP_BackendPollEvent()' usage.
376 -------------------------------------------------------------------------------
377 /* Called either repeatedly or when data are ready on backend fd */
381 while (GP_BackendPollEvent(backend, &ev) {
386 -------------------------------------------------------------------------------
393 -------------------------------------------------------------------------------
394 #include <backends/GP_Backend.h>
398 void GP_BackendWait(GP_Backend *self);
399 -------------------------------------------------------------------------------
401 Blocks until backend event arrives.
404 Events received by backend are not necessarily translated into the input
411 -------------------------------------------------------------------------------
412 #include <backends/GP_Backend.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
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.
431 -------------------------------------------------------------------------------
432 /* This is the main program loop */
436 GP_BackendWaitEvent(backend, &ev);
441 -------------------------------------------------------------------------------
448 -------------------------------------------------------------------------------
449 #include <backends/GP_Backend.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].
471 -------------------------------------------------------------------------------
472 #include <backends/GP_Backend.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 ^^^^^^^^^^^^^^^^^^^^^^^
485 -------------------------------------------------------------------------------
486 #include <backends/GP_Backend.h>
490 void GP_BackendTimersInQueue(GP_Backend *self);
491 -------------------------------------------------------------------------------
493 Returns number of timers scheduled in backend timer queue.
495 GP_BackendEventsQueued
496 ^^^^^^^^^^^^^^^^^^^^^^
499 -------------------------------------------------------------------------------
500 #include <backends/GP_Backend.h>
504 unsigned int GP_BackendEventsQueued(GP_Backend *self);
505 -------------------------------------------------------------------------------
507 Returns number of events queued in the backend event queue.
515 -------------------------------------------------------------------------------
516 #include <backends/GP_Backend.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
527 If there are no events queued the call returns immediately with zero return
530 TIP: For more information on events see link:input.html[input events]
538 -------------------------------------------------------------------------------
539 #include <backends/GP_Backend.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
549 GP_BackendPutEventBack
550 ^^^^^^^^^^^^^^^^^^^^^^
553 -------------------------------------------------------------------------------
554 #include <backends/GP_Backend.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.
568 -------------------------------------------------------------------------------
569 #include <backends/GP_Backend.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.
585 -------------------------------------------------------------------------------
586 #include <backends/GP_Backend.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.
607 -------------------------------------------------------------------------------
608 #include <backends/GP_Backend.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