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
13 TIP: For example usage see backend link:example_backend.html[example].
15 Initialization functions
16 ------------------------
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.
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,
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
60 The caption is window caption.
62 And finally flags may change the SDL to go to full-screen mode or make the
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].
87 -------------------------------------------------------------------------------
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,
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,
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
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].
128 -------------------------------------------------------------------------------
131 #include <backends/GP_X11.h>
134 * Returns non-zero if backend is X11 backend
136 int GP_BackendIsX11(GP_Backend *self);
137 -------------------------------------------------------------------------------
139 The 'GP_BackendIsX11()' returns non-zero if backend is X11 backend, zero
143 GP_BackendX11RequestFullscreen
144 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
147 -------------------------------------------------------------------------------
150 #include <backends/GP_X11.h>
153 * Changes full screen mode.
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
174 -------------------------------------------------------------------------------
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'.
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.
202 -------------------------------------------------------------------------------
203 typdef struct GP_Backend {
210 * Pointer to context APP should draw to.
217 * Connection fd. Set to -1 if not available
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
231 -------------------------------------------------------------------------------
232 #include <backends/GP_Backend.h>
236 void GP_BackendExit(GP_Backend *backend);
237 -------------------------------------------------------------------------------
239 Calls an backend exit callback. Restores the display, keyboard, etc. state
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.
255 -------------------------------------------------------------------------------
256 #include <backends/GP_Backend.h>
260 GP_BackendFlip(GP_Backend *backend);
261 -------------------------------------------------------------------------------
263 Flips a screen. Blits backend buffer to the screen or window if the backend is
271 -------------------------------------------------------------------------------
272 #include <backends/GP_Backend.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.
288 -------------------------------------------------------------------------------
289 #include <backends/GP_Backend.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
302 This call returns immediately after queued events (from X11 socket, etc.) were
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
317 -------------------------------------------------------------------------------
318 #include <backends/GP_Backend.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
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
338 .Example 'GP_BackendPollEvent()' usage.
340 -------------------------------------------------------------------------------
341 /* Called either repeatedly or when data are ready on backend fd */
345 while (GP_BackendPollEvent(backend, &ev) {
350 -------------------------------------------------------------------------------
357 -------------------------------------------------------------------------------
358 #include <backends/GP_Backend.h>
362 void GP_BackendWait(GP_Backend *self);
363 -------------------------------------------------------------------------------
365 Blocks until backend event arrives.
368 Events received by backend are not necessarily translated into the input
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.
383 -------------------------------------------------------------------------------
384 #include <backends/GP_Backend.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
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.
403 -------------------------------------------------------------------------------
404 /* This is the main program loop */
408 GP_BackendWaitEvent(backend, &ev);
413 -------------------------------------------------------------------------------
416 GP_BackendEventsQueued
417 ^^^^^^^^^^^^^^^^^^^^^^
420 -------------------------------------------------------------------------------
421 #include <backends/GP_Backend.h>
425 unsigned int GP_BackendEventsQueued(GP_Backend *self);
426 -------------------------------------------------------------------------------
428 Returns number of events queued in the backend event queue.
436 -------------------------------------------------------------------------------
437 #include <backends/GP_Backend.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
448 If there are no events queued the call returns immediately with zero return
451 TIP: For more information on events see link:input.html[input events]
459 -------------------------------------------------------------------------------
460 #include <backends/GP_Backend.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.
476 -------------------------------------------------------------------------------
477 #include <backends/GP_Backend.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.
497 -------------------------------------------------------------------------------
498 #include <backends/GP_Backend.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