/** Really dumb windowing library, providing just a shared-memory * framebuffer you can flush onto the screen and some events, with * so far just an X11 XShm backend. See * README.xshmu.md for more details. */ typedef struct _xshmu *xshmu; /** Call xshmu_open to connect to the X11 display, open a window, and * set up a framebuffer for it. This function takes care of * allocating and initializing the data structure. The options string * is kind of a gateway for future options. Passing an empty string * is safe. */ xshmu xshmu_open(const char *name, int width, int height, const char *options); /** Call xshmu_close to disconnect if the process is going to continue. */ void xshmu_close(xshmu w); /** xshmu_pic — a TrueColor in-memory image — either a framebuffer, or not. * (It may be just a plain memory buffer or part of a larger xshmu_pic.) * Pixels are 32-bit little-endian RGB pixels: the least-significant * byte is blue, the next is green, the next is red, and the most * significant byte is ignored. */ typedef struct { uint32_t *p; int w, stride, h; } xshmu_pic; /** Call xshmu_framebuffer to get a framebuffer xshmu_pic to paint in. * The width and height may be different from what you requested in * `xshmu_open` because the user may have resized the window.) */ xshmu_pic xshmu_framebuffer(xshmu w); /** Call xshmu_flush to make visible on the screen the image you * have drawn in the framebuffer. */ void xshmu_flush(xshmu w); /** xshmu_pix computes the address of a pixel in a xshmu_pic. No bounds check. */ static inline uint32_t * xshmu_pix(xshmu_pic c, int x, int y) { return &c.p[x + y*c.stride]; } /** Create an in-memory xshmu_pic. */ xshmu_pic xshmu_canvas(int w, int h); /** Represent a subrectangle of an xshmu_pic as an xshmu_pic. * Unlike xshmu_pix, this does do bounds-checking and clipping. This * function is the reason `stride` and `w` are separate in xshmu_pic: * a 10×10 xshmu_subpic of a 1024×1024 canvas or framebuffer still has * a stride of 1024. */ xshmu_pic xshmu_subpic(xshmu_pic start, int x, int y, int w, int h); /** Copy (possibly overlapping) image rectangles. */ void xshmu_copy(xshmu_pic dest, xshmu_pic src); /** The opaque `xshmu_event` type returned by `xshmu_get_event` is * polymorphic; it can contain one of `xshmu_mouse_event`, * `xshmu_key_event`, or `xshmu_raw_event`. Call the associated * `xshmu_as_` function for each event type you want to handle. It * will return NULL if the event is of the wrong type. * * Currently these event types are mutually exclusive, but they offer * the possibility of adding event subtypes at some point — either to * add more information, such as timestamps or keycodes, or to provide * subsets of existing event types, such as a hypothetical * `xshmu_as_keydown_event`. */ typedef struct xshmu_event xshmu_event; /** Call `xshmu_get_event` to get the next input event, or NULL if there * is none yet. The pointer this returns is to the `xshmu_event` allocated * within the xshmu struct, so it gets overwritten the next time you * call this function. This function does not block! */ xshmu_event *xshmu_get_event(xshmu w); /** Call xshmu_wait to block the program until an input event arrives. */ void xshmu_wait(xshmu w); typedef struct { int32_t x, y; /* Mouse coordinates relative to upper left */ uint8_t buttons; /* Bitmask of buttons that are down */ } xshmu_mouse_event; xshmu_mouse_event *xshmu_as_mouse_event(xshmu_event *); typedef struct { char *s; /* pointer to UTF-8 bytes generated */ uint32_t keysym; /* X11 standard (?) keysym */ uint8_t down; /* 0 if this is a keyup, 1 if keydown */ uint8_t len; /* number of bytes in string s */ } xshmu_key_event; xshmu_key_event *xshmu_as_key_event(xshmu_event *); /* useful keysyms */ enum { xks_left = 0xff51, xks_up, xks_right, xks_down, xks_pgup, xks_pgdn, xks_end, xks_home, xks_shift_l = 0xffe1, xks_shift_r, xks_control_l, xks_control_r, xks_caps_lock, xks_shift_lock, xks_meta_l, xks_meta_r, xks_backspace = 0xff08, xks_return = 0xff0d }; typedef void *xshmu_raw_event; /* an XEvent pointer in disguise */ xshmu_raw_event *xshmu_as_raw_event(xshmu_event *); typedef int xshmu_die_event; /* False unless the event is a die event */ xshmu_die_event xshmu_as_die_event(xshmu_event *); /** Call xshmu_fd to get the Unix file descriptor of the X11 * connection so that you can use it in select() or epoll or whatever. * Keep in mind that there may already be events pending that have * been read from the file descriptor the last time you called * xshmu_pending or xshmu_get_event. */ int xshmu_fd(xshmu w); typedef void (*xshmu_error_handler_t)(const char *msg); /** If you set xshmu_error_handler to point to a function of yours, it * will be invoked with a message when there’s an error; the default * function prints a message to stderr and calls abort(). */ extern xshmu_error_handler_t xshmu_error_handler;