# DVX Shell Applications Every DVX application is a DXE3 module packaged as a `.app` file, installed under `bin/apps/kpunch//.app`. The Program Manager scans this directory at startup and displays each discovered app as a launchable icon on the desktop. This directory holds the source for the bundled applications plus the BASIC-based sample apps. Two flavours of app live side by side: * **C apps** -- written directly against the DVX SDK headers, compiled to a DXE3 by `dxe3gen`. See `progman/`, `clock/`, `dvxdemo/`, `cpanel/`, `dvxhelp/`. * **BASIC apps** -- `.dbp` projects compiled to `.app` files by the host-side `bascomp`. The compiler links the BASIC bytecode into a copy of `basstub.app`, which acts as the runtime host. See `iconed/`, `notepad/`, `imgview/`, `basicdemo/`, `resedit/`, `dvxhelp/helpedit/`. The rest of this document covers writing a C app against the SDK. For BASIC apps, see `dvxbasic/README.md`. ## DXE App Contract Every `.app` binary exports two required symbols and one optional symbol: ```c AppDescriptorT appDescriptor; // required int32_t appMain(DxeAppContextT *ctx); // required void appShutdown(void); // optional ``` ### `appDescriptor` A statically-initialised struct read by the shell at load time to decide how to launch the app: ```c typedef struct { char name[SHELL_APP_NAME_MAX]; // display name (<= 64 chars) bool hasMainLoop; // see below bool multiInstance; // may have multiple copies open int32_t stackSize; // SHELL_STACK_DEFAULT or byte count int32_t priority; // TS_PRIORITY_* for main-loop apps } AppDescriptorT; ``` Example (from `clock/clock.c`): ```c AppDescriptorT appDescriptor = { .name = "Clock", .hasMainLoop = true, .multiInstance = true, .stackSize = SHELL_STACK_DEFAULT, .priority = TS_PRIORITY_LOW }; ``` ### `appMain` Entry point. The shell calls it with a `DxeAppContextT` that exposes the shell's GUI context, the app's ID, its install directory, a writable config directory, launch arguments, and a help-topic query callback for F1. Returning from `appMain` signals that the app has finished; the shell unloads the DXE, frees per-app memory, and reclaims the app slot. ### `appShutdown` Called by the shell when the app is force-killed (by the Task Manager) or when the shell is shutting down with this app still running. Main-loop apps use it to set a flag that their main loop observes, so the loop exits cleanly and `appMain` can return. ## App Types ### Callback-only apps (`hasMainLoop = false`) `appMain` creates windows, registers callbacks, and returns 0. The shell drives all further work by invoking those callbacks in response to user input and timers. No dedicated task is allocated; no per-app stack is consumed. The app's lifetime ends when the last window closes (or when every callback has released all references). Use this pattern for event-driven UI: Notepad, Program Manager, DVX Demo, Control Panel, Image Viewer. ### Main-loop apps (`hasMainLoop = true`) The shell creates a cooperative task for the app and calls `appMain` from inside it. `appMain` runs a loop that calls `tsYield()` periodically to share the CPU. Exit by breaking out of the loop and returning. Use this pattern when the app needs continuous background work that does not map cleanly onto event callbacks: Clock (polls the system clock every second), terminal emulators, games. ## Resource Conventions Apps attach resources to their `.app` binary using `dvxres build` (see `src/tools/README.md`). The standard resource names are: | Name | Type | Meaning | |---------------|--------|---------| | `icon32` | icon | 32x32 BMP shown in Program Manager and the Task Manager. | | `name` | text | Human-readable display name (overrides `appDescriptor.name` for UI where available). | | `author` | text | Author / maintainer name. | | `publisher` | text | Publisher or studio. | | `copyright` | text | Copyright notice. | | `version` | text | Version string, free-form. | | `description` | text | One-sentence description shown in About dialogs. | | `helpfile` | text | Optional relative path to a `.hlp` file for F1 context help. | Additional application-specific resources may be attached with any unique name. The runtime reads them via `dvxResOpen(appPath)` / `dvxResRead(handle, name, &size)` / `dvxResClose(handle)`. Typical `.res` manifest: ``` # clock.res icon32 icon icon32.bmp name text "Clock" author text "Scott Duensing" copyright text "Copyright 2026 Scott Duensing" publisher text "Kangaroo Punch Studios" description text "Digital clock with date display" ``` ## Bundled Applications ### Program Manager (progman) | | | |---|---| | File | `apps/kpunch/progman/progman.app` | | Type | Callback-only | | Multi-instance | No | The desktop. Recursively scans `apps/` for `.app` files and displays them as a launchable grid with icons, names, and publishers. Double click or Enter to launch. Includes a Help menu with the system help viewer and the About / System Info dialog. Registers with `shellRegisterDesktopUpdate()` so the grid refreshes when apps are loaded, terminated, or crash. Widget headers used: `box/box.h`, `button/button.h`, `label/label.h`, `statusBar/statBar.h`, `textInput/textInpt.h`, `imageButton/imgBtn.h`, `scrollPane/scrlPane.h`, `wrapBox/wrapBox.h`. ### Notepad (notepad, BASIC) | | | |---|---| | File | `apps/kpunch/notepad/notepad.app` | | Type | BASIC (main-loop via basstub) | | Multi-instance | No | Plain-text editor with File menu (New, Open, Save, Save As) and Edit menu (Cut, Copy, Paste, Select All). Built from a BASIC project (`notepad.dbp` + `notepad.frm`); demonstrates the form designer, TextInput widget, and common dialog integration. ### Clock (clock) | | | |---|---| | File | `apps/kpunch/clock/clock.app` | | Type | Main-loop | | Multi-instance | Yes | Digital clock showing time and date. Polls the system clock every second and invalidates the window to trigger a repaint. Uses the raw `onPaint` callback (no widgets) to draw centered text. Reference implementation for main-loop apps. ### DVX Demo (dvxdemo) | | | |---|---| | File | `apps/kpunch/dvxdemo/dvxdemo.app` | | Type | Callback-only | | Multi-instance | No | Widget toolkit showcase. Opens multiple windows demonstrating virtually every widget type: * Main window -- raw paint callbacks (gradients, patterns, text) * Widget demo -- form widgets (TextInput, Checkbox, Radio, ListBox) * Controls window -- tabbed advanced widgets (Dropdown, ProgressBar, Slider, Spinner, TreeView, ListView, ScrollPane, Toolbar, Canvas, Splitter, Image) * Terminal window -- AnsiTerm widget Resources include `logo.bmp`, `new.bmp`, `open.bmp`, `sample.bmp`, `save.bmp`. Reference implementation for widget-based UIs. ### Control Panel (cpanel) | | | |---|---| | File | `apps/kpunch/cpanel/cpanel.app` | | Type | Callback-only | | Multi-instance | No | System configuration with four tabs: * **Mouse** -- scroll direction, wheel speed, double-click speed, acceleration, cursor speed * **Colors** -- every system colour with live preview; theme load and save * **Desktop** -- wallpaper image and display mode * **Video** -- resolution and colour depth switching Changes preview live. OK writes to `CONFIG/DVX.INI`; Cancel reverts to the snapshot taken when the panel opened. ### Image Viewer (imgview, BASIC) | | | |---|---| | File | `apps/kpunch/imgview/imgview.app` | | Type | BASIC (main-loop via basstub) | | Multi-instance | No | Displays BMP, PNG, JPEG, and GIF images scaled to fit the window with aspect ratio preserved. Resize to zoom. Open via the File menu or via launch arguments. Built from a BASIC project using the Canvas widget. ### DVX BASIC (dvxbasic) | | | |---|---| | File | `apps/kpunch/dvxbasic/dvxbasic.app` | | Type | Callback-only | | Multi-instance | No | Visual Basic 3 compatible IDE: form designer, per-procedure code editor, project manager, compiler, and runtime VM. See `dvxbasic/README.md` for a detailed architecture description. `dvxbasic/` also builds: * `bin/libs/kpunch/basrt/basrt.lib` -- the BASIC runtime (VM + values) as a separately loadable library, so compiled BASIC apps do not carry their own copy of the runtime. * `bin/apps/kpunch/dvxbasic/basstub.app` -- the stub used as the template for every compiled BASIC app. ### DVX Help Viewer (dvxhelp) | | | |---|---| | File | `apps/kpunch/dvxhelp/dvxhelp.app` | | Type | Callback-only | | Multi-instance | Yes | Renders compiled `.hlp` files produced by `dvxhlpc`. Supports table of contents, keyword index, full-text search (trigram), hyperlinks, and inline images. ### Icon Editor (iconed, BASIC) | | | |---|---| | File | `apps/kpunch/iconed/iconed.app` | | Type | BASIC (main-loop via basstub) | | Multi-instance | No | Paint-program-style editor for creating 32x32 BMP icons. Pen / eraser / fill tools, 16-colour palette, BMP save / load. ### Help Editor (helpedit, BASIC) | | | |---|---| | File | `apps/kpunch/dvxhelp/helpedit.app` | | Type | BASIC (main-loop via basstub) | | Multi-instance | No | Editor for `.dhs` help source files with syntax-aware controls. Runs the compiled system help viewer by default for live preview. ### Resource Editor (resedit, BASIC) | | | |---|---| | File | `apps/kpunch/resedit/resedit.app` | | Type | BASIC (main-loop via basstub) | | Multi-instance | No | GUI wrapper around `dvxres`: open a `.app` / `.wgt` / `.lib`, browse its resources, add, replace, extract, or remove them. ### BASIC Demo (basicdemo, BASIC) | | | |---|---| | File | `apps/kpunch/basicdemo/basicdemo.app` | | Type | BASIC (main-loop via basstub) | | Multi-instance | No | Gallery of short BASIC programs demonstrating the language and the form designer. Intended as sample source for reading. ## Build ``` make # build every app (C apps + BASIC apps) make # build a single app make clean # remove all app build artifacts ``` The `apps/kpunch/Makefile` orchestrates both C and BASIC builds: * **C apps** compile each `/.c` to an object file, run `dxe3gen -U` on it to produce `.app`, then attach resources with `dvxres build` if a `.res` manifest exists. * **BASIC apps** run `bascomp .dbp -o .app -release`, which handles project-file parsing, compilation, resource attachment, and linking into `basstub.app`. Build output goes to `bin/apps/kpunch//.app`. ## Writing a New C App Minimal skeleton: ```c #include "dvxApp.h" #include "dvxWgt.h" #include "shellApp.h" #include #include // Prototypes static int32_t appMainImpl(DxeAppContextT *ctx); static void onClose(WindowT *win); // Required descriptor AppDescriptorT appDescriptor = { .name = "My App", .hasMainLoop = false, .multiInstance = false, .stackSize = SHELL_STACK_DEFAULT, .priority = 0 }; static void onClose(WindowT *win) { (void)win; // Callback-only apps: nothing to do; the shell reaps us when // the last window closes. } int32_t appMain(DxeAppContextT *ctx) { return appMainImpl(ctx); } static int32_t appMainImpl(DxeAppContextT *ctx) { AppContextT *ac = ctx->shellCtx; WindowT *win = dvxCreateWindow(ac, appDescriptor.name, 100, 100, 320, 240, true); if (!win) { return -1; } win->onClose = onClose; return 0; } ``` Add a Makefile target that mirrors the existing apps (see `apps/kpunch/Makefile` for the pattern), drop a `.res` manifest next to the source, and provide a 32x32 `icon32.bmp`. `make ` should then produce `bin/apps/kpunch//.app`. ## Testing Locally After `make`, the app is deployed in-tree under `bin/apps/kpunch/`. Launch the full system (`bin/dvx.exe`) and the Program Manager picks up the new app automatically on the next boot. To iterate quickly: rebuild the single app, restart DVX, and launch it. The log at `bin/DVX.LOG` records load errors, missing dependencies, and per-app crash diagnostics. ## Files ``` apps/kpunch/ Makefile top-level app build README.md this file # C apps progman/ progman.c Program Manager dvxhelp.hcf help-compiler config (system reference) clock/ clock.c digital clock (main-loop reference) clock.res icon32.bmp dvxdemo/ dvxdemo.c widget showcase dvxdemo.res icon32.bmp logo.bmp / new.bmp / open.bmp / sample.bmp / save.bmp cpanel/ cpanel.c Control Panel cpanel.res icon32.bmp dvxhelp/ dvxhelp.c help viewer dvxhelp.res help.dhs source for the dvxhelp app's own help hlpformat.h binary format shared with the compiler sample.dhs small sample source icon32.bmp helpedit/ BASIC project: help editor helpedit.dbp helpedit.frm ICON32.BMP # BASIC apps iconed/ iconed.dbp iconed.frm ICON32.BMP notepad/ notepad.dbp notepad.frm ICON32.BMP imgview/ imgview.dbp imgview.frm ICON32.BMP basicdemo/ basicdemo.dbp basicdemo.frm ICON32.BMP resedit/ resedit.dbp resedit.frm ICON32.BMP dvxbasic/ see dvxbasic/README.md compiler/ lexer, parser, codegen, strip, obfuscate runtime/ VM + value system formrt/ form runtime (BASIC <-> DVX widgets) ide/ IDE front end stub/ bascomp + basstub ... ```