DVX_GUI/core
2026-03-26 14:29:11 -05:00
..
platform Tabbing bugs fixed. 2026-03-26 14:29:11 -05:00
thirdparty MAJOR refactoring. Everything is dynamically loaded now. All new bugs to squash! 2026-03-24 23:03:05 -05:00
dvxApp.c Tabbing bugs fixed. 2026-03-26 14:29:11 -05:00
dvxApp.h First pass of major debugging. At a glance, everything is working again. 2026-03-25 21:43:41 -05:00
dvxComp.c Start of major refactor for dynamic library and widget loading. 2026-03-22 20:50:25 -05:00
dvxComp.h Start of major refactor for dynamic library and widget loading. 2026-03-22 20:50:25 -05:00
dvxCursor.h First pass of major debugging. At a glance, everything is working again. 2026-03-25 21:43:41 -05:00
dvxDialog.c MAJOR refactoring. Everything is dynamically loaded now. All new bugs to squash! 2026-03-24 23:03:05 -05:00
dvxDialog.h Start of major refactor for dynamic library and widget loading. 2026-03-22 20:50:25 -05:00
dvxDraw.c MAJOR refactoring. Everything is dynamically loaded now. All new bugs to squash! 2026-03-24 23:03:05 -05:00
dvxDraw.h Start of major refactor for dynamic library and widget loading. 2026-03-22 20:50:25 -05:00
dvxFont.h MAJOR refactoring. Everything is dynamically loaded now. All new bugs to squash! 2026-03-24 23:03:05 -05:00
dvxImage.c MAJOR refactoring. Everything is dynamically loaded now. All new bugs to squash! 2026-03-24 23:03:05 -05:00
dvxImageWrite.c Start of major refactor for dynamic library and widget loading. 2026-03-22 20:50:25 -05:00
dvxPalette.h Start of major refactor for dynamic library and widget loading. 2026-03-22 20:50:25 -05:00
dvxPrefs.c Start of major refactor for dynamic library and widget loading. 2026-03-22 20:50:25 -05:00
dvxPrefs.h Start of major refactor for dynamic library and widget loading. 2026-03-22 20:50:25 -05:00
dvxTypes.h MAJOR refactoring. Everything is dynamically loaded now. All new bugs to squash! 2026-03-24 23:03:05 -05:00
dvxVideo.c Start of major refactor for dynamic library and widget loading. 2026-03-22 20:50:25 -05:00
dvxVideo.h Start of major refactor for dynamic library and widget loading. 2026-03-22 20:50:25 -05:00
dvxWidget.h Tabbing bugs fixed. 2026-03-26 14:29:11 -05:00
dvxWidgetPlugin.h First pass of major debugging. At a glance, everything is working again. 2026-03-25 21:43:41 -05:00
dvxWm.c MAJOR refactoring. Everything is dynamically loaded now. All new bugs to squash! 2026-03-24 23:03:05 -05:00
dvxWm.h MAJOR refactoring. Everything is dynamically loaded now. All new bugs to squash! 2026-03-24 23:03:05 -05:00
Makefile MAJOR refactoring. Everything is dynamically loaded now. All new bugs to squash! 2026-03-24 23:03:05 -05:00
README.md Docs. 2026-03-25 22:42:07 -05:00
widgetClass.c MAJOR refactoring. Everything is dynamically loaded now. All new bugs to squash! 2026-03-24 23:03:05 -05:00
widgetCore.c First pass of major debugging. At a glance, everything is working again. 2026-03-25 21:43:41 -05:00
widgetEvent.c MAJOR refactoring. Everything is dynamically loaded now. All new bugs to squash! 2026-03-24 23:03:05 -05:00
widgetLayout.c MAJOR refactoring. Everything is dynamically loaded now. All new bugs to squash! 2026-03-24 23:03:05 -05:00
widgetOps.c MAJOR refactoring. Everything is dynamically loaded now. All new bugs to squash! 2026-03-24 23:03:05 -05:00
widgetScrollbar.c MAJOR refactoring. Everything is dynamically loaded now. All new bugs to squash! 2026-03-24 23:03:05 -05:00

DVX Core Library (libdvx.lib)

The core GUI infrastructure for DVX, built as a DXE3 module. Provides VESA video setup, 2D drawing primitives, dirty-rectangle compositing, a window manager with Motif-style chrome, and the widget infrastructure (layout engine, event dispatch, class registration). Individual widget type implementations live in ../widgets/ as separate .wgt DXE modules that register themselves at runtime via wgtRegisterClass().

