loaders: JPG: Fix bussy loop on corrupted file.
[gfxprim.git] / doc / input.txt
blobcda880038ac9cda9236ca45ce347bc6ba058ff22
1 Input Events
2 ------------
3 Input events are somehow tied to the link:backends.html[backends] where they
4 are stored in the link:event_queue.html[event queue].
6 Possibly in contrast with other libraries there is not always 1:1
7 correspondence between input driver and backend graphics driver. That means
8 that you can, for example, use Linux input events together with X Window
9 without any problems.  You can even write application that doesn't draw any
10 graphics at all and still use some of the input drivers. There are, of course,
11 cases where input driver is created only together with graphics driver, this
12 is the case for example for X Window backends or SDL backends.
14 The basic structure is roughly modeled after Linux kernel input API. The main
15 difference is that events that belongs together are delivered together (the
16 kernel input API sends one event for each value i.e. x or y coordinate and has
17 sync event that finalizes the changes in the values).
19 TIP: For example usage see input events link:example_input.html[example].
21 Event Structure Description
22 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 [source,c]
25 -------------------------------------------------------------------------------
26 #include <GP.h>
27 /* or */
28 #include <input/GP_Event.h>
30 typedef struct GP_Event {
31         /* event */
32         uint16_t type;
33         uint32_t code;
34         union GP_EventValue val;
36         /* input device id */
37         uint32_t dev_id;
39         /* event timestamp */
40         struct timeval time;
42         /*
43          * Cursor position, position on screen accumulated
44          * from all pointer devices
45          */
46         uint32_t cursor_x;
47         uint32_t cursor_y;
49         /*
50          * Bitmap of pressed keys including mouse buttons
51          * accumulated for all input devices.
52          */
53         uint8_t keys_pressed[GP_EVENT_KEYMAP_BYTES];
54 } GP_Event;
55 -------------------------------------------------------------------------------
57 The 'GP_Event' structure describes an input event (i.e. key was
58 pressed/released, mouse was moved, window was resized by user).
60 [source,c]
61 -------------------------------------------------------------------------------
62 enum GP_EventType {
63         GP_EV_KEY, /* key/button press event */
64         GP_EV_REL, /* relative event */
65         GP_EV_ABS, /* absolute event */
66         GP_EV_SYS, /* system events window close, resize... */
67         GP_EV_TMR, /* timer expired event */
68         GP_EV_MAX = GP_EV_TMR, /* maximum, greater values are free */
70 -------------------------------------------------------------------------------
72 The event 'type' determines high-level nature of the event.
74 * Key events covers keyboard button presses, mouse buttons, etc.
75 * Relative events covers mouse coordinates, mouse wheel, etc.
76 * Absolute events covers touchscreens and tablets
77 * System events are used for propagating window close and window
78   resize events
79 * Timer expired event are generated by when a link:#Timers[timer] has expired.
80 * Values greater than 'GP_EV_MAX' are free for user events
82 [source,c]
83 -------------------------------------------------------------------------------
84 enum GP_EventKeyCode {
85         GP_EV_KEY_UP,
86         GP_EV_KEY_DOWN,
87         GP_EV_KEY_REPEAT,
90 enum GP_EventRelCode {
91         GP_EV_REL_POS,
92         GP_EV_REL_WHEEL,
95 enum GP_EventAbsCode {
96         GP_EV_ABS_POS,
99 enum GP_EventSysCode {
100         GP_EV_SYS_QUIT,
101         GP_EV_SYS_RESIZE,
103 -------------------------------------------------------------------------------
105 The event 'code' specifies the event nature more closely, it has different
106 meaning for each event type. The names are (hopefully) self explanatory.
108 [source,c]
109 -------------------------------------------------------------------------------
110 union GP_EventValue {
111         /* generic one integer value */
112         int32_t val;
113         /* key */
114         struct GP_EventKey key;
115         /* position */
116         struct GP_EventPosRel rel;
117         struct GP_EventPosAbs abs;
118         /* system event */
119         struct GP_EventSys sys;
120         /* timer event */
121         GP_Timer *tmr;
124 struct GP_EventPosRel {
125         int32_t rx;
126         int32_t ry;
129 struct GP_EventPosAbs {
130         uint32_t x, x_max; /* the x is between 0 and x_max */
131         uint32_t y, y_max;
132         uint32_t pressure, pressure_max;
135 struct GP_EventKey {
136         uint32_t key;
137         char ascii;
140 struct GP_EventSys {
141         uint32_t w, h;
143 -------------------------------------------------------------------------------
145 The event 'value' is a union that could hold different information. The right
146 format of the data is known from the 'type' and 'code'. Some types of the
147 events has no value at all.
149 * The relative coordinates are used for 'GP_EV_REL_POS' and absolute coordinates
150   for 'GP_EV_ABS_POS'.
152 * The key event value is used for key-presses, additionally it holds the key
153   value mapped to ASCII if conversion is applicable otherwise it's set to
154   zero. You should consult the header 'input/GP_Event.h' for the comprehensive
155   list of key values.
157 This image shows GFXprim key names without the 'GP_KEY_' prefix (Click for a
158 higher resolution). So for example 'LEFTSHIFT' on the image is
159 'GP_KEY_LEFT_SHIFT'.
161 [[Keyboard Layout]]
162 .GFXprim key names without the 'GP_KEY_' prefix.
163 image::keyboard.svg["Keyboard Layout",width=800,link="keyboard.svg"]
165 * The system event is used with 'GP_EV_SYS_RESIZE' and informs you
166   of the new window size.
168 * The value of timer event is simply pointer to the expired link:#Timers[Timer].
170 The 'dev_id' is not used at the moment and may be removed.
172 The timeval structure 'time' holds time when the event was created (or
173 received by GFXprim input driver).
175 The 'cursor_x' and 'cursor_y' holds current pointer coordinates. (All relative
176 and absolute events are mixed together to compute current cursor position.)
178 The 'key_pressed' is bitflag array of currently pressed keys which is useful
179 for using keys as modificators. The array always holds state of the standard
180 keyboard keys and mouse buttons.
182 Event API
183 ~~~~~~~~~
185 [source,c]
186 -------------------------------------------------------------------------------
187 #include <GP.h>
188 /* or */
189 #include <input/GP_Event.h>
191 void GP_EventDump(struct GP_Event *ev);
192 -------------------------------------------------------------------------------
194 The 'GP_EventDump' dumps event in human-readable format into the stdout.
196 [source,c]
197 -------------------------------------------------------------------------------
198 #include <GP.h>
199 /* or */
200 #include <input/GP_Event.h>
202 const char *GP_EventKeyName(enum GP_EventKeyValue key);
203 -------------------------------------------------------------------------------
205 Returns human-readable key name.
207 The returned string must not be modified.
209 [source,c]
210 -------------------------------------------------------------------------------
211 #include <GP.h>
212 /* or */
213 #include <input/GP_Event.h>
215 void GP_EventSetKey(struct GP_Event *ev, uint32_t key)
217 GP_EventGetKey(struct GP_Event *ev, uint32_t key)
219 GP_EventResetKey(struct GP_Event *ev, uint32_t key)
220 -------------------------------------------------------------------------------
222 These functions are helpers for setting/getting key pressed bits in the
223 'keys_pressed' bit array.
225 You will mostly need the 'GP_EventGetKey' function to figure out if some of
226 the modificator keys (such as Ctrl or Shift) was pressed at the time the event
227 was received.
229 [[Timers]]
230 Timers
231 ~~~~~~
233 Input layer also implements 'priority queue' (implemented using binary heap)
234 to store multiple timer events. This part of the code is used in
235 link:backends.html[backends] where you can simply add timer which gets
236 processed automatically in the program main loop (while you call the backend
237 Wait or Poll functions).
239 [source,c]
240 -------------------------------------------------------------------------------
241 #include <GP.h>
242 /* or */
243 #include <input/GP_Timer.h>
245 typedef struct GP_Timer {
246         /* Heap pointers and number of sons */
247         struct GP_Timer *left;
248         struct GP_Timer *right;
249         unsigned int sons;
251         /* Expiration time */
252         uint64_t expires;
253         /*
254          * If not zero return value from Callback is ignored and
255          * timer is rescheduled each time it expires.
256          */
257         uint32_t period;
259         /* Timer id, showed in debug messages */
260         const char *id;
262         /*
263          * Timer Callback
264          *
265          * If non-zero is returned, the timer is rescheduled to expire
266          * return value from now.
267          */
268         uint32_t (*Callback)(struct GP_Timer *self);
269         void *priv;
270 } GP_Timer;
272 #define GP_TIMER_DECLARE(name, expires, period, id, Callback, priv) \
273         ...
274 -------------------------------------------------------------------------------
276 Timers are implemented as a simple structure with a callback, expiration, id
277 string and internal heap pointers. The priority queue is described simply by
278 the pointer to the top timer (soonest to expire).
280 The 'priv' pointer is used to pass a user pointer to the callback function.
282 The number of timers in the queue is the number of sons of the top timer plus
283 one.
285 The 'GP_TIMER_DECLARE()' creates and initializes timer on the program stack.
286 The 'name' is the name of the declared timer structure and the rest of the
287 variables corresponds to the structure members.
289 [source,c]
290 -------------------------------------------------------------------------------
291 #include <GP.h>
292 /* or */
293 #include <input/GP_Timer.h>
295 void GP_TimerQueueDump(GP_Timer *queue);
296 -------------------------------------------------------------------------------
298 Prints the structure of binary heap into stdout, only for debugging.
300 [source,c]
301 -------------------------------------------------------------------------------
302 #include <GP.h>
303 /* or */
304 #include <input/GP_Timer.h>
306 void GP_TimerQueueInsert(GP_Timer **queue, uint64_t now, GP_Timer *timer);
307 -------------------------------------------------------------------------------
309 Inserts timer into the timer priority queue. The timer is scheduled to expire
310 at `now + timer->expire`.
312 [source,c]
313 -------------------------------------------------------------------------------
314 #include <GP.h>
315 /* or */
316 #include <input/GP_Timer.h>
318 void GP_TimerQueueRemove(GP_Timer **queue, GP_Timer *timer);
319 -------------------------------------------------------------------------------
321 Removes timer from the queue.
323 If timer is not found in the queue nothing is done but warning is printed.
325 Runs in 'O(n)' time (the insert and process runs in 'O(nlog(n))').
327 [source,c]
328 -------------------------------------------------------------------------------
329 #include <GP.h>
330 /* or */
331 #include <input/GP_Timer.h>
333 int GP_TimerQueueProcess(GP_Timer **queue, uint64_t now);
334 -------------------------------------------------------------------------------
336 Processes all expired timers (all timers with `timer->expires <= now` are processed).
338 Recurrent timers and timers that returned non-zero from callback are reinserted
339 into the queue with new expiration time.
341 Returns number of timers processed.
343 [source,c]
344 -------------------------------------------------------------------------------
345 #include <GP.h>
346 /* or */
347 #include <input/GP_Timer.h>
349 unsigned int GP_TimerQueueSize(GP_Timer *queue);
350 -------------------------------------------------------------------------------
352 Returns number of timers in the queue.
354 [[TimeStamp]]
355 TimerStamp
356 ~~~~~~~~~~
358 Timestamp provides fast monotonously increasing timestamps in milliseconds.
360 Timestamp is used together with link:#Timers[timers].
362 [source,c]
363 -------------------------------------------------------------------------------
364 #include <GP.h>
365 /* or */
366 #include <input/GP_TimeStamp.h>
368 uint64_t GP_GetTimeStamp(void);
369 -------------------------------------------------------------------------------
371 Returns timestamp (i.e. time elapsed since some point) in milliseconds.