Input Events
------------
Input events are somehow tied to the link:backends.html[backends] where they
are stored in the link:event_queue.html[event queue].

Possibly in contrast with other libraries there is not always 1:1
correspondence between input driver and backend graphics driver. That means
that you can, for example, use Linux input events together with X Window
without any problems.  You can even write application that doesn't draw any
graphics at all and still use some of the input drivers. There are, of course,
cases where input driver is created only together with graphics driver, this
is the case for example for X Window backends or SDL backends.

The basic structure is roughly modeled after Linux kernel input API. The main
difference is that events that belongs together are delivered together (the
kernel input API sends one event for each value i.e. x or y coordinate and has
sync event that finalizes the changes in the values).

TIP: For example usage see input events link:example_input.html[example].

Event Structure Description
~~~~~~~~~~~~~~~~~~~~~~~~~~~

[source,c]
-------------------------------------------------------------------------------
#include <gfxprim.h>
/* or */
#include <input/gp_event.h>

struct gp_event_pos_rel {
	int32_t rx;
	int32_t ry;
};

struct gp_event_pos_abs {
	uint32_t x, x_max; /* the x is between 0 and x_max */
	uint32_t y, y_max;
	uint32_t pressure, pressure_max;
};

struct gp_event_key {
	uint32_t key;
	char ascii;
};

struct gp_event_sys {
	uint32_t w, h;
};

struct gp_events_state {
	/** Bitmap of pressed keys including mouse buttons. */
	uint8_t keys_pressed[GP_EVENT_KEY_BITMAP_BYTES];

	/** Cursor coordinates */
	uint32_t cursor_x;
	uint32_t cursor_y;
};

typedef struct gp_event {
	/** enum gp_event_type */
	uint16_t type;
        /** enum gp_event_*_code */
        uint16_t code;
	union {
		/* generic integer value */
		int32_t val;
		/* key */
		struct gp_event_key key;
		/* position */
		struct gp_event_pos_rel rel;
		struct gp_event_pos_abs abs;
		/* system event */
		struct gp_event_sys sys;
		/* timer event */
		gp_timer *tmr;
	};

	/* event timestamp */
	struct timeval time;

	/* overall accumulated state, pressed keys, cursor, etc. */
	gp_events_state *st;
} gp_event;
-------------------------------------------------------------------------------

The 'gp_event' structure describes an input event (i.e. key was
pressed/released, mouse was moved, window was resized by user).

[source,c]
-------------------------------------------------------------------------------
enum gp_event_type {
	GP_EV_KEY, /* key/button press event */
	GP_EV_REL, /* relative event */
	GP_EV_ABS, /* absolute event */
	GP_EV_SYS, /* system events window close, resize... */
	GP_EV_TMR, /* timer expired event */
	GP_EV_MAX = GP_EV_TMR, /* maximum, greater values are free */
};
-------------------------------------------------------------------------------

The event 'type' determines high-level nature of the event.

* Key events covers keyboard button presses, mouse buttons, etc.
* Relative events covers mouse coordinates, mouse wheel, etc.
* Absolute events covers touchscreens and tablets
* System events are used for propagating window close and window
  resize events
* Timer expired event are generated by when a link:#Timers[timer] has expired.
* Values greater than 'GP_EV_MAX' are free for user events

[source,c]
-------------------------------------------------------------------------------
enum gp_event_key_code {
	GP_EV_KEY_UP,
	GP_EV_KEY_DOWN,
	GP_EV_KEY_REPEAT,
};

enum gp_event_rel_code {
	GP_EV_REL_POS,
	GP_EV_REL_WHEEL,
};

enum gp_event_abs_code {
	GP_EV_ABS_POS,
};

enum gp_event_sys_code {
	GP_EV_SYS_QUIT,
	GP_EV_SYS_RESIZE,
};
-------------------------------------------------------------------------------

The event 'code' specifies the event nature more closely, it has different
meaning for each event type. The names are (hopefully) self explanatory.

The event 'value' is a union that could hold different information. The right
format of the data is known from the 'type' and 'code'. Some types of the
events has no value at all.

Relative coordinates are used for 'GP_EV_REL_POS' and absolute coordinates for
'GP_EV_ABS_POS'.

The key event value is used for key-presses, additionally it holds the key
value mapped to ASCII if conversion is applicable otherwise it's set to zero.
You should consult the header 'input/gp_event.h' for the comprehensive list of
key values.

Following image shows GFXprim key names without the 'GP_KEY_' prefix (Click
for a higher resolution). So for example 'LEFTSHIFT' on the image is
'GP_KEY_LEFT_SHIFT'.

[[Keyboard Layout]]
.GFXprim key names without the 'GP_KEY_' prefix.
image::keyboard.svg["Keyboard Layout",width=800,link="keyboard.svg"]

* The system event is used with 'GP_EV_SYS_RESIZE' and informs you
  of the new window size.

* The value of timer event is simply pointer to the expired link:#Timers[Timer].

The timeval structure 'time' holds time when the event was created (or
received by GFXprim input driver).

The 'st' pointer points to a global accumulated event queue state, i.e. bitmap
of currently pressed keys and overall cursor position.

WARNING: The values in the global state are valid only for the last event removed
         from the queue by 'gp_ev_queue_get()'.

Event API
~~~~~~~~~

[source,c]
-------------------------------------------------------------------------------
#include <gfxprim.h>
/* or */
#include <input/gp_event.h>

void gp_ev_dump(struct gp_event *ev);
-------------------------------------------------------------------------------

The 'gp_ev_dump' dumps event in human-readable format into the stdout.

[source,c]
-------------------------------------------------------------------------------
#include <gfxprim.h>
/* or */
#include <input/gp_event.h>

const char *gp_ev_key_name(unsigned int key);

int gp_ev_key_val(const char *name);
-------------------------------------------------------------------------------

Converts key id into human readable name and human readable name into an id.

[source,c]
-------------------------------------------------------------------------------
#include <gfxprim.h>
/* or */
#include <input/gp_event.h>

int gp_ev_key_pressed(gp_event *ev, uint32_t key);
-------------------------------------------------------------------------------

A shortcut for 'gp_events_state_pressed(ev->st, GP_KEY_FOO)' that also returns
0 if 'ev->st' is NULL.

[source,c]
-------------------------------------------------------------------------------
#include <gfxprim.h>
/* or */
#include <input/gp_event.h>

int gp_ev_any_key_pressed(gp_event *ev, ...);

int gp_ev_all_keys_pressed(gp_event *ev, ...);
-------------------------------------------------------------------------------

These functions do logical or/and on the list of keys passed as arguments.

Use it as: 'gp_ev_any_key_pressed(ev, GP_KEY_LEFT_ALT, GP_KEY_RIGHT_ALT)'
