# DVX -- DOS Visual eXecutive A windowed GUI compositor and desktop shell for DOS, built with DJGPP/DPMI. DVX combines a Motif-style window manager, dirty-rectangle compositor, cooperative task switcher, and a modular DXE3 architecture into a multitasking desktop environment. The bootstrap loader dynamically discovers and loads core libraries, widget plugins, and applications at runtime. Targets real and emulated 486+ hardware with VESA VBE 2.0+ linear framebuffer. No bank switching -- LFB or fail. ## Features - Motif/GEOS-style beveled window chrome with drag, resize, minimize, maximize, and restore - Dirty-rectangle compositor -- only changed regions are flushed to video memory, critical for acceptable frame rates on 486/Pentium hardware - 32 widget types across 26 DXE modules: buttons, text inputs, list boxes, tree views, list views, tab controls, sliders, spinners, progress bars, dropdowns, combo boxes, splitters, scroll panes, ANSI terminal emulator, and more - Flexbox-style automatic layout engine (VBox/HBox containers with weighted space distribution) - Dropdown menus with cascading submenus, checkbox and radio items, keyboard accelerators, and context menus - Modal dialogs: message box (OK/Cancel/Yes/No/Retry) and file open/save with directory navigation and filter dropdown - 20-color theme system with live preview and INI-based theme files - Wallpaper support: stretch, tile, or center with bilinear scaling and 16bpp ordered dithering - Live video mode switching without restart - Mouse wheel support (CuteMouse Wheel API) - Screenshots (full screen or per-window) saved as PNG - Clipboard (copy/cut/paste within DVX) - Timer widget for periodic callbacks - Cooperative task switcher for apps that need their own main loop - DXE3 dynamic application loading with crash recovery (SIGSEGV, SIGFPE, SIGILL caught and isolated per-app) - INI-based preferences system with typed read/write accessors - Encrypted serial networking stack (DH key exchange, XTEA-CTR cipher) - Platform abstraction layer -- DOS/DJGPP production target, Linux/SDL2 development target - Modular DXE architecture with dependency resolution -- core libraries, widget plugins, and applications are all separate loadable modules ## Target Hardware - **CPU**: 486 baseline, Pentium-optimized paths where significant - **Video**: VESA VBE 2.0+ with linear framebuffer - **OS**: DOS with DPMI (CWSDPMI or equivalent) - **Supported depths**: 8, 15, 16, 24, 32 bpp - **Test platform**: 86Box with PCI video cards ## Architecture DVX uses a modular DXE3 architecture. The bootstrap loader (`dvx.exe`) is a small executable that discovers, dependency-sorts, and loads all modules at startup. Core libraries, widget plugins, and applications are separate `.lib`, `.wgt`, and `.app` DXE shared libraries. ``` dvx.exe (bootstrap loader) | +-- platformRegisterDxeExports() -- platform + libc/libm symbols | +-- libs/ (scanned, dependency-ordered) | libtasks.lib -- cooperative task switching, stb_ds | libdvx.lib -- draw, comp, wm, app, widget infrastructure | dvxshell.lib -- shell, app lifecycle, crash recovery | +-- widgets/ (scanned, each calls wgtRegister) | box.wgt, button.wgt, label.wgt, ... (26 modules) | +-- shellMain() -- found via dlsym, enters main loop | +-- apps/ (loaded on demand by shell) progman.app, notepad.app, clock.app, ... ``` ### Boot Sequence 1. `dvx.exe` starts, calls `platformRegisterDxeExports()` to register platform and libc/libm symbols for DXE modules 2. Scans `libs/` recursively for `*.lib` files, reads `.dep` files, topologically sorts, and loads in dependency order 3. Scans `widgets/` recursively for `*.wgt` files, loads each, and calls `wgtRegister()` on any module that exports it 4. Finds `shellMain()` across loaded modules via `dlsym` 5. Calls `shellMain()`, which initializes the GUI, loads the desktop app, and enters the main event loop ### Dependency Resolution Each DXE module may have a `.dep` file (same base name, `.dep` extension) listing the base names of modules that must be loaded before it. The loader reads all `.dep` files, builds a dependency graph, and loads modules in topological order. For example, `libdvx.dep` contains `libtasks`, and `dvxshell.dep` lists `libtasks`, `libdvx`, and all widget modules it requires. ### Widget DXE Modules The 32 widget types in the `WidgetTypeE` enum are implemented across 26 `.wgt` DXE modules. Some modules register multiple widget types: | Module | Widget Types | |--------|-------------| | `box.wgt` | VBox, HBox, Frame | | `radio.wgt` | RadioGroup, Radio | | `textinpt.wgt` | TextInput, TextArea | | `tabctrl.wgt` | TabControl, TabPage | | `treeview.wgt` | TreeView, TreeItem | Each widget DXE exports a standard `wgtRegister()` function that registers its widget class(es) with the core widget infrastructure. Widget DXEs are discovered by directory scanning, not hardcoded. ### 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. If an app crashes, the handler `longjmp`s 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`. ## Directory Structure ### Source Tree ``` dvxgui/ core/ Core GUI infrastructure (-> libs/libdvx.lib) platform/ Platform abstraction (dvxPlatform.h, dvxPlatformDos.c) thirdparty/ stb_image.h, stb_image_write.h tasks/ Cooperative task switcher (-> libs/libtasks.lib) thirdparty/ stb_ds.h shell/ Desktop shell (-> libs/dvxshell.lib) widgets/ Widget modules (-> widgets/*.wgt, 26 files) loader/ Bootstrap loader (-> dvx.exe) apps/ Application modules (-> apps/*.app) progman/ Program Manager -- app launcher grid notepad/ Text editor with file I/O clock/ Digital clock (multi-instance, main-loop) dvxdemo/ Widget system showcase / demo app cpanel/ Control Panel -- themes, wallpaper, video, mouse imgview/ Image Viewer -- BMP/PNG/JPEG/GIF display config/ Themes, wallpapers, dvx.ini, dependency files rs232/ ISR-driven UART serial driver (librs232.a) packet/ HDLC framing, CRC-16, Go-Back-N (libpacket.a) security/ DH key exchange, XTEA-CTR cipher (libsecurity.a) seclink/ Secure serial link wrapper (libseclink.a) proxy/ Linux serial-to-telnet proxy (secproxy) termdemo/ Encrypted ANSI terminal demo (termdemo.exe) bin/ Build output lib/ Build output (static libraries) releases/ Release archives ``` ### Build Output (`bin/`) ``` bin/ dvx.exe Bootstrap loader dvx.map Linker map libs/ libtasks.lib Task switching DXE libdvx.lib Core GUI DXE libdvx.dep Dependencies: libtasks dvxshell.lib Shell DXE dvxshell.dep Dependencies: libtasks, libdvx, box, button, etc. widgets/ box.wgt VBox/HBox/Frame button.wgt Button canvas.wgt Canvas checkbox.wgt Checkbox combobox.wgt ComboBox dropdown.wgt Dropdown image.wgt Image imgbtn.wgt ImageButton label.wgt Label listbox.wgt ListBox listview.wgt ListView progress.wgt ProgressBar radio.wgt RadioGroup/Radio scrlpane.wgt ScrollPane separatr.wgt Separator slider.wgt Slider spacer.wgt Spacer spinner.wgt Spinner splitter.wgt Splitter statbar.wgt StatusBar tabctrl.wgt TabControl/TabPage terminal.wgt AnsiTerm textinpt.wgt TextInput/TextArea timer.wgt Timer toolbar.wgt Toolbar treeview.wgt TreeView/TreeItem apps/ progman/progman.app notepad/notepad.app clock/clock.app dvxdemo/dvxdemo.app cpanel/cpanel.app imgview/imgview.app config/ dvx.ini themes/ cde.thm geos.thm win31.thm wpaper/ blueglow.jpg swoop.jpg triangle.jpg ``` ## Building Requires the DJGPP cross-compiler (`i586-pc-msdosdjgpp-gcc`). ```bash # Build everything (loader, core, tasks, shell, widgets, all apps) make # Build individual components make -C loader # builds dvx.exe make -C core # builds libs/libdvx.lib + widgets/*.wgt make -C tasks # builds libs/libtasks.lib make -C shell # builds libs/dvxshell.lib + config make -C widgets # builds widgets/*.wgt make -C apps # builds apps/*/*.app # Clean all build artifacts make clean ``` Set `DJGPP_PREFIX` in the component Makefiles if your toolchain is installed somewhere other than `~/djgpp/djgpp`. ## Deployment ### CD-ROM ISO (86Box) The primary deployment method is an ISO image mounted as a CD-ROM in 86Box: ```bash ./mkcd.sh ``` This builds everything, then creates an ISO 9660 image with 8.3 filenames at `~/.var/app/net._86box._86Box/data/86Box/dvx.iso`. Mount it in 86Box as a CD-ROM drive and run `D:\DVX.EXE` (or whatever drive letter is assigned). ## Configuration DVX reads its configuration from `CONFIG\DVX.INI` on the target filesystem. The INI file uses a standard `[section]` / `key = value` format. Settings are applied at startup and can be changed live from the Control Panel app. ```ini [video] width = 640 height = 480 bpp = 16 [mouse] wheel = normal doubleclick = 500 acceleration = medium [colors] desktop = 0,128,128 windowFace = 192,192,192 windowHighlight = 255,255,255 windowShadow = 128,128,128 activeTitleBg = 48,48,48 activeTitleFg = 255,255,255 inactiveTitleBg = 160,160,160 inactiveTitleFg = 64,64,64 contentBg = 192,192,192 contentFg = 0,0,0 menuBg = 192,192,192 menuFg = 0,0,0 menuHighlightBg = 48,48,48 menuHighlightFg = 255,255,255 buttonFace = 192,192,192 scrollbarBg = 192,192,192 scrollbarFg = 128,128,128 scrollbarTrough = 160,160,160 cursorColor = 255,255,255 cursorOutline = 0,0,0 [desktop] wallpaper = C:\DVX\WPAPER\SWOOP.JPG mode = stretch ``` ### Video Section - `width`, `height` -- requested resolution (closest VESA mode is used) - `bpp` -- preferred color depth (8, 15, 16, 24, or 32) ### Mouse Section - `wheel` -- `normal` or `reversed` - `doubleclick` -- double-click speed in milliseconds (200--900) - `acceleration` -- `off`, `low`, `medium`, or `high` ### Colors Section All 20 system colors as `R,G,B` triplets (0--255). Key names match the `ColorIdE` enum: `desktop`, `windowFace`, `windowHighlight`, `windowShadow`, `activeTitleBg`, `activeTitleFg`, `inactiveTitleBg`, `inactiveTitleFg`, `contentBg`, `contentFg`, `menuBg`, `menuFg`, `menuHighlightBg`, `menuHighlightFg`, `buttonFace`, `scrollbarBg`, `scrollbarFg`, `scrollbarTrough`, `cursorColor`, `cursorOutline`. Missing keys fall back to compiled-in defaults (GEOS Ensemble palette). Colors can also be loaded from standalone `.thm` theme files via the Control Panel. ### Desktop Section - `wallpaper` -- path to wallpaper image (BMP, PNG, JPEG, GIF) - `mode` -- `stretch`, `tile`, or `center` ## Bundled Applications | App | File | Type | Description | |-----|------|------|-------------| | Program Manager | `progman.app` | Callback | App launcher grid with icons; Help menu opens the shell's Task Manager (Ctrl+Esc) | | Notepad | `notepad.app` | Callback | Text editor with File/Edit menus, open/save dialogs, clipboard, and undo | | Clock | `clock.app` | Main-loop | Digital clock display; multi-instance capable | | DVX Demo | `dvxdemo.app` | Callback | Widget system showcase demonstrating all 32 widget types | | Control Panel | `cpanel.app` | Callback | System settings: color themes with live preview, wallpaper selection, video mode switching, mouse configuration | | Image Viewer | `imgview.app` | Callback | Displays BMP, PNG, JPEG, and GIF images with file dialog | ## 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 with FIFO support, automatic UART type detection (8250 through 16750), configurable baud rate | | packet | `libpacket.a` | HDLC framing with byte stuffing, CRC-16 integrity checks, Go-Back-N sliding window for reliable delivery, 255-byte max payload | | security | `libsecurity.a` | 1024-bit Diffie-Hellman key exchange (RFC 2409 Group 2), XTEA-CTR stream cipher, XTEA-CTR DRBG random number generator | | seclink | `libseclink.a` | Convenience wrapper: multiplexed channels (0--127), per-packet encryption flag, bulk send helper | | proxy | `secproxy` | Linux-side bridge: 86Box emulated serial port <-> secLink <-> telnet BBS; socket shim replaces rs232 API | ## Third-Party Dependencies All third-party code is vendored as single-header libraries with no external dependencies: | Library | Location | Purpose | |---------|----------|---------| | stb_image.h | `core/thirdparty/` | Image loading (BMP, PNG, JPEG, GIF) | | stb_image_write.h | `core/thirdparty/` | Image writing (PNG export for screenshots) | | stb_ds.h | `tasks/thirdparty/` | Dynamic array and hash map (used by task manager) | ## Component Documentation Each component directory has its own README with detailed API reference: - [`core/README.md`](core/README.md) -- Core GUI library architecture and API - [`tasks/README.md`](tasks/README.md) -- Task switcher API - [`shell/README.md`](shell/README.md) -- Shell internals and DXE app contract - [`apps/README.md`](apps/README.md) -- Writing DXE applications - [`rs232/README.md`](rs232/README.md) -- Serial port driver - [`packet/README.md`](packet/README.md) -- Packet transport protocol - [`security/README.md`](security/README.md) -- Cryptographic primitives - [`seclink/README.md`](seclink/README.md) -- Secure serial link - [`proxy/README.md`](proxy/README.md) -- Linux SecLink proxy - [`termdemo/README.md`](termdemo/README.md) -- Encrypted terminal demo