Files
video-setup/include/xorg.h
mikael-lovqvists-claude-agent 611376dbc1 feat: xorg text overlays, font atlas generator, v4l2_view_cli
- tools/gen_font_atlas: Python/Pillow build tool — skyline packs DejaVu
  Sans glyphs 32-255 into a grayscale atlas, emits build/gen/font_atlas.h
  with pixel data and Font_Glyph[256] metrics table
- xorg: bitmap font atlas text overlay rendering (GL_R8 atlas texture,
  alpha-blended glyph quads, dark background rect per overlay)
- xorg: add xorg_viewer_set_overlay_text / clear_overlays API
- xorg: add xorg_viewer_handle_events for streaming use (events only,
  no redundant render)
- xorg_cli: show today's date as white text overlay
- v4l2_view_cli: new tool — V4L2 capture with format auto-selection
  (highest FPS then largest resolution), MJPEG/YUYV, measured FPS overlay
- docs: update README, planning, architecture to reflect current status

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 22:13:59 +00:00

83 lines
2.9 KiB
C

#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
typedef struct Xorg_Viewer Xorg_Viewer;
/*
* How the frame is scaled to fit the window.
* SCALE_STRETCH is the only implemented mode; others are reserved.
*/
typedef enum Xorg_Scale {
XORG_SCALE_STRETCH, /* fill window, ignore aspect ratio (default) */
XORG_SCALE_FIT, /* largest rect that fits, preserve aspect, black bars */
XORG_SCALE_FILL, /* smallest rect that covers, preserve aspect, crop edges */
XORG_SCALE_1_1, /* native pixel size, no scaling */
} Xorg_Scale;
/*
* Where the frame is positioned within the window.
* Used with XORG_SCALE_FIT, XORG_SCALE_FILL, and XORG_SCALE_1_1.
*/
typedef enum Xorg_Anchor {
XORG_ANCHOR_CENTER, /* center frame in window (default) */
XORG_ANCHOR_TOP_LEFT, /* align frame to top-left corner */
} Xorg_Anchor;
/* Returns false when compiled without HAVE_GLFW. */
bool xorg_available(void);
/*
* Open a viewer window at screen position (x, y) with the given size.
* Returns NULL if xorg is unavailable or if window/context creation fails.
*/
Xorg_Viewer *xorg_viewer_open(int x, int y, int width, int height,
const char *title);
/* Push a YUV 4:2:0 planar frame for immediate display. */
bool xorg_viewer_push_yuv420(Xorg_Viewer *v,
const uint8_t *y, const uint8_t *cb, const uint8_t *cr,
int width, int height);
/* Push a packed BGRA frame for immediate display. */
bool xorg_viewer_push_bgra(Xorg_Viewer *v,
const uint8_t *data, int width, int height);
/*
* Push a MJPEG frame. Decoded via libjpeg-turbo to planar YUV before upload.
* Returns false if compiled without HAVE_TURBOJPEG.
*/
bool xorg_viewer_push_mjpeg(Xorg_Viewer *v,
const uint8_t *data, size_t size);
/* Change scale/anchor at any time; takes effect on the next render. */
void xorg_viewer_set_scale(Xorg_Viewer *v, Xorg_Scale scale);
void xorg_viewer_set_anchor(Xorg_Viewer *v, Xorg_Anchor anchor);
/*
* Set a text overlay at window-pixel position (x, y) — top-left of the text.
* Up to 8 overlays (idx 0..7); calling with the same idx replaces it.
* r, g, b are in [0, 1].
*/
void xorg_viewer_set_overlay_text(Xorg_Viewer *v, int idx, int x, int y,
const char *text, float r, float g, float b);
/* Remove all text overlays. */
void xorg_viewer_clear_overlays(Xorg_Viewer *v);
/*
* Process pending window events.
* Returns false when the user has closed the window.
* Must be called from the thread that created the viewer.
*
* poll() — processes events then re-renders; use for static images.
* handle_events() — processes events only, no render; use when push_* drives
* rendering (e.g. live camera feed).
*/
bool xorg_viewer_poll(Xorg_Viewer *v);
bool xorg_viewer_handle_events(Xorg_Viewer *v);
void xorg_viewer_close(Xorg_Viewer *v);