Core knows nothing about individual widget types. There is no WidgetTypeE enum, no widget union, and no per-widget structs in dvxWidget.h. All widget-specific behavior is dispatched through the WidgetClassT vtable.

5-Layer Architecture

Layer Header Source Description
1. Video dvxVideo.h dvxVideo.c VESA VBE init, LFB mapping, backbuffer, pixel format, packColor()
2. Draw dvxDraw.h dvxDraw.c Rect fills, bevels, text, bitmap cursors, focus rects, lines
3. Compositor dvxComp.h dvxComp.c Dirty rect tracking, merge, clip, LFB flush
4. Window Manager dvxWm.h dvxWm.c Window stack, chrome, drag/resize, menus, scrollbars, hit test
5. Application dvxApp.h dvxApp.c Event loop, input polling, color schemes, wallpaper, public API

Additional modules built into libdvx.lib:

Header Source Description
dvxDialog.h dvxDialog.c Modal message box and file open/save dialogs
dvxPrefs.h dvxPrefs.c INI-based preferences (read/write with typed accessors)
dvxWidget.h widgetClass.c, widgetCore.c, widgetEvent.c, widgetLayout.c, widgetOps.c, widgetScrollbar.c Widget infrastructure
dvxWidgetPlugin.h (header only) Plugin API for widget DXE modules
-- dvxImage.c Image loading via stb_image (BMP, PNG, JPEG, GIF)
-- dvxImageWrite.c PNG export via stb_image_write

Source Files

File Description
dvxVideo.c VESA mode negotiation, LFB mapping via DPMI, backbuffer alloc, packColor()
dvxDraw.c rectFill(), rectCopy(), drawBevel(), drawText(), drawTextN(), drawTermRow(), cursor rendering
dvxComp.c dirtyListAdd(), dirtyListMerge(), flushRect(), rectIntersect()
dvxWm.c Window create/destroy, Z-order, chrome drawing, drag/resize, menu bar, scrollbars, minimize/maximize
dvxApp.c dvxInit(), dvxRun(), dvxUpdate(), dvxCreateWindow(), color schemes, wallpaper, screenshots
dvxDialog.c dvxMessageBox(), dvxFileDialog() -- modal dialogs with own event loops
dvxPrefs.c prefsLoad(), prefsSave(), typed get/set for string/int/bool
dvxImage.c dvxLoadImage() -- stb_image loader, converts to native pixel format
dvxImageWrite.c dvxSaveImage() -- PNG writer for screenshots
widgetClass.c wgtRegisterClass(), wgtRegisterApi(), wgtGetApi(), class table
widgetCore.c Widget allocation, tree ops, focus management, clipboard, hit testing, cursor blink
widgetEvent.c widgetOnMouse(), widgetOnKey(), widgetOnPaint(), widgetOnResize(), scrollbar management
widgetLayout.c Two-pass flexbox layout: bottom-up calcMinSize, top-down space allocation with weights
widgetOps.c wgtPaint(), wgtLayout(), wgtInitWindow(), text get/set, invalidation
widgetScrollbar.c Scrollbar drawing (H/V), thumb calculation, hit testing, drag update

Public Headers

Header Purpose
dvxTypes.h All shared types: DisplayT, RectT, BlitOpsT, BevelStyleT, BitmapFontT, ColorSchemeT, WindowT, MenuT, ScrollbarT, CursorT, PopupStateT
dvxVideo.h videoInit(), videoShutdown(), packColor(), setClipRect(), resetClipRect()
dvxDraw.h All drawing functions: rectFill(), drawBevel(), drawText(), drawTextN(), drawTermRow(), etc.
dvxComp.h Dirty list operations: dirtyListAdd(), dirtyListMerge(), flushRect(), rectIntersect()
dvxWm.h Window management: wmCreateWindow(), wmDestroyWindow(), wmRaiseWindow(), menus, scrollbars, chrome
dvxApp.h Application API: dvxInit(), dvxRun(), dvxUpdate(), dvxCreateWindow(), color schemes, wallpaper, image I/O
dvxDialog.h Modal dialogs: dvxMessageBox(), dvxFileDialog()
dvxPrefs.h INI preferences: prefsLoad(), prefsSave(), typed accessors
dvxWidget.h Widget system public API: WidgetT, WidgetClassT, size tags, layout, API registry
dvxWidgetPlugin.h Plugin API for widget DXE authors: tree ops, focus, scrollbar helpers, shared state
dvxFont.h Embedded 8x14 and 8x16 bitmap font data (CP437)
dvxCursor.h Mouse cursor AND/XOR mask data (arrow, resize H/V/diag, busy)
dvxPalette.h Default 256-color VGA palette for 8-bit mode

Platform Layer

File Description
platform/dvxPlatform.h Platform abstraction API (video, input, spans, DXE, crash recovery)
platform/dvxPlatformDos.c DJGPP/DPMI implementation (VESA VBE, INT 33h mouse, INT 16h keyboard, asm spans)

The platform layer is compiled into dvx.exe (the loader), not into libdvx.lib. Platform functions are exported to all DXE modules via platformRegisterDxeExports().

Third-Party Libraries

File Description
thirdparty/stb_image.h Image loading (implementation compiled into dvxImage.c)
thirdparty/stb_image_write.h PNG writing (implementation compiled into dvxImageWrite.c)
thirdparty/stb_ds.h Dynamic arrays/hash maps (implementation in loader, exported to all DXEs)

WidgetT Structure

The WidgetT struct is generic -- no widget-specific fields or union:

typedef struct WidgetT {
    int32_t                    type;       // assigned by wgtRegisterClass()
    const struct WidgetClassT *wclass;     // vtable pointer
    char                       name[32];

    // Tree linkage
    struct WidgetT  *parent, *firstChild, *lastChild, *nextSibling;
    WindowT         *window;

    // Geometry (relative to window content area)
    int32_t  x, y, w, h;
    int32_t  calcMinW, calcMinH;           // computed minimum size

    // Size hints (tagged: wgtPixels/wgtChars/wgtPercent, 0 = auto)
    int32_t  minW, minH, maxW, maxH;
    int32_t  prefW, prefH;
    int32_t  weight;                       // extra-space distribution (0 = fixed)

    // Container properties
    WidgetAlignE align;
    int32_t  spacing, padding;             // tagged sizes

    // Colors (0 = use color scheme defaults)
    uint32_t fgColor, bgColor;

    // State
    bool  visible, enabled, readOnly, focused;
    char  accelKey;

    // User data and callbacks
    void        *userData;
    void        *data;         // widget-private data (allocated by widget DXE)
    const char  *tooltip;
    MenuT       *contextMenu;
    void (*onClick)(struct WidgetT *w);
    void (*onDblClick)(struct WidgetT *w);
    void (*onChange)(struct WidgetT *w);
    void (*onFocus)(struct WidgetT *w);
    void (*onBlur)(struct WidgetT *w);
} WidgetT;

WidgetClassT Vtable

Each widget type defines a static WidgetClassT with flags and function pointers. The vtable has 26 function slots plus a flags field:

Slot Signature Purpose
flags uint32_t Static properties (see Flags below)
paint (w, d, ops, font, colors) Render the widget
paintOverlay (w, d, ops, font, colors) Render overlay (dropdown popup)
calcMinSize (w, font) Compute minimum size (bottom-up pass)
layout (w, font) Position children (top-down pass)
getLayoutMetrics (w, font, pad, gap, extraTop, borderW) Return padding/gap for box layout
onMouse (w, root, vx, vy) Handle mouse click
onKey (w, key, mod) Handle keyboard input
onAccelActivate (w, root) Handle accelerator key match
destroy (w) Free widget-private data
onChildChanged (parent, child) Notification when a child changes
getText (w) Return widget text
setText (w, text) Set widget text
clearSelection (w) Clear text/item selection
dragSelect (w, root, vx, vy) Handle drag selection
openPopup (w) Open dropdown popup
closePopup (w) Close dropdown popup
getPopupItemCount (w) Return number of popup items
getPopupRect (w, font, contentH, popX, popY, popW, popH) Compute popup rectangle
setPressed (w, pressed) Set button press visual state
reorderDrop (w) Complete drag-reorder operation
reorderUpdate (w, root, x, y) Update drag-reorder position
getCursorShape (w, vx, vy) Return cursor ID for this position
poll (w, win) Periodic polling (AnsiTerm comms)
quickRepaint (w, outY, outH) Fast incremental repaint
getTextFieldWidth (w) Text field width for scroll calc
scrollDragUpdate (w, orient, dragOff, mouseX, mouseY) Scrollbar drag update

