Navigation C API Pages Python bindings Applications

Input Events

Input events are somehow tied to the backends where they are stored in the 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 example.

Event Structure Description

#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).

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 timer has expired.

  • Values greater than GP_EV_MAX are free for user events

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.

Figure 1. GFXprim key names without the GP_KEY_ prefix.
  • 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 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

#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.

#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.

#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.

#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)