Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/DRESsedAlarm184/LWXGL/llms.txt

Use this file to discover all available pages before exploring further.

In addition to the event callback system, LWXGL exposes polling functions that let you read the current input state at any point during the frame. This is useful for smooth per-frame movement where you want to respond to keys that are held down, rather than reacting to individual press events. Polling and event callbacks are not mutually exclusive — both mechanisms read from the same internal state and can be used together.

Key Constants

ConstantValueKey
KEY_LEFT170Left arrow
KEY_RIGHT171Right arrow
KEY_UP172Up arrow
KEY_DOWN173Down arrow
KEY_FN150Base value — add 1–12 for F1–F12

QueryKeyboard

unsigned char* QueryKeyboard(void);
Returns a pointer to the internal 8-element array of currently pressed key values. Each slot holds the character value of a key that is currently held down, using the same values as the EventAttachKey callback (ASCII for printable characters, or the special constants above). Slots that are not in use contain 0. The array supports up to 8 simultaneously held keys. When more than 8 keys are held, additional presses are silently dropped.
(return value)
unsigned char*
Pointer to an 8-byte array owned by LWXGL. Do not free() this pointer. The values are valid for the duration of the current frame callback.
The array is updated at the start of each frame loop iteration by _handle_window_events(). Reading it outside the frame callback (e.g. from a timer thread) may produce stale values.

QueryKeyDown

int QueryKeyDown(int ch);
Returns 1 if the key with value ch is currently held down, 0 otherwise. Equivalent to scanning the array returned by QueryKeyboard for a matching entry, but more convenient for checking individual keys.
ch
int
required
Key value to test. Use ASCII for printable characters, or the KEY_* constants for special keys.

QueryMouse

void QueryMouse(int* x, int* y, int* btn);
Reads the current mouse state into the three output parameters. All three pointers must be non-NULL.
OutputMeaning
*xCursor X position relative to the window origin, or -1 when outside the window
*yCursor Y position relative to the window origin, or -1 when outside the window
*btnCurrently held mouse button (1=left, 2=middle, 3=right), or 0 if none
The position is updated on every MotionNotify event; it becomes -1, -1 on LeaveNotify.
x
int*
required
Output pointer for the cursor X coordinate.
y
int*
required
Output pointer for the cursor Y coordinate.
btn
int*
required
Output pointer for the currently pressed button. 0 means no button is pressed.
QueryMouse reflects the button held state (set on ButtonPress, cleared on ButtonRelease), not a click event. For click detection use EventAttachClick.

Code Example

#include "libLWXGL.h"

static int player_x = 100, player_y = 100;
static const int SPEED = 3; // pixels per frame

void on_frame(int tick, float dt) {
    // WASD / arrow key movement using held-key polling
    if (QueryKeyDown('w') || QueryKeyDown(KEY_UP))    player_y -= SPEED;
    if (QueryKeyDown('s') || QueryKeyDown(KEY_DOWN))  player_y += SPEED;
    if (QueryKeyDown('a') || QueryKeyDown(KEY_LEFT))  player_x -= SPEED;
    if (QueryKeyDown('d') || QueryKeyDown(KEY_RIGHT)) player_x += SPEED;

    // Clamp to window
    if (player_x < 0)   player_x = 0;
    if (player_x > 310) player_x = 310;
    if (player_y < 0)   player_y = 0;
    if (player_y > 190) player_y = 190;

    // Draw scene
    ClearImage(1, CLR_BLACK);
    PrimitiveCircle(1, player_x, player_y, 10, CLR_WHITE, CLR_RED);

    // Show cursor position
    int mx, my, mbtn;
    QueryMouse(&mx, &my, &mbtn);
    if (mx >= 0 && my >= 0) {
        PrimitiveCircle(1, mx, my, 3, CLR_NONE, CLR_YELLOW);
    }

    UpdateImage(1);
}

int main(void) {
    CreateWindow(320, 200, "Polling Demo", CLR_BLACK, FLAG_NONE);
    CreateImage(1, 0, 0, 0, 0);
    MainWindowLoop(60, on_frame);
    TerminateWindow();
    return 0;
}
Multiply movement by dt (the delta-time parameter passed to the frame callback) to make speed frame-rate independent: player_x += (int)(SPEED * dt * 60);

Build docs developers (and LLMs) love