# 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)
  |
  +-- libs/basrt.lib          BASIC runtime (VM + values)
  +-- libs/serial.lib         serial communications (rs232 + packet + seclink)
  |
  +-- 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`, `bin/mkicon`, `bin/mktbicon` | Resource and icon tools (host native) |
| `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)
    basrt.lib                BASIC runtime (VM + values)
    serial.lib               serial communications stack
    *.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
    dvxbasic/dvxbasic.app    DVX BASIC IDE + compiler
  config/
    dvx.ini                  system configuration
    themes/                  color theme files (.thm)
    wpaper/                  wallpaper images
```


## Core Architecture (5 Layers)

1. **dvxVideo** -- VESA VBE init, LFB mapping, backbuffer, pixel format, color packing
2. **dvxDraw** -- Rectangle fills, bevels, text rendering, cursor/icon drawing
3. **dvxComp** -- Dirty rectangle tracking, merge, compositor, LFB flush
4. **dvxWm** -- Window stack, chrome, drag/resize, menus, scrollbars, hit testing
5. **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 by `WGT_METHOD_*` constants (0-20, room for 32). Core
  dispatches via `w->wclass->handlers[WGT_METHOD_PAINT]` etc., so adding
  new methods does not break existing widget DXE binaries
* **Generic drag**: `WGT_METHOD_ON_DRAG_UPDATE` and `WGT_METHOD_ON_DRAG_END`
  provide 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.h` etc. 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 `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`.


## 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 |
| DVX BASIC       | `dvxbasic.app` | Callback  | Visual Basic 3 clone: form designer, compiler, VM          |


## 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