WidgetClassT Flags

Flag Value Description
WCLASS_FOCUSABLE 0x0001 Can receive keyboard focus
WCLASS_BOX_CONTAINER 0x0002 Uses VBox/HBox layout algorithm
WCLASS_HORIZ_CONTAINER 0x0004 Lays out children horizontally
WCLASS_PAINTS_CHILDREN 0x0008 Widget handles child rendering
WCLASS_NO_HIT_RECURSE 0x0010 Hit testing stops here
WCLASS_FOCUS_FORWARD 0x0020 Accel hit forwards focus to next focusable
WCLASS_HAS_POPUP 0x0040 Has dropdown popup overlay
WCLASS_SCROLLABLE 0x0080 Accepts mouse wheel events
WCLASS_SCROLL_CONTAINER 0x0100 Scroll container (ScrollPane)
WCLASS_NEEDS_POLL 0x0200 Needs periodic polling
WCLASS_SWALLOWS_TAB 0x0400 Tab key goes to widget, not focus nav
WCLASS_RELAYOUT_ON_SCROLL 0x0800 Full relayout on scrollbar drag
WCLASS_PRESS_RELEASE 0x1000 Click = press+release (buttons)
WCLASS_ACCEL_WHEN_HIDDEN 0x2000 Accel matching works when invisible

Widget Registration

Each widget DXE exports wgtRegister(), called by the loader after dlopen. A typical registration:

static int32_t sButtonType;

static const WidgetClassT sButtonClass = {
    .flags      = WCLASS_FOCUSABLE | WCLASS_PRESS_RELEASE,
    .paint      = buttonPaint,
    .calcMinSize = buttonCalcMinSize,
    .onMouse    = buttonOnMouse,
    .onKey      = buttonOnKey,
    .destroy    = buttonDestroy,
    .getText    = buttonGetText,
    .setText    = buttonSetText,
    .setPressed = buttonSetPressed,
    .onAccelActivate = buttonAccelActivate,
};

static const ButtonApiT sApi = { .create = buttonCreate };

void wgtRegister(void) {
    sButtonType = wgtRegisterClass(&sButtonClass);
    wgtRegisterApi("button", &sApi);
}

Per-Widget API Registry

The monolithic WidgetApiT is gone. Each widget registers a small API struct under a name via wgtRegisterApi(). Callers retrieve it via wgtGetApi() and cast to the widget-specific type. Per-widget headers (e.g. widgetButton.h) provide typed accessors and convenience macros:

// widgetButton.h
typedef struct {
    WidgetT *(*create)(WidgetT *parent, const char *text);
} ButtonApiT;

static inline const ButtonApiT *dvxButtonApi(void) {
    static const ButtonApiT *sApi;
    if (!sApi) { sApi = (const ButtonApiT *)wgtGetApi("button"); }
    return sApi;
}

#define wgtButton(parent, text) dvxButtonApi()->create(parent, text)

Tagged Size Values

Size hints encode both unit type and numeric value in a single int32_t:

Macro Encoding Example
wgtPixels(v) Bits 31:30 = 00 w->minW = wgtPixels(200);
wgtChars(v) Bits 31:30 = 01 w->minW = wgtChars(40);
wgtPercent(v) Bits 31:30 = 10 w->minW = wgtPercent(50);
0 -- Auto (use computed minimum)

Layout Algorithm

Two-pass flexbox-like layout:

  1. Bottom-up (calcMinSize): Each widget computes its minimum size. Containers sum children along the main axis, max across the cross axis.
  2. Top-down (layout): Available space is allocated to children. Extra space beyond minimum is distributed proportionally to weights. weight=0 means fixed size, weight=100 is the default flexible weight.

Exported Symbols

libdvx.lib exports symbols matching these prefixes:

dvx*, wgt*, wm*, prefs*, rect*, draw*, pack*, text*, setClip*,
resetClip*, stbi*, dirtyList*, widget*, accelParse*, clipboard*,
multiClick*, sCursor*, sDbl*, sDebug*, sClosed*, sFocused*, sKey*,
sOpen*, sPressed*, sDrag*, sDrawing*, sResize*, sListView*,
sSplitter*, sTreeView*

Build

make            # builds bin/libs/libdvx.lib + bin/libs/libdvx.dep
make clean      # removes objects and library

Depends on: libtasks.lib (via libdvx.dep).