| apps | ||
| config | ||
| core | ||
| listhelp | ||
| loader | ||
| packet | ||
| proxy | ||
| releases | ||
| rs232 | ||
| seclink | ||
| security | ||
| serial | ||
| shell | ||
| taskmgr | ||
| tasks | ||
| termdemo | ||
| texthelp | ||
| tools | ||
| widgets | ||
| .gitattributes | ||
| .gitignore | ||
| dosbox-x.conf | ||
| Makefile | ||
| mkcd.sh | ||
| README.md | ||
| run.sh | ||
DVX -- DOS Visual eXecutive
A windowed GUI compositor and widget toolkit targeting DJGPP/DPMI on 486+ hardware. VESA VBE 2.0+ LFB only. Motif-inspired visual style with 2px bevels, fixed bitmap fonts, and dirty-rect compositing.
The system runs on 86Box (primary target) and real DOS hardware.
Architecture
DVX is built as a set of DXE3 dynamic modules loaded by a bootstrap executable. The loader resolves dependencies and loads modules in topological order, then hands control to the shell.
dvx.exe (loader)
|
+-- libs/libtasks.lib cooperative task switcher
+-- libs/libdvx.lib core GUI (draw, comp, wm, app, widget infra)
+-- libs/texthelp.lib shared text editing helpers
+-- libs/listhelp.lib shared list/dropdown helpers
+-- libs/dvxshell.lib shell (app lifecycle, desktop)
+-- libs/taskmgr.lib task manager (Ctrl+Esc, separate DXE)
|
+-- widgets/*.wgt 26 widget type plugins
|
+-- apps/*/*.app DXE applications
Directory Structure
| Directory | Output | Description |
|---|---|---|
loader/ |
bin/dvx.exe |
Bootstrap loader, platform layer, stb_ds |
core/ |
bin/libs/libdvx.lib |
Core GUI library (5 layers + widget infra) |
tasks/ |
bin/libs/libtasks.lib |
Cooperative task switching |
texthelp/ |
bin/libs/texthelp.lib |
Shared text editing helpers |
listhelp/ |
bin/libs/listhelp.lib |
Shared list/dropdown helpers |
shell/ |
bin/libs/dvxshell.lib |
DVX Shell (app lifecycle, desktop) |
taskmgr/ |
bin/libs/taskmgr.lib |
Task Manager (separate DXE, Ctrl+Esc) |
widgets/ |
bin/widgets/*.wgt |
26 individual widget DXE modules |
apps/ |
bin/apps/*/*.app |
Application DXE modules |
tools/ |
bin/dvxres |
Resource tool (host native, not DXE) |
config/ |
bin/config/, bin/libs/, bin/widgets/ |
INI config, themes, wallpapers, dep files |
rs232/ |
lib/librs232.a |
ISR-driven UART serial driver |
packet/ |
lib/libpacket.a |
HDLC framing, CRC-16, Go-Back-N ARQ |
security/ |
lib/libsecurity.a |
DH key exchange, XTEA-CTR cipher, RNG |
seclink/ |
lib/libseclink.a |
Secure serial link (channels, encryption) |
proxy/ |
bin/secproxy |
Linux proxy: 86Box <-> telnet BBS |
termdemo/ |
bin/termdemo.exe |
Standalone encrypted terminal demo |
Build
Requires the DJGPP cross-compiler at ~/djgpp/djgpp.
make # build everything
make clean # remove all build artifacts
./mkcd.sh # build + create ISO for 86Box
The top-level Makefile builds in dependency order:
core -> tasks -> loader -> texthelp -> listhelp -> widgets -> shell -> taskmgr -> apps
tools (host native, parallel)
Build output goes to bin/ (executables, DXE modules, config) and
obj/ (intermediate object files).
Runtime Directory Layout (bin/)
bin/
dvx.exe bootstrap loader (entry point)
libs/
libtasks.lib task switching library
libdvx.lib core GUI library
texthelp.lib text editing helpers
listhelp.lib list/dropdown helpers
dvxshell.lib DVX shell
taskmgr.lib task manager (Ctrl+Esc)
*.dep dependency files for load ordering
widgets/
box.wgt VBox/HBox/Frame containers
button.wgt push button
... (26 widget modules total)
*.dep dependency files
apps/
progman/progman.app Program Manager (desktop)
notepad/notepad.app text editor
clock/clock.app clock display
dvxdemo/dvxdemo.app widget showcase
cpanel/cpanel.app control panel
imgview/imgview.app image viewer
config/
dvx.ini system configuration
themes/ color theme files (.thm)
wpaper/ wallpaper images
Core Architecture (5 Layers)
- dvxVideo -- VESA VBE init, LFB mapping, backbuffer, pixel format, color packing
- dvxDraw -- Rectangle fills, bevels, text rendering, cursor/icon drawing
- dvxComp -- Dirty rectangle tracking, merge, compositor, LFB flush
- dvxWm -- Window stack, chrome, drag/resize, menus, scrollbars, hit testing
- dvxApp -- Event loop, input polling, public API, color schemes, wallpaper
Widget System
Widgets are isolated DXE modules. Core knows nothing about individual widget types -- no compile-time enum, no union, no per-widget structs in dvxWidget.h.
- Dynamic type IDs:
wgtRegisterClass()assigns IDs at load time - *void data: Each widget allocates its own private data struct
- ABI-stable dispatch:
WidgetClassT.handlers[]is an array of function pointers indexed byWGT_METHOD_*constants (0-20, room for 32). Core dispatches viaw->wclass->handlers[WGT_METHOD_PAINT]etc., so adding new methods does not break existing widget DXE binaries - Generic drag:
WGT_METHOD_ON_DRAG_UPDATEandWGT_METHOD_ON_DRAG_ENDprovide widget-level drag support without per-widget hacks in core - Per-widget API registry:
wgtRegisterApi("name", &api)replaces the monolithic API - Per-widget headers:
widgets/widgetButton.hetc. provide typed macros - Shared helpers: texthelp.lib (text editing) and listhelp.lib (dropdown/list)
- All limits dynamic: widget child arrays, app slots, and desktop callbacks are stb_ds dynamic arrays with no fixed maximums
DXE Module System
All modules are DXE3 dynamic libraries loaded by dvx.exe at startup.
The loader recursively scans libs/ for .lib files and widgets/ for .wgt
files, reads .dep files for dependencies, and loads in topological
order. Widget modules that export wgtRegister() have it called after
loading.
Each .dep file lists base names of modules that must load first, one
per line. Comments start with #.
App Types
Callback-only (hasMainLoop = false): appMain creates windows,
registers callbacks, and returns. The app lives through event callbacks
in the shell's main loop. No dedicated task or stack needed.
Main-loop (hasMainLoop = true): A cooperative task is created for
the app. appMain runs its own loop calling tsYield() to share CPU.
Used for apps that need continuous processing (clocks, terminal
emulators, games).
Crash Recovery
The shell installs signal handlers for SIGSEGV, SIGFPE, and SIGILL
before loading any apps, so even crashes during app initialization are
caught. If an app crashes, the handler longjmps back to the shell's
main loop, the crashed app is force-killed, and the shell continues
running. Diagnostic information (registers, faulting EIP) is logged to
dvx.log.
Bundled Applications
| App | File | Type | Description |
|---|---|---|---|
| Program Manager | progman.app |
Callback | App launcher grid, system info dialog |
| Notepad | notepad.app |
Callback | Text editor with File/Edit menus, open/save, clipboard |
| Clock | clock.app |
Main-loop | Digital clock display; multi-instance capable |
| DVX Demo | dvxdemo.app |
Callback | Widget system showcase demonstrating 31 widget types |
| Control Panel | cpanel.app |
Callback | Themes, wallpaper, video mode, mouse configuration |
| Image Viewer | imgview.app |
Callback | Displays BMP, PNG, JPEG, GIF images with aspect-ratio zoom |
Serial / Networking Stack
A layered encrypted serial communications stack for connecting DVX to remote systems (BBS, etc.) through 86Box's emulated UART:
| Layer | Library | Description |
|---|---|---|
| rs232 | librs232.a |
ISR-driven UART driver, ring buffers, flow control |
| packet | libpacket.a |
HDLC framing, CRC-16, Go-Back-N ARQ |
| security | libsecurity.a |
1024-bit DH, XTEA-CTR cipher, DRBG RNG |
| seclink | libseclink.a |
Channel multiplexing, per-packet encryption |
| proxy | secproxy |
Linux bridge: 86Box serial <-> telnet BBS |
Third-Party Dependencies
All third-party code is vendored as single-header libraries:
| Library | Location | Purpose |
|---|---|---|
| stb_image.h | core/thirdparty/ |
Image loading (BMP, PNG, JPEG, GIF) |
| stb_image_write.h | core/thirdparty/ |
PNG export for screenshots |
| stb_ds.h | core/thirdparty/ |
Dynamic arrays and hash maps |
stb_ds implementation is compiled into dvx.exe (the loader) with
STBDS_REALLOC/STBDS_FREE overridden to use dvxRealloc/dvxFree,
so all arrput/arrfree calls in DXE code are tracked per-app. The
functions are exported via dlregsym to all DXE modules.
Target Hardware
- CPU: 486 baseline, Pentium-optimized paths where significant
- Video: VESA VBE 2.0+ with LFB (no bank switching)
- Platform: 86Box emulator (trusted reference), real DOS hardware
- Resolutions: 640x480, 800x600, 1024x768 at 8/15/16/32 bpp