From 2a641f42c340439468f258c40b8521bff4df7017 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Tue, 7 Apr 2026 18:28:39 -0500 Subject: [PATCH] Now using -Wall -Werror (for real). All warnings fixed. Help system added. --- apps/Makefile | 15 +- apps/cpanel/cpanel.c | 4 +- apps/dvxbasic/Makefile | 2 +- apps/dvxbasic/compiler/codegen.c | 1 + apps/dvxbasic/ide/ideMain.c | 71 +- apps/dvxbasic/ide/ideMenuEditor.c | 2 +- apps/dvxbasic/ide/ideProject.c | 12 +- apps/dvxbasic/ide/ideProperties.c | 8 +- apps/dvxbasic/runtime/vm.h | 1 + apps/dvxhelp/dvxhelp.c | 1406 +++++ apps/dvxhelp/dvxhelp.res | 5 + apps/dvxhelp/hlpformat.h | 157 + apps/dvxhelp/icon32.bmp | 3 + apps/dvxhelp/sample.dvxhelp | 155 + apps/progman/progman.c | 2 +- core/Makefile | 2 +- core/dvxApp.c | 9 + core/dvxApp.h | 3 + core/dvxDialog.c | 10 +- core/dvxResource.h | 6 +- core/dvxTypes.h | 8 - core/platform/dvxPlatform.h | 7 + docs/dvx_api_reference.html | 4927 ++++++++---------- docs/dvx_architecture.html | 1322 ++--- docs/dvx_help_sample.html | 155 + docs/dvx_widget_reference.html | 2718 +++++----- docs/dvxbasic_control_reference.html | 2523 ++++----- docs/dvxbasic_ide_guide.html | 1597 +++--- docs/dvxbasic_language_reference.html | 2643 ++++------ docs/src/dvx_api_reference.dvxhelp | 3499 +++++++++++++ docs/src/dvx_architecture.dvxhelp | 776 +++ docs/src/dvx_widget_reference.dvxhelp | 1801 +++++++ docs/src/dvxbasic_control_reference.dvxhelp | 1567 ++++++ docs/src/dvxbasic_ide_guide.dvxhelp | 944 ++++ docs/src/dvxbasic_language_reference.dvxhelp | 1574 ++++++ listhelp/Makefile | 2 +- loader/Makefile | 2 +- loader/loaderMain.c | 2 +- packet/Makefile | 2 +- proxy/Makefile | 2 +- rs232/Makefile | 2 +- seclink/Makefile | 2 +- security/Makefile | 2 +- serial/Makefile | 2 +- shell/Makefile | 2 +- shell/shellApp.c | 20 +- shell/shellApp.h | 7 + shell/shellMain.c | 43 + sql/Makefile | 2 +- sql/thirdparty/sqlite/src/btree.c | 3 + sql/thirdparty/sqlite/src/build.c | 3 +- sql/thirdparty/sqlite/src/insert.c | 10 +- sql/thirdparty/sqlite/src/os_unix.c | 9 +- sql/thirdparty/sqlite/src/printf.c | 1 + sql/thirdparty/sqlite/src/select.c | 40 +- sql/thirdparty/sqlite/src/update.c | 8 +- sql/thirdparty/sqlite/src/vdbe.c | 12 +- sql/thirdparty/sqlite/src/vdbeapi.c | 1 + taskmgr/Makefile | 2 +- tasks/Makefile | 2 +- texthelp/Makefile | 2 +- tools/Makefile | 7 +- tools/dvxhlpc.c | 1726 ++++++ tools/mkicon.c | 35 +- widgets/Makefile | 2 +- widgets/ansiTerm/widgetAnsiTerm.c | 6 +- widgets/checkbox/widgetCheckbox.c | 2 +- widgets/comboBox/widgetComboBox.c | 2 +- widgets/dropdown/widgetDropdown.c | 2 +- widgets/image/widgetImage.c | 6 +- widgets/imageButton/widgetImageButton.c | 6 +- widgets/listBox/widgetListBox.c | 2 +- widgets/listView/widgetListView.c | 2 +- widgets/progressBar/widgetProgressBar.c | 2 +- widgets/radio/widgetRadio.c | 2 +- widgets/slider/widgetSlider.c | 2 +- widgets/splitter/widgetSplitter.c | 2 +- widgets/tabControl/widgetTabControl.c | 2 +- widgets/textInput/widgetTextInput.c | 22 +- widgets/timer/widgetTimer.c | 4 +- 80 files changed, 20540 insertions(+), 9414 deletions(-) create mode 100644 apps/dvxhelp/dvxhelp.c create mode 100644 apps/dvxhelp/dvxhelp.res create mode 100644 apps/dvxhelp/hlpformat.h create mode 100644 apps/dvxhelp/icon32.bmp create mode 100644 apps/dvxhelp/sample.dvxhelp create mode 100644 docs/dvx_help_sample.html create mode 100644 docs/src/dvx_api_reference.dvxhelp create mode 100644 docs/src/dvx_architecture.dvxhelp create mode 100644 docs/src/dvx_widget_reference.dvxhelp create mode 100644 docs/src/dvxbasic_control_reference.dvxhelp create mode 100644 docs/src/dvxbasic_ide_guide.dvxhelp create mode 100644 docs/src/dvxbasic_language_reference.dvxhelp create mode 100644 tools/dvxhlpc.c diff --git a/apps/Makefile b/apps/Makefile index 9dd8285..7f33e51 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -4,14 +4,14 @@ DJGPP_PREFIX = $(HOME)/djgpp/djgpp DJGPP_LIBPATH = $(HOME)/claude/windriver/tools/lib CC = $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-gcc DXE3GEN = PATH=$(DJGPP_PREFIX)/bin:$(PATH) DJDIR=$(DJGPP_PREFIX)/i586-pc-msdosdjgpp $(DJGPP_PREFIX)/i586-pc-msdosdjgpp/bin/dxe3gen -CFLAGS = -O2 -Wall -Wextra -Wno-type-limits -Wno-sign-compare -march=i486 -mtune=i586 -I../core -I../core/platform -I../core/thirdparty -I../widgets -I../tasks -I../core/thirdparty -I../shell +CFLAGS = -O2 -Wall -Wextra -Werror -Wno-type-limits -Wno-sign-compare -Wno-format-truncation -march=i486 -mtune=i586 -I../core -I../core/platform -I../core/thirdparty -I../widgets -I../tasks -I../core/thirdparty -I../shell OBJDIR = ../obj/apps BINDIR = ../bin/apps DVXRES = ../bin/dvxres # App definitions: each is a subdir with a single .c file -APPS = progman notepad clock dvxdemo cpanel imgview +APPS = progman notepad clock dvxdemo cpanel imgview dvxhelp .PHONY: all clean $(APPS) dvxbasic @@ -26,6 +26,7 @@ progman: $(BINDIR)/progman/progman.app notepad: $(BINDIR)/notepad/notepad.app clock: $(BINDIR)/clock/clock.app dvxdemo: $(BINDIR)/dvxdemo/dvxdemo.app +dvxhelp: $(BINDIR)/dvxhelp/dvxhelp.app $(BINDIR)/cpanel/cpanel.app: $(OBJDIR)/cpanel.o cpanel/cpanel.res cpanel/icon32.bmp | $(BINDIR)/cpanel $(DXE3GEN) -o $@ -E _appDescriptor -E _appMain -U $< @@ -71,6 +72,13 @@ $(OBJDIR)/clock.o: clock/clock.c | $(OBJDIR) $(OBJDIR)/dvxdemo.o: dvxdemo/dvxdemo.c | $(OBJDIR) $(CC) $(CFLAGS) -c -o $@ $< +$(BINDIR)/dvxhelp/dvxhelp.app: $(OBJDIR)/dvxhelp.o dvxhelp/dvxhelp.res dvxhelp/icon32.bmp | $(BINDIR)/dvxhelp + $(DXE3GEN) -o $@ -E _appDescriptor -E _appMain -U $< + $(DVXRES) build $@ dvxhelp/dvxhelp.res + +$(OBJDIR)/dvxhelp.o: dvxhelp/dvxhelp.c dvxhelp/hlpformat.h | $(OBJDIR) + $(CC) $(CFLAGS) -c -o $@ $< + $(OBJDIR): mkdir -p $(OBJDIR) @@ -92,6 +100,9 @@ $(BINDIR)/clock: $(BINDIR)/dvxdemo: mkdir -p $(BINDIR)/dvxdemo +$(BINDIR)/dvxhelp: + mkdir -p $(BINDIR)/dvxhelp + # Dependencies $(OBJDIR)/imgview.o: imgview/imgview.c ../core/dvxApp.h ../core/dvxDialog.h ../core/dvxWidget.h ../core/dvxWm.h ../core/dvxVideo.h ../shell/shellApp.h $(OBJDIR)/cpanel.o: cpanel/cpanel.c ../core/dvxApp.h ../core/dvxDialog.h ../core/dvxPrefs.h ../core/dvxWidget.h ../core/dvxWm.h ../core/platform/dvxPlatform.h ../shell/shellApp.h diff --git a/apps/cpanel/cpanel.c b/apps/cpanel/cpanel.c index a405970..b3c83aa 100644 --- a/apps/cpanel/cpanel.c +++ b/apps/cpanel/cpanel.c @@ -955,7 +955,7 @@ static void scanThemes(void) { memcpy(entry.name, ent->d_name, nameLen); entry.name[nameLen] = '\0'; - snprintf(entry.path, sizeof(entry.path), "%s/%s", THEME_DIR, entry.name); + snprintf(entry.path, sizeof(entry.path), "%s%c%s", THEME_DIR, DVX_PATH_SEP, entry.name); arrput(sThemeEntries, entry); } @@ -1010,7 +1010,7 @@ static void scanWallpapers(void) { memcpy(entry.name, ent->d_name, nl); entry.name[nl] = '\0'; - snprintf(entry.path, sizeof(entry.path), "%s/%s", WPAPER_DIR, entry.name); + snprintf(entry.path, sizeof(entry.path), "%s%c%s", WPAPER_DIR, DVX_PATH_SEP, entry.name); arrput(sWpaperEntries, entry); } diff --git a/apps/dvxbasic/Makefile b/apps/dvxbasic/Makefile index 905d04e..3813482 100644 --- a/apps/dvxbasic/Makefile +++ b/apps/dvxbasic/Makefile @@ -12,7 +12,7 @@ DJGPP_PREFIX = $(HOME)/djgpp/djgpp CC = $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-gcc DXE3GEN = PATH=$(DJGPP_PREFIX)/bin:$(PATH) DJDIR=$(DJGPP_PREFIX)/i586-pc-msdosdjgpp $(DJGPP_PREFIX)/i586-pc-msdosdjgpp/bin/dxe3gen -CFLAGS = -O2 -Wall -Wextra -Wno-type-limits -Wno-sign-compare -march=i486 -mtune=i586 -I../../core -I../../core/platform -I../../widgets -I../../shell -I../../tasks -I../../core/thirdparty -I. +CFLAGS = -O2 -Wall -Wextra -Werror -Wno-type-limits -Wno-sign-compare -Wno-format-truncation -march=i486 -mtune=i586 -I../../core -I../../core/platform -I../../widgets -I../../shell -I../../tasks -I../../core/thirdparty -I. OBJDIR = ../../obj/dvxbasic LIBSDIR = ../../bin/libs diff --git a/apps/dvxbasic/compiler/codegen.c b/apps/dvxbasic/compiler/codegen.c index 9937c39..fcb4683 100644 --- a/apps/dvxbasic/compiler/codegen.c +++ b/apps/dvxbasic/compiler/codegen.c @@ -5,6 +5,7 @@ #include "opcodes.h" #include "thirdparty/stb_ds_wrap.h" +#include #include #include #include diff --git a/apps/dvxbasic/ide/ideMain.c b/apps/dvxbasic/ide/ideMain.c index a5e0595..9b23c80 100644 --- a/apps/dvxbasic/ide/ideMain.c +++ b/apps/dvxbasic/ide/ideMain.c @@ -203,7 +203,6 @@ static const BasDebugVarT *findDebugVar(const char *name); static void formatValue(const BasValueT *v, char *buf, int32_t bufSize); static bool readDebugVar(const BasDebugVarT *dv, BasValueT *outVal); static BasValueT *getDebugVarSlot(const BasDebugVarT *dv); -static bool writeDebugVar(const BasDebugVarT *dv, BasValueT newVal); static void loadFrmFiles(BasFormRtT *rt); static void onEvtDropdownChange(WidgetT *w); static void onImmediateChange(WidgetT *w); @@ -329,7 +328,7 @@ typedef struct { int32_t fileIdx; // project file index int32_t codeLine; // line within file's code section (1-based) int32_t procIdx; // procedure index at time of toggle (-1 = general) - char procName[64]; // procedure name at time of toggle + char procName[BAS_MAX_PROC_NAME * 2]; // "obj.evt" combined name } IdeBreakpointT; static IdeDebugStateE sDbgState = DBG_IDLE; @@ -1072,45 +1071,6 @@ static int32_t localToConcatLine(int32_t editorLine) { } -// ============================================================ -// concatToLocalLine -- convert concatenated source line to editor-local line -// ============================================================ - -// Convert a full-source line number back to an editor-local line number. -// Reverses the file offset, BEGINFORM offset, and procedure offset so -// the line matches what the user sees in the editor. -static int32_t concatToLocalLine(int32_t concatLine) { - int32_t fileLine = concatLine; - - // Strip multi-file offset and BEGINFORM offset - if (sProject.sourceMapCount > 0) { - int32_t fileIdx = -1; - int32_t localLine = concatLine; - - if (prjMapLine(&sProject, concatLine, &fileIdx, &localLine)) { - fileLine = localLine; - - // For .frm files, subtract the BEGINFORM line - if (fileIdx >= 0 && fileIdx < sProject.fileCount && - sProject.files[fileIdx].isForm) { - fileLine--; - } - } - } - - // Strip procedure offset to get editor-local line - if (sCurProcIdx >= 0 && sCurProcIdx < (int32_t)arrlen(sProcTable)) { - int32_t procStart = sProcTable[sCurProcIdx].lineNum; - - if (fileLine >= procStart) { - return fileLine - procStart + 1; - } - } - - return fileLine; -} - - // ============================================================ // debugLineDecorator -- highlight breakpoints and current debug line // ============================================================ @@ -1860,7 +1820,6 @@ static void runModule(BasModuleT *mod) { // Hide designer windows while the program runs. // Keep the code window visible if debugging (breakpoints or step-into). - bool debugging = sDbgEnabled; bool hadFormWin = sFormWin && sFormWin->visible; bool hadToolbox = sToolboxWin && sToolboxWin->visible; bool hadProps = sPropsWin && sPropsWin->visible; @@ -3882,7 +3841,6 @@ static bool findInProject(const char *needle, bool caseSensitive) { // Start from the active file, searching from after the current selection int32_t startFile = sProject.activeFileIdx >= 0 ? sProject.activeFileIdx : 0; - int32_t startPos = 0; // If the editor is open on the current file, try the current proc // first (no wrap — returns false if no more matches ahead). @@ -5447,8 +5405,6 @@ static void dsgnPasteControl(void) { break; } - const char *lineStart = line; - while (*line == ' ' || *line == '\t') { line++; } @@ -6366,7 +6322,7 @@ static void showImmediateWindow(void) { #define MAX_BP_DISPLAY 64 static char sBpFiles[MAX_BP_DISPLAY][DVX_MAX_PATH]; -static char sBpProcs[MAX_BP_DISPLAY][64]; +static char sBpProcs[MAX_BP_DISPLAY][BAS_MAX_PROC_NAME * 2]; static char sBpLines[MAX_BP_DISPLAY][12]; static const char *sBpCells[MAX_BP_DISPLAY * 3]; @@ -6507,7 +6463,7 @@ static void updateBreakpointWindow(void) { snprintf(sBpProcs[i], sizeof(sBpProcs[i]), "%s", sBreakpoints[i].procName); // Line number - snprintf(sBpLines[i], sizeof(sBpLines[i]), "%d", sBreakpoints[i].codeLine); + snprintf(sBpLines[i], sizeof(sBpLines[i]), "%d", (int)sBreakpoints[i].codeLine); sBpCells[i * 3] = sBpFiles[i]; sBpCells[i * 3 + 1] = sBpProcs[i]; @@ -6605,8 +6561,8 @@ static void formatValue(const BasValueT *v, char *buf, int32_t bufSize) { case BAS_TYPE_DOUBLE: snprintf(buf, bufSize, "%.10g", v->dblVal); break; case BAS_TYPE_BOOLEAN: snprintf(buf, bufSize, "%s", v->boolVal ? "True" : "False"); break; case BAS_TYPE_STRING: { - if (v->strVal && v->strVal->data) { - snprintf(buf, bufSize, "\"%.*s\"", bufSize - 3, v->strVal->data); + if (v->strVal) { + snprintf(buf, bufSize, "\"%.*s\"", (int)(bufSize - 3), v->strVal->data); } else { snprintf(buf, bufSize, "\"\""); } @@ -6872,7 +6828,7 @@ static void updateCallStackWindow(void) { } snprintf(sCallNames[rowCount], BAS_MAX_PROC_NAME, "%s", name); - snprintf(sCallLines[rowCount], 16, ""); + sCallLines[rowCount][0] = '\0'; sCallCells[rowCount * 2 + 0] = sCallNames[rowCount]; sCallCells[rowCount * 2 + 1] = sCallLines[rowCount]; rowCount++; @@ -7106,19 +7062,6 @@ static BasValueT *getDebugVarSlot(const BasDebugVarT *dv) { } -static bool writeDebugVar(const BasDebugVarT *dv, BasValueT newVal) { - BasValueT *slot = getDebugVarSlot(dv); - - if (!slot) { - return false; - } - - basValRelease(slot); - *slot = basValCopy(newVal); - return true; -} - - // findDebugVar -- find a debug variable by name, respecting scope static const BasDebugVarT *findDebugVar(const char *name) { if (!sDbgModule || !sDbgModule->debugVars) { @@ -7448,7 +7391,7 @@ static void updateWatchWindow(void) { snprintf(sWatchValBuf[i], 256, ""); } } else { - snprintf(sWatchValBuf[i], 256, ""); + sWatchValBuf[i][0] = '\0'; } sWatchCells[i * 2 + 0] = sWatchExprBuf[i]; diff --git a/apps/dvxbasic/ide/ideMenuEditor.c b/apps/dvxbasic/ide/ideMenuEditor.c index fbf87ce..b258950 100644 --- a/apps/dvxbasic/ide/ideMenuEditor.c +++ b/apps/dvxbasic/ide/ideMenuEditor.c @@ -117,7 +117,7 @@ static void applyFields(void) { } } - snprintf(autoName, DSGN_MAX_NAME, "mnuSep%d", sepNum); + snprintf(autoName, DSGN_MAX_NAME, "mnuSep%d", (int)sepNum); } else { // Normal item: strip & and non-alphanumeric, prefix "mnu" int32_t p = 0; diff --git a/apps/dvxbasic/ide/ideProject.c b/apps/dvxbasic/ide/ideProject.c index ce2585b..4fc57be 100644 --- a/apps/dvxbasic/ide/ideProject.c +++ b/apps/dvxbasic/ide/ideProject.c @@ -279,7 +279,7 @@ void prjNew(PrjStateT *prj, const char *name, const char *directory, PrefsHandle prjInit(prj); snprintf(prj->name, sizeof(prj->name), "%s", name); snprintf(prj->projectDir, sizeof(prj->projectDir), "%s", directory); - snprintf(prj->projectPath, sizeof(prj->projectPath), "%s/%s.dbp", directory, name); + snprintf(prj->projectPath, sizeof(prj->projectPath), "%s%c%s.dbp", directory, DVX_PATH_SEP, name); prj->dirty = true; // Apply defaults from preferences @@ -416,7 +416,7 @@ void prjFullPath(const PrjStateT *prj, int32_t fileIdx, char *outPath, int32_t o return; } - snprintf(outPath, outSize, "%s/%s", prj->projectDir, prj->files[fileIdx].path); + snprintf(outPath, outSize, "%s%c%s", prj->projectDir, DVX_PATH_SEP, prj->files[fileIdx].path); } @@ -633,7 +633,7 @@ static void ppdOnOk(WidgetT *w) { // Validate icon path if set if (sPpd.iconPath[0] && sPpd.prj) { char fullPath[DVX_MAX_PATH * 2]; - snprintf(fullPath, sizeof(fullPath), "%s/%s", sPpd.prj->projectDir, sPpd.iconPath); + snprintf(fullPath, sizeof(fullPath), "%s%c%s", sPpd.prj->projectDir, DVX_PATH_SEP, sPpd.iconPath); if (!validateIcon(fullPath, true)) { return; @@ -686,7 +686,7 @@ static void ppdLoadIconPreview(void) { const char *relPath = sPpd.iconPath; char fullPath[DVX_MAX_PATH * 2]; - snprintf(fullPath, sizeof(fullPath), "%s/%s", sPpd.prj->projectDir, relPath); + snprintf(fullPath, sizeof(fullPath), "%s%c%s", sPpd.prj->projectDir, DVX_PATH_SEP, relPath); if (!validateIcon(fullPath, true)) { sPpd.iconPath[0] = '\0'; @@ -750,7 +750,7 @@ static void ppdOnBrowseIcon(WidgetT *w) { // Check if destination already exists char destPath[DVX_MAX_PATH * 2]; - snprintf(destPath, sizeof(destPath), "%s/%s", sPpd.prj->projectDir, fname); + snprintf(destPath, sizeof(destPath), "%s%c%s", sPpd.prj->projectDir, DVX_PATH_SEP, fname); FILE *existing = fopen(destPath, "rb"); @@ -875,7 +875,7 @@ bool prjPropertiesDialog(AppContextT *ctx, PrjStateT *prj, const char *appPath) // Use the cached form object name, fall back to filename const char *name = prj->files[i].formName; - char fallback[PRJ_MAX_NAME]; + char fallback[DVX_MAX_PATH]; if (!name[0]) { snprintf(fallback, sizeof(fallback), "%s", prj->files[i].path); diff --git a/apps/dvxbasic/ide/ideProperties.c b/apps/dvxbasic/ide/ideProperties.c index 1359150..d86089e 100644 --- a/apps/dvxbasic/ide/ideProperties.c +++ b/apps/dvxbasic/ide/ideProperties.c @@ -107,7 +107,7 @@ static void resolveDbPath(const char *dbName, char *out, int32_t outSize) { // Resolve relative to project directory if (sDs && sDs->projectDir && sDs->projectDir[0]) { - snprintf(out, outSize, "%s/%s", sDs->projectDir, dbName); + snprintf(out, outSize, "%s%c%s", sDs->projectDir, DVX_PATH_SEP, dbName); } else { snprintf(out, outSize, "%s", dbName); } @@ -549,7 +549,7 @@ static void onPropDblClick(WidgetT *w) { } if (chosenIdx == 0) { - snprintf(newValue, sizeof(newValue), ""); + newValue[0] = '\0'; } else { snprintf(newValue, sizeof(newValue), "%s", dataNames[chosenIdx]); } @@ -611,7 +611,7 @@ static void onPropDblClick(WidgetT *w) { } if (chosenIdx == 0) { - snprintf(newValue, sizeof(newValue), ""); + newValue[0] = '\0'; } else { snprintf(newValue, sizeof(newValue), "%s", fieldNames[chosenIdx - 1]); } @@ -669,7 +669,7 @@ static void onPropDblClick(WidgetT *w) { } if (chosenIdx == 0) { - snprintf(newValue, sizeof(newValue), ""); + newValue[0] = '\0'; } else { snprintf(newValue, sizeof(newValue), "%s", tableNames[chosenIdx - 1]); } diff --git a/apps/dvxbasic/runtime/vm.h b/apps/dvxbasic/runtime/vm.h index ef138ca..b87b899 100644 --- a/apps/dvxbasic/runtime/vm.h +++ b/apps/dvxbasic/runtime/vm.h @@ -16,6 +16,7 @@ #include "values.h" #include "dvxTypes.h" +#include "dvxPlatform.h" #include #include diff --git a/apps/dvxhelp/dvxhelp.c b/apps/dvxhelp/dvxhelp.c new file mode 100644 index 0000000..b1cf7ae --- /dev/null +++ b/apps/dvxhelp/dvxhelp.c @@ -0,0 +1,1406 @@ +// dvxhelp.c -- DVX Help Viewer application +// +// A callback-only DXE app that displays .hlp help files with a TreeView +// TOC sidebar and scrollable content area. Supports headings, text, +// links, images, lists, horizontal rules, notes, and code blocks. +// +// The content area is rebuilt per-topic by reading records from the .hlp +// file and creating private widget types (HelpText, HelpHeading, HelpLink) +// registered via wgtRegisterClass at startup. +// +// Navigation history supports back/forward with a fixed-size circular stack. + +#include "hlpformat.h" +#include "dvxApp.h" +#include "dvxDialog.h" +#include "dvxWidget.h" +#include "dvxWidgetPlugin.h" +#include "dvxWm.h" +#include "dvxDraw.h" +#include "dvxVideo.h" +#include "dvxPlatform.h" +#include "shellApp.h" +#include "widgetBox.h" +#include "widgetButton.h" +#include "widgetSplitter.h" +#include "widgetTreeView.h" +#include "widgetScrollPane.h" +#include "widgetToolbar.h" +#include "widgetImage.h" + +#include +#include +#include +#include +#include + +#include "dvxMem.h" + +// ============================================================ +// Constants +// ============================================================ + +#define HELP_WIN_W 560 +#define HELP_WIN_H 400 +#define HELP_CASCADE_OFFSET 16 +#define HELP_SPLITTER_POS 160 +#define HELP_TOC_MIN_W 100 +#define HELP_CONTENT_PAD 6 +#define HELP_HEADING1_PAD 4 +#define HELP_HEADING2_PAD 2 +#define HELP_LINK_PAD_X 2 +#define HELP_LINK_PAD_Y 1 +#define HELP_NOTE_PAD 6 +#define HELP_NOTE_PREFIX_W 4 +#define HELP_CODE_PAD 4 +#define HELP_LIST_INDENT 12 +#define HELP_LIST_BULLET_W 8 + +#define MAX_HISTORY 64 +#define MAX_SEARCH_BUF 128 + +#define CMD_BACK 100 +#define CMD_FORWARD 101 +#define CMD_INDEX 102 +#define CMD_SEARCH 103 + +// ============================================================ +// Module state +// ============================================================ + +static DxeAppContextT *sCtx = NULL; +static AppContextT *sAc = NULL; +static WindowT *sWin = NULL; +static WidgetT *sTocTree = NULL; +static WidgetT *sContentScroll = NULL; +static WidgetT *sContentBox = NULL; +static WidgetT *sBtnBack = NULL; +static WidgetT *sBtnForward = NULL; + +// .hlp file data +static FILE *sHlpFile = NULL; +static HlpHeaderT sHeader; +static HlpTopicDirT *sTopicDir = NULL; +static char *sStringTable = NULL; +static HlpTocEntryT *sTocEntries = NULL; +static HlpIndexEntryT *sIndexEntries = NULL; + +// Navigation history +static int32_t sHistory[MAX_HISTORY]; +static int32_t sHistoryPos = -1; +static int32_t sHistoryCount = 0; +static int32_t sCurrentTopic = -1; + +// Custom widget type IDs +static int32_t sHelpTextTypeId = -1; +static int32_t sHelpHeadingTypeId = -1; +static int32_t sHelpLinkTypeId = -1; +static int32_t sHelpNoteTypeId = -1; +static int32_t sHelpCodeTypeId = -1; +static int32_t sHelpRuleTypeId = -1; +static int32_t sHelpListItemTypeId = -1; + +// ============================================================ +// Private widget data types +// ============================================================ + +typedef struct { + char *text; + int32_t lineCount; +} HelpTextDataT; + +typedef struct { + char *text; + int32_t level; +} HelpHeadingDataT; + +typedef struct { + char *displayText; + char *targetTopicId; +} HelpLinkDataT; + +typedef struct { + char *text; + int32_t lineCount; + uint8_t noteType; +} HelpNoteDataT; + +typedef struct { + char *text; + int32_t lineCount; +} HelpCodeDataT; + +typedef struct { + char *text; +} HelpListItemDataT; + +// ============================================================ +// Prototypes +// ============================================================ + +int32_t appMain(DxeAppContextT *ctx); +static void buildContentWidgets(void); +static void closeHelpFile(void); +static int32_t countLines(const char *text); +static void displayRecord(const HlpRecordHdrT *hdr, const char *payload); +static int32_t findTopicByIdStr(const char *topicId); +static void helpCodeCalcMinSize(WidgetT *w, const BitmapFontT *font); +static void helpCodeDestroy(WidgetT *w); +static void helpCodePaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors); +static void helpHeadingCalcMinSize(WidgetT *w, const BitmapFontT *font); +static void helpHeadingDestroy(WidgetT *w); +static void helpHeadingPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors); +static void helpLinkCalcMinSize(WidgetT *w, const BitmapFontT *font); +static void helpLinkDestroy(WidgetT *w); +static void helpLinkOnMouse(WidgetT *w, WidgetT *root, int32_t vx, int32_t vy); +static void helpLinkPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors); +static void helpListItemCalcMinSize(WidgetT *w, const BitmapFontT *font); +static void helpListItemDestroy(WidgetT *w); +static void helpListItemPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors); +static void helpNoteCalcMinSize(WidgetT *w, const BitmapFontT *font); +static void helpNoteDestroy(WidgetT *w); +static void helpNotePaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors); +static void helpRuleCalcMinSize(WidgetT *w, const BitmapFontT *font); +static void helpRulePaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors); +static void helpTextCalcMinSize(WidgetT *w, const BitmapFontT *font); +static void helpTextDestroy(WidgetT *w); +static void helpTextPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors); +static void historyPush(int32_t topicIdx); +static const char *hlpString(uint32_t offset); +static int32_t maxLineWidth(const BitmapFontT *font, const char *text); +static void navigateBack(void); +static void navigateForward(void); +static void navigateToTopic(int32_t topicIdx); +static void onClose(WindowT *win); +static void onIndex(WidgetT *w); +static void onMenu(WindowT *win, int32_t menuId); +static void onNavBack(WidgetT *w); +static void onNavForward(WidgetT *w); +static void onSearch(WidgetT *w); +static void onTocChange(WidgetT *w); +static bool openHelpFile(const char *path); +static void paintLines(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, int32_t x, int32_t y, const char *text, int32_t lineCount, uint32_t fg); +static void populateToc(void); +static void registerWidgetClasses(void); +static void updateNavButtons(void); + +// ============================================================ +// App descriptor +// ============================================================ + +AppDescriptorT appDescriptor = { + .name = "DVX Help", + .hasMainLoop = false, + .multiInstance = true, + .stackSize = SHELL_STACK_DEFAULT, + .priority = TS_PRIORITY_NORMAL +}; + +// ============================================================ +// Utility helpers +// ============================================================ + +static int32_t countLines(const char *text) { + int32_t count = 1; + + for (const char *p = text; *p; p++) { + if (*p == '\n') { + count++; + } + } + + return count; +} + + +static int32_t maxLineWidth(const BitmapFontT *font, const char *text) { + int32_t maxW = 0; + int32_t lineLen = 0; + + for (const char *p = text; ; p++) { + if (*p == '\n' || *p == '\0') { + int32_t w = lineLen * font->charWidth; + + if (w > maxW) { + maxW = w; + } + + lineLen = 0; + + if (*p == '\0') { + break; + } + } else { + lineLen++; + } + } + + return maxW; +} + + +static void paintLines(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, int32_t x, int32_t y, const char *text, int32_t lineCount, uint32_t fg) { + const char *line = text; + + for (int32_t i = 0; i < lineCount; i++) { + const char *end = strchr(line, '\n'); + int32_t len = end ? (int32_t)(end - line) : (int32_t)strlen(line); + + if (len > 0) { + drawTextN(d, ops, font, x, y, line, len, fg, 0, false); + } + + y += font->charHeight; + line = end ? end + 1 : line + len; + } +} + +// ============================================================ +// HelpText widget class +// ============================================================ + +static void helpTextCalcMinSize(WidgetT *w, const BitmapFontT *font) { + HelpTextDataT *td = (HelpTextDataT *)w->data; + w->calcMinW = maxLineWidth(font, td->text) + HELP_CONTENT_PAD * 2; + w->calcMinH = td->lineCount * font->charHeight; +} + + +static void helpTextPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors) { + HelpTextDataT *td = (HelpTextDataT *)w->data; + paintLines(d, ops, font, w->x + HELP_CONTENT_PAD, w->y, td->text, td->lineCount, colors->contentFg); +} + + +static void helpTextDestroy(WidgetT *w) { + HelpTextDataT *td = (HelpTextDataT *)w->data; + + if (td) { + dvxFree(td->text); + dvxFree(td); + w->data = NULL; + } +} + +// ============================================================ +// HelpHeading widget class +// ============================================================ + +static void helpHeadingCalcMinSize(WidgetT *w, const BitmapFontT *font) { + HelpHeadingDataT *hd = (HelpHeadingDataT *)w->data; + int32_t textW = textWidth(font, hd->text); + int32_t textH = font->charHeight; + + w->calcMinW = textW + HELP_CONTENT_PAD * 2; + + if (hd->level == 1) { + // Full bar with padding above and below + w->calcMinH = textH + HELP_HEADING1_PAD * 2 + 2; + } else if (hd->level == 2) { + // Text with underline + w->calcMinH = textH + HELP_HEADING2_PAD + 2; + } else { + // Plain bold text + w->calcMinH = textH + 2; + } +} + + +static void helpHeadingPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors) { + HelpHeadingDataT *hd = (HelpHeadingDataT *)w->data; + int32_t textLen = (int32_t)strlen(hd->text); + + if (hd->level == 1) { + // Filled bar with title bar colors + rectFill(d, ops, w->x, w->y, w->w, w->h, colors->activeTitleBg); + int32_t textY = w->y + HELP_HEADING1_PAD; + drawTextN(d, ops, font, w->x + HELP_CONTENT_PAD, textY, hd->text, textLen, colors->activeTitleFg, 0, false); + } else if (hd->level == 2) { + // Text with underline + int32_t textY = w->y; + drawTextN(d, ops, font, w->x + HELP_CONTENT_PAD, textY, hd->text, textLen, colors->contentFg, 0, false); + int32_t lineY = textY + font->charHeight + 1; + drawHLine(d, ops, w->x + HELP_CONTENT_PAD, lineY, w->w - HELP_CONTENT_PAD * 2, colors->windowShadow); + } else { + // Plain text + drawTextN(d, ops, font, w->x + HELP_CONTENT_PAD, w->y, hd->text, textLen, colors->contentFg, 0, false); + } +} + + +static void helpHeadingDestroy(WidgetT *w) { + HelpHeadingDataT *hd = (HelpHeadingDataT *)w->data; + + if (hd) { + dvxFree(hd->text); + dvxFree(hd); + w->data = NULL; + } +} + +// ============================================================ +// HelpLink widget class +// ============================================================ + +static void helpLinkCalcMinSize(WidgetT *w, const BitmapFontT *font) { + HelpLinkDataT *ld = (HelpLinkDataT *)w->data; + w->calcMinW = textWidth(font, ld->displayText) + HELP_CONTENT_PAD * 2 + HELP_LINK_PAD_X * 2; + w->calcMinH = font->charHeight + HELP_LINK_PAD_Y * 2; +} + + +static void helpLinkPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors) { + HelpLinkDataT *ld = (HelpLinkDataT *)w->data; + int32_t textLen = (int32_t)strlen(ld->displayText); + int32_t x = w->x + HELP_CONTENT_PAD + HELP_LINK_PAD_X; + int32_t y = w->y + HELP_LINK_PAD_Y; + + // Use active title color as link color + uint32_t linkColor = colors->activeTitleBg; + + drawTextN(d, ops, font, x, y, ld->displayText, textLen, linkColor, 0, false); + + // Underline + int32_t lineY = y + font->charHeight; + int32_t lineW = textLen * font->charWidth; + drawHLine(d, ops, x, lineY, lineW, linkColor); +} + + +static void helpLinkOnMouse(WidgetT *w, WidgetT *root, int32_t vx, int32_t vy) { + (void)root; + (void)vx; + (void)vy; + + HelpLinkDataT *ld = (HelpLinkDataT *)w->data; + + if (!ld || !ld->targetTopicId) { + return; + } + + int32_t topicIdx = findTopicByIdStr(ld->targetTopicId); + + if (topicIdx >= 0) { + navigateToTopic(topicIdx); + } +} + + +static void helpLinkDestroy(WidgetT *w) { + HelpLinkDataT *ld = (HelpLinkDataT *)w->data; + + if (ld) { + dvxFree(ld->displayText); + dvxFree(ld->targetTopicId); + dvxFree(ld); + w->data = NULL; + } +} + +// ============================================================ +// HelpNote widget class +// ============================================================ + +static void helpNoteCalcMinSize(WidgetT *w, const BitmapFontT *font) { + HelpNoteDataT *nd = (HelpNoteDataT *)w->data; + w->calcMinW = maxLineWidth(font, nd->text) + HELP_CONTENT_PAD * 2 + HELP_NOTE_PAD * 2 + HELP_NOTE_PREFIX_W; + w->calcMinH = nd->lineCount * font->charHeight + HELP_NOTE_PAD * 2; +} + + +static void helpNotePaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors) { + HelpNoteDataT *nd = (HelpNoteDataT *)w->data; + + // Left accent bar color varies by note type; background is always windowFace + uint32_t barColor; + + if (nd->noteType == HLP_NOTE_WARNING) { + barColor = colors->activeTitleBg; + } else if (nd->noteType == HLP_NOTE_TIP) { + barColor = colors->menuHighlightBg; + } else { + barColor = colors->windowShadow; + } + + int32_t boxX = w->x + HELP_CONTENT_PAD; + int32_t boxW = w->w - HELP_CONTENT_PAD * 2; + + rectFill(d, ops, boxX, w->y, boxW, w->h, colors->windowFace); + rectFill(d, ops, boxX, w->y, HELP_NOTE_PREFIX_W, w->h, barColor); + + int32_t textX = boxX + HELP_NOTE_PREFIX_W + HELP_NOTE_PAD; + paintLines(d, ops, font, textX, w->y + HELP_NOTE_PAD, nd->text, nd->lineCount, colors->contentFg); +} + + +static void helpNoteDestroy(WidgetT *w) { + HelpNoteDataT *nd = (HelpNoteDataT *)w->data; + + if (nd) { + dvxFree(nd->text); + dvxFree(nd); + w->data = NULL; + } +} + +// ============================================================ +// HelpCode widget class +// ============================================================ + +static void helpCodeCalcMinSize(WidgetT *w, const BitmapFontT *font) { + HelpCodeDataT *cd = (HelpCodeDataT *)w->data; + w->calcMinW = maxLineWidth(font, cd->text) + HELP_CONTENT_PAD * 2 + HELP_CODE_PAD * 2; + w->calcMinH = cd->lineCount * font->charHeight + HELP_CODE_PAD * 2; +} + + +static void helpCodePaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors) { + HelpCodeDataT *cd = (HelpCodeDataT *)w->data; + + int32_t boxX = w->x + HELP_CONTENT_PAD; + int32_t boxW = w->w - HELP_CONTENT_PAD * 2; + + // Sunken background + rectFill(d, ops, boxX, w->y, boxW, w->h, colors->contentBg); + drawHLine(d, ops, boxX, w->y, boxW, colors->windowShadow); + drawHLine(d, ops, boxX, w->y + w->h - 1, boxW, colors->windowHighlight); + + paintLines(d, ops, font, boxX + HELP_CODE_PAD, w->y + HELP_CODE_PAD, cd->text, cd->lineCount, colors->contentFg); +} + + +static void helpCodeDestroy(WidgetT *w) { + HelpCodeDataT *cd = (HelpCodeDataT *)w->data; + + if (cd) { + dvxFree(cd->text); + dvxFree(cd); + w->data = NULL; + } +} + +// ============================================================ +// HelpRule widget class +// ============================================================ + +static void helpRuleCalcMinSize(WidgetT *w, const BitmapFontT *font) { + (void)font; + w->calcMinW = 0; + w->calcMinH = 5; +} + + +static void helpRulePaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors) { + (void)font; + int32_t lineY = w->y + 2; + drawHLine(d, ops, w->x + HELP_CONTENT_PAD, lineY, w->w - HELP_CONTENT_PAD * 2, colors->windowShadow); + drawHLine(d, ops, w->x + HELP_CONTENT_PAD, lineY + 1, w->w - HELP_CONTENT_PAD * 2, colors->windowHighlight); +} + +// ============================================================ +// HelpListItem widget class +// ============================================================ + +static void helpListItemCalcMinSize(WidgetT *w, const BitmapFontT *font) { + HelpListItemDataT *ld = (HelpListItemDataT *)w->data; + w->calcMinW = textWidth(font, ld->text) + HELP_CONTENT_PAD * 2 + HELP_LIST_INDENT; + w->calcMinH = font->charHeight; +} + + +static void helpListItemPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors) { + HelpListItemDataT *ld = (HelpListItemDataT *)w->data; + int32_t textLen = (int32_t)strlen(ld->text); + int32_t bulletX = w->x + HELP_CONTENT_PAD + HELP_LIST_INDENT - HELP_LIST_BULLET_W; + int32_t textX = w->x + HELP_CONTENT_PAD + HELP_LIST_INDENT; + int32_t textY = w->y; + + // Bullet character + drawTextN(d, ops, font, bulletX, textY, "\x07", 1, colors->contentFg, 0, false); + + if (textLen > 0) { + drawTextN(d, ops, font, textX, textY, ld->text, textLen, colors->contentFg, 0, false); + } +} + + +static void helpListItemDestroy(WidgetT *w) { + HelpListItemDataT *ld = (HelpListItemDataT *)w->data; + + if (ld) { + dvxFree(ld->text); + dvxFree(ld); + w->data = NULL; + } +} + +// ============================================================ +// Widget class registration +// ============================================================ + +static const WidgetClassT sClassHelpText = { + .version = WGT_CLASS_VERSION, + .flags = 0, + .handlers = { + [WGT_METHOD_PAINT] = (void *)helpTextPaint, + [WGT_METHOD_CALC_MIN_SIZE] = (void *)helpTextCalcMinSize, + [WGT_METHOD_DESTROY] = (void *)helpTextDestroy, + } +}; + +static const WidgetClassT sClassHelpHeading = { + .version = WGT_CLASS_VERSION, + .flags = 0, + .handlers = { + [WGT_METHOD_PAINT] = (void *)helpHeadingPaint, + [WGT_METHOD_CALC_MIN_SIZE] = (void *)helpHeadingCalcMinSize, + [WGT_METHOD_DESTROY] = (void *)helpHeadingDestroy, + } +}; + +static const WidgetClassT sClassHelpLink = { + .version = WGT_CLASS_VERSION, + .flags = WCLASS_FOCUSABLE, + .handlers = { + [WGT_METHOD_PAINT] = (void *)helpLinkPaint, + [WGT_METHOD_CALC_MIN_SIZE] = (void *)helpLinkCalcMinSize, + [WGT_METHOD_ON_MOUSE] = (void *)helpLinkOnMouse, + [WGT_METHOD_DESTROY] = (void *)helpLinkDestroy, + } +}; + +static const WidgetClassT sClassHelpNote = { + .version = WGT_CLASS_VERSION, + .flags = 0, + .handlers = { + [WGT_METHOD_PAINT] = (void *)helpNotePaint, + [WGT_METHOD_CALC_MIN_SIZE] = (void *)helpNoteCalcMinSize, + [WGT_METHOD_DESTROY] = (void *)helpNoteDestroy, + } +}; + +static const WidgetClassT sClassHelpCode = { + .version = WGT_CLASS_VERSION, + .flags = 0, + .handlers = { + [WGT_METHOD_PAINT] = (void *)helpCodePaint, + [WGT_METHOD_CALC_MIN_SIZE] = (void *)helpCodeCalcMinSize, + [WGT_METHOD_DESTROY] = (void *)helpCodeDestroy, + } +}; + +static const WidgetClassT sClassHelpRule = { + .version = WGT_CLASS_VERSION, + .flags = 0, + .handlers = { + [WGT_METHOD_PAINT] = (void *)helpRulePaint, + [WGT_METHOD_CALC_MIN_SIZE] = (void *)helpRuleCalcMinSize, + } +}; + +static const WidgetClassT sClassHelpListItem = { + .version = WGT_CLASS_VERSION, + .flags = 0, + .handlers = { + [WGT_METHOD_PAINT] = (void *)helpListItemPaint, + [WGT_METHOD_CALC_MIN_SIZE] = (void *)helpListItemCalcMinSize, + [WGT_METHOD_DESTROY] = (void *)helpListItemDestroy, + } +}; + + +static void registerWidgetClasses(void) { + sHelpTextTypeId = wgtRegisterClass(&sClassHelpText); + sHelpHeadingTypeId = wgtRegisterClass(&sClassHelpHeading); + sHelpLinkTypeId = wgtRegisterClass(&sClassHelpLink); + sHelpNoteTypeId = wgtRegisterClass(&sClassHelpNote); + sHelpCodeTypeId = wgtRegisterClass(&sClassHelpCode); + sHelpRuleTypeId = wgtRegisterClass(&sClassHelpRule); + sHelpListItemTypeId = wgtRegisterClass(&sClassHelpListItem); +} + +// ============================================================ +// String table lookup +// ============================================================ + +static const char *hlpString(uint32_t offset) { + if (!sStringTable || offset >= sHeader.stringTableSize) { + return ""; + } + + return sStringTable + offset; +} + +// ============================================================ +// Topic lookup by ID string +// ============================================================ + +static int32_t findTopicByIdStr(const char *topicId) { + if (!topicId || !sTopicDir) { + return -1; + } + + // Linear search -- topic directory is typically small + for (uint32_t i = 0; i < sHeader.topicCount; i++) { + const char *id = hlpString(sTopicDir[i].topicIdStr); + + if (strcmp(id, topicId) == 0) { + return (int32_t)i; + } + } + + return -1; +} + +// ============================================================ +// History management +// ============================================================ + +static void historyPush(int32_t topicIdx) { + // Truncate forward history when navigating to a new topic + sHistoryPos++; + + if (sHistoryPos >= MAX_HISTORY) { + // Shift history down to make room + memmove(&sHistory[0], &sHistory[1], (MAX_HISTORY - 1) * sizeof(int32_t)); + sHistoryPos = MAX_HISTORY - 1; + } + + sHistory[sHistoryPos] = topicIdx; + sHistoryCount = sHistoryPos + 1; +} + + +static void navigateBack(void) { + if (sHistoryPos <= 0) { + return; + } + + sHistoryPos--; + int32_t topicIdx = sHistory[sHistoryPos]; + sCurrentTopic = topicIdx; + buildContentWidgets(); + updateNavButtons(); +} + + +static void navigateForward(void) { + if (sHistoryPos >= sHistoryCount - 1) { + return; + } + + sHistoryPos++; + int32_t topicIdx = sHistory[sHistoryPos]; + sCurrentTopic = topicIdx; + buildContentWidgets(); + updateNavButtons(); +} + + +static void navigateToTopic(int32_t topicIdx) { + if (topicIdx < 0 || (uint32_t)topicIdx >= sHeader.topicCount) { + return; + } + + if (topicIdx == sCurrentTopic) { + return; + } + + historyPush(topicIdx); + sCurrentTopic = topicIdx; + buildContentWidgets(); + updateNavButtons(); + + // Update window title + const char *title = hlpString(sTopicDir[topicIdx].titleStr); + char winTitle[300]; + snprintf(winTitle, sizeof(winTitle), "%s - DVX Help", title); + dvxSetTitle(sAc, sWin, winTitle); +} + + +static void updateNavButtons(void) { + if (sBtnBack) { + wgtSetEnabled(sBtnBack, sHistoryPos > 0); + } + + if (sBtnForward) { + wgtSetEnabled(sBtnForward, sHistoryPos < sHistoryCount - 1); + } +} + +// ============================================================ +// Content display +// ============================================================ + +static void displayRecord(const HlpRecordHdrT *hdr, const char *payload) { + if (!sContentBox) { + return; + } + + switch (hdr->type) { + case HLP_REC_TEXT: { + WidgetT *w = widgetAlloc(sContentBox, sHelpTextTypeId); + + if (w) { + HelpTextDataT *td = (HelpTextDataT *)dvxCalloc(1, sizeof(HelpTextDataT)); + td->text = dvxStrdup(payload); + td->lineCount = countLines(td->text); + w->data = td; + } + + break; + } + + case HLP_REC_HEADING1: + case HLP_REC_HEADING2: + case HLP_REC_HEADING3: { + WidgetT *w = widgetAlloc(sContentBox, sHelpHeadingTypeId); + + if (w) { + HelpHeadingDataT *hd = (HelpHeadingDataT *)dvxCalloc(1, sizeof(HelpHeadingDataT)); + hd->text = dvxStrdup(payload); + hd->level = hdr->type - HLP_REC_HEADING1 + 1; + w->data = hd; + } + + break; + } + + case HLP_REC_LINK: { + // Payload: display text \0 target topic ID \0 + const char *displayText = payload; + const char *targetTopicId = payload + strlen(payload) + 1; + WidgetT *w = widgetAlloc(sContentBox, sHelpLinkTypeId); + + if (w) { + HelpLinkDataT *ld = (HelpLinkDataT *)dvxCalloc(1, sizeof(HelpLinkDataT)); + ld->displayText = dvxStrdup(displayText); + ld->targetTopicId = dvxStrdup(targetTopicId); + w->data = ld; + } + + break; + } + + case HLP_REC_IMAGE: { + if (hdr->length >= sizeof(HlpImageRefT)) { + const HlpImageRefT *imgRef = (const HlpImageRefT *)payload; + uint32_t absOffset = sHeader.imagePoolOffset + imgRef->imageOffset; + + // Read BMP data from file + uint8_t *bmpData = (uint8_t *)dvxMalloc(imgRef->imageSize); + + if (bmpData) { + fseek(sHlpFile, absOffset, SEEK_SET); + size_t bytesRead = fread(bmpData, 1, imgRef->imageSize, sHlpFile); + + if (bytesRead == imgRef->imageSize) { + int32_t imgW = 0; + int32_t imgH = 0; + int32_t imgP = 0; + uint8_t *pixels = dvxLoadImageFromMemory(sAc, bmpData, (int32_t)imgRef->imageSize, &imgW, &imgH, &imgP); + + if (pixels) { + wgtImage(sContentBox, pixels, imgW, imgH, imgP); + // wgtImage takes ownership of the pixel data + } + } + + dvxFree(bmpData); + } + } + + break; + } + + case HLP_REC_LIST_ITEM: { + WidgetT *w = widgetAlloc(sContentBox, sHelpListItemTypeId); + + if (w) { + HelpListItemDataT *ld = (HelpListItemDataT *)dvxCalloc(1, sizeof(HelpListItemDataT)); + ld->text = dvxStrdup(payload); + w->data = ld; + } + + break; + } + + case HLP_REC_HRULE: { + widgetAlloc(sContentBox, sHelpRuleTypeId); + break; + } + + case HLP_REC_NOTE: { + WidgetT *w = widgetAlloc(sContentBox, sHelpNoteTypeId); + + if (w) { + HelpNoteDataT *nd = (HelpNoteDataT *)dvxCalloc(1, sizeof(HelpNoteDataT)); + nd->text = dvxStrdup(payload); + nd->lineCount = countLines(nd->text); + nd->noteType = hdr->flags; + w->data = nd; + } + + break; + } + + case HLP_REC_CODE: { + WidgetT *w = widgetAlloc(sContentBox, sHelpCodeTypeId); + + if (w) { + HelpCodeDataT *cd = (HelpCodeDataT *)dvxCalloc(1, sizeof(HelpCodeDataT)); + cd->text = dvxStrdup(payload); + cd->lineCount = countLines(cd->text); + w->data = cd; + } + + break; + } + + case HLP_REC_TABLE: { + // Render tables as preformatted text + WidgetT *w = widgetAlloc(sContentBox, sHelpCodeTypeId); + + if (w) { + HelpCodeDataT *cd = (HelpCodeDataT *)dvxCalloc(1, sizeof(HelpCodeDataT)); + cd->text = dvxStrdup(payload); + cd->lineCount = countLines(cd->text); + w->data = cd; + } + + break; + } + } +} + + +static void buildContentWidgets(void) { + if (!sContentBox || sCurrentTopic < 0) { + return; + } + + // Destroy old content + widgetDestroyChildren(sContentBox); + + // Read topic content from file + HlpTopicDirT *topic = &sTopicDir[sCurrentTopic]; + + fseek(sHlpFile, topic->contentOffset, SEEK_SET); + + uint32_t bytesRead = 0; + + while (bytesRead < topic->contentSize) { + HlpRecordHdrT recHdr; + + if (fread(&recHdr, sizeof(recHdr), 1, sHlpFile) != 1) { + break; + } + + bytesRead += sizeof(recHdr); + + if (recHdr.type == HLP_REC_END) { + break; + } + + if (recHdr.length == 0) { + displayRecord(&recHdr, ""); + continue; + } + + // Read payload + char *payload = (char *)dvxMalloc(recHdr.length + 1); + + if (!payload) { + break; + } + + if (fread(payload, 1, recHdr.length, sHlpFile) != recHdr.length) { + dvxFree(payload); + break; + } + + payload[recHdr.length] = '\0'; + bytesRead += recHdr.length; + + displayRecord(&recHdr, payload); + dvxFree(payload); + } + + // Scroll to top by scrolling the first child into view + if (sContentScroll && sContentBox->firstChild) { + wgtScrollPaneScrollToChild(sContentScroll, sContentBox->firstChild); + } + + wgtInvalidate(sContentBox); +} + +// ============================================================ +// TOC population +// ============================================================ + +static void populateToc(void) { + if (!sTocTree || !sTocEntries) { + return; + } + + // Track parent nodes at each depth level + #define MAX_TOC_DEPTH 16 + WidgetT *parents[MAX_TOC_DEPTH]; + + for (int32_t i = 0; i < MAX_TOC_DEPTH; i++) { + parents[i] = sTocTree; + } + + for (uint32_t i = 0; i < sHeader.tocCount; i++) { + HlpTocEntryT *entry = &sTocEntries[i]; + const char *title = hlpString(entry->titleStr); + int32_t depth = entry->depth; + + if (depth >= MAX_TOC_DEPTH) { + depth = MAX_TOC_DEPTH - 1; + } + + WidgetT *parent = parents[depth]; + WidgetT *item = wgtTreeItem(parent, title); + + if (item) { + // Store topic index in userData for selection callback + item->userData = (void *)(intptr_t)entry->topicIdx; + + // Update parent for next deeper level + if (depth + 1 < MAX_TOC_DEPTH) { + parents[depth + 1] = item; + } + + // Expand by default if flagged + if (entry->flags & HLP_TOC_EXPANDED) { + wgtTreeItemSetExpanded(item, true); + } + } + } +} + +// ============================================================ +// File I/O +// ============================================================ + +static bool openHelpFile(const char *path) { + sHlpFile = fopen(path, "rb"); + + if (!sHlpFile) { + return false; + } + + // Read header from end of file + fseek(sHlpFile, -(long)sizeof(HlpHeaderT), SEEK_END); + + if (fread(&sHeader, sizeof(HlpHeaderT), 1, sHlpFile) != 1) { + fclose(sHlpFile); + sHlpFile = NULL; + return false; + } + + // Validate magic + if (sHeader.magic != HLP_MAGIC) { + fclose(sHlpFile); + sHlpFile = NULL; + return false; + } + + // Validate version + if (sHeader.version != HLP_VERSION) { + fclose(sHlpFile); + sHlpFile = NULL; + return false; + } + + // Read topic directory + sTopicDir = (HlpTopicDirT *)dvxMalloc(sHeader.topicCount * sizeof(HlpTopicDirT)); + + if (!sTopicDir) { + closeHelpFile(); + return false; + } + + fseek(sHlpFile, sHeader.topicDirOffset, SEEK_SET); + + if (fread(sTopicDir, sizeof(HlpTopicDirT), sHeader.topicCount, sHlpFile) != sHeader.topicCount) { + closeHelpFile(); + return false; + } + + // Read string table + sStringTable = (char *)dvxMalloc(sHeader.stringTableSize); + + if (!sStringTable) { + closeHelpFile(); + return false; + } + + fseek(sHlpFile, sHeader.stringTableOffset, SEEK_SET); + + if (fread(sStringTable, 1, sHeader.stringTableSize, sHlpFile) != sHeader.stringTableSize) { + closeHelpFile(); + return false; + } + + // Read TOC entries + if (sHeader.tocCount > 0) { + sTocEntries = (HlpTocEntryT *)dvxMalloc(sHeader.tocCount * sizeof(HlpTocEntryT)); + + if (!sTocEntries) { + closeHelpFile(); + return false; + } + + fseek(sHlpFile, sHeader.tocOffset, SEEK_SET); + + if (fread(sTocEntries, sizeof(HlpTocEntryT), sHeader.tocCount, sHlpFile) != sHeader.tocCount) { + closeHelpFile(); + return false; + } + } + + // Read keyword index + if (sHeader.indexCount > 0) { + sIndexEntries = (HlpIndexEntryT *)dvxMalloc(sHeader.indexCount * sizeof(HlpIndexEntryT)); + + if (!sIndexEntries) { + closeHelpFile(); + return false; + } + + fseek(sHlpFile, sHeader.indexOffset, SEEK_SET); + + if (fread(sIndexEntries, sizeof(HlpIndexEntryT), sHeader.indexCount, sHlpFile) != sHeader.indexCount) { + closeHelpFile(); + return false; + } + } + + return true; +} + + +static void closeHelpFile(void) { + if (sHlpFile) { + fclose(sHlpFile); + sHlpFile = NULL; + } + + dvxFree(sTopicDir); + sTopicDir = NULL; + + dvxFree(sStringTable); + sStringTable = NULL; + + dvxFree(sTocEntries); + sTocEntries = NULL; + + dvxFree(sIndexEntries); + sIndexEntries = NULL; +} + +// ============================================================ +// Callbacks +// ============================================================ + +static void onClose(WindowT *win) { + closeHelpFile(); + dvxDestroyWindow(sAc, win); + sWin = NULL; + sTocTree = NULL; + sContentScroll = NULL; + sContentBox = NULL; + sBtnBack = NULL; + sBtnForward = NULL; +} + + +static void onIndex(WidgetT *w) { + (void)w; + + if (!sIndexEntries || sHeader.indexCount == 0) { + dvxMessageBox(sAc, "DVX Help", "No index available.", MB_OK | MB_ICONINFO); + return; + } + + // Build list of keyword strings + const char **items = (const char **)dvxMalloc(sHeader.indexCount * sizeof(const char *)); + + if (!items) { + return; + } + + for (uint32_t i = 0; i < sHeader.indexCount; i++) { + items[i] = hlpString(sIndexEntries[i].keywordStr); + } + + int32_t selected = -1; + bool ok = dvxChoiceDialog(sAc, "Index", "Select a topic:", items, (int32_t)sHeader.indexCount, 0, &selected); + + if (ok && selected >= 0 && (uint32_t)selected < sHeader.indexCount) { + int32_t topicIdx = (int32_t)sIndexEntries[selected].topicIdx; + navigateToTopic(topicIdx); + } + + dvxFree(items); +} + + +static void onMenu(WindowT *win, int32_t menuId) { + (void)win; + + switch (menuId) { + case CMD_BACK: + navigateBack(); + break; + + case CMD_FORWARD: + navigateForward(); + break; + + case CMD_INDEX: + onIndex(NULL); + break; + + case CMD_SEARCH: + onSearch(NULL); + break; + } +} + + +static void onNavBack(WidgetT *w) { + (void)w; + navigateBack(); +} + + +static void onNavForward(WidgetT *w) { + (void)w; + navigateForward(); +} + + +static void onSearch(WidgetT *w) { + (void)w; + + if (!sIndexEntries || sHeader.indexCount == 0) { + dvxMessageBox(sAc, "DVX Help", "No search index available.", MB_OK | MB_ICONINFO); + return; + } + + char searchBuf[MAX_SEARCH_BUF] = ""; + + if (!dvxInputBox(sAc, "Search Help", "Search for:", NULL, searchBuf, sizeof(searchBuf))) { + return; + } + + if (searchBuf[0] == '\0') { + return; + } + + // Linear scan of keyword index for case-insensitive substring match + int32_t firstMatch = -1; + + for (uint32_t i = 0; i < sHeader.indexCount; i++) { + const char *keyword = hlpString(sIndexEntries[i].keywordStr); + // Case-insensitive substring search + const char *kp = keyword; + const char *sp = searchBuf; + bool found = false; + + while (*kp && !found) { + const char *k = kp; + const char *s = sp; + bool match = true; + + while (*s && *k) { + char kc = *k; + char sc = *s; + + if (kc >= 'A' && kc <= 'Z') { + kc += 32; + } + + if (sc >= 'A' && sc <= 'Z') { + sc += 32; + } + + if (kc != sc) { + match = false; + break; + } + + k++; + s++; + } + + if (match && *s == '\0') { + found = true; + } + + kp++; + } + + if (found) { + firstMatch = (int32_t)sIndexEntries[i].topicIdx; + break; + } + } + + if (firstMatch >= 0) { + navigateToTopic(firstMatch); + } else { + dvxMessageBox(sAc, "Search Help", "No matching topics found.", MB_OK | MB_ICONINFO); + } +} + + +static void onTocChange(WidgetT *w) { + WidgetT *selected = wgtTreeViewGetSelected(w); + + if (!selected) { + return; + } + + int32_t topicIdx = (int32_t)(intptr_t)selected->userData; + + if (topicIdx == 0xFFFF) { + return; + } + + navigateToTopic(topicIdx); +} + +// ============================================================ +// Entry point +// ============================================================ + +int32_t appMain(DxeAppContextT *ctx) { + sCtx = ctx; + sAc = ctx->shellCtx; + + // Register private widget classes + registerWidgetClasses(); + + // Determine help file path: use args if provided, else default + char hlpPath[DVX_MAX_PATH]; + + if (ctx->args[0]) { + // args may be "path/to/file.hlp" or "path/to/file.hlp topicId" + snprintf(hlpPath, sizeof(hlpPath), "%s", ctx->args); + + // Truncate at first space to separate path from topic ID + char *space = strchr(hlpPath, ' '); + + if (space) { + *space = '\0'; + } + } else { + snprintf(hlpPath, sizeof(hlpPath), "%s%c%s", ctx->appDir, DVX_PATH_SEP, "dvxhelp.hlp"); + } + + if (!openHelpFile(hlpPath)) { + dvxSetBusy(sAc, false); + dvxMessageBox(sAc, "DVX Help", "Could not open help file.", MB_OK | MB_ICONERROR); + return -1; + } + + // Create window + int32_t screenW = sAc->display.width; + int32_t screenH = sAc->display.height; + int32_t winW = HELP_WIN_W; + int32_t winH = HELP_WIN_H; + int32_t winX = (screenW - winW) / 2 + HELP_CASCADE_OFFSET; + int32_t winY = (screenH - winH) / 3 + HELP_CASCADE_OFFSET; + + sWin = dvxCreateWindow(sAc, "DVX Help", winX, winY, winW, winH, true); + + if (!sWin) { + closeHelpFile(); + return -1; + } + + sWin->onClose = onClose; + sWin->onMenu = onMenu; + + // Menu bar + MenuBarT *menuBar = wmAddMenuBar(sWin); + + MenuT *navMenu = wmAddMenu(menuBar, "&Navigate"); + wmAddMenuItem(navMenu, "&Back", CMD_BACK); + wmAddMenuItem(navMenu, "&Forward", CMD_FORWARD); + wmAddMenuSeparator(navMenu); + wmAddMenuItem(navMenu, "&Index...", CMD_INDEX); + wmAddMenuItem(navMenu, "&Search...", CMD_SEARCH); + + // Widget tree + WidgetT *root = wgtInitWindow(sAc, sWin); + + // Toolbar + WidgetT *toolbar = wgtToolbar(root); + + sBtnBack = wgtButton(toolbar, "< Back"); + sBtnBack->onClick = onNavBack; + wgtSetEnabled(sBtnBack, false); + + sBtnForward = wgtButton(toolbar, "Fwd >"); + sBtnForward->onClick = onNavForward; + wgtSetEnabled(sBtnForward, false); + + WidgetT *btnIndex = wgtButton(toolbar, "Index"); + btnIndex->onClick = onIndex; + + WidgetT *btnSearch = wgtButton(toolbar, "Search"); + btnSearch->onClick = onSearch; + + // Splitter with TOC tree and content scroll pane + WidgetT *splitter = wgtSplitter(root, true); + splitter->weight = 100; + + sTocTree = wgtTreeView(splitter); + sTocTree->weight = 0; + sTocTree->minW = wgtPixels(HELP_TOC_MIN_W); + sTocTree->onChange = onTocChange; + + sContentScroll = wgtScrollPane(splitter); + sContentScroll->weight = 100; + + sContentBox = wgtVBox(sContentScroll); + sContentBox->spacing = wgtPixels(2); + sContentBox->padding = wgtPixels(HELP_CONTENT_PAD); + + wgtSplitterSetPos(splitter, HELP_SPLITTER_POS); + + // Populate TOC tree + populateToc(); + + // Navigate to requested topic (from args) or default + int32_t startTopic = -1; + + if (ctx->args[0]) { + // Check for topic ID after the file path + const char *space = strchr(ctx->args, ' '); + + if (space && space[1]) { + startTopic = findTopicByIdStr(space + 1); + } + } + + if (startTopic < 0) { + startTopic = findTopicByIdStr(hlpString(sHeader.defaultTopicStr)); + } + + if (startTopic < 0 && sHeader.topicCount > 0) { + startTopic = 0; + } + + if (startTopic >= 0) { + navigateToTopic(startTopic); + } + + return 0; +} diff --git a/apps/dvxhelp/dvxhelp.res b/apps/dvxhelp/dvxhelp.res new file mode 100644 index 0000000..b3d402f --- /dev/null +++ b/apps/dvxhelp/dvxhelp.res @@ -0,0 +1,5 @@ +# dvxhelp.res -- Resource manifest for DVX Help Viewer +icon32 icon dvxhelp/icon32.bmp +name text "DVX Help" +author text "DVX Project" +description text "Help file viewer" diff --git a/apps/dvxhelp/hlpformat.h b/apps/dvxhelp/hlpformat.h new file mode 100644 index 0000000..b78d444 --- /dev/null +++ b/apps/dvxhelp/hlpformat.h @@ -0,0 +1,157 @@ +// hlpformat.h -- DVX Help binary file format structures +// +// Shared between the host-side help compiler and the DVX help viewer app. + +#ifndef HLPFORMAT_H +#define HLPFORMAT_H + +#include +#include + + +// --------------------------------------------------------------------------- +// File magic and version +// --------------------------------------------------------------------------- + +#define HLP_MAGIC 0x484C5044 // "HLPD" little-endian +#define HLP_VERSION 1 + + +// --------------------------------------------------------------------------- +// Record types (HlpRecordHdrT.type) +// --------------------------------------------------------------------------- + +#define HLP_REC_TEXT 0x01 +#define HLP_REC_HEADING1 0x02 +#define HLP_REC_HEADING2 0x03 +#define HLP_REC_HEADING3 0x04 +#define HLP_REC_IMAGE 0x05 +#define HLP_REC_LINK 0x06 +#define HLP_REC_LIST_ITEM 0x07 +#define HLP_REC_TABLE 0x08 +#define HLP_REC_HRULE 0x09 +#define HLP_REC_NOTE 0x0A +#define HLP_REC_CODE 0x0B +#define HLP_REC_END 0xFF + + +// --------------------------------------------------------------------------- +// Note flags (HlpRecordHdrT.flags when type == HLP_REC_NOTE) +// --------------------------------------------------------------------------- + +#define HLP_NOTE_INFO 0x00 +#define HLP_NOTE_TIP 0x01 +#define HLP_NOTE_WARNING 0x02 + + +// --------------------------------------------------------------------------- +// TOC entry flags +// --------------------------------------------------------------------------- + +#define HLP_TOC_EXPANDED 0x01 + + +// --------------------------------------------------------------------------- +// File header (64 bytes, stored at EOF) +// --------------------------------------------------------------------------- + +typedef struct { + uint32_t magic; // HLP_MAGIC + uint32_t version; // HLP_VERSION + uint32_t topicCount; + uint32_t topicDirOffset; // absolute file offset + uint32_t tocOffset; + uint32_t tocCount; + uint32_t indexOffset; + uint32_t indexCount; + uint32_t searchOffset; + uint32_t searchSize; + uint32_t stringTableOffset; + uint32_t stringTableSize; + uint32_t imagePoolOffset; + uint32_t imagePoolSize; + uint32_t defaultTopicStr; // string table offset of default topic ID + uint32_t wrapWidth; // column width text was pre-wrapped at +} HlpHeaderT; + + +// --------------------------------------------------------------------------- +// Topic directory entry (20 bytes) +// --------------------------------------------------------------------------- + +typedef struct { + uint32_t topicIdStr; // string table offset + uint32_t titleStr; // string table offset + uint32_t contentOffset; // absolute file offset + uint32_t contentSize; + uint32_t reserved; +} HlpTopicDirT; + + +// --------------------------------------------------------------------------- +// Content record header (4 bytes) +// --------------------------------------------------------------------------- + +typedef struct { + uint8_t type; + uint8_t flags; + uint16_t length; // payload length (excluding this header) +} HlpRecordHdrT; + + +// --------------------------------------------------------------------------- +// Image reference (8 bytes, payload of HLP_REC_IMAGE) +// --------------------------------------------------------------------------- + +typedef struct { + uint32_t imageOffset; // offset within image pool + uint32_t imageSize; // BMP data size +} HlpImageRefT; + + +// --------------------------------------------------------------------------- +// TOC entry (8 bytes) +// --------------------------------------------------------------------------- + +typedef struct { + uint32_t titleStr; // string table offset + uint16_t topicIdx; // index into topic directory (0xFFFF = no topic) + uint8_t depth; // nesting depth (0 = root) + uint8_t flags; // HLP_TOC_EXPANDED +} HlpTocEntryT; + + +// --------------------------------------------------------------------------- +// Keyword index entry (8 bytes) +// --------------------------------------------------------------------------- + +typedef struct { + uint32_t keywordStr; // string table offset + uint16_t topicIdx; // index into topic directory + uint16_t reserved; +} HlpIndexEntryT; + + +// --------------------------------------------------------------------------- +// Search index -- trigram entry (8 bytes) +// --------------------------------------------------------------------------- + +typedef struct { + uint8_t trigram[3]; + uint8_t postingCount; + uint32_t postingOffset; // byte offset within search section to uint16_t[] posting list +} HlpTrigramEntryT; + + +// --------------------------------------------------------------------------- +// Search section header +// --------------------------------------------------------------------------- + +typedef struct { + uint32_t trigramCount; + // followed by HlpTrigramEntryT[trigramCount] + // followed by uint16_t posting lists +} HlpSearchHeaderT; + + +#endif // HLPFORMAT_H diff --git a/apps/dvxhelp/icon32.bmp b/apps/dvxhelp/icon32.bmp new file mode 100644 index 0000000..52ced7f --- /dev/null +++ b/apps/dvxhelp/icon32.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:414c6612a049642fca53b817761ff1376f95c7beec8146c9a6640b850d193b01 +size 3126 diff --git a/apps/dvxhelp/sample.dvxhelp b/apps/dvxhelp/sample.dvxhelp new file mode 100644 index 0000000..2d1d835 --- /dev/null +++ b/apps/dvxhelp/sample.dvxhelp @@ -0,0 +1,155 @@ +.topic intro +.title Welcome to DVX +.toc 0 Welcome to DVX +.default +.index DVX +.index Introduction +.index Getting Started + +.h1 Welcome to DVX + +DVX is a graphical user interface environment for DOS, designed +for 486-class hardware and above. It provides a windowing system +with a Motif-inspired visual style, cooperative multitasking, +and a widget-based application framework. + +DVX features include: + +.list +.item A window manager with drag, resize, and minimize support +.item Over 25 built-in widget types including buttons, lists, and trees +.item Dynamic application loading via DXE3 modules +.item Theme support with customizable color schemes +.item VESA VBE 2.0+ linear framebuffer rendering +.endlist + +.link overview See also: System Overview + +.hr + +.note tip +Press F1 from any DVX application to open context-sensitive help. +.endnote + +.topic overview +.title System Overview +.toc 0 System Overview +.index Architecture +.index Layers + +.h1 System Overview + +DVX is built as a five-layer architecture, with each layer +providing services to the layer above it. + +.h2 Video Layer + +The video layer (dvxVideo) handles VESA VBE initialization, +linear framebuffer mapping, backbuffer allocation, and pixel +format detection. It supports 8-bit, 16-bit, and 32-bit color +depths. + +.h2 Drawing Layer + +The drawing layer (dvxDraw) provides primitive rendering +operations: filled rectangles, beveled borders, text rendering, +bitmap blitting, and clipped drawing. + +.h2 Compositor + +The compositor (dvxComp) manages a dirty rectangle list. Only +regions that have changed since the last frame are flushed from +the system RAM backbuffer to the video card's linear framebuffer. + +.h2 Window Manager + +The window manager (dvxWm) handles the window stack, chrome +rendering (title bars, borders, close buttons), drag and resize +interaction, focus management, and menu bars. + +.h2 Application Layer + +The application layer (dvxApp) ties everything together with +the event loop, mouse and keyboard input, accelerator tables, +and the public API used by applications. + +.link widgets See also: Widget System + +.topic widgets +.title Widget System +.toc 0 Widget System +.index Widgets +.index Controls + +.h1 Widget System + +DVX provides a rich set of widgets (controls) for building +application user interfaces. Widgets are loaded as DXE3 plugin +modules at startup. + +.h2 Layout Widgets + +.list +.item VBox -- Vertical box layout (stacks children vertically) +.item HBox -- Horizontal box layout (stacks children horizontally) +.item Frame -- Labeled group box with border +.item ScrollPane -- Scrollable container for oversized content +.item Splitter -- Resizable split between two panes +.item TabControl -- Tabbed container +.endlist + +.h2 Input Widgets + +.list +.item Button -- Push button with text label +.item TextInput -- Single-line text entry field +.item TextArea -- Multi-line text editor with syntax highlighting +.item Checkbox -- Boolean toggle with label +.item Radio -- Mutually exclusive option selector +.item Dropdown -- Drop-down selection list +.item ComboBox -- Editable dropdown with text entry +.item Slider -- Horizontal or vertical value slider +.item Spinner -- Numeric up/down control +.endlist + +.h2 Display Widgets + +.list +.item Label -- Single-line text display +.item Image -- Bitmap image display +.item ProgressBar -- Visual progress indicator +.item Canvas -- Custom drawing surface +.item Separator -- Horizontal or vertical divider line +.endlist + +.h2 Data Widgets + +.list +.item ListBox -- Scrollable list of text items +.item ListView -- Multi-column sortable list with headers +.item TreeView -- Hierarchical tree with expand/collapse +.endlist + +.topic keyboard +.title Keyboard Shortcuts +.toc 0 Keyboard Shortcuts +.index Keyboard +.index Shortcuts +.index Hotkeys + +.h1 Keyboard Shortcuts + +The following keyboard shortcuts are available system-wide +in DVX: + +.table + Shortcut Action + -------- ------ + Alt+F4 Close active window + F10 Activate menu bar + Ctrl+Esc Open task manager + Tab Move focus to next widget + Shift+Tab Move focus to previous widget + Enter Activate focused button + Escape Close dialog or cancel operation +.endtable diff --git a/apps/progman/progman.c b/apps/progman/progman.c index f2817cd..0bbb2ec 100644 --- a/apps/progman/progman.c +++ b/apps/progman/progman.c @@ -418,7 +418,7 @@ static void scanAppsDirRecurse(const char *dirPath) { } char fullPath[MAX_PATH_LEN]; - snprintf(fullPath, sizeof(fullPath), "%s/%s", dirPath, ent->d_name); + snprintf(fullPath, sizeof(fullPath), "%s%c%s", dirPath, DVX_PATH_SEP, ent->d_name); // Check if this is a directory -- recurse into it struct stat st; diff --git a/core/Makefile b/core/Makefile index 9372323..81f6994 100644 --- a/core/Makefile +++ b/core/Makefile @@ -7,7 +7,7 @@ DJGPP_PREFIX = $(HOME)/djgpp/djgpp CC = $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-gcc DXE3GEN = PATH=$(DJGPP_PREFIX)/bin:$(PATH) DJDIR=$(DJGPP_PREFIX)/i586-pc-msdosdjgpp $(DJGPP_PREFIX)/i586-pc-msdosdjgpp/bin/dxe3gen -CFLAGS = -O2 -Wall -Wextra -Wno-type-limits -Wno-sign-compare -march=i486 -mtune=i586 -I. -Iplatform -I../tasks -Ithirdparty +CFLAGS = -O2 -Wall -Wextra -Werror -Wno-type-limits -Wno-sign-compare -Wno-format-truncation -march=i486 -mtune=i586 -I. -Iplatform -I../tasks -Ithirdparty OBJDIR = ../obj/core LIBSDIR = ../bin/libs diff --git a/core/dvxApp.c b/core/dvxApp.c index 17ee880..8626bf1 100644 --- a/core/dvxApp.c +++ b/core/dvxApp.c @@ -2412,6 +2412,15 @@ static void pollKeyboard(AppContextT *ctx) { continue; } + // F1 -- system-wide help + if (ascii == 0 && scancode == 0x3B && !(shiftFlags & (KEY_MOD_CTRL | KEY_MOD_ALT | KEY_MOD_SHIFT))) { + if (ctx->onF1) { + ctx->onF1(ctx->f1Ctx); + } + + continue; + } + // F10 -- activate menu bar if (ascii == 0 && scancode == 0x44) { if (ctx->stack.focusedIdx >= 0) { diff --git a/core/dvxApp.h b/core/dvxApp.h index 435158a..d2e55fc 100644 --- a/core/dvxApp.h +++ b/core/dvxApp.h @@ -15,6 +15,7 @@ #include "dvxCursor.h" #include "dvxTypes.h" +#include "dvxPlatform.h" #include "dvxVideo.h" #include "dvxDraw.h" #include "dvxComp.h" @@ -81,6 +82,8 @@ typedef struct AppContextT { WindowT *modalWindow; // if non-NULL, only this window receives input void (*onCtrlEsc)(void *ctx); // system-wide Ctrl+Esc handler (e.g. task manager) void *ctrlEscCtx; + void (*onF1)(void *ctx); // system-wide F1 handler (context-sensitive help) + void *f1Ctx; void (*onTitleChange)(void *ctx); // called when any window title changes void *titleChangeCtx; int32_t currentAppId; // set by shell before calling app code (0 = shell) diff --git a/core/dvxDialog.c b/core/dvxDialog.c index d2137ad..bf83e65 100644 --- a/core/dvxDialog.c +++ b/core/dvxDialog.c @@ -1231,7 +1231,7 @@ static void fdLoadDir(void) { // Build full path to stat char fullPath[FD_MAX_PATH * 2]; - snprintf(fullPath, sizeof(fullPath), "%s/%s", sFd.curDir, ent->d_name); + snprintf(fullPath, sizeof(fullPath), "%s%c%s", sFd.curDir, DVX_PATH_SEP, ent->d_name); struct stat st; @@ -1352,7 +1352,7 @@ static void fdNavigate(const char *path) { resolved[FD_MAX_PATH - 1] = '\0'; } else { char tmp[FD_MAX_PATH * 2]; - snprintf(tmp, sizeof(tmp), "%s/%s", sFd.curDir, path); + snprintf(tmp, sizeof(tmp), "%s%c%s", sFd.curDir, DVX_PATH_SEP, path); strncpy(resolved, tmp, FD_MAX_PATH - 1); resolved[FD_MAX_PATH - 1] = '\0'; } @@ -1411,7 +1411,7 @@ static bool fdAcceptFile(const char *name) { } char fullPath[FD_MAX_PATH * 2]; - snprintf(fullPath, sizeof(fullPath), "%s/%s", sFd.curDir, name); + snprintf(fullPath, sizeof(fullPath), "%s%c%s", sFd.curDir, DVX_PATH_SEP, name); struct stat st; bool exists = (stat(fullPath, &st) == 0 && S_ISREG(st.st_mode)); @@ -1551,7 +1551,7 @@ static void fdOnOk(WidgetT *w) { // If user typed a directory path, navigate there char testPath[FD_MAX_PATH * 2]; - snprintf(testPath, sizeof(testPath), "%s/%s", sFd.curDir, name); + snprintf(testPath, sizeof(testPath), "%s%c%s", sFd.curDir, DVX_PATH_SEP, name); struct stat st; @@ -1734,7 +1734,7 @@ bool dvxFileDialog(AppContextT *ctx, const char *title, int32_t flags, const cha if (name && name[0]) { char tmp[FD_MAX_PATH * 2]; - snprintf(tmp, sizeof(tmp), "%s/%s", sFd.curDir, name); + snprintf(tmp, sizeof(tmp), "%s%c%s", sFd.curDir, DVX_PATH_SEP, name); strncpy(sFd.outPath, tmp, FD_MAX_PATH - 1); sFd.outPath[FD_MAX_PATH - 1] = '\0'; diff --git a/core/dvxResource.h b/core/dvxResource.h index c4a5723..bab79c7 100644 --- a/core/dvxResource.h +++ b/core/dvxResource.h @@ -18,11 +18,7 @@ #include -// Fallback for the native dvxres tool, which includes this header -// without dvxTypes.h. The canonical definition is in dvxTypes.h. -#ifndef DVX_MAX_PATH -#define DVX_MAX_PATH 260 -#endif +#include "dvxPlatform.h" // Resource type IDs #define DVX_RES_ICON 1 // image data (BMP icon: 16x16, 32x32, etc.) diff --git a/core/dvxTypes.h b/core/dvxTypes.h index 140f927..c58cd93 100644 --- a/core/dvxTypes.h +++ b/core/dvxTypes.h @@ -12,14 +12,6 @@ #include // ============================================================ -// Path limits -// ============================================================ -// -// Maximum file path length. 260 matches DOS MAX_PATH. Future -// platforms (Linux, Windows) should increase this. - -#define DVX_MAX_PATH 260 - // ============================================================ // Pixel format descriptor // ============================================================ diff --git a/core/platform/dvxPlatform.h b/core/platform/dvxPlatform.h index 65d8958..8be2a55 100644 --- a/core/platform/dvxPlatform.h +++ b/core/platform/dvxPlatform.h @@ -26,6 +26,9 @@ #include +// Maximum file path length. 260 matches DOS MAX_PATH. +#define DVX_MAX_PATH 260 + // ============================================================ // Keyboard event // ============================================================ @@ -262,6 +265,10 @@ void platformVideoFreeBuffers(DisplayT *d); // accepts either. char *platformPathDirEnd(const char *path); +// The platform's native directory separator character. +// '/' on DJGPP (which accepts both '/' and '\\'). +#define DVX_PATH_SEP '/' + // Return the platform's native line ending string. // "\r\n" on DOS. const char *platformLineEnding(void); diff --git a/docs/dvx_api_reference.html b/docs/dvx_api_reference.html index 93c1f6a..3818b7e 100644 --- a/docs/dvx_api_reference.html +++ b/docs/dvx_api_reference.html @@ -1,2933 +1,2136 @@ - + - + DVX GUI API Reference - -
-

DVX GUI API Reference

-

DOS Visual eXecutive -- Complete public API documentation generated from source headers

-
- -
- - - - - - - - - - -
-

dvxTypes.h -- Shared Type Definitions

-

- Central type definitions shared across all five layers of the DVX GUI stack. - Every header includes this file. Contains no function definitions -- only structs, - enums, typedefs, and compile-time constants. -

- +
+
+

DVX GUI API Reference

+

DVX GUI API Reference

+

DOS Visual eXecutive -- Complete public API documentation generated from +source headers.

+

The DVX GUI is built as a five-layer architecture. Each layer is defined in +its own header file. This reference covers every public function, type, and +constant.

+

Layers

+
    +
  • dvxTypes.h -- Shared type definitions
  • +
  • dvxCursor.h -- Cursor definitions
  • +
  • dvxVideo.h -- Layer 1: VESA VBE Video Backend
  • +
  • dvxDraw.h -- Layer 2: Drawing Primitives
  • +
  • dvxComp.h -- Layer 3: Dirty Rectangle Compositor
  • +
  • dvxWm.h -- Layer 4: Window Manager
  • +
  • dvxApp.h -- Layer 5: Application API
  • +
+

dvxWidget.h -- Widget System

+

dvxTypes.h -- Shared Type Definitions

+

dvxCursor.h -- Cursor Definitions

+

dvxVideo.h -- Layer 1: VESA VBE Video Backend

+

dvxDraw.h -- Layer 2: Drawing Primitives

+

dvxComp.h -- Layer 3: Dirty Rectangle Compositor

+

dvxWm.h -- Layer 4: Window Manager

+

dvxApp.h -- Layer 5: Application API

+

dvxWidget.h -- Widget System

+
+
+

dvxTypes.h -- Shared Type Definitions

+

dvxTypes.h -- Shared Type Definitions

+

Central type definitions shared across all five layers of the DVX GUI stack. +Every header includes this file. Contains no function definitions -- only +structs, enums, typedefs, and compile-time constants.

Core Structures

- -
-
PixelFormatT
-
- Describes the pixel encoding for the active VESA video mode. Populated once at - startup from the VBE mode info block, then treated as read-only. -
-
int32_t bitsPerPixel
8, 15, 16, or 32
-
int32_t bytesPerPixel
1, 2, 2, or 4
-
uint32_t redMask, greenMask, blueMask
Bitmasks for each color channel (e.g. 0xF800 for red in 565)
-
int32_t redShift, greenShift, blueShift
Bit position of each color field
-
int32_t redBits, greenBits, blueBits
Number of bits per channel (5, 6, 8, etc.)
-
-
-
- -
-
DisplayT
-
- Single display context passed by pointer through every layer. All drawing targets - the backBuf; only dirty rects are flushed to lfb. -
-
int32_t width, height
Screen dimensions in pixels
-
int32_t pitch
Bytes per scanline
-
PixelFormatT format
Active pixel format
-
uint8_t *lfb
Mapped linear framebuffer (VESA LFB)
-
uint8_t *backBuf
System RAM backbuffer
-
uint8_t *palette
768 bytes for 8-bit mode, NULL otherwise
-
int32_t clipX, clipY, clipW, clipH
Current clip rectangle
-
-
-
- -
-
RectT
-
- Rectangle in origin + extent form. Used throughout the compositor, window manager, - and widget layout engine. -
-
int32_t x, y
Top-left corner
-
int32_t w, h
Width and height
-
-
-
- -
-
BlitOpsT
-
- Vtable for hot-path span operations. Resolved at init time based on pixel depth. - On DOS, these dispatch to hand-written asm (rep stosl / rep movsd). -
-
SpanFillFnT spanFill
Fill a horizontal span with a solid color
-
SpanCopyFnT spanCopy
Copy a horizontal span between buffers
-
int32_t bytesPerPixel
Bytes per pixel for the active mode
-
int32_t pitch
Bytes per scanline
-
-
-
- -
-
BevelStyleT
-
- Bevel drawing parameters. Swapping highlight/shadow flips raised vs. sunken appearance. -
-
uint32_t highlight
Lighter color (top/left edges)
-
uint32_t shadow
Darker color (bottom/right edges)
-
uint32_t face
Interior fill color (0 = no fill)
-
int32_t width
Border thickness in pixels (typically 2)
-
-
-
- -
-
BitmapFontT
-
- Fixed-width 8-pixel-wide bitmap font descriptor. One size provided: 8x16 - (standard VGA ROM font, CP437 encoding). -
-
int32_t charWidth
Fixed width per glyph (always 8)
-
int32_t charHeight
Glyph height (14 or 16)
-
int32_t firstChar
ASCII code of first glyph (typically 0)
-
int32_t numChars
Number of glyphs (typically 256)
-
const uint8_t *glyphData
Packed 1bpp data, charHeight bytes per glyph
-
-
-
- -
-
ColorSchemeT
-
- All UI colors pre-packed into display pixel format at init time. Theme support - is achieved by swapping this struct. -
-
uint32_t desktop
Desktop background color
-
uint32_t windowFace
Window body / chrome face
-
uint32_t windowHighlight
Bevel highlight (top/left edge)
-
uint32_t windowShadow
Bevel shadow (bottom/right edge)
-
uint32_t activeTitleBg, activeTitleFg
Focused window title bar
-
uint32_t inactiveTitleBg, inactiveTitleFg
Unfocused window title bar
-
uint32_t contentBg, contentFg
Window content area default colors
-
uint32_t menuBg, menuFg
Menu bar and popup background/text
-
uint32_t menuHighlightBg, menuHighlightFg
Menu item highlight
-
uint32_t buttonFace
Button face color
-
uint32_t scrollbarBg, scrollbarFg, scrollbarTrough
Scrollbar element colors
-
uint32_t cursorFg, cursorBg
Mouse cursor colors
-
-
-
- -
-
ColorIdE
-
- Enum for addressing individual colors in ColorSchemeT. Order matches struct field order. - Values: ColorDesktopE, ColorWindowFaceE, ColorWindowHighlightE, ColorWindowShadowE, - ColorActiveTitleBgE, ColorActiveTitleFgE, ColorInactiveTitleBgE, ColorInactiveTitleFgE, - ColorContentBgE, ColorContentFgE, ColorMenuBgE, ColorMenuFgE, ColorMenuHighlightBgE, - ColorMenuHighlightFgE, ColorButtonFaceE, ColorScrollbarBgE, ColorScrollbarFgE, - ColorScrollbarTroughE, ColorCursorFgE, ColorCursorBgE, ColorCountE. -
-
- -
-
DirtyListT
-
- Fixed-capacity list of dirty rectangles. Dynamic array, grows on demand. -
-
RectT *rects
Dynamic array of dirty rectangles
-
int32_t count
Current number of dirty rects
-
int32_t cap
Allocated capacity
-
-
-
- -
-
WindowT
-
- Central window object. Each window owns a persistent content backbuffer and - receives events through callback function pointers. -
-
int32_t id
Unique window identifier
-
int32_t appId
Shell app ID (0 = shell itself)
-
int32_t x, y, w, h
Outer frame position and dimensions
-
int32_t contentX, contentY, contentW, contentH
Content area inset from frame
-
char title[MAX_TITLE_LEN]
Window title text (max 128 chars)
-
bool visible, focused, minimized, maximized, resizable, modal
Window state flags
-
bool contentDirty
true when contentBuf has changed since last icon refresh
-
bool needsPaint
true until first onPaint call (auto-paint on next frame)
-
int32_t maxW, maxH
Maximum dimensions (WM_MAX_FROM_SCREEN = use screen size)
-
int32_t preMaxX, preMaxY, preMaxW, preMaxH
Saved geometry before maximize (for restore)
-
uint8_t *contentBuf
Per-window content backbuffer
-
int32_t contentPitch
Content buffer bytes per row
-
uint8_t *iconData
Icon pixel data (display format), NULL if none
-
int32_t iconW, iconH, iconPitch
Icon image dimensions and row pitch
-
MenuBarT *menuBar
Menu bar (NULL if no menus)
-
ScrollbarT *vScroll, *hScroll
Scrollbars (NULL if not present)
-
struct WidgetT *widgetRoot
Widget tree root (NULL if no widgets)
-
MenuT *contextMenu
Right-click context menu (NULL if none)
-
AccelTableT *accelTable
Keyboard accelerator table (NULL if none)
-
void *userData
Application-defined data pointer
-
-

Callbacks:

-
-
onPaint(WindowT *win, RectT *dirtyArea)
Content repaint requested
-
onKey(WindowT *win, int32_t key, int32_t mod)
Key press
-
onKeyUp(WindowT *win, int32_t scancode, int32_t mod)
Key release
-
onMouse(WindowT *win, int32_t x, int32_t y, int32_t buttons)
Mouse event (content-relative coords)
-
onResize(WindowT *win, int32_t newW, int32_t newH)
Window resized
-
onClose(WindowT *win)
Close requested
-
onMenu(WindowT *win, int32_t menuId)
Menu item or accelerator activated
-
onScroll(WindowT *win, ScrollbarOrientE orient, int32_t value)
Scrollbar value changed
-
onCursorQuery(WindowT *win, int32_t x, int32_t y)
Return CURSOR_* for hit position
-
onFocus(WindowT *win)
Window gained focus
-
onBlur(WindowT *win)
Window lost focus
-
-
-
- -
-
WindowStackT
-
- Z-ordered window stack (front-to-back: index count-1 is topmost). Owns system-wide - drag/resize/scroll interaction state. -
-
WindowT **windows
Dynamic array of window pointers
-
int32_t count, cap
Current count and allocated capacity
-
int32_t focusedIdx
Stack index of focused window
-
int32_t dragWindow, dragOffX, dragOffY
Active drag state
-
int32_t resizeWindow, resizeEdge
Active resize state
-
int32_t scrollWindow, scrollOrient, scrollDragOff
Active scroll drag state
-
-
-
- -
-
MenuT / MenuItemT / MenuBarT
-
- Menu system types. Fixed-size label buffers (MAX_MENU_LABEL = 32). Cascading - submenus supported via MenuItemT.subMenu pointer. -
-
MenuItemT.label
Item text (supports & accelerator markers)
-
MenuItemT.id
Application-defined command ID
-
MenuItemT.type
MenuItemNormalE, MenuItemCheckE, or MenuItemRadioE
-
MenuItemT.separator
true = horizontal divider line
-
MenuItemT.enabled, checked
Item state
-
MenuItemT.subMenu
Child menu for cascading (NULL if leaf)
-
MenuBarT.activeIdx
Open popup index (-1 = none)
-
-
-
- -
-
ScrollbarT
-
- Window-level scrollbar state. Managed by the WM layer, drawn after content. -
-
ScrollbarOrientE orient
ScrollbarVerticalE or ScrollbarHorizontalE
-
int32_t min, max
Scroll range
-
int32_t value
Current position
-
int32_t pageSize
Visible portion (for proportional thumb sizing)
-
int32_t x, y, length
Computed screen position and track length
-
-
-
- -
-
AccelTableT / AccelEntryT
-
- Per-window keyboard accelerator table. Entries are matched against keystrokes - in the event loop and fire onMenu(cmdId) on match. -
-
AccelEntryT.key
ASCII character or KEY_Fxx constant
-
AccelEntryT.modifiers
Bitmask of ACCEL_CTRL, ACCEL_SHIFT, ACCEL_ALT
-
AccelEntryT.cmdId
Command ID passed to onMenu
-
-
-
- -
-
VideoModeInfoT
-
- Describes an available video mode (enumerated at init). -
-
int32_t w, h
Resolution
-
int32_t bpp
Bits per pixel
-
-
-
- -
-
CursorT
-
- Software-rendered 16x16 cursor using AND/XOR mask encoding. -
-
int32_t width, height
Cursor dimensions (always 16x16)
-
int32_t hotX, hotY
Hot spot coordinates
-
const uint16_t *andMask
AND mask (0 = draw pixel, 1 = transparent)
-
const uint16_t *xorData
XOR data (0 = black, 1 = white where AND = 0)
-
-
-
- +

PixelFormatT

+

Describes the pixel encoding for the active VESA video mode. Populated once +at startup from the VBE mode info block, then treated as read-only.

+
  Field                                        Description
+  -----                                        -----------
+  int32_t bitsPerPixel                         8, 15, 16, or 32
+  int32_t bytesPerPixel                        1, 2, 2, or 4
+  uint32_t redMask, greenMask, blueMask        Bitmasks for each color channel
+  int32_t redShift, greenShift, blueShift      Bit position of each color field
+  int32_t redBits, greenBits, blueBits         Number of bits per channel
+

DisplayT

+

Single display context passed by pointer through every layer. All drawing +targets the backBuf; only dirty rects are flushed to lfb.

+
  Field                                  Description
+  -----                                  -----------
+  int32_t width, height                  Screen dimensions in pixels
+  int32_t pitch                          Bytes per scanline
+  PixelFormatT format                    Active pixel format
+  uint8_t *lfb                           Mapped linear framebuffer (VESA LFB)
+  uint8_t *backBuf                       System RAM backbuffer
+  uint8_t *palette                       768 bytes for 8-bit mode, NULL otherwise
+  int32_t clipX, clipY, clipW, clipH     Current clip rectangle
+

RectT

+

Rectangle in origin + extent form. Used throughout the compositor, window +manager, and widget layout engine.

+
  Field              Description
+  -----              -----------
+  int32_t x, y       Top-left corner
+  int32_t w, h       Width and height
+

BlitOpsT

+

Vtable for hot-path span operations. Resolved at init time based on pixel +depth. On DOS, these dispatch to hand-written asm (rep stosl / rep movsd).

+
  Field                    Description
+  -----                    -----------
+  SpanFillFnT spanFill     Fill a horizontal span with a solid color
+  SpanCopyFnT spanCopy     Copy a horizontal span between buffers
+  int32_t bytesPerPixel    Bytes per pixel for the active mode
+  int32_t pitch            Bytes per scanline
+

BevelStyleT

+

Bevel drawing parameters. Swapping highlight/shadow flips raised vs. sunken +appearance.

+
  Field                  Description
+  -----                  -----------
+  uint32_t highlight     Lighter color (top/left edges)
+  uint32_t shadow        Darker color (bottom/right edges)
+  uint32_t face          Interior fill color (0 = no fill)
+  int32_t width          Border thickness in pixels (typically 2)
+

BitmapFontT

+

Fixed-width 8-pixel-wide bitmap font descriptor. One size provided: 8x16 +(standard VGA ROM font, CP437 encoding).

+
  Field                          Description
+  -----                          -----------
+  int32_t charWidth              Fixed width per glyph (always 8)
+  int32_t charHeight             Glyph height (14 or 16)
+  int32_t firstChar              ASCII code of first glyph (typically 0)
+  int32_t numChars               Number of glyphs (typically 256)
+  const uint8_t *glyphData       Packed 1bpp data, charHeight bytes per glyph
+

ColorSchemeT

+

All UI colors pre-packed into display pixel format at init time. Theme +support is achieved by swapping this struct.

+
  Field                                              Description
+  -----                                              -----------
+  uint32_t desktop                                   Desktop background color
+  uint32_t windowFace                                Window body / chrome face
+  uint32_t windowHighlight                           Bevel highlight (top/left edge)
+  uint32_t windowShadow                              Bevel shadow (bottom/right edge)
+  uint32_t activeTitleBg, activeTitleFg              Focused window title bar
+  uint32_t inactiveTitleBg, inactiveTitleFg          Unfocused window title bar
+  uint32_t contentBg, contentFg                      Window content area default colors
+  uint32_t menuBg, menuFg                            Menu bar and popup background/text
+  uint32_t menuHighlightBg, menuHighlightFg          Menu item highlight
+  uint32_t buttonFace                                Button face color
+  uint32_t scrollbarBg, scrollbarFg, scrollbarTrough Scrollbar element colors
+  uint32_t cursorFg, cursorBg                        Mouse cursor colors
+

ColorIdE

+

Enum for addressing individual colors in ColorSchemeT. Order matches struct +field order.

+

Values: ColorDesktopE, ColorWindowFaceE, ColorWindowHighlightE, +ColorWindowShadowE, ColorActiveTitleBgE, ColorActiveTitleFgE, +ColorInactiveTitleBgE, ColorInactiveTitleFgE, ColorContentBgE, +ColorContentFgE, ColorMenuBgE, ColorMenuFgE, ColorMenuHighlightBgE, +ColorMenuHighlightFgE, ColorButtonFaceE, ColorScrollbarBgE, +ColorScrollbarFgE, ColorScrollbarTroughE, ColorCursorFgE, ColorCursorBgE, +ColorCountE.

+

DirtyListT

+

Fixed-capacity list of dirty rectangles. Dynamic array, grows on demand.

+
  Field              Description
+  -----              -----------
+  RectT *rects       Dynamic array of dirty rectangles
+  int32_t count      Current number of dirty rects
+  int32_t cap        Allocated capacity
+

WindowT

+

Central window object. Each window owns a persistent content backbuffer and +receives events through callback function pointers.

+
  Field                                                          Description
+  -----                                                          -----------
+  int32_t id                                                     Unique window identifier
+  int32_t appId                                                  Shell app ID (0 = shell itself)
+  int32_t x, y, w, h                                            Outer frame position and dimensions
+  int32_t contentX, contentY, contentW, contentH                 Content area inset from frame
+  char title[MAX_TITLE_LEN]                                      Window title text (max 128 chars)
+  bool visible, focused, minimized, maximized, resizable, modal  Window state flags
+  bool contentDirty                                              true when contentBuf has changed
+  bool needsPaint                                                true until first onPaint call
+  int32_t maxW, maxH                                             Maximum dimensions
+  int32_t preMaxX, preMaxY, preMaxW, preMaxH                    Saved geometry before maximize
+  uint8_t *contentBuf                                            Per-window content backbuffer
+  int32_t contentPitch                                           Content buffer bytes per row
+  uint8_t *iconData                                              Icon pixel data, NULL if none
+  int32_t iconW, iconH, iconPitch                                Icon image dimensions and pitch
+  MenuBarT *menuBar                                              Menu bar (NULL if no menus)
+  ScrollbarT *vScroll, *hScroll                                  Scrollbars (NULL if not present)
+  struct WidgetT *widgetRoot                                     Widget tree root (NULL if none)
+  MenuT *contextMenu                                             Right-click context menu
+  AccelTableT *accelTable                                        Keyboard accelerator table
+  void *userData                                                 Application-defined data pointer
+

Callbacks:

+
  Callback                                                     Description
+  --------                                                     -----------
+  onPaint(WindowT *win, RectT *dirtyArea)                      Content repaint requested
+  onKey(WindowT *win, int32_t key, int32_t mod)                Key press
+  onKeyUp(WindowT *win, int32_t scancode, int32_t mod)         Key release
+  onMouse(WindowT *win, int32_t x, int32_t y, int32_t btn)    Mouse event (content-relative)
+  onResize(WindowT *win, int32_t newW, int32_t newH)           Window resized
+  onClose(WindowT *win)                                        Close requested
+  onMenu(WindowT *win, int32_t menuId)                         Menu item or accelerator activated
+  onScroll(WindowT *win, ScrollbarOrientE orient, int32_t val) Scrollbar value changed
+  onCursorQuery(WindowT *win, int32_t x, int32_t y)            Return CURSOR_* for hit position
+  onFocus(WindowT *win)                                        Window gained focus
+  onBlur(WindowT *win)                                         Window lost focus
+

WindowStackT

+

Z-ordered window stack (front-to-back: index count-1 is topmost). Owns +system-wide drag/resize/scroll interaction state.

+
  Field                                        Description
+  -----                                        -----------
+  WindowT **windows                            Dynamic array of window pointers
+  int32_t count, cap                           Current count and allocated capacity
+  int32_t focusedIdx                           Stack index of focused window
+  int32_t dragWindow, dragOffX, dragOffY       Active drag state
+  int32_t resizeWindow, resizeEdge             Active resize state
+  int32_t scrollWindow, scrollOrient, scrollDragOff  Active scroll drag state
+

MenuT / MenuItemT / MenuBarT

+

Menu system types. Fixed-size label buffers (MAX_MENU_LABEL = 32). Cascading +submenus supported via MenuItemT.subMenu pointer.

+
  Field                        Description
+  -----                        -----------
+  MenuItemT.label              Item text (supports & accelerator markers)
+  MenuItemT.id                 Application-defined command ID
+  MenuItemT.type               MenuItemNormalE, MenuItemCheckE, or MenuItemRadioE
+  MenuItemT.separator          true = horizontal divider line
+  MenuItemT.enabled, checked   Item state
+  MenuItemT.subMenu            Child menu for cascading (NULL if leaf)
+  MenuBarT.activeIdx           Open popup index (-1 = none)
+

ScrollbarT

+

Window-level scrollbar state. Managed by the WM layer, drawn after content.

+
  Field                        Description
+  -----                        -----------
+  ScrollbarOrientE orient      ScrollbarVerticalE or ScrollbarHorizontalE
+  int32_t min, max             Scroll range
+  int32_t value                Current position
+  int32_t pageSize             Visible portion (for proportional thumb sizing)
+  int32_t x, y, length         Computed screen position and track length
+

AccelTableT / AccelEntryT

+

Per-window keyboard accelerator table. Entries are matched against +keystrokes in the event loop and fire onMenu(cmdId) on match.

+
  Field                      Description
+  -----                      -----------
+  AccelEntryT.key            ASCII character or KEY_Fxx constant
+  AccelEntryT.modifiers      Bitmask of ACCEL_CTRL, ACCEL_SHIFT, ACCEL_ALT
+  AccelEntryT.cmdId          Command ID passed to onMenu
+

VideoModeInfoT

+

Describes an available video mode (enumerated at init).

+
  Field            Description
+  -----            -----------
+  int32_t w, h     Resolution
+  int32_t bpp      Bits per pixel
+

CursorT

+

Software-rendered 16x16 cursor using AND/XOR mask encoding.

+
  Field                          Description
+  -----                          -----------
+  int32_t width, height          Cursor dimensions (always 16x16)
+  int32_t hotX, hotY             Hot spot coordinates
+  const uint16_t *andMask        AND mask (0 = draw pixel, 1 = transparent)
+  const uint16_t *xorData        XOR data (0 = black, 1 = white where AND = 0)

Bevel Convenience Macros

- - - - - - - -
MacroDescription
BEVEL_RAISED(cs, bw)Raised bevel style from a ColorSchemeT pointer and border width
BEVEL_SUNKEN(cs, face, bw)Sunken bevel style with explicit face color
BEVEL_TROUGH(cs)1px sunken trough (for scrollbar tracks)
BEVEL_SB_BUTTON(cs)1px raised scrollbar button
- +
  Macro                      Description
+  -----                      -----------
+  BEVEL_RAISED(cs, bw)       Raised bevel style from ColorSchemeT ptr and border width
+  BEVEL_SUNKEN(cs, face, bw) Sunken bevel style with explicit face color
+  BEVEL_TROUGH(cs)           1px sunken trough (for scrollbar tracks)
+  BEVEL_SB_BUTTON(cs)        1px raised scrollbar button

Chrome Constants

- - - - - - - - - - - - -
DefineValueDescription
CHROME_BORDER_WIDTH4Outer frame border width
CHROME_TITLE_HEIGHT20Title bar height
CHROME_TITLE_PAD4Title text padding
CHROME_INNER_BORDER2Inner chrome border
CHROME_MENU_HEIGHT20Menu bar height
CHROME_TOTAL_TOP26Total inset from top of frame to content
CHROME_TOTAL_SIDE6Total inset from side of frame to content
CHROME_TOTAL_BOTTOM6Total inset from bottom of frame to content
CHROME_CLOSE_BTN_SIZE16Close button gadget size
- +
  Define                  Value   Description
+  ------                  -----   -----------
+  CHROME_BORDER_WIDTH     4       Outer frame border width
+  CHROME_TITLE_HEIGHT     20      Title bar height
+  CHROME_TITLE_PAD        4       Title text padding
+  CHROME_INNER_BORDER     2       Inner chrome border
+  CHROME_MENU_HEIGHT      20      Menu bar height
+  CHROME_TOTAL_TOP        26      Total inset from top of frame to content
+  CHROME_TOTAL_SIDE       6       Total inset from side of frame to content
+  CHROME_TOTAL_BOTTOM     6       Total inset from bottom of frame to content
+  CHROME_CLOSE_BTN_SIZE   16      Close button gadget size

Hit Test Constants

- - - - - - - - - - - - - -
DefineValueDescription
HIT_CONTENT0Content area
HIT_TITLE1Title bar
HIT_CLOSE2Close gadget
HIT_RESIZE3Resize border
HIT_MENU4Menu bar
HIT_VSCROLL5Vertical scrollbar
HIT_HSCROLL6Horizontal scrollbar
HIT_MINIMIZE7Minimize gadget
HIT_MAXIMIZE8Maximize gadget
HIT_NONE-1No window hit (desktop)
- +
  Define          Value   Description
+  ------          -----   -----------
+  HIT_CONTENT     0       Content area
+  HIT_TITLE       1       Title bar
+  HIT_CLOSE       2       Close gadget
+  HIT_RESIZE      3       Resize border
+  HIT_MENU        4       Menu bar
+  HIT_VSCROLL     5       Vertical scrollbar
+  HIT_HSCROLL     6       Horizontal scrollbar
+  HIT_MINIMIZE    7       Minimize gadget
+  HIT_MAXIMIZE    8       Maximize gadget
+  HIT_NONE        -1      No window hit (desktop)

Mouse Button Flags

- - - - - - -
DefineValueDescription
MOUSE_LEFT1Left mouse button
MOUSE_RIGHT2Right mouse button
MOUSE_MIDDLE4Middle mouse button
- +
  Define          Value   Description
+  ------          -----   -----------
+  MOUSE_LEFT      1       Left mouse button
+  MOUSE_RIGHT     2       Right mouse button
+  MOUSE_MIDDLE    4       Middle mouse button

Accelerator Modifier Flags

- - - - - - -
DefineValueDescription
ACCEL_SHIFT0x03Shift key (matches BIOS shift state bits)
ACCEL_CTRL0x04Ctrl key
ACCEL_ALT0x08Alt key
- +
  Define          Value   Description
+  ------          -----   -----------
+  ACCEL_SHIFT     0x03    Shift key (matches BIOS shift state bits)
+  ACCEL_CTRL      0x04    Ctrl key
+  ACCEL_ALT       0x08    Alt key

Extended Key Codes

- - - - - - - - - - -
DefineDescription
KEY_F1 .. KEY_F12Function keys (scancode | 0x100)
KEY_INSERTInsert key
KEY_DELETEDelete key
KEY_HOMEHome key
KEY_ENDEnd key
KEY_PGUPPage Up key
KEY_PGDNPage Down key
- +
  Define                  Description
+  ------                  -----------
+  KEY_F1 .. KEY_F12       Function keys (scancode | 0x100)
+  KEY_INSERT              Insert key
+  KEY_DELETE              Delete key
+  KEY_HOME                Home key
+  KEY_END                 End key
+  KEY_PGUP                Page Up key
+  KEY_PGDN                Page Down key

Resize Edge Flags

- - - - - - - - -
DefineValueDescription
RESIZE_NONE0No resize edge
RESIZE_LEFT1Left edge
RESIZE_RIGHT2Right edge
RESIZE_TOP4Top edge
RESIZE_BOTTOM8Bottom edge (combinable via OR for corners)
- +
  Define          Value   Description
+  ------          -----   -----------
+  RESIZE_NONE     0       No resize edge
+  RESIZE_LEFT     1       Left edge
+  RESIZE_RIGHT    2       Right edge
+  RESIZE_TOP      4       Top edge
+  RESIZE_BOTTOM   8       Bottom edge (combinable via OR for corners)

Utility Macros

- - - - - -
MacroDescription
DVX_MIN(a, b)Return the smaller of two values
DVX_MAX(a, b)Return the larger of two values
- +
  Macro           Description
+  -----           -----------
+  DVX_MIN(a, b)   Return the smaller of two values
+  DVX_MAX(a, b)   Return the larger of two values
- - - - - -
-

dvxCursor.h -- Cursor Definitions

-

- Embedded 16x16 mouse cursor bitmaps compiled as static const data. No external cursor - files. Uses the standard AND/XOR mask encoding from the IBM VGA hardware cursor spec. -

- +
+

dvxCursor.h -- Cursor Definitions

+

dvxCursor.h -- Cursor Definitions

+

Embedded 16x16 mouse cursor bitmaps compiled as static const data. No +external cursor files. Uses the standard AND/XOR mask encoding from the IBM +VGA hardware cursor spec.

Cursor Shape IDs

- - - - - - - - - - - -
DefineValueDescription
CURSOR_ARROW0Standard arrow (hot spot at tip)
CURSOR_RESIZE_H1Horizontal resize (left/right arrows)
CURSOR_RESIZE_V2Vertical resize (up/down arrows)
CURSOR_RESIZE_DIAG_NWSE3NW-SE diagonal resize
CURSOR_RESIZE_DIAG_NESW4NE-SW diagonal resize
CURSOR_BUSY5Hourglass (wait)
CURSOR_CROSSHAIR6Crosshair for placement
CURSOR_COUNT7Total number of cursor shapes
- +
  Define                      Value   Description
+  ------                      -----   -----------
+  CURSOR_ARROW                0       Standard arrow (hot spot at tip)
+  CURSOR_RESIZE_H             1       Horizontal resize (left/right arrows)
+  CURSOR_RESIZE_V             2       Vertical resize (up/down arrows)
+  CURSOR_RESIZE_DIAG_NWSE     3       NW-SE diagonal resize
+  CURSOR_RESIZE_DIAG_NESW     4       NE-SW diagonal resize
+  CURSOR_BUSY                 5       Hourglass (wait)
+  CURSOR_CROSSHAIR            6       Crosshair for placement
+  CURSOR_COUNT                7       Total number of cursor shapes

Data

- -
-
dvxCursors[CURSOR_COUNT]
-
- Static const array of CursorT structs, indexed by CURSOR_xxx constants. - Each entry includes the AND mask, XOR data, dimensions, and hot spot coordinates. +

dvxCursors[CURSOR_COUNT]

+

Static const array of CursorT structs, indexed by CURSOR_xxx constants. Each +entry includes the AND mask, XOR data, dimensions, and hot spot coordinates.

+
+

dvxVideo.h -- Layer 1: VESA VBE Video Backend

+

dvxVideo.h -- Layer 1: VESA VBE Video Backend

+

The lowest layer. Responsible for VESA VBE mode negotiation, LFB mapping via +DPMI, system RAM backbuffer allocation, pixel format discovery, and color +packing. LFB-only design: bank switching is deliberately unsupported.

+

videoInit

+
int32_t videoInit(DisplayT *d, int32_t requestedW, int32_t requestedH, int32_t preferredBpp);
+

Probe VBE for a mode matching the requested resolution and depth, enable it, +map the LFB into DPMI linear address space, and allocate a system RAM +backbuffer. preferredBpp is a hint; the closest available depth is used if +an exact match is not found.

+
  Parameter        Description
+  ---------        -----------
+  d                Display context to initialize
+  requestedW/H     Desired screen resolution
+  preferredBpp     Preferred bits per pixel (8, 15, 16, or 32)
+

Returns: 0 on success, negative on failure.

+

videoShutdown

+
void videoShutdown(DisplayT *d);
+

Restore VGA text mode (mode 3), unmap the LFB, and free the backbuffer. Safe +to call even if videoInit() failed.

+
  Parameter   Description
+  ---------   -----------
+  d           Display context to shut down
+

packColor

+
uint32_t packColor(const DisplayT *d, uint8_t r, uint8_t g, uint8_t b);
+

Pack an RGB triplet into the display's native pixel format. For direct-color +modes (15/16/32 bpp), returns a packed pixel value using shift/mask fields. +For 8-bit mode, returns the nearest palette index via Euclidean distance in +RGB space.

+
  Parameter   Description
+  ---------   -----------
+  d           Display context (provides pixel format)
+  r, g, b     Color components (0-255)
+

Returns: Native pixel value suitable for direct framebuffer write.

+

setClipRect

+
void setClipRect(DisplayT *d, int32_t x, int32_t y, int32_t w, int32_t h);
+

Set the clip rectangle on the display. All subsequent draw operations clip +to this rectangle. The caller must save and restore the clip rect around +scoped operations.

+
  Parameter   Description
+  ---------   -----------
+  d           Display context
+  x, y, w, h Clip rectangle in screen coordinates
+

resetClipRect

+
void resetClipRect(DisplayT *d);
+

Reset the clip rectangle to the full display dimensions.

+
  Parameter   Description
+  ---------   -----------
+  d           Display context
- +
+

dvxDraw.h -- Layer 2: Drawing Primitives

+

dvxDraw.h -- Layer 2: Drawing Primitives

+

All 2D drawing operations: rectangle fills, bitmap blits, text rendering, +bevels, lines, and cursor rendering. Every function draws into the display's +backbuffer and clips to the current clip rectangle. This layer is stateless +beyond the clip rect on DisplayT.

+

drawInit

+
void drawInit(BlitOpsT *ops, const DisplayT *d);
+

Populate a BlitOpsT with the correct span functions for the display's pixel +depth. Must be called once after videoInit().

+
  Parameter   Description
+  ---------   -----------
+  ops         BlitOpsT to populate
+  d           Initialized display context
+

rectFill

+
void rectFill(DisplayT *d, const BlitOpsT *ops, int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color);
+

Fill a rectangle with a solid color. Clips to the display clip rect. +Workhorse for backgrounds, window fills, and clear operations.

+
  Parameter   Description
+  ---------   -----------
+  d           Display context
+  ops         Blit operations vtable
+  x, y, w, h Rectangle to fill
+  color       Packed pixel color
+

rectCopy

+
void rectCopy(DisplayT *d, const BlitOpsT *ops, int32_t dstX, int32_t dstY, const uint8_t *srcBuf, int32_t srcPitch, int32_t srcX, int32_t srcY, int32_t w, int32_t h);
+

Copy a rectangle from an arbitrary source buffer into the backbuffer. Used +to blit per-window content buffers during compositing.

+
  Parameter     Description
+  ---------     -----------
+  d             Display context
+  ops           Blit operations vtable
+  dstX, dstY    Destination position in backbuffer
+  srcBuf        Source pixel buffer
+  srcPitch      Source buffer bytes per row
+  srcX, srcY    Origin within source buffer
+  w, h          Rectangle dimensions to copy
+

rectCopyGrayscale

+
void rectCopyGrayscale(DisplayT *d, const BlitOpsT *ops, int32_t dstX, int32_t dstY, const uint8_t *srcBuf, int32_t srcPitch, int32_t srcX, int32_t srcY, int32_t w, int32_t h);
+

Copy a rectangle with grayscale conversion. Each pixel's RGB is converted to +luminance (0.299R + 0.587G + 0.114B) for a disabled/grayed appearance.

+
  Parameter       Description
+  ---------       -----------
+  d               Display context
+  ops             Blit operations vtable
+  dstX, dstY      Destination position
+  srcBuf, srcPitch Source buffer and pitch
+  srcX, srcY      Source origin
+  w, h            Rectangle dimensions
+

drawBevel

+
void drawBevel(DisplayT *d, const BlitOpsT *ops, int32_t x, int32_t y, int32_t w, int32_t h, const BevelStyleT *style);
+

Draw a beveled frame. Top/left edges in highlight color, bottom/right in +shadow. Interior filled with face color if non-zero.

+
  Parameter   Description
+  ---------   -----------
+  d           Display context
+  ops         Blit operations vtable
+  x, y, w, h Outer bevel rectangle
+  style       Bevel colors and width
+

drawChar

+
int32_t drawChar(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, int32_t x, int32_t y, char ch, uint32_t fg, uint32_t bg, bool opaque);
+

Draw a single character glyph. When opaque is true, the background fills the +entire cell; when false, only foreground pixels are drawn (transparent +background).

+
  Parameter   Description
+  ---------   -----------
+  d           Display context
+  ops         Blit operations vtable
+  font        Bitmap font
+  x, y        Character position
+  ch          Character to draw
+  fg, bg      Foreground and background packed colors
+  opaque      true = fill background, false = transparent
+

Returns: Advance width (always charWidth).

+

drawText

+
void drawText(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, int32_t x, int32_t y, const char *text, uint32_t fg, uint32_t bg, bool opaque);
+

Draw a null-terminated string. Calls drawChar per character.

+
  Parameter   Description
+  ---------   -----------
+  d           Display context
+  ops         Blit operations vtable
+  font        Bitmap font
+  x, y        Start position
+  text        Null-terminated string
+  fg, bg      Foreground and background packed colors
+  opaque      true = fill background, false = transparent
+

drawTextN

+
void drawTextN(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, int32_t x, int32_t y, const char *text, int32_t count, uint32_t fg, uint32_t bg, bool opaque);
+

Optimized batch text rendering for a known character count. Computes clip +bounds once, fills background in a single rectFill, then overlays glyph +foreground pixels. Significantly faster than per-character drawChar for long +runs (terminal rows, list items).

+
  Parameter   Description
+  ---------   -----------
+  d           Display context
+  ops         Blit operations vtable
+  font        Bitmap font
+  x, y        Start position
+  text        Character buffer (not required to be null-terminated)
+  count       Number of characters to render
+  fg, bg      Foreground and background packed colors
+  opaque      true = fill background, false = transparent
+

textWidth

+
int32_t textWidth(const BitmapFontT *font, const char *text);
+

Return the pixel width of a null-terminated string (strlen(text) * +charWidth).

+
  Parameter   Description
+  ---------   -----------
+  font        Bitmap font
+  text        Null-terminated string
+

Returns: Width in pixels.

+

accelParse

+
char accelParse(const char *text);
+

Scan text for an & prefix and return the following character as a lowercase +accelerator key. "&File" returns 'f', "E&xit" returns 'x'.

+
  Parameter   Description
+  ---------   -----------
+  text        Text with optional & accelerator marker
+

Returns: Lowercase accelerator character, or 0 if none.

+

drawTextAccel

+
void drawTextAccel(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, int32_t x, int32_t y, const char *text, uint32_t fg, uint32_t bg, bool opaque);
+

Draw text with & accelerator markers. The character after & is drawn +underlined to indicate the keyboard shortcut. && produces a literal &. Used +for menu items and button labels.

+
  Parameter   Description
+  ---------   -----------
+  d           Display context
+  ops         Blit operations vtable
+  font        Bitmap font
+  x, y        Start position
+  text        Text with & markers
+  fg, bg      Foreground and background packed colors
+  opaque      true = fill background, false = transparent
+

textWidthAccel

+
int32_t textWidthAccel(const BitmapFontT *font, const char *text);
+

Measure text width excluding & markers (so "&File" measures as 4 chars).

+
  Parameter   Description
+  ---------   -----------
+  font        Bitmap font
+  text        Text with optional & markers
+

Returns: Width in pixels.

+

drawMaskedBitmap

+
void drawMaskedBitmap(DisplayT *d, const BlitOpsT *ops, int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *andMask, const uint16_t *xorData, uint32_t fgColor, uint32_t bgColor);
+

Draw a 1-bit AND/XOR masked bitmap. Used for software-rendered mouse +cursors.

+
  Parameter       Description
+  ---------       -----------
+  d               Display context
+  ops             Blit operations vtable
+  x, y            Screen position
+  w, h            Bitmap dimensions
+  andMask         AND transparency mask (one uint16_t per row)
+  xorData         XOR color data
+  fgColor, bgColor Cursor foreground and background packed colors
+

drawTermRow

+
void drawTermRow(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, int32_t x, int32_t y, int32_t cols, const uint8_t *lineData, const uint32_t *palette, bool blinkVisible, int32_t cursorCol);
+

Render an entire row of terminal character cells (ch/attr byte pairs) in a +single pass. Colors looked up from a 16-color palette. Attribute bit 7 +controls blink.

+
  Parameter       Description
+  ---------       -----------
+  d               Display context
+  ops             Blit operations vtable
+  font            Bitmap font
+  x, y            Row start position
+  cols            Number of columns
+  lineData        Packed ch/attr byte pairs (2 bytes per cell)
+  palette         16-entry packed color palette
+  blinkVisible    false = hide blinking characters
+  cursorCol       Column for inverted text cursor (-1 = none)
+

drawFocusRect

+
void drawFocusRect(DisplayT *d, const BlitOpsT *ops, int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color);
+

Draw a 1px dotted rectangle (alternating pixels). Used for keyboard focus +indicators, matching the Windows 3.x focus rectangle convention.

+
  Parameter   Description
+  ---------   -----------
+  d           Display context
+  ops         Blit operations vtable
+  x, y, w, h Focus rectangle bounds
+  color       Dot color (packed)
+

drawHLine

+
void drawHLine(DisplayT *d, const BlitOpsT *ops, int32_t x, int32_t y, int32_t w, uint32_t color);
+

Draw a horizontal line (1px tall).

+
  Parameter   Description
+  ---------   -----------
+  d           Display context
+  ops         Blit operations vtable
+  x, y        Start position
+  w           Width in pixels
+  color       Packed pixel color
+

drawVLine

+
void drawVLine(DisplayT *d, const BlitOpsT *ops, int32_t x, int32_t y, int32_t h, uint32_t color);
+

Draw a vertical line (1px wide).

+
  Parameter   Description
+  ---------   -----------
+  d           Display context
+  ops         Blit operations vtable
+  x, y        Start position
+  h           Height in pixels
+  color       Packed pixel color
- - - - - -
-

dvxVideo.h -- Layer 1: VESA VBE Video Backend

-

- The lowest layer. Responsible for VESA VBE mode negotiation, LFB mapping via DPMI, - system RAM backbuffer allocation, pixel format discovery, and color packing. - LFB-only design: bank switching is deliberately unsupported. -

- -
-
int32_t videoInit(DisplayT *d, int32_t requestedW, int32_t requestedH, int32_t preferredBpp);
-
-

Probe VBE for a mode matching the requested resolution and depth, enable it, map - the LFB into DPMI linear address space, and allocate a system RAM backbuffer. - preferredBpp is a hint; the closest available depth is used if an exact match is not found.

-
-
d
Display context to initialize
-
requestedW, requestedH
Desired screen resolution
-
preferredBpp
Preferred bits per pixel (8, 15, 16, or 32)
-
-

Returns: 0 on success, negative on failure

+
+

dvxComp.h -- Layer 3: Dirty Rectangle Compositor

+

dvxComp.h -- Layer 3: Dirty Rectangle Compositor

+

Tracks changed screen regions and ensures only dirty regions are redrawn and +flushed to video memory. The compositing pipeline: mark dirty, merge +overlapping rects, redraw desktop + windows (back-to-front, painter's +algorithm), flush to LFB.

+

dirtyListInit

+
void dirtyListInit(DirtyListT *dl);
+

Zero the dirty rect count. Called at the start of each frame.

+
  Parameter   Description
+  ---------   -----------
+  dl          Dirty list to initialize
+

dirtyListAdd

+
void dirtyListAdd(DirtyListT *dl, int32_t x, int32_t y, int32_t w, int32_t h);
+

Enqueue a dirty rectangle. Grows dynamically; triggers merge at a soft +capacity limit.

+
  Parameter   Description
+  ---------   -----------
+  dl          Dirty list
+  x, y, w, h Dirty rectangle in screen coordinates
+

dirtyListMerge

+
void dirtyListMerge(DirtyListT *dl);
+

Consolidate the dirty list by merging overlapping and adjacent rects. Uses +iterative pairwise merge: if combining two rects does not increase total +area beyond a threshold, they are merged. Reduces compositor passes and LFB +flush operations.

+
  Parameter   Description
+  ---------   -----------
+  dl          Dirty list to merge
+

dirtyListClear

+
void dirtyListClear(DirtyListT *dl);
+

Reset the dirty list to empty (sets count to 0).

+
  Parameter   Description
+  ---------   -----------
+  dl          Dirty list to clear
+

flushRect

+
void flushRect(DisplayT *d, const RectT *r);
+

Copy a rectangle from the system RAM backbuffer to the LFB (video memory). +This is the only place the real framebuffer is written. Uses +platform-specific fast copy (rep movsd on DOS) for each scanline.

+
  Parameter   Description
+  ---------   -----------
+  d           Display context
+  r           Rectangle to flush
+

rectIntersect

+
bool rectIntersect(const RectT *a, const RectT *b, RectT *result);
+

Compute the intersection of two rectangles.

+
  Parameter   Description
+  ---------   -----------
+  a, b        Input rectangles
+  result      Output: intersection rectangle (valid only when return is true)
+

Returns: true if the rectangles overlap, false if disjoint.

+

rectIsEmpty

+
bool rectIsEmpty(const RectT *r);
+

Test whether a rectangle has zero or negative area.

+
  Parameter   Description
+  ---------   -----------
+  r           Rectangle to test
+

Returns: true if w <= 0 or h <= 0.

-
- -
-
void videoShutdown(DisplayT *d);
-
-

Restore VGA text mode (mode 3), unmap the LFB, and free the backbuffer. - Safe to call even if videoInit() failed.

-
-
d
Display context to shut down
-
-
-
- -
-
uint32_t packColor(const DisplayT *d, uint8_t r, uint8_t g, uint8_t b);
-
-

Pack an RGB triplet into the display's native pixel format. For direct-color modes - (15/16/32 bpp), returns a packed pixel value using shift/mask fields. For 8-bit mode, - returns the nearest palette index via Euclidean distance in RGB space.

-
-
d
Display context (provides pixel format)
-
r, g, b
Color components (0-255)
-
-

Returns: Native pixel value suitable for direct framebuffer write

-
-
- -
-
void setClipRect(DisplayT *d, int32_t x, int32_t y, int32_t w, int32_t h);
-
-

Set the clip rectangle on the display. All subsequent draw operations clip to this rectangle. - The caller must save and restore the clip rect around scoped operations.

-
-
d
Display context
-
x, y, w, h
Clip rectangle in screen coordinates
-
-
-
- -
-
void resetClipRect(DisplayT *d);
-
-

Reset the clip rectangle to the full display dimensions.

-
-
d
Display context
-
-
-
- -
- - - - - -
-

dvxDraw.h -- Layer 2: Drawing Primitives

-

- All 2D drawing operations: rectangle fills, bitmap blits, text rendering, bevels, lines, - and cursor rendering. Every function draws into the display's backbuffer and clips to - the current clip rectangle. This layer is stateless beyond the clip rect on DisplayT. -

- -
-
void drawInit(BlitOpsT *ops, const DisplayT *d);
-
-

Populate a BlitOpsT with the correct span functions for the display's pixel depth. - Must be called once after videoInit().

-
-
ops
BlitOpsT to populate
-
d
Initialized display context
-
-
-
- -
-
void rectFill(DisplayT *d, const BlitOpsT *ops, int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color);
-
-

Fill a rectangle with a solid color. Clips to the display clip rect. Workhorse for - backgrounds, window fills, and clear operations.

-
-
d
Display context
-
ops
Blit operations vtable
-
x, y, w, h
Rectangle to fill
-
color
Packed pixel color
-
-
-
- -
-
void rectCopy(DisplayT *d, const BlitOpsT *ops, int32_t dstX, int32_t dstY, const uint8_t *srcBuf, int32_t srcPitch, int32_t srcX, int32_t srcY, int32_t w, int32_t h);
-
-

Copy a rectangle from an arbitrary source buffer into the backbuffer. Used to blit - per-window content buffers during compositing.

-
-
d
Display context
-
ops
Blit operations vtable
-
dstX, dstY
Destination position in backbuffer
-
srcBuf
Source pixel buffer
-
srcPitch
Source buffer bytes per row
-
srcX, srcY
Origin within source buffer
-
w, h
Rectangle dimensions to copy
-
-
-
- -
-
void rectCopyGrayscale(DisplayT *d, const BlitOpsT *ops, int32_t dstX, int32_t dstY, const uint8_t *srcBuf, int32_t srcPitch, int32_t srcX, int32_t srcY, int32_t w, int32_t h);
-
-

Copy a rectangle with grayscale conversion. Each pixel's RGB is converted to luminance - (0.299R + 0.587G + 0.114B) for a disabled/grayed appearance.

-
-
d
Display context
-
ops
Blit operations vtable
-
dstX, dstY
Destination position
-
srcBuf, srcPitch
Source buffer and pitch
-
srcX, srcY
Source origin
-
w, h
Rectangle dimensions
-
-
-
- -
-
void drawBevel(DisplayT *d, const BlitOpsT *ops, int32_t x, int32_t y, int32_t w, int32_t h, const BevelStyleT *style);
-
-

Draw a beveled frame. Top/left edges in highlight color, bottom/right in shadow. - Interior filled with face color if non-zero.

-
-
d
Display context
-
ops
Blit operations vtable
-
x, y, w, h
Outer bevel rectangle
-
style
Bevel colors and width
-
-
-
- -
-
int32_t drawChar(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, int32_t x, int32_t y, char ch, uint32_t fg, uint32_t bg, bool opaque);
-
-

Draw a single character glyph. When opaque is true, the background fills the entire cell; - when false, only foreground pixels are drawn (transparent background).

-
-
d
Display context
-
ops
Blit operations vtable
-
font
Bitmap font
-
x, y
Character position
-
ch
Character to draw
-
fg, bg
Foreground and background packed colors
-
opaque
true = fill background, false = transparent
-
-

Returns: Advance width (always charWidth)

-
-
- -
-
void drawText(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, int32_t x, int32_t y, const char *text, uint32_t fg, uint32_t bg, bool opaque);
-
-

Draw a null-terminated string. Calls drawChar per character.

-
-
d
Display context
-
ops
Blit operations vtable
-
font
Bitmap font
-
x, y
Start position
-
text
Null-terminated string
-
fg, bg
Foreground and background packed colors
-
opaque
true = fill background, false = transparent
-
-
-
- -
-
void drawTextN(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, int32_t x, int32_t y, const char *text, int32_t count, uint32_t fg, uint32_t bg, bool opaque);
-
-

Optimized batch text rendering for a known character count. Computes clip bounds once, - fills background in a single rectFill, then overlays glyph foreground pixels. Significantly - faster than per-character drawChar for long runs (terminal rows, list items).

-
-
d
Display context
-
ops
Blit operations vtable
-
font
Bitmap font
-
x, y
Start position
-
text
Character buffer (not required to be null-terminated)
-
count
Number of characters to render
-
fg, bg
Foreground and background packed colors
-
opaque
true = fill background, false = transparent
-
-
-
- -
-
int32_t textWidth(const BitmapFontT *font, const char *text);
-
-

Return the pixel width of a null-terminated string (strlen(text) * charWidth).

-
-
font
Bitmap font
-
text
Null-terminated string
-
-

Returns: Width in pixels

-
-
- -
-
char accelParse(const char *text);
-
-

Scan text for an & prefix and return the following character as a lowercase accelerator - key. "&File" returns 'f', "E&xit" returns 'x'.

-
-
text
Text with optional & accelerator marker
-
-

Returns: Lowercase accelerator character, or 0 if none

-
-
- -
-
void drawTextAccel(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, int32_t x, int32_t y, const char *text, uint32_t fg, uint32_t bg, bool opaque);
-
-

Draw text with & accelerator markers. The character after & is drawn underlined to - indicate the keyboard shortcut. && produces a literal &. Used for menu items and button labels.

-
-
d
Display context
-
ops
Blit operations vtable
-
font
Bitmap font
-
x, y
Start position
-
text
Text with & markers
-
fg, bg
Foreground and background packed colors
-
opaque
true = fill background, false = transparent
-
-
-
- -
-
int32_t textWidthAccel(const BitmapFontT *font, const char *text);
-
-

Measure text width excluding & markers (so "&File" measures as 4 chars).

-
-
font
Bitmap font
-
text
Text with optional & markers
-
-

Returns: Width in pixels

-
-
- -
-
void drawMaskedBitmap(DisplayT *d, const BlitOpsT *ops, int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *andMask, const uint16_t *xorData, uint32_t fgColor, uint32_t bgColor);
-
-

Draw a 1-bit AND/XOR masked bitmap. Used for software-rendered mouse cursors.

-
-
d
Display context
-
ops
Blit operations vtable
-
x, y
Screen position
-
w, h
Bitmap dimensions
-
andMask
AND transparency mask (one uint16_t per row)
-
xorData
XOR color data
-
fgColor, bgColor
Cursor foreground and background packed colors
-
-
-
- -
-
void drawTermRow(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, int32_t x, int32_t y, int32_t cols, const uint8_t *lineData, const uint32_t *palette, bool blinkVisible, int32_t cursorCol);
-
-

Render an entire row of terminal character cells (ch/attr byte pairs) in a single pass. - Colors looked up from a 16-color palette. Attribute bit 7 controls blink.

-
-
d
Display context
-
ops
Blit operations vtable
-
font
Bitmap font
-
x, y
Row start position
-
cols
Number of columns
-
lineData
Packed ch/attr byte pairs (2 bytes per cell)
-
palette
16-entry packed color palette
-
blinkVisible
false = hide blinking characters
-
cursorCol
Column for inverted text cursor (-1 = none)
-
-
-
- -
-
void drawFocusRect(DisplayT *d, const BlitOpsT *ops, int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color);
-
-

Draw a 1px dotted rectangle (alternating pixels). Used for keyboard focus indicators, - matching the Windows 3.x focus rectangle convention.

-
-
d
Display context
-
ops
Blit operations vtable
-
x, y, w, h
Focus rectangle bounds
-
color
Dot color (packed)
-
-
-
- -
-
void drawHLine(DisplayT *d, const BlitOpsT *ops, int32_t x, int32_t y, int32_t w, uint32_t color);
-
-

Draw a horizontal line (1px tall).

-
-
d
Display context
-
ops
Blit operations vtable
-
x, y
Start position
-
w
Width in pixels
-
color
Packed pixel color
-
-
-
- -
-
void drawVLine(DisplayT *d, const BlitOpsT *ops, int32_t x, int32_t y, int32_t h, uint32_t color);
-
-

Draw a vertical line (1px wide).

-
-
d
Display context
-
ops
Blit operations vtable
-
x, y
Start position
-
h
Height in pixels
-
color
Packed pixel color
-
-
-
- -
- - - - - -
-

dvxComp.h -- Layer 3: Dirty Rectangle Compositor

-

- Tracks changed screen regions and ensures only dirty regions are redrawn and flushed - to video memory. The compositing pipeline: mark dirty, merge overlapping rects, redraw - desktop + windows (back-to-front, painter's algorithm), flush to LFB. -

- -
-
void dirtyListInit(DirtyListT *dl);
-
-

Zero the dirty rect count. Called at the start of each frame.

-
-
dl
Dirty list to initialize
-
-
-
- -
-
void dirtyListAdd(DirtyListT *dl, int32_t x, int32_t y, int32_t w, int32_t h);
-
-

Enqueue a dirty rectangle. Grows dynamically; triggers merge at a soft capacity limit.

-
-
dl
Dirty list
-
x, y, w, h
Dirty rectangle in screen coordinates
-
-
-
- -
-
void dirtyListMerge(DirtyListT *dl);
-
-

Consolidate the dirty list by merging overlapping and adjacent rects. Uses iterative - pairwise merge: if combining two rects does not increase total area beyond a threshold, - they are merged. Reduces compositor passes and LFB flush operations.

-
-
dl
Dirty list to merge
-
-
-
- -
-
void dirtyListClear(DirtyListT *dl);
-
-

Reset the dirty list to empty (sets count to 0).

-
-
dl
Dirty list to clear
-
-
-
- -
-
void flushRect(DisplayT *d, const RectT *r);
-
-

Copy a rectangle from the system RAM backbuffer to the LFB (video memory). This is - the only place the real framebuffer is written. Uses platform-specific fast copy - (rep movsd on DOS) for each scanline.

-
-
d
Display context
-
r
Rectangle to flush
-
-
-
- -
-
bool rectIntersect(const RectT *a, const RectT *b, RectT *result);
-
-

Compute the intersection of two rectangles.

-
-
a, b
Input rectangles
-
result
Output: intersection rectangle (valid only when return is true)
-
-

Returns: true if the rectangles overlap, false if disjoint

-
-
- -
-
bool rectIsEmpty(const RectT *r);
-
-

Test whether a rectangle has zero or negative area.

-
-
r
Rectangle to test
-
-

Returns: true if w <= 0 or h <= 0

-
-
- -
- - - - - -
-

dvxWm.h -- Layer 4: Window Manager

-

- Manages the window lifecycle, Z-order stack, chrome drawing, hit testing, and - interactive operations (drag, resize, scroll). The WM owns window geometry and chrome; - content is owned by the application via callbacks or the widget system. -

- +
+

dvxWm.h -- Layer 4: Window Manager

+

dvxWm.h -- Layer 4: Window Manager

+

Manages the window lifecycle, Z-order stack, chrome drawing, hit testing, +and interactive operations (drag, resize, scroll). The WM owns window +geometry and chrome; content is owned by the application via callbacks or +the widget system.

Initialization

- -
-
void wmInit(WindowStackT *stack);
-
-

Zero the window stack. Must be called before any other WM function.

-
-
stack
Window stack to initialize
-
-
-
- +

wmInit

+
void wmInit(WindowStackT *stack);
+

Zero the window stack. Must be called before any other WM function.

+
  Parameter   Description
+  ---------   -----------
+  stack       Window stack to initialize

Window Lifecycle

- -
-
WindowT *wmCreateWindow(WindowStackT *stack, DisplayT *d, const char *title, int32_t x, int32_t y, int32_t w, int32_t h, bool resizable);
-
-

Allocate a new window, initialize its geometry and content buffer, and push it to - the top of the Z-order stack. Returns with all callbacks NULL; the caller should set - onPaint/onKey/etc. before the next event loop iteration.

-
-
stack
Window stack
-
d
Display context
-
title
Window title text
-
x, y
Initial position
-
w, h
Initial outer frame dimensions
-
resizable
true = allow user resize
-
-

Returns: Pointer to new WindowT, or NULL on failure

-
-
- -
-
void wmDestroyWindow(WindowStackT *stack, WindowT *win);
-
-

Free the window's content buffer and all attached resources (menu bar, scrollbars, - widget tree), remove it from the stack, and dirty the vacated region.

-
-
stack
Window stack
-
win
Window to destroy
-
-
-
- +

wmCreateWindow

+
WindowT *wmCreateWindow(WindowStackT *stack, DisplayT *d, const char *title, int32_t x, int32_t y, int32_t w, int32_t h, bool resizable);
+

Allocate a new window, initialize its geometry and content buffer, and push +it to the top of the Z-order stack. Returns with all callbacks NULL; the +caller should set onPaint/onKey/etc. before the next event loop iteration.

+
  Parameter   Description
+  ---------   -----------
+  stack       Window stack
+  d           Display context
+  title       Window title text
+  x, y        Initial position
+  w, h        Initial outer frame dimensions
+  resizable   true = allow user resize
+

Returns: Pointer to new WindowT, or NULL on failure.

+

wmDestroyWindow

+
void wmDestroyWindow(WindowStackT *stack, WindowT *win);
+

Free the window's content buffer and all attached resources (menu bar, +scrollbars, widget tree), remove it from the stack, and dirty the vacated +region.

+
  Parameter   Description
+  ---------   -----------
+  stack       Window stack
+  win         Window to destroy

Z-Order and Focus

- -
-
void wmRaiseWindow(WindowStackT *stack, DirtyListT *dl, int32_t idx);
-
-

Move window at stack index idx to the top of the Z-order. Dirties both old and new - top positions so overlapping windows get repainted.

-
-
stack
Window stack
-
dl
Dirty list for repaint marking
-
idx
Stack index of window to raise
-
-
-
- -
-
void wmSetFocus(WindowStackT *stack, DirtyListT *dl, int32_t idx);
-
-

Transfer keyboard focus to the window at stack index idx. Unfocuses the previously - focused window and dirties both title bars.

-
-
stack
Window stack
-
dl
Dirty list
-
idx
Stack index of window to focus
-
-
-
- +

wmRaiseWindow

+
void wmRaiseWindow(WindowStackT *stack, DirtyListT *dl, int32_t idx);
+

Move window at stack index idx to the top of the Z-order. Dirties both old +and new top positions so overlapping windows get repainted.

+
  Parameter   Description
+  ---------   -----------
+  stack       Window stack
+  dl          Dirty list for repaint marking
+  idx         Stack index of window to raise
+

wmSetFocus

+
void wmSetFocus(WindowStackT *stack, DirtyListT *dl, int32_t idx);
+

Transfer keyboard focus to the window at stack index idx. Unfocuses the +previously focused window and dirties both title bars.

+
  Parameter   Description
+  ---------   -----------
+  stack       Window stack
+  dl          Dirty list
+  idx         Stack index of window to focus

Geometry

- -
-
void wmUpdateContentRect(WindowT *win);
-
-

Recompute contentX/Y/W/H from the window's outer frame dimensions, accounting for - chrome borders, title bar, menu bar, and scrollbars. Must be called after any change - to frame size or chrome configuration.

-
-
win
Window to update
-
-
-
- -
-
int32_t wmReallocContentBuf(WindowT *win, const DisplayT *d);
-
-

Reallocate the per-window content backbuffer to match current contentW/H. Old buffer - contents are lost; caller should trigger a full repaint via onPaint afterward.

-
-
win
Window to reallocate
-
d
Display context (for bytes-per-pixel)
-
-

Returns: 0 on success, -1 on allocation failure

-
-
- -
-
void wmMinWindowSize(const WindowT *win, int32_t *minW, int32_t *minH);
-
-

Get the minimum window size. Accounts for chrome, gadgets, and menu bar.

-
-
win
Window
-
minW, minH
Output: minimum width and height
-
-
-
- +

wmUpdateContentRect

+
void wmUpdateContentRect(WindowT *win);
+

Recompute contentX/Y/W/H from the window's outer frame dimensions, +accounting for chrome borders, title bar, menu bar, and scrollbars. Must be +called after any change to frame size or chrome configuration.

+
  Parameter   Description
+  ---------   -----------
+  win         Window to update
+

wmReallocContentBuf

+
int32_t wmReallocContentBuf(WindowT *win, const DisplayT *d);
+

Reallocate the per-window content backbuffer to match current contentW/H. +Old buffer contents are lost; caller should trigger a full repaint via +onPaint afterward.

+
  Parameter   Description
+  ---------   -----------
+  win         Window to reallocate
+  d           Display context (for bytes-per-pixel)
+

Returns: 0 on success, -1 on allocation failure.

+

wmMinWindowSize

+
void wmMinWindowSize(const WindowT *win, int32_t *minW, int32_t *minH);
+

Get the minimum window size. Accounts for chrome, gadgets, and menu bar.

+
  Parameter    Description
+  ---------    -----------
+  win          Window
+  minW, minH   Output: minimum width and height

Menu Bar

- -
-
MenuBarT *wmAddMenuBar(WindowT *win);
-
-

Allocate and attach a menu bar to a window. Adjusts content area to make room - (CHROME_MENU_HEIGHT pixels). One menu bar per window.

-
-
win
Window to add menu bar to
-
-

Returns: Pointer to the new MenuBarT

-
-
- -
-
void wmDestroyMenuBar(WindowT *win);
-
-

Free the menu bar and reclaim the content area.

-
-
win
Window to remove menu bar from
-
-
-
- -
-
MenuT *wmAddMenu(MenuBarT *bar, const char *label);
-
-

Append a dropdown menu to the menu bar. The label supports & accelerator markers - (e.g. "&File").

-
-
bar
Menu bar
-
label
Menu label text
-
-

Returns: Pointer to the new MenuT to populate with items

-
-
- -
-
void wmAddMenuItem(MenuT *menu, const char *label, int32_t id);
-
-

Append a clickable item to a menu. The id is passed to the window's onMenu callback - when selected.

-
-
menu
Menu to append to
-
label
Item label (supports & markers)
-
id
Application-defined command ID
-
-
-
- -
-
void wmAddMenuCheckItem(MenuT *menu, const char *label, int32_t id, bool checked);
-
-

Add a checkbox-style menu item. Check state toggles on click; rendered with a checkmark glyph.

-
-
menu
Menu to append to
-
label
Item label
-
id
Command ID
-
checked
Initial checked state
-
-
-
- -
-
void wmAddMenuRadioItem(MenuT *menu, const char *label, int32_t id, bool checked);
-
-

Add a radio-style menu item. Radio groups are defined implicitly by consecutive radio - items; selecting one unchecks the others in the group.

-
-
menu
Menu to append to
-
label
Item label
-
id
Command ID
-
checked
Initial checked state
-
-
-
- -
-
void wmAddMenuSeparator(MenuT *menu);
-
-

Insert a horizontal separator line. Separators are not interactive.

-
-
menu
Menu to append separator to
-
-
-
- -
-
bool wmMenuItemIsChecked(MenuBarT *bar, int32_t id);
-
-

Query the checked state of a menu item by command ID. Searches all menus in the bar.

-
-
bar
Menu bar
-
id
Command ID to query
-
-

Returns: true if checked

-
-
- -
-
void wmMenuItemSetChecked(MenuBarT *bar, int32_t id, bool checked);
-
-

Set the checked state of a menu item by command ID. For radio items, setting - checked=true also unchecks other radio items in the same group.

-
-
bar
Menu bar
-
id
Command ID
-
checked
New checked state
-
-
-
- -
-
void wmMenuItemSetEnabled(MenuBarT *bar, int32_t id, bool enabled);
-
-

Enable or disable a menu item by command ID.

-
-
bar
Menu bar
-
id
Command ID
-
enabled
true = enabled, false = grayed out
-
-
-
- -
-
MenuT *wmAddSubMenu(MenuT *parentMenu, const char *label);
-
-

Create a cascading submenu attached to a parent menu. The child MenuT is heap-allocated - and freed when the parent window is destroyed.

-
-
parentMenu
Parent menu to attach submenu to
-
label
Submenu label text
-
-

Returns: Pointer to the child MenuT, or NULL on allocation failure

-
-
- -
-
MenuT *wmCreateMenu(void);
-
-

Allocate a heap-resident MenuT for use as a context menu (right-click). Unlike menu - bar menus, context menus are standalone allocations. Free with wmFreeMenu().

-

Returns: Pointer to the new MenuT

-
-
- -
-
void wmFreeMenu(MenuT *menu);
-
-

Free a standalone menu allocated with wmCreateMenu(). Also frees any heap-allocated - submenu children recursively.

-
-
menu
Menu to free
-
-
-
- +

wmAddMenuBar

+
MenuBarT *wmAddMenuBar(WindowT *win);
+

Allocate and attach a menu bar to a window. Adjusts content area to make +room (CHROME_MENU_HEIGHT pixels). One menu bar per window.

+
  Parameter   Description
+  ---------   -----------
+  win         Window to add menu bar to
+

Returns: Pointer to the new MenuBarT.

+

wmDestroyMenuBar

+
void wmDestroyMenuBar(WindowT *win);
+

Free the menu bar and reclaim the content area.

+
  Parameter   Description
+  ---------   -----------
+  win         Window to remove menu bar from
+

wmAddMenu

+
MenuT *wmAddMenu(MenuBarT *bar, const char *label);
+

Append a dropdown menu to the menu bar. The label supports & accelerator +markers (e.g. "&File").

+
  Parameter   Description
+  ---------   -----------
+  bar         Menu bar
+  label       Menu label text
+

Returns: Pointer to the new MenuT to populate with items.

+

wmAddMenuItem

+
void wmAddMenuItem(MenuT *menu, const char *label, int32_t id);
+

Append a clickable item to a menu. The id is passed to the window's onMenu +callback when selected.

+
  Parameter   Description
+  ---------   -----------
+  menu        Menu to append to
+  label       Item label (supports & markers)
+  id          Application-defined command ID
+

wmAddMenuCheckItem

+
void wmAddMenuCheckItem(MenuT *menu, const char *label, int32_t id, bool checked);
+

Add a checkbox-style menu item. Check state toggles on click; rendered with +a checkmark glyph.

+
  Parameter   Description
+  ---------   -----------
+  menu        Menu to append to
+  label       Item label
+  id          Command ID
+  checked     Initial checked state
+

wmAddMenuRadioItem

+
void wmAddMenuRadioItem(MenuT *menu, const char *label, int32_t id, bool checked);
+

Add a radio-style menu item. Radio groups are defined implicitly by +consecutive radio items; selecting one unchecks the others in the group.

+
  Parameter   Description
+  ---------   -----------
+  menu        Menu to append to
+  label       Item label
+  id          Command ID
+  checked     Initial checked state
+

wmAddMenuSeparator

+
void wmAddMenuSeparator(MenuT *menu);
+

Insert a horizontal separator line. Separators are not interactive.

+
  Parameter   Description
+  ---------   -----------
+  menu        Menu to append separator to
+

wmMenuItemIsChecked

+
bool wmMenuItemIsChecked(MenuBarT *bar, int32_t id);
+

Query the checked state of a menu item by command ID. Searches all menus in +the bar.

+
  Parameter   Description
+  ---------   -----------
+  bar         Menu bar
+  id          Command ID to query
+

Returns: true if checked.

+

wmMenuItemSetChecked

+
void wmMenuItemSetChecked(MenuBarT *bar, int32_t id, bool checked);
+

Set the checked state of a menu item by command ID. For radio items, setting +checked=true also unchecks other radio items in the same group.

+
  Parameter   Description
+  ---------   -----------
+  bar         Menu bar
+  id          Command ID
+  checked     New checked state
+

wmMenuItemSetEnabled

+
void wmMenuItemSetEnabled(MenuBarT *bar, int32_t id, bool enabled);
+

Enable or disable a menu item by command ID.

+
  Parameter   Description
+  ---------   -----------
+  bar         Menu bar
+  id          Command ID
+  enabled     true = enabled, false = grayed out
+

wmAddSubMenu

+
MenuT *wmAddSubMenu(MenuT *parentMenu, const char *label);
+

Create a cascading submenu attached to a parent menu. The child MenuT is +heap-allocated and freed when the parent window is destroyed.

+
  Parameter    Description
+  ---------    -----------
+  parentMenu   Parent menu to attach submenu to
+  label        Submenu label text
+

Returns: Pointer to the child MenuT, or NULL on allocation failure.

+

wmCreateMenu

+
MenuT *wmCreateMenu(void);
+

Allocate a heap-resident MenuT for use as a context menu (right-click). +Unlike menu bar menus, context menus are standalone allocations. Free with +wmFreeMenu().

+

Returns: Pointer to the new MenuT.

+

wmFreeMenu

+
void wmFreeMenu(MenuT *menu);
+

Free a standalone menu allocated with wmCreateMenu(). Also frees any +heap-allocated submenu children recursively.

+
  Parameter   Description
+  ---------   -----------
+  menu        Menu to free

Scrollbars

- -
-
ScrollbarT *wmAddVScrollbar(WindowT *win, int32_t min, int32_t max, int32_t pageSize);
-
-

Attach a vertical scrollbar to the right edge of the window's content area. Shrinks - contentW by SCROLLBAR_WIDTH pixels.

-
-
win
Window
-
min, max
Scroll value range
-
pageSize
Visible portion (controls thumb size)
-
-

Returns: Pointer to the new ScrollbarT

-
-
- -
-
ScrollbarT *wmAddHScrollbar(WindowT *win, int32_t min, int32_t max, int32_t pageSize);
-
-

Attach a horizontal scrollbar to the bottom edge. Shrinks contentH by SCROLLBAR_WIDTH pixels.

-
-
win
Window
-
min, max
Scroll value range
-
pageSize
Visible portion
-
-

Returns: Pointer to the new ScrollbarT

-
-
- +

wmAddVScrollbar

+
ScrollbarT *wmAddVScrollbar(WindowT *win, int32_t min, int32_t max, int32_t pageSize);
+

Attach a vertical scrollbar to the right edge of the window's content area. +Shrinks contentW by SCROLLBAR_WIDTH pixels.

+
  Parameter   Description
+  ---------   -----------
+  win         Window
+  min, max    Scroll value range
+  pageSize    Visible portion (controls thumb size)
+

Returns: Pointer to the new ScrollbarT.

+

wmAddHScrollbar

+
ScrollbarT *wmAddHScrollbar(WindowT *win, int32_t min, int32_t max, int32_t pageSize);
+

Attach a horizontal scrollbar to the bottom edge. Shrinks contentH by +SCROLLBAR_WIDTH pixels.

+
  Parameter   Description
+  ---------   -----------
+  win         Window
+  min, max    Scroll value range
+  pageSize    Visible portion
+

Returns: Pointer to the new ScrollbarT.

Drawing

- -
-
void wmDrawChrome(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors, WindowT *win, const RectT *clipTo);
-
-

Draw the window frame: outer bevel, title bar with text, close/minimize/maximize - gadgets, and menu bar if present. Drawing is clipped to the intersection with clipTo.

-
-
d
Display context
-
ops
Blit operations vtable
-
font
Bitmap font for title text
-
colors
Color scheme
-
win
Window to draw chrome for
-
clipTo
Dirty rectangle to clip drawing to
-
-
-
- -
-
void wmDrawContent(DisplayT *d, const BlitOpsT *ops, WindowT *win, const RectT *clipTo);
-
-

Blit the window's content backbuffer into the display backbuffer, clipped to the - dirty rect. Pure copy operation (no drawing).

-
-
d
Display context
-
ops
Blit operations vtable
-
win
Window
-
clipTo
Dirty rectangle
-
-
-
- -
-
void wmDrawScrollbars(DisplayT *d, const BlitOpsT *ops, const ColorSchemeT *colors, WindowT *win, const RectT *clipTo);
-
-

Draw scrollbars (track, arrows, proportional thumb) for a window. Drawn after content - so scrollbars overlay the content area edge.

-
-
d
Display context
-
ops
Blit operations vtable
-
colors
Color scheme
-
win
Window
-
clipTo
Dirty rectangle
-
-
-
- -
-
void wmDrawMinimizedIcons(DisplayT *d, const BlitOpsT *ops, const ColorSchemeT *colors, const WindowStackT *stack, const RectT *clipTo);
-
-

Draw icons for all minimized windows along the bottom of the screen. Each icon shows - a scaled preview of the window's content with a beveled border.

-
-
d
Display context
-
ops
Blit operations vtable
-
colors
Color scheme
-
stack
Window stack
-
clipTo
Dirty rectangle
-
-
-
- +

wmDrawChrome

+
void wmDrawChrome(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors, WindowT *win, const RectT *clipTo);
+

Draw the window frame: outer bevel, title bar with text, +close/minimize/maximize gadgets, and menu bar if present. Drawing is clipped +to the intersection with clipTo.

+
  Parameter   Description
+  ---------   -----------
+  d           Display context
+  ops         Blit operations vtable
+  font        Bitmap font for title text
+  colors      Color scheme
+  win         Window to draw chrome for
+  clipTo      Dirty rectangle to clip drawing to
+

wmDrawContent

+
void wmDrawContent(DisplayT *d, const BlitOpsT *ops, WindowT *win, const RectT *clipTo);
+

Blit the window's content backbuffer into the display backbuffer, clipped to +the dirty rect. Pure copy operation (no drawing).

+
  Parameter   Description
+  ---------   -----------
+  d           Display context
+  ops         Blit operations vtable
+  win         Window
+  clipTo      Dirty rectangle
+

wmDrawScrollbars

+
void wmDrawScrollbars(DisplayT *d, const BlitOpsT *ops, const ColorSchemeT *colors, WindowT *win, const RectT *clipTo);
+

Draw scrollbars (track, arrows, proportional thumb) for a window. Drawn +after content so scrollbars overlay the content area edge.

+
  Parameter   Description
+  ---------   -----------
+  d           Display context
+  ops         Blit operations vtable
+  colors      Color scheme
+  win         Window
+  clipTo      Dirty rectangle
+

wmDrawMinimizedIcons

+
void wmDrawMinimizedIcons(DisplayT *d, const BlitOpsT *ops, const ColorSchemeT *colors, const WindowStackT *stack, const RectT *clipTo);
+

Draw icons for all minimized windows along the bottom of the screen. Each +icon shows a scaled preview of the window's content with a beveled border.

+
  Parameter   Description
+  ---------   -----------
+  d           Display context
+  ops         Blit operations vtable
+  colors      Color scheme
+  stack       Window stack
+  clipTo      Dirty rectangle

Hit Testing

- -
-
int32_t wmHitTest(const WindowStackT *stack, int32_t mx, int32_t my, int32_t *hitPart);
-
-

Determine which window and chrome region is under the given screen coordinates. - Iterates front-to-back (highest Z first) so the topmost window wins.

-
-
stack
Window stack
-
mx, my
Screen coordinates
-
hitPart
Output: HIT_CONTENT, HIT_TITLE, HIT_CLOSE, HIT_RESIZE, HIT_MENU, HIT_VSCROLL, HIT_HSCROLL, HIT_MINIMIZE, HIT_MAXIMIZE
-
-

Returns: Stack index of hit window, or -1 for desktop

-
-
- -
-
int32_t wmResizeEdgeHit(const WindowT *win, int32_t mx, int32_t my);
-
-

Determine which edge(s) of a window's border zone are targeted for resize.

-
-
win
Window
-
mx, my
Screen coordinates
-
-

Returns: Bitmask of RESIZE_LEFT / RESIZE_RIGHT / RESIZE_TOP / RESIZE_BOTTOM

-
-
- -
-
int32_t wmMinimizedIconHit(const WindowStackT *stack, const DisplayT *d, int32_t mx, int32_t my);
-
-

Hit-test minimized icons at the bottom of the screen.

-
-
stack
Window stack
-
d
Display context
-
mx, my
Screen coordinates
-
-

Returns: Stack index of the minimized window, or -1

-
-
- +

wmHitTest

+
int32_t wmHitTest(const WindowStackT *stack, int32_t mx, int32_t my, int32_t *hitPart);
+

Determine which window and chrome region is under the given screen +coordinates. Iterates front-to-back (highest Z first) so the topmost window +wins.

+
  Parameter   Description
+  ---------   -----------
+  stack       Window stack
+  mx, my      Screen coordinates
+  hitPart     Output: HIT_CONTENT, HIT_TITLE, HIT_CLOSE, etc.
+

Returns: Stack index of hit window, or -1 for desktop.

+

wmResizeEdgeHit

+
int32_t wmResizeEdgeHit(const WindowT *win, int32_t mx, int32_t my);
+

Determine which edge(s) of a window's border zone are targeted for resize.

+
  Parameter   Description
+  ---------   -----------
+  win         Window
+  mx, my      Screen coordinates
+

Returns: Bitmask of RESIZE_LEFT / RESIZE_RIGHT / RESIZE_TOP / RESIZE_BOTTOM.

+

wmMinimizedIconHit

+
int32_t wmMinimizedIconHit(const WindowStackT *stack, const DisplayT *d, int32_t mx, int32_t my);
+

Hit-test minimized icons at the bottom of the screen.

+
  Parameter   Description
+  ---------   -----------
+  stack       Window stack
+  d           Display context
+  mx, my      Screen coordinates
+

Returns: Stack index of the minimized window, or -1.

Drag and Resize

- -
-
void wmDragBegin(WindowStackT *stack, int32_t idx, int32_t mouseX, int32_t mouseY);
-
-

Begin a window drag operation. Records the mouse offset from the window origin.

-
-
stack
Window stack
-
idx
Stack index of window to drag
-
mouseX, mouseY
Current mouse position
-
-
-
- -
-
void wmDragMove(WindowStackT *stack, DirtyListT *dl, int32_t mouseX, int32_t mouseY, int32_t screenW, int32_t screenH);
-
-

Update window position during an active drag. Dirties both old and new positions.

-
-
stack
Window stack
-
dl
Dirty list
-
mouseX, mouseY
Current mouse position
-
screenW, screenH
Screen dimensions (for clamping)
-
-
-
- -
-
void wmDragEnd(WindowStackT *stack);
-
-

End the current drag operation. Clears dragWindow state.

-
-
stack
Window stack
-
-
-
- -
-
void wmResizeBegin(WindowStackT *stack, int32_t idx, int32_t edge, int32_t mouseX, int32_t mouseY);
-
-

Begin a window resize operation. Records which edge(s) are being dragged.

-
-
stack
Window stack
-
idx
Stack index
-
edge
Bitmask of RESIZE_xxx flags
-
mouseX, mouseY
Current mouse position
-
-
-
- -
-
void wmResizeMove(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, int32_t *mouseX, int32_t *mouseY);
-
-

Update window dimensions during an active resize. Enforces MIN_WINDOW_W/H and - maxW/maxH constraints. Reallocates content buffer and calls onResize if size changed. - mouseX/mouseY are in/out: clamped on return for cursor warping.

-
-
stack
Window stack
-
dl
Dirty list
-
d
Display context
-
mouseX, mouseY
In/out: mouse position (clamped on return)
-
-
-
- -
-
void wmResizeEnd(WindowStackT *stack);
-
-

End the current resize operation. Clears resizeWindow state.

-
-
stack
Window stack
-
-
-
- +

wmDragBegin

+
void wmDragBegin(WindowStackT *stack, int32_t idx, int32_t mouseX, int32_t mouseY);
+

Begin a window drag operation. Records the mouse offset from the window +origin.

+
  Parameter     Description
+  ---------     -----------
+  stack         Window stack
+  idx           Stack index of window to drag
+  mouseX/Y      Current mouse position
+

wmDragMove

+
void wmDragMove(WindowStackT *stack, DirtyListT *dl, int32_t mouseX, int32_t mouseY, int32_t screenW, int32_t screenH);
+

Update window position during an active drag. Dirties both old and new +positions.

+
  Parameter      Description
+  ---------      -----------
+  stack          Window stack
+  dl             Dirty list
+  mouseX/Y       Current mouse position
+  screenW/H      Screen dimensions (for clamping)
+

wmDragEnd

+
void wmDragEnd(WindowStackT *stack);
+

End the current drag operation. Clears dragWindow state.

+
  Parameter   Description
+  ---------   -----------
+  stack       Window stack
+

wmResizeBegin

+
void wmResizeBegin(WindowStackT *stack, int32_t idx, int32_t edge, int32_t mouseX, int32_t mouseY);
+

Begin a window resize operation. Records which edge(s) are being dragged.

+
  Parameter   Description
+  ---------   -----------
+  stack       Window stack
+  idx         Stack index
+  edge        Bitmask of RESIZE_xxx flags
+  mouseX/Y    Current mouse position
+

wmResizeMove

+
void wmResizeMove(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, int32_t *mouseX, int32_t *mouseY);
+

Update window dimensions during an active resize. Enforces MIN_WINDOW_W/H +and maxW/maxH constraints. Reallocates content buffer and calls onResize if +size changed. mouseX/mouseY are in/out: clamped on return for cursor +warping.

+
  Parameter   Description
+  ---------   -----------
+  stack       Window stack
+  dl          Dirty list
+  d           Display context
+  mouseX/Y    In/out: mouse position (clamped on return)
+

wmResizeEnd

+
void wmResizeEnd(WindowStackT *stack);
+

End the current resize operation. Clears resizeWindow state.

+
  Parameter   Description
+  ---------   -----------
+  stack       Window stack

Scrollbar Interaction

- -
-
void wmScrollbarClick(WindowStackT *stack, DirtyListT *dl, int32_t idx, int32_t orient, int32_t mx, int32_t my);
-
-

Handle an initial click on a scrollbar. Determines what was hit (arrows, trough, or - thumb) and either adjusts the value immediately or begins a thumb drag.

-
-
stack
Window stack
-
dl
Dirty list
-
idx
Stack index of window
-
orient
SCROLL_VERTICAL or SCROLL_HORIZONTAL
-
mx, my
Click screen coordinates
-
-
-
- -
-
void wmScrollbarDrag(WindowStackT *stack, DirtyListT *dl, int32_t mx, int32_t my);
-
-

Update the scroll value during an active thumb drag. Maps mouse position along the - track to a proportional scroll value.

-
-
stack
Window stack
-
dl
Dirty list
-
mx, my
Current mouse position
-
-
-
- -
-
void wmScrollbarEnd(WindowStackT *stack);
-
-

End an active scrollbar thumb drag.

-
-
stack
Window stack
-
-
-
- +

wmScrollbarClick

+
void wmScrollbarClick(WindowStackT *stack, DirtyListT *dl, int32_t idx, int32_t orient, int32_t mx, int32_t my);
+

Handle an initial click on a scrollbar. Determines what was hit (arrows, +trough, or thumb) and either adjusts the value immediately or begins a thumb +drag.

+
  Parameter   Description
+  ---------   -----------
+  stack       Window stack
+  dl          Dirty list
+  idx         Stack index of window
+  orient      SCROLL_VERTICAL or SCROLL_HORIZONTAL
+  mx, my      Click screen coordinates
+

wmScrollbarDrag

+
void wmScrollbarDrag(WindowStackT *stack, DirtyListT *dl, int32_t mx, int32_t my);
+

Update the scroll value during an active thumb drag. Maps mouse position +along the track to a proportional scroll value.

+
  Parameter   Description
+  ---------   -----------
+  stack       Window stack
+  dl          Dirty list
+  mx, my      Current mouse position
+

wmScrollbarEnd

+
void wmScrollbarEnd(WindowStackT *stack);
+

End an active scrollbar thumb drag.

+
  Parameter   Description
+  ---------   -----------
+  stack       Window stack

Minimize / Maximize / Restore

- -
-
void wmMaximize(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, WindowT *win);
-
-

Maximize a window. Saves current geometry, then expands to screen or maxW/maxH bounds.

-
-
stack
Window stack
-
dl
Dirty list
-
d
Display context
-
win
Window to maximize
-
-
-
- -
-
void wmMinimize(WindowStackT *stack, DirtyListT *dl, WindowT *win);
-
-

Minimize a window. Hides the window and shows an icon at the bottom of the screen.

-
-
stack
Window stack
-
dl
Dirty list
-
win
Window to minimize
-
-
-
- -
-
void wmRestore(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, WindowT *win);
-
-

Restore a maximized window to its pre-maximize geometry.

-
-
stack
Window stack
-
dl
Dirty list
-
d
Display context
-
win
Maximized window to restore
-
-
-
- -
-
void wmRestoreMinimized(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, WindowT *win);
-
-

Restore a minimized window (show it again and remove the icon).

-
-
stack
Window stack
-
dl
Dirty list
-
d
Display context
-
win
Minimized window to restore
-
-
-
- +

wmMaximize

+
void wmMaximize(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, WindowT *win);
+

Maximize a window. Saves current geometry, then expands to screen or +maxW/maxH bounds.

+
  Parameter   Description
+  ---------   -----------
+  stack       Window stack
+  dl          Dirty list
+  d           Display context
+  win         Window to maximize
+

wmMinimize

+
void wmMinimize(WindowStackT *stack, DirtyListT *dl, WindowT *win);
+

Minimize a window. Hides the window and shows an icon at the bottom of the +screen.

+
  Parameter   Description
+  ---------   -----------
+  stack       Window stack
+  dl          Dirty list
+  win         Window to minimize
+

wmRestore

+
void wmRestore(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, WindowT *win);
+

Restore a maximized window to its pre-maximize geometry.

+
  Parameter   Description
+  ---------   -----------
+  stack       Window stack
+  dl          Dirty list
+  d           Display context
+  win         Maximized window to restore
+

wmRestoreMinimized

+
void wmRestoreMinimized(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, WindowT *win);
+

Restore a minimized window (show it again and remove the icon).

+
  Parameter   Description
+  ---------   -----------
+  stack       Window stack
+  dl          Dirty list
+  d           Display context
+  win         Minimized window to restore

Minimized Icon Layout

- -
-
void wmMinimizedIconPos(const DisplayT *d, int32_t index, int32_t *x, int32_t *y);
-
-

Compute the screen position of a minimized icon by ordinal index. Icons wrap into - rows from bottom to top when the screen fills up.

-
-
d
Display context
-
index
Ordinal index of the minimized icon
-
x, y
Output: screen position
-
-
-
- -
-
void wmMinimizedIconRect(const WindowStackT *stack, const DisplayT *d, int32_t *y, int32_t *h);
-
-

Compute the screen rect covering all minimized icon rows. Used to dirty the icon area - when windows are minimized or restored.

-
-
stack
Window stack
-
d
Display context
-
y, h
Output: vertical extent of icon area
-
-
-
- +

wmMinimizedIconPos

+
void wmMinimizedIconPos(const DisplayT *d, int32_t index, int32_t *x, int32_t *y);
+

Compute the screen position of a minimized icon by ordinal index. Icons wrap +into rows from bottom to top when the screen fills up.

+
  Parameter   Description
+  ---------   -----------
+  d           Display context
+  index       Ordinal index of the minimized icon
+  x, y        Output: screen position
+

wmMinimizedIconRect

+
void wmMinimizedIconRect(const WindowStackT *stack, const DisplayT *d, int32_t *y, int32_t *h);
+

Compute the screen rect covering all minimized icon rows. Used to dirty the +icon area when windows are minimized or restored.

+
  Parameter   Description
+  ---------   -----------
+  stack       Window stack
+  d           Display context
+  y, h        Output: vertical extent of icon area

Miscellaneous

- -
-
void wmSetTitle(WindowT *win, DirtyListT *dl, const char *title);
-
-

Set the window title and dirty the title bar for repaint.

-
-
win
Window
-
dl
Dirty list
-
title
New title text
-
+

wmSetTitle

+
void wmSetTitle(WindowT *win, DirtyListT *dl, const char *title);
+

Set the window title and dirty the title bar for repaint.

+
  Parameter   Description
+  ---------   -----------
+  win         Window
+  dl          Dirty list
+  title       New title text
+

wmSetIcon

+
int32_t wmSetIcon(WindowT *win, const char *path, const DisplayT *d);
+

Load an icon image for a window from a file. Converts to display pixel +format.

+
  Parameter   Description
+  ---------   -----------
+  win         Window
+  path        Image file path
+  d           Display context
+

Returns: 0 on success, -1 on failure.

-
- -
-
int32_t wmSetIcon(WindowT *win, const char *path, const DisplayT *d);
-
-

Load an icon image for a window from a file. Converts to display pixel format.

-
-
win
Window
-
path
Image file path
-
d
Display context
-
-

Returns: 0 on success, -1 on failure

-
-
- -
- - - - - -
-

dvxApp.h -- Layer 5: Application API

-

- The topmost layer and the public-facing API. Aggregates all lower layers into a single - AppContextT. Applications interact exclusively through dvx*() functions and window - callbacks. The event loop follows a cooperative model: poll, dispatch, composite, yield. -

- +
+

dvxApp.h -- Layer 5: Application API

+

dvxApp.h -- Layer 5: Application API

+

The topmost layer and the public-facing API. Aggregates all lower layers +into a single AppContextT. Applications interact exclusively through dvx*() +functions and window callbacks. The event loop follows a cooperative model: +poll, dispatch, composite, yield.

AppContextT

- -
-
AppContextT
-
- Single monolithic context that owns all GUI state. Contains the display, window stack, - dirty list, blit ops, font, color scheme, popup state, cursor state, mouse/keyboard state, - tooltip state, wallpaper buffer, video mode list, and various configuration fields. - Allocated on the caller's stack or statically. -
-
- +

Single monolithic context that owns all GUI state. Contains the display, +window stack, dirty list, blit ops, font, color scheme, popup state, cursor +state, mouse/keyboard state, tooltip state, wallpaper buffer, video mode +list, and various configuration fields. Allocated on the caller's stack or +statically.

Initialization and Shutdown

- -
-
int32_t dvxInit(AppContextT *ctx, int32_t requestedW, int32_t requestedH, int32_t preferredBpp);
-
-

Initialize the entire GUI stack: video mode, input devices, font, color scheme, cursor - shapes, and internal state. Single entry point for starting a DVX application.

-
-
ctx
Application context to initialize
-
requestedW, requestedH
Desired screen resolution
-
preferredBpp
Preferred bits per pixel
-
-

Returns: 0 on success, negative on failure

-
-
- -
-
void dvxShutdown(AppContextT *ctx);
-
-

Tear down the GUI stack in reverse order: destroy all windows, restore text mode, - release input devices. Safe to call after a failed dvxInit().

-
-
ctx
Application context
-
-
-
- -
-
int32_t dvxChangeVideoMode(AppContextT *ctx, int32_t requestedW, int32_t requestedH, int32_t preferredBpp);
-
-

Switch to a new video mode live. Reallocates the backbuffer, all window content buffers, - repacks colors, rescales wallpaper, and repositions off-screen windows.

-
-
ctx
Application context
-
requestedW, requestedH
New resolution
-
preferredBpp
New bits per pixel
-
-

Returns: 0 on success, -1 on failure (old mode restored)

-
-
- +

dvxInit

+
int32_t dvxInit(AppContextT *ctx, int32_t requestedW, int32_t requestedH, int32_t preferredBpp);
+

Initialize the entire GUI stack: video mode, input devices, font, color +scheme, cursor shapes, and internal state. Single entry point for starting a +DVX application.

+
  Parameter        Description
+  ---------        -----------
+  ctx              Application context to initialize
+  requestedW/H     Desired screen resolution
+  preferredBpp     Preferred bits per pixel
+

Returns: 0 on success, negative on failure.

+

dvxShutdown

+
void dvxShutdown(AppContextT *ctx);
+

Tear down the GUI stack in reverse order: destroy all windows, restore text +mode, release input devices. Safe to call after a failed dvxInit().

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+

dvxChangeVideoMode

+
int32_t dvxChangeVideoMode(AppContextT *ctx, int32_t requestedW, int32_t requestedH, int32_t preferredBpp);
+

Switch to a new video mode live. Reallocates the backbuffer, all window +content buffers, repacks colors, rescales wallpaper, and repositions +off-screen windows.

+
  Parameter        Description
+  ---------        -----------
+  ctx              Application context
+  requestedW/H     New resolution
+  preferredBpp     New bits per pixel
+

Returns: 0 on success, -1 on failure (old mode restored).

Event Loop

- -
-
void dvxRun(AppContextT *ctx);
-
-

Enter the main event loop. Polls input, dispatches events, composites dirty regions, - and yields on each iteration. Returns when ctx->running becomes false.

-
-
ctx
Application context
-
-
-
- -
-
bool dvxUpdate(AppContextT *ctx);
-
-

Process exactly one frame of the event loop. For applications that integrate the GUI - into their own main loop (e.g. polling serial ports between frames).

-
-
ctx
Application context
-
-

Returns: false when the GUI wants to exit

-
-
- -
-
void dvxQuit(AppContextT *ctx);
-
-

Request exit from the main event loop (sets ctx->running = false).

-
-
ctx
Application context
-
-
-
- +

dvxRun

+
void dvxRun(AppContextT *ctx);
+

Enter the main event loop. Polls input, dispatches events, composites dirty +regions, and yields on each iteration. Returns when ctx->running becomes +false.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+

dvxUpdate

+
bool dvxUpdate(AppContextT *ctx);
+

Process exactly one frame of the event loop. For applications that integrate +the GUI into their own main loop (e.g. polling serial ports between frames).

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+

Returns: false when the GUI wants to exit.

+

dvxQuit

+
void dvxQuit(AppContextT *ctx);
+

Request exit from the main event loop (sets ctx->running = false).

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context

Window Management

- -
-
WindowT *dvxCreateWindow(AppContextT *ctx, const char *title, int32_t x, int32_t y, int32_t w, int32_t h, bool resizable);
-
-

Create a window at an explicit screen position. The window is raised to the top, - focused, and its entire region is dirtied.

-
-
ctx
Application context
-
title
Window title
-
x, y
Screen position
-
w, h
Outer frame dimensions
-
resizable
true = allow user resize
-
-

Returns: Pointer to new WindowT

-
-
- -
-
WindowT *dvxCreateWindowCentered(AppContextT *ctx, const char *title, int32_t w, int32_t h, bool resizable);
-
-

Convenience wrapper that centers the window on screen.

-
-
ctx
Application context
-
title
Window title
-
w, h
Outer frame dimensions
-
resizable
true = allow user resize
-
-

Returns: Pointer to new WindowT

-
-
- -
-
void dvxDestroyWindow(AppContextT *ctx, WindowT *win);
-
-

Destroy a window, free all its resources, and dirty its former region.

-
-
ctx
Application context
-
win
Window to destroy
-
-
-
- -
-
void dvxRaiseWindow(AppContextT *ctx, WindowT *win);
-
-

Raise a window to the top of the Z-order and give it focus.

-
-
ctx
Application context
-
win
Window to raise
-
-
-
- -
-
void dvxFitWindow(AppContextT *ctx, WindowT *win);
-
-

Resize a window to exactly fit its widget tree's computed minimum size (plus chrome). - Used for dialog boxes and fixed-layout windows.

-
-
ctx
Application context
-
win
Window to fit
-
-
-
- -
-
void dvxFitWindowW(AppContextT *ctx, WindowT *win);
-
-

Resize window width only to fit widget tree's minimum width (plus chrome).

-
-
ctx
Application context
-
win
Window to fit
-
-
-
- -
-
void dvxFitWindowH(AppContextT *ctx, WindowT *win);
-
-

Resize window height only to fit widget tree's minimum height (plus chrome).

-
-
ctx
Application context
-
win
Window to fit
-
-
-
- -
-
void dvxResizeWindow(AppContextT *ctx, WindowT *win, int32_t newW, int32_t newH);
-
-

Programmatically resize a window to the specified outer dimensions.

-
-
ctx
Application context
-
win
Window to resize
-
newW, newH
New outer frame dimensions
-
-
-
- -
-
void dvxMinimizeWindow(AppContextT *ctx, WindowT *win);
-
-

Minimize a window (show as icon at bottom of screen).

-
-
ctx
Application context
-
win
Window to minimize
-
-
-
- -
-
void dvxMaximizeWindow(AppContextT *ctx, WindowT *win);
-
-

Maximize a window (expand to fill screen or maxW/maxH).

-
-
ctx
Application context
-
win
Window to maximize
-
-
-
- -
-
void dvxHideWindow(AppContextT *ctx, WindowT *win);
-
-

Hide a window without destroying it. Marks the exposed region dirty.

-
-
ctx
Application context
-
win
Window to hide
-
-
-
- -
-
void dvxShowWindow(AppContextT *ctx, WindowT *win);
-
-

Show a previously hidden window. Marks its region dirty for repaint.

-
-
ctx
Application context
-
win
Window to show
-
-
-
- +

dvxCreateWindow

+
WindowT *dvxCreateWindow(AppContextT *ctx, const char *title, int32_t x, int32_t y, int32_t w, int32_t h, bool resizable);
+

Create a window at an explicit screen position. The window is raised to the +top, focused, and its entire region is dirtied.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  title       Window title
+  x, y        Screen position
+  w, h        Outer frame dimensions
+  resizable   true = allow user resize
+

Returns: Pointer to new WindowT.

+

dvxCreateWindowCentered

+
WindowT *dvxCreateWindowCentered(AppContextT *ctx, const char *title, int32_t w, int32_t h, bool resizable);
+

Convenience wrapper that centers the window on screen.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  title       Window title
+  w, h        Outer frame dimensions
+  resizable   true = allow user resize
+

Returns: Pointer to new WindowT.

+

dvxDestroyWindow

+
void dvxDestroyWindow(AppContextT *ctx, WindowT *win);
+

Destroy a window, free all its resources, and dirty its former region.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  win         Window to destroy
+

dvxRaiseWindow

+
void dvxRaiseWindow(AppContextT *ctx, WindowT *win);
+

Raise a window to the top of the Z-order and give it focus.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  win         Window to raise
+

dvxFitWindow

+
void dvxFitWindow(AppContextT *ctx, WindowT *win);
+

Resize a window to exactly fit its widget tree's computed minimum size (plus +chrome). Used for dialog boxes and fixed-layout windows.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  win         Window to fit
+

dvxFitWindowW

+
void dvxFitWindowW(AppContextT *ctx, WindowT *win);
+

Resize window width only to fit widget tree's minimum width (plus chrome).

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  win         Window to fit
+

dvxFitWindowH

+
void dvxFitWindowH(AppContextT *ctx, WindowT *win);
+

Resize window height only to fit widget tree's minimum height (plus chrome).

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  win         Window to fit
+

dvxResizeWindow

+
void dvxResizeWindow(AppContextT *ctx, WindowT *win, int32_t newW, int32_t newH);
+

Programmatically resize a window to the specified outer dimensions.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  win         Window to resize
+  newW, newH  New outer frame dimensions
+

dvxMinimizeWindow

+
void dvxMinimizeWindow(AppContextT *ctx, WindowT *win);
+

Minimize a window (show as icon at bottom of screen).

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  win         Window to minimize
+

dvxMaximizeWindow

+
void dvxMaximizeWindow(AppContextT *ctx, WindowT *win);
+

Maximize a window (expand to fill screen or maxW/maxH).

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  win         Window to maximize
+

dvxHideWindow

+
void dvxHideWindow(AppContextT *ctx, WindowT *win);
+

Hide a window without destroying it. Marks the exposed region dirty.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  win         Window to hide
+

dvxShowWindow

+
void dvxShowWindow(AppContextT *ctx, WindowT *win);
+

Show a previously hidden window. Marks its region dirty for repaint.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  win         Window to show

Invalidation

- -
-
void dvxInvalidateRect(AppContextT *ctx, WindowT *win, int32_t x, int32_t y, int32_t w, int32_t h);
-
-

Mark a sub-region of a window's content area as needing repaint. Coordinates are - relative to the content area, not the screen. Triggers onPaint during the next - composite pass.

-
-
ctx
Application context
-
win
Window
-
x, y, w, h
Dirty rectangle in content-relative coordinates
-
-
-
- -
-
void dvxInvalidateWindow(AppContextT *ctx, WindowT *win);
-
-

Mark the entire window content area as dirty.

-
-
ctx
Application context
-
win
Window to invalidate
-
-
-
- +

dvxInvalidateRect

+
void dvxInvalidateRect(AppContextT *ctx, WindowT *win, int32_t x, int32_t y, int32_t w, int32_t h);
+

Mark a sub-region of a window's content area as needing repaint. Coordinates +are relative to the content area, not the screen. Triggers onPaint during +the next composite pass.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  win         Window
+  x, y, w, h Dirty rectangle in content-relative coordinates
+

dvxInvalidateWindow

+
void dvxInvalidateWindow(AppContextT *ctx, WindowT *win);
+

Mark the entire window content area as dirty.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  win         Window to invalidate

Window Properties

- -
-
void dvxSetTitle(AppContextT *ctx, WindowT *win, const char *title);
-
-

Set a window's title text and dirty the title bar.

-
-
ctx
Application context
-
win
Window
-
title
New title text
-
-
-
- -
-
int32_t dvxSetWindowIcon(AppContextT *ctx, WindowT *win, const char *path);
-
-

Load an icon for a window from an image file.

-
-
ctx
Application context
-
win
Window
-
path
Image file path
-
-

Returns: 0 on success, -1 on failure

-
-
- -
-
void dvxSetBusy(AppContextT *ctx, bool busy);
-
-

Set or clear busy state. While busy, the hourglass cursor is shown and input is blocked.

-
-
ctx
Application context
-
busy
true = show hourglass, false = normal
-
-
-
- +

dvxSetTitle

+
void dvxSetTitle(AppContextT *ctx, WindowT *win, const char *title);
+

Set a window's title text and dirty the title bar.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  win         Window
+  title       New title text
+

dvxSetWindowIcon

+
int32_t dvxSetWindowIcon(AppContextT *ctx, WindowT *win, const char *path);
+

Load an icon for a window from an image file.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  win         Window
+  path        Image file path
+

Returns: 0 on success, -1 on failure.

+

dvxSetBusy

+
void dvxSetBusy(AppContextT *ctx, bool busy);
+

Set or clear busy state. While busy, the hourglass cursor is shown and input +is blocked.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  busy        true = show hourglass, false = normal

Accessors

- -
-
const BitmapFontT *dvxGetFont(const AppContextT *ctx);
-
-

Get a pointer to the default font.

-
-
ctx
Application context
-
-

Returns: Pointer to the active BitmapFontT

-
-
- -
-
const ColorSchemeT *dvxGetColors(const AppContextT *ctx);
-
-

Get a pointer to the current color scheme.

-
-
ctx
Application context
-
-

Returns: Pointer to the active ColorSchemeT

-
-
- -
-
DisplayT *dvxGetDisplay(AppContextT *ctx);
-
-

Get a pointer to the display context.

-
-
ctx
Application context
-
-

Returns: Pointer to the DisplayT

-
-
- -
-
const BlitOpsT *dvxGetBlitOps(const AppContextT *ctx);
-
-

Get a pointer to the blit operations vtable.

-
-
ctx
Application context
-
-

Returns: Pointer to the active BlitOpsT

-
-
- -
-
const VideoModeInfoT *dvxGetVideoModes(const AppContextT *ctx, int32_t *count);
-
-

Return the list of available video modes enumerated at init time.

-
-
ctx
Application context
-
count
Output: number of mode entries
-
-

Returns: Pointer to the VideoModeInfoT array

-
-
- +

dvxGetFont

+
const BitmapFontT *dvxGetFont(const AppContextT *ctx);
+

Get a pointer to the default font.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+

Returns: Pointer to the active BitmapFontT.

+

dvxGetColors

+
const ColorSchemeT *dvxGetColors(const AppContextT *ctx);
+

Get a pointer to the current color scheme.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+

Returns: Pointer to the active ColorSchemeT.

+

dvxGetDisplay

+
DisplayT *dvxGetDisplay(AppContextT *ctx);
+

Get a pointer to the display context.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+

Returns: Pointer to the DisplayT.

+

dvxGetBlitOps

+
const BlitOpsT *dvxGetBlitOps(const AppContextT *ctx);
+

Get a pointer to the blit operations vtable.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+

Returns: Pointer to the active BlitOpsT.

+

dvxGetVideoModes

+
const VideoModeInfoT *dvxGetVideoModes(const AppContextT *ctx, int32_t *count);
+

Return the list of available video modes enumerated at init time.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  count       Output: number of mode entries
+

Returns: Pointer to the VideoModeInfoT array.

Color Scheme

- -
-
void dvxSetColor(AppContextT *ctx, ColorIdE id, uint8_t r, uint8_t g, uint8_t b);
-
-

Set a single color by ID. Repacks to native pixel format and invalidates the entire screen.

-
-
ctx
Application context
-
id
Color ID (ColorIdE)
-
r, g, b
RGB values (0-255)
-
-
-
- -
-
void dvxGetColor(const AppContextT *ctx, ColorIdE id, uint8_t *r, uint8_t *g, uint8_t *b);
-
-

Get a color's RGB values by ID.

-
-
ctx
Application context
-
id
Color ID (ColorIdE)
-
r, g, b
Output: RGB values
-
-
-
- -
-
void dvxApplyColorScheme(AppContextT *ctx);
-
-

Apply all colors from ctx->colorRgb[] at once (repack + full repaint).

-
-
ctx
Application context
-
-
-
- -
-
void dvxResetColorScheme(AppContextT *ctx);
-
-

Reset all colors to the built-in defaults and repaint.

-
-
ctx
Application context
-
-
-
- -
-
bool dvxLoadTheme(AppContextT *ctx, const char *filename);
-
-

Load a theme file (INI format with [colors] section) and apply it.

-
-
ctx
Application context
-
filename
Path to theme INI file
-
-

Returns: true on success

-
-
- -
-
bool dvxSaveTheme(const AppContextT *ctx, const char *filename);
-
-

Save the current color scheme to a theme file.

-
-
ctx
Application context
-
filename
Output file path
-
-

Returns: true on success

-
-
- -
-
const char *dvxColorName(ColorIdE id);
-
-

Return the INI key name for a color ID (e.g. "desktop", "windowFace").

-
-
id
Color ID
-
-

Returns: Static string

-
-
- -
-
const char *dvxColorLabel(ColorIdE id);
-
-

Return a human-readable display label (e.g. "Desktop", "Cursor Color").

-
-
id
Color ID
-
-

Returns: Static string

-
-
- +

dvxSetColor

+
void dvxSetColor(AppContextT *ctx, ColorIdE id, uint8_t r, uint8_t g, uint8_t b);
+

Set a single color by ID. Repacks to native pixel format and invalidates the +entire screen.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  id          Color ID (ColorIdE)
+  r, g, b     RGB values (0-255)
+

dvxGetColor

+
void dvxGetColor(const AppContextT *ctx, ColorIdE id, uint8_t *r, uint8_t *g, uint8_t *b);
+

Get a color's RGB values by ID.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  id          Color ID (ColorIdE)
+  r, g, b     Output: RGB values
+

dvxApplyColorScheme

+
void dvxApplyColorScheme(AppContextT *ctx);
+

Apply all colors from ctx->colorRgb[] at once (repack + full repaint).

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+

dvxResetColorScheme

+
void dvxResetColorScheme(AppContextT *ctx);
+

Reset all colors to the built-in defaults and repaint.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+

dvxLoadTheme

+
bool dvxLoadTheme(AppContextT *ctx, const char *filename);
+

Load a theme file (INI format with [colors] section) and apply it.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  filename    Path to theme INI file
+

Returns: true on success.

+

dvxSaveTheme

+
bool dvxSaveTheme(const AppContextT *ctx, const char *filename);
+

Save the current color scheme to a theme file.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  filename    Output file path
+

Returns: true on success.

+

dvxColorName

+
const char *dvxColorName(ColorIdE id);
+

Return the INI key name for a color ID (e.g. "desktop", "windowFace").

+
  Parameter   Description
+  ---------   -----------
+  id          Color ID
+

Returns: Static string.

+

dvxColorLabel

+
const char *dvxColorLabel(ColorIdE id);
+

Return a human-readable display label (e.g. "Desktop", "Cursor Color").

+
  Parameter   Description
+  ---------   -----------
+  id          Color ID
+

Returns: Static string.

Wallpaper

- -
-
bool dvxSetWallpaper(AppContextT *ctx, const char *path);
-
-

Load and apply a wallpaper image using the current wallpaperMode (stretch/tile/center). - Pass NULL to clear the wallpaper.

-
-
ctx
Application context
-
path
Image file path, or NULL to clear
-
-

Returns: true on success

-
-
- -
-
void dvxSetWallpaperMode(AppContextT *ctx, WallpaperModeE mode);
-
-

Change the wallpaper display mode and re-render. No effect if no wallpaper is loaded.

-
-
ctx
Application context
-
mode
WallpaperStretchE, WallpaperTileE, or WallpaperCenterE
-
-
-
- +

dvxSetWallpaper

+
bool dvxSetWallpaper(AppContextT *ctx, const char *path);
+

Load and apply a wallpaper image using the current wallpaperMode +(stretch/tile/center). Pass NULL to clear the wallpaper.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  path        Image file path, or NULL to clear
+

Returns: true on success.

+

dvxSetWallpaperMode

+
void dvxSetWallpaperMode(AppContextT *ctx, WallpaperModeE mode);
+

Change the wallpaper display mode and re-render. No effect if no wallpaper +is loaded.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  mode        WallpaperStretchE, WallpaperTileE, or WallpaperCenterE

Mouse Configuration

- -
-
void dvxSetMouseConfig(AppContextT *ctx, int32_t wheelDir, int32_t dblClickMs, int32_t accelThreshold);
-
-

Configure mouse behavior.

-
-
ctx
Application context
-
wheelDir
1 = normal, -1 = reversed
-
dblClickMs
Double-click speed in milliseconds (e.g. 500)
-
accelThreshold
Double-speed threshold in mickeys/sec (0 = don't change)
-
-
-
- +

dvxSetMouseConfig

+
void dvxSetMouseConfig(AppContextT *ctx, int32_t wheelDir, int32_t dblClickMs, int32_t accelThreshold);
+

Configure mouse behavior.

+
  Parameter        Description
+  ---------        -----------
+  ctx              Application context
+  wheelDir         1 = normal, -1 = reversed
+  dblClickMs       Double-click speed in milliseconds (e.g. 500)
+  accelThreshold   Double-speed threshold in mickeys/sec (0 = don't change)

Accelerators

- -
-
AccelTableT *dvxCreateAccelTable(void);
-
-

Allocate a new accelerator table. Attach to a window via win->accelTable.

-

Returns: Pointer to new AccelTableT

-
-
- -
-
void dvxFreeAccelTable(AccelTableT *table);
-
-

Free an accelerator table and its entries.

-
-
table
Table to free
-
-
-
- -
-
void dvxAddAccel(AccelTableT *table, int32_t key, int32_t modifiers, int32_t cmdId);
-
-

Register a keyboard shortcut. On match, fires the window's onMenu callback with cmdId.

-
-
table
Accelerator table
-
key
ASCII character or KEY_Fxx constant
-
modifiers
Bitmask of ACCEL_CTRL / ACCEL_SHIFT / ACCEL_ALT
-
cmdId
Command ID passed to onMenu
-
-
-
- +

dvxCreateAccelTable

+
AccelTableT *dvxCreateAccelTable(void);
+

Allocate a new accelerator table. Attach to a window via win->accelTable.

+

Returns: Pointer to new AccelTableT.

+

dvxFreeAccelTable

+
void dvxFreeAccelTable(AccelTableT *table);
+

Free an accelerator table and its entries.

+
  Parameter   Description
+  ---------   -----------
+  table       Table to free
+

dvxAddAccel

+
void dvxAddAccel(AccelTableT *table, int32_t key, int32_t modifiers, int32_t cmdId);
+

Register a keyboard shortcut. On match, fires the window's onMenu callback +with cmdId.

+
  Parameter   Description
+  ---------   -----------
+  table       Accelerator table
+  key         ASCII character or KEY_Fxx constant
+  modifiers   Bitmask of ACCEL_CTRL / ACCEL_SHIFT / ACCEL_ALT
+  cmdId       Command ID passed to onMenu

Window Arrangement

- -
-
void dvxCascadeWindows(AppContextT *ctx);
-
-

Cascade all visible, non-minimized windows. Each is offset diagonally by the title bar height.

-
-
ctx
Application context
-
-
-
- -
-
void dvxTileWindows(AppContextT *ctx);
-
-

Arrange visible windows in an NxM grid filling the screen.

-
-
ctx
Application context
-
-
-
- -
-
void dvxTileWindowsH(AppContextT *ctx);
-
-

Tile windows horizontally (side by side, equal width, full height).

-
-
ctx
Application context
-
-
-
- -
-
void dvxTileWindowsV(AppContextT *ctx);
-
-

Tile windows vertically (stacked, full width, equal height).

-
-
ctx
Application context
-
-
-
- +

dvxCascadeWindows

+
void dvxCascadeWindows(AppContextT *ctx);
+

Cascade all visible, non-minimized windows. Each is offset diagonally by the +title bar height.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+

dvxTileWindows

+
void dvxTileWindows(AppContextT *ctx);
+

Arrange visible windows in an NxM grid filling the screen.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+

dvxTileWindowsH

+
void dvxTileWindowsH(AppContextT *ctx);
+

Tile windows horizontally (side by side, equal width, full height).

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+

dvxTileWindowsV

+
void dvxTileWindowsV(AppContextT *ctx);
+

Tile windows vertically (stacked, full width, equal height).

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context

Image I/O

- -
-
uint8_t *dvxLoadImage(const AppContextT *ctx, const char *path, int32_t *outW, int32_t *outH, int32_t *outPitch);
-
-

Load an image file (BMP, PNG, JPEG, GIF) and convert to the display's native pixel - format. Caller must free with dvxFreeImage().

-
-
ctx
Application context
-
path
Image file path
-
outW, outH
Output: image dimensions
-
outPitch
Output: row pitch in bytes
-
-

Returns: Pixel buffer, or NULL on failure

-
-
- -
-
uint8_t *dvxLoadImageFromMemory(const AppContextT *ctx, const uint8_t *data, int32_t dataLen, int32_t *outW, int32_t *outH, int32_t *outPitch);
-
-

Load an image from a memory buffer. Same output format as dvxLoadImage(). Caller must - free with dvxFreeImage().

-
-
ctx
Application context
-
data
Image data buffer
-
dataLen
Buffer size in bytes
-
outW, outH
Output: image dimensions
-
outPitch
Output: row pitch in bytes
-
-

Returns: Pixel buffer, or NULL on failure

-
-
- -
-
void dvxFreeImage(uint8_t *data);
-
-

Free a pixel buffer returned by dvxLoadImage() or dvxLoadImageFromMemory().

-
-
data
Buffer to free
-
-
-
- -
-
bool dvxImageInfo(const char *path, int32_t *outW, int32_t *outH);
-
-

Query image dimensions without decoding the full file.

-
-
path
Image file path
-
outW, outH
Output: image dimensions
-
-

Returns: true on success

-
-
- -
-
int32_t dvxSaveImage(const AppContextT *ctx, const uint8_t *data, int32_t w, int32_t h, int32_t pitch, const char *path);
-
-

Save native-format pixel data to a PNG file.

-
-
ctx
Application context
-
data
Pixel data in display native format
-
w, h
Image dimensions
-
pitch
Row pitch in bytes
-
path
Output file path
-
-

Returns: 0 on success, -1 on failure

-
-
- +

dvxLoadImage

+
uint8_t *dvxLoadImage(const AppContextT *ctx, const char *path, int32_t *outW, int32_t *outH, int32_t *outPitch);
+

Load an image file (BMP, PNG, JPEG, GIF) and convert to the display's native +pixel format. Caller must free with dvxFreeImage().

+
  Parameter     Description
+  ---------     -----------
+  ctx           Application context
+  path          Image file path
+  outW, outH    Output: image dimensions
+  outPitch      Output: row pitch in bytes
+

Returns: Pixel buffer, or NULL on failure.

+

dvxLoadImageFromMemory

+
uint8_t *dvxLoadImageFromMemory(const AppContextT *ctx, const uint8_t *data, int32_t dataLen, int32_t *outW, int32_t *outH, int32_t *outPitch);
+

Load an image from a memory buffer. Same output format as dvxLoadImage(). +Caller must free with dvxFreeImage().

+
  Parameter     Description
+  ---------     -----------
+  ctx           Application context
+  data          Image data buffer
+  dataLen       Buffer size in bytes
+  outW, outH    Output: image dimensions
+  outPitch      Output: row pitch in bytes
+

Returns: Pixel buffer, or NULL on failure.

+

dvxFreeImage

+
void dvxFreeImage(uint8_t *data);
+

Free a pixel buffer returned by dvxLoadImage() or dvxLoadImageFromMemory().

+
  Parameter   Description
+  ---------   -----------
+  data        Buffer to free
+

dvxImageInfo

+
bool dvxImageInfo(const char *path, int32_t *outW, int32_t *outH);
+

Query image dimensions without decoding the full file.

+
  Parameter     Description
+  ---------     -----------
+  path          Image file path
+  outW, outH    Output: image dimensions
+

Returns: true on success.

+

dvxSaveImage

+
int32_t dvxSaveImage(const AppContextT *ctx, const uint8_t *data, int32_t w, int32_t h, int32_t pitch, const char *path);
+

Save native-format pixel data to a PNG file.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  data        Pixel data in display native format
+  w, h        Image dimensions
+  pitch       Row pitch in bytes
+  path        Output file path
+

Returns: 0 on success, -1 on failure.

Screenshots

- -
-
int32_t dvxScreenshot(AppContextT *ctx, const char *path);
-
-

Save the entire screen (backbuffer contents) to a PNG file. Converts from native - pixel format to RGB.

-
-
ctx
Application context
-
path
Output PNG file path
-
-

Returns: 0 on success, -1 on failure

-
-
- -
-
int32_t dvxWindowScreenshot(AppContextT *ctx, WindowT *win, const char *path);
-
-

Save a window's content to a PNG file.

-
-
ctx
Application context
-
win
Window
-
path
Output PNG file path
-
-

Returns: 0 on success, -1 on failure

-
-
- +

dvxScreenshot

+
int32_t dvxScreenshot(AppContextT *ctx, const char *path);
+

Save the entire screen (backbuffer contents) to a PNG file. Converts from +native pixel format to RGB.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  path        Output PNG file path
+

Returns: 0 on success, -1 on failure.

+

dvxWindowScreenshot

+
int32_t dvxWindowScreenshot(AppContextT *ctx, WindowT *win, const char *path);
+

Save a window's content to a PNG file.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  win         Window
+  path        Output PNG file path
+

Returns: 0 on success, -1 on failure.

Clipboard

- -
-
void dvxClipboardCopy(const char *text, int32_t len);
-
-

Copy text to the process-wide clipboard buffer. Simple static buffer (not inter-process).

-
-
text
Text to copy
-
len
Length in bytes
-
-
-
- -
-
const char *dvxClipboardGet(int32_t *outLen);
-
-

Retrieve the current clipboard contents. Returns a pointer to the internal buffer - (valid until the next dvxClipboardCopy), or NULL if empty.

-
-
outLen
Output: length of clipboard text
-
-

Returns: Clipboard text, or NULL

-
-
- +

dvxClipboardCopy

+
void dvxClipboardCopy(const char *text, int32_t len);
+

Copy text to the process-wide clipboard buffer. Simple static buffer (not +inter-process).

+
  Parameter   Description
+  ---------   -----------
+  text        Text to copy
+  len         Length in bytes
+

dvxClipboardGet

+
const char *dvxClipboardGet(int32_t *outLen);
+

Retrieve the current clipboard contents. Returns a pointer to the internal +buffer (valid until the next dvxClipboardCopy), or NULL if empty.

+
  Parameter   Description
+  ---------   -----------
+  outLen      Output: length of clipboard text
+

Returns: Clipboard text, or NULL.

Resource Loading

- -
-
uint8_t *dvxResLoadIcon(AppContextT *ctx, const char *dxePath, const char *resName, int32_t *outW, int32_t *outH, int32_t *outPitch);
-
-

Load an icon/image resource from a DXE file and decode to native pixel format. - Caller must free with dvxFreeImage().

-
-
ctx
Application context
-
dxePath
Path to DXE file
-
resName
Resource name within the DXE
-
outW, outH
Output: image dimensions
-
outPitch
Output: row pitch
-
-

Returns: Pixel buffer, or NULL if not found

-
-
- -
-
bool dvxResLoadText(const char *dxePath, const char *resName, char *buf, int32_t bufSize);
-
-

Load a text resource from a DXE file into a caller-provided buffer. Null-terminated - and truncated to fit bufSize.

-
-
dxePath
Path to DXE file
-
resName
Resource name
-
buf
Output buffer
-
bufSize
Buffer capacity
-
-

Returns: true on success

-
-
- -
-
void *dvxResLoadData(const char *dxePath, const char *resName, uint32_t *outSize);
-
-

Load a raw binary resource from a DXE file. Returns a malloc'd buffer that the - caller must free.

-
-
dxePath
Path to DXE file
-
resName
Resource name
-
outSize
Output: data size in bytes
-
-

Returns: Data buffer, or NULL if not found

-
-
- +

dvxResLoadIcon

+
uint8_t *dvxResLoadIcon(AppContextT *ctx, const char *dxePath, const char *resName, int32_t *outW, int32_t *outH, int32_t *outPitch);
+

Load an icon/image resource from a DXE file and decode to native pixel +format. Caller must free with dvxFreeImage().

+
  Parameter     Description
+  ---------     -----------
+  ctx           Application context
+  dxePath       Path to DXE file
+  resName       Resource name within the DXE
+  outW, outH    Output: image dimensions
+  outPitch      Output: row pitch
+

Returns: Pixel buffer, or NULL if not found.

+

dvxResLoadText

+
bool dvxResLoadText(const char *dxePath, const char *resName, char *buf, int32_t bufSize);
+

Load a text resource from a DXE file into a caller-provided buffer. +Null-terminated and truncated to fit bufSize.

+
  Parameter   Description
+  ---------   -----------
+  dxePath     Path to DXE file
+  resName     Resource name
+  buf         Output buffer
+  bufSize     Buffer capacity
+

Returns: true on success.

+

dvxResLoadData

+
void *dvxResLoadData(const char *dxePath, const char *resName, uint32_t *outSize);
+

Load a raw binary resource from a DXE file. Returns a malloc'd buffer that +the caller must free.

+
  Parameter   Description
+  ---------   -----------
+  dxePath     Path to DXE file
+  resName     Resource name
+  outSize     Output: data size in bytes
+

Returns: Data buffer, or NULL if not found.

Utilities

- -
-
uint32_t dvxTextHash(const char *text);
-
-

Compute a djb2-xor hash for cheap dirty detection. Compare at save time with - the current hash to detect changes without a shadow copy. Not cryptographic.

-
-
text
Null-terminated string to hash
-
-

Returns: 32-bit hash value

+

dvxTextHash

+
uint32_t dvxTextHash(const char *text);
+

Compute a djb2-xor hash for cheap dirty detection. Compare at save time with +the current hash to detect changes without a shadow copy. Not cryptographic.

+
  Parameter   Description
+  ---------   -----------
+  text        Null-terminated string to hash
+

Returns: 32-bit hash value.

-
- -
- - - - - -
-

dvxWidget.h -- Widget System

-

- Retained-mode widget toolkit layered on the DVX window manager. Widgets form a tree - (parent-child) rooted at a per-window VBox container. Layout is automatic: measure - minimum sizes bottom-up, then allocate space top-down with flexbox-like weighted - distribution. Widget types are registered dynamically at runtime via DXE plugins. -

- +
+

dvxWidget.h -- Widget System

+

dvxWidget.h -- Widget System

+

Retained-mode widget toolkit layered on the DVX window manager. Widgets form +a tree (parent-child) rooted at a per-window VBox container. Layout is +automatic: measure minimum sizes bottom-up, then allocate space top-down +with flexbox-like weighted distribution. Widget types are registered +dynamically at runtime via DXE plugins.

WidgetT Structure

- -
-
WidgetT
-
- Core widget structure. Generic across all widget types; type-specific data lives in - the void *data pointer managed by each widget's DXE. -
-
int32_t type
Widget type ID (assigned by wgtRegisterClass)
-
const WidgetClassT *wclass
Vtable for this widget type
-
char name[MAX_WIDGET_NAME]
Widget name for lookup via wgtFind
-
parent, firstChild, lastChild, nextSibling
Tree linkage pointers
-
WindowT *window
Owning window
-
int32_t x, y, w, h
Computed geometry (relative to window content area)
-
int32_t calcMinW, calcMinH
Computed minimum size (from layout pass)
-
int32_t minW, minH, maxW, maxH, prefW, prefH
Size hints (tagged: wgtPixels/wgtChars/wgtPercent)
-
int32_t weight
Extra-space distribution weight (0 = fixed, 100 = normal)
-
WidgetAlignE align
Main-axis alignment for children
-
int32_t spacing, padding
Tagged sizes for child spacing and internal padding
-
uint32_t fgColor, bgColor
Custom colors (0 = use scheme defaults)
-
bool visible, enabled, readOnly
State flags
-
bool swallowTab
Tab key goes to widget, not focus navigation
-
char accelKey
Accelerator character (0 = none)
-
void *userData, *data
Application data and widget-private data
-
const char *tooltip
Tooltip text (NULL = none)
-
MenuT *contextMenu
Right-click menu (NULL = none)
-
-

Universal Callbacks:

-
-
onClick(WidgetT *w)
Widget clicked
-
onDblClick(WidgetT *w)
Widget double-clicked
-
onChange(WidgetT *w)
Value changed
-
onFocus(WidgetT *w)
Widget gained focus
-
onBlur(WidgetT *w)
Widget lost focus
-
onKeyPress(WidgetT *w, int32_t keyAscii)
ASCII key press
-
onKeyDown(WidgetT *w, int32_t keyCode, int32_t shift)
Key down
-
onKeyUp(WidgetT *w, int32_t keyCode, int32_t shift)
Key up
-
onMouseDown(WidgetT *w, int32_t button, int32_t x, int32_t y)
Mouse button pressed
-
onMouseUp(WidgetT *w, int32_t button, int32_t x, int32_t y)
Mouse button released
-
onMouseMove(WidgetT *w, int32_t button, int32_t x, int32_t y)
Mouse moved
-
onScroll(WidgetT *w, int32_t delta)
Mouse wheel
-
onValidate(WidgetT *w)
Return false to cancel a write
-
-
-
- +

Core widget structure. Generic across all widget types; type-specific data +lives in the void *data pointer managed by each widget's DXE.

+
  Field                                       Description
+  -----                                       -----------
+  int32_t type                                Widget type ID (assigned by wgtRegisterClass)
+  const WidgetClassT *wclass                  Vtable for this widget type
+  char name[MAX_WIDGET_NAME]                  Widget name for lookup via wgtFind
+  parent, firstChild, lastChild, nextSibling  Tree linkage pointers
+  WindowT *window                             Owning window
+  int32_t x, y, w, h                         Computed geometry (relative to content area)
+  int32_t calcMinW, calcMinH                  Computed minimum size (from layout pass)
+  int32_t minW, minH, maxW, maxH, prefW, prefH  Size hints (tagged sizes)
+  int32_t weight                              Extra-space distribution weight (0=fixed, 100=normal)
+  WidgetAlignE align                          Main-axis alignment for children
+  int32_t spacing, padding                    Tagged sizes for child spacing and padding
+  uint32_t fgColor, bgColor                   Custom colors (0 = use scheme defaults)
+  bool visible, enabled, readOnly             State flags
+  bool swallowTab                             Tab key goes to widget, not focus navigation
+  char accelKey                               Accelerator character (0 = none)
+  void *userData, *data                       Application data and widget-private data
+  const char *tooltip                         Tooltip text (NULL = none)
+  MenuT *contextMenu                          Right-click menu (NULL = none)
+

Universal Callbacks:

+
  Callback                                           Description
+  --------                                           -----------
+  onClick(WidgetT *w)                                Widget clicked
+  onDblClick(WidgetT *w)                             Widget double-clicked
+  onChange(WidgetT *w)                               Value changed
+  onFocus(WidgetT *w)                                Widget gained focus
+  onBlur(WidgetT *w)                                 Widget lost focus
+  onKeyPress(WidgetT *w, int32_t keyAscii)           ASCII key press
+  onKeyDown(WidgetT *w, int32_t keyCode, int32_t shift)  Key down
+  onKeyUp(WidgetT *w, int32_t keyCode, int32_t shift)    Key up
+  onMouseDown(WidgetT *w, int32_t btn, int32_t x, int32_t y)  Mouse button pressed
+  onMouseUp(WidgetT *w, int32_t btn, int32_t x, int32_t y)    Mouse button released
+  onMouseMove(WidgetT *w, int32_t btn, int32_t x, int32_t y)  Mouse moved
+  onScroll(WidgetT *w, int32_t delta)                Mouse wheel
+  onValidate(WidgetT *w)                             Return false to cancel a write

Size Specification Macros

- - - - - - -
MacroDescription
wgtPixels(v)Size in pixels
wgtChars(v)Size in character widths (multiplied by charWidth at layout time)
wgtPercent(v)Size as percentage of parent dimension
- +
  Macro            Description
+  -----            -----------
+  wgtPixels(v)     Size in pixels
+  wgtChars(v)      Size in character widths (multiplied by charWidth at layout)
+  wgtPercent(v)    Size as percentage of parent dimension

Widget Class Flags

- - - - - - - - - - - - - - - - -
FlagDescription
WCLASS_FOCUSABLECan receive keyboard focus (Tab navigation)
WCLASS_HORIZ_CONTAINERLays out children horizontally (vs. vertical)
WCLASS_PAINTS_CHILDRENWidget handles child rendering itself
WCLASS_NO_HIT_RECURSEHit testing stops here, no child recursion
WCLASS_FOCUS_FORWARDAccel hit forwards focus to next focusable sibling
WCLASS_HAS_POPUPHas dropdown popup overlay
WCLASS_SCROLLABLEAccepts mouse wheel events
WCLASS_SCROLL_CONTAINERScroll container (ScrollPane)
WCLASS_NEEDS_POLLNeeds periodic polling
WCLASS_SWALLOWS_TABTab key goes to widget, not focus navigation
WCLASS_RELAYOUT_ON_SCROLLFull relayout on scrollbar drag
WCLASS_PRESS_RELEASEClick = press + release (Button, ImageButton)
WCLASS_ACCEL_WHEN_HIDDENAccelerator matching works even when invisible
- +
  Flag                        Description
+  ----                        -----------
+  WCLASS_FOCUSABLE            Can receive keyboard focus (Tab navigation)
+  WCLASS_HORIZ_CONTAINER      Lays out children horizontally (vs. vertical)
+  WCLASS_PAINTS_CHILDREN      Widget handles child rendering itself
+  WCLASS_NO_HIT_RECURSE       Hit testing stops here, no child recursion
+  WCLASS_FOCUS_FORWARD        Accel hit forwards focus to next focusable sibling
+  WCLASS_HAS_POPUP            Has dropdown popup overlay
+  WCLASS_SCROLLABLE           Accepts mouse wheel events
+  WCLASS_SCROLL_CONTAINER     Scroll container (ScrollPane)
+  WCLASS_NEEDS_POLL           Needs periodic polling
+  WCLASS_SWALLOWS_TAB         Tab key goes to widget, not focus navigation
+  WCLASS_RELAYOUT_ON_SCROLL   Full relayout on scrollbar drag
+  WCLASS_PRESS_RELEASE        Click = press + release (Button, ImageButton)
+  WCLASS_ACCEL_WHEN_HIDDEN    Accelerator matching works even when invisible

Window Integration

- -
-
WidgetT *wgtInitWindow(AppContextT *ctx, WindowT *win);
-
-

Initialize the widget system for a window. Creates a root VBox container that fills - the content area, and installs callback handlers (onPaint, onMouse, onKey, onResize) - for widget-based event dispatch. The window's userData is set to the AppContextT pointer.

-
-
ctx
Application context
-
win
Window to initialize
-
-

Returns: Root VBox widget (add children to this)

-
-
- +

wgtInitWindow

+
WidgetT *wgtInitWindow(AppContextT *ctx, WindowT *win);
+

Initialize the widget system for a window. Creates a root VBox container +that fills the content area, and installs callback handlers (onPaint, +onMouse, onKey, onResize) for widget-based event dispatch. The window's +userData is set to the AppContextT pointer.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  win         Window to initialize
+

Returns: Root VBox widget (add children to this).

Widget Operations

- -
-
AppContextT *wgtGetContext(const WidgetT *w);
-
-

Walk from any widget up the tree to the root, then retrieve the AppContextT stored - in the window's userData. Lets any widget access the full application context.

-
-
w
Any widget in the tree
-
-

Returns: Pointer to the AppContextT

-
-
- -
-
void wgtInvalidate(WidgetT *w);
-
-

Mark a widget as needing both re-layout (measure + position) and repaint. Propagates - upward to ancestors. Use after structural changes (adding/removing children, text changes - that affect size).

-
-
w
Widget to invalidate
-
-
-
- -
-
void wgtInvalidatePaint(WidgetT *w);
-
-

Mark a widget as needing repaint only, without re-layout. Use for visual-only changes - (checkbox toggle, selection highlight, cursor blink).

-
-
w
Widget to repaint
-
-
-
- -
-
void wgtSetText(WidgetT *w, const char *text);
-
-

Set widget text content (dispatches to the widget class's SET_TEXT handler).

-
-
w
Widget
-
text
New text
-
-
-
- -
-
const char *wgtGetText(const WidgetT *w);
-
-

Get the widget's current text content.

-
-
w
Widget
-
-

Returns: Text string (empty string if no handler)

-
-
- -
-
void wgtSetEnabled(WidgetT *w, bool enabled);
-
-

Enable or disable a widget. Disabled widgets are grayed out and do not receive input.

-
-
w
Widget
-
enabled
true = enabled, false = disabled
-
-
-
- -
-
void wgtSetReadOnly(WidgetT *w, bool readOnly);
-
-

Set read-only mode. Allows scrolling and selection but blocks editing.

-
-
w
Widget
-
readOnly
true = read-only
-
-
-
- -
-
void wgtSetFocused(WidgetT *w);
-
-

Set keyboard focus to a widget.

-
-
w
Widget to focus
-
-
-
- -
-
WidgetT *wgtGetFocused(void);
-
-

Get the currently focused widget.

-

Returns: Focused widget, or NULL

-
-
- -
-
void wgtSetVisible(WidgetT *w, bool visible);
-
-

Show or hide a widget.

-
-
w
Widget
-
visible
true = visible, false = hidden
-
-
-
- -
-
void wgtSetName(WidgetT *w, const char *name);
-
-

Set a widget's name for lookup via wgtFind().

-
-
w
Widget
-
name
Name string (max MAX_WIDGET_NAME chars)
-
-
-
- -
-
WidgetT *wgtFind(WidgetT *root, const char *name);
-
-

Find a widget by name. Searches the subtree rooted at root.

-
-
root
Root of subtree to search
-
name
Widget name to find
-
-

Returns: Matching widget, or NULL

-
-
- -
-
void wgtDestroy(WidgetT *w);
-
-

Destroy a widget and all its children. Removes from parent's child list.

-
-
w
Widget to destroy
-
-
-
- -
-
void wgtSetTooltip(WidgetT *w, const char *text);
-
-

Set tooltip text for a widget. Pass NULL to remove. Caller owns the string and it - must outlive the widget.

-
-
w
Widget
-
text
Tooltip text, or NULL
-
-
-
- -
-
void widgetOnResize(WindowT *win, int32_t newW, int32_t newH);
-
-

Default window resize handler installed by wgtInitWindow(). Re-evaluates scrollbars - and relayouts the widget tree. Call from custom onResize handlers to chain to the - widget system.

-
-
win
Window being resized
-
newW, newH
New content dimensions
-
-
-
- +

wgtGetContext

+
AppContextT *wgtGetContext(const WidgetT *w);
+

Walk from any widget up the tree to the root, then retrieve the AppContextT +stored in the window's userData. Lets any widget access the full application +context.

+
  Parameter   Description
+  ---------   -----------
+  w           Any widget in the tree
+

Returns: Pointer to the AppContextT.

+

wgtInvalidate

+
void wgtInvalidate(WidgetT *w);
+

Mark a widget as needing both re-layout (measure + position) and repaint. +Propagates upward to ancestors. Use after structural changes +(adding/removing children, text changes that affect size).

+
  Parameter   Description
+  ---------   -----------
+  w           Widget to invalidate
+

wgtInvalidatePaint

+
void wgtInvalidatePaint(WidgetT *w);
+

Mark a widget as needing repaint only, without re-layout. Use for +visual-only changes (checkbox toggle, selection highlight, cursor blink).

+
  Parameter   Description
+  ---------   -----------
+  w           Widget to repaint
+

wgtSetText

+
void wgtSetText(WidgetT *w, const char *text);
+

Set widget text content (dispatches to the widget class's SET_TEXT handler).

+
  Parameter   Description
+  ---------   -----------
+  w           Widget
+  text        New text
+

wgtGetText

+
const char *wgtGetText(const WidgetT *w);
+

Get the widget's current text content.

+
  Parameter   Description
+  ---------   -----------
+  w           Widget
+

Returns: Text string (empty string if no handler).

+

wgtSetEnabled

+
void wgtSetEnabled(WidgetT *w, bool enabled);
+

Enable or disable a widget. Disabled widgets are grayed out and do not +receive input.

+
  Parameter   Description
+  ---------   -----------
+  w           Widget
+  enabled     true = enabled, false = disabled
+

wgtSetReadOnly

+
void wgtSetReadOnly(WidgetT *w, bool readOnly);
+

Set read-only mode. Allows scrolling and selection but blocks editing.

+
  Parameter   Description
+  ---------   -----------
+  w           Widget
+  readOnly    true = read-only
+

wgtSetFocused

+
void wgtSetFocused(WidgetT *w);
+

Set keyboard focus to a widget.

+
  Parameter   Description
+  ---------   -----------
+  w           Widget to focus
+

wgtGetFocused

+
WidgetT *wgtGetFocused(void);
+

Get the currently focused widget.

+

Returns: Focused widget, or NULL.

+

wgtSetVisible

+
void wgtSetVisible(WidgetT *w, bool visible);
+

Show or hide a widget.

+
  Parameter   Description
+  ---------   -----------
+  w           Widget
+  visible     true = visible, false = hidden
+

wgtSetName

+
void wgtSetName(WidgetT *w, const char *name);
+

Set a widget's name for lookup via wgtFind().

+
  Parameter   Description
+  ---------   -----------
+  w           Widget
+  name        Name string (max MAX_WIDGET_NAME chars)
+

wgtFind

+
WidgetT *wgtFind(WidgetT *root, const char *name);
+

Find a widget by name. Searches the subtree rooted at root.

+
  Parameter   Description
+  ---------   -----------
+  root        Root of subtree to search
+  name        Widget name to find
+

Returns: Matching widget, or NULL.

+

wgtDestroy

+
void wgtDestroy(WidgetT *w);
+

Destroy a widget and all its children. Removes from parent's child list.

+
  Parameter   Description
+  ---------   -----------
+  w           Widget to destroy
+

wgtSetTooltip

+
void wgtSetTooltip(WidgetT *w, const char *text);
+

Set tooltip text for a widget. Pass NULL to remove. Caller owns the string +and it must outlive the widget.

+
  Parameter   Description
+  ---------   -----------
+  w           Widget
+  text        Tooltip text, or NULL
+

widgetOnResize

+
void widgetOnResize(WindowT *win, int32_t newW, int32_t newH);
+

Default window resize handler installed by wgtInitWindow(). Re-evaluates +scrollbars and relayouts the widget tree. Call from custom onResize handlers +to chain to the widget system.

+
  Parameter    Description
+  ---------    -----------
+  win          Window being resized
+  newW, newH   New content dimensions

Layout

- -
-
int32_t wgtResolveSize(int32_t taggedSize, int32_t parentSize, int32_t charWidth);
-
-

Decode a tagged size value (WGT_SIZE_PIXELS/CHARS/PERCENT) into a concrete pixel count. - Returns 0 for a raw 0 input (meaning "auto").

-
-
taggedSize
Tagged size value
-
parentSize
Parent dimension (for PERCENT mode)
-
charWidth
Font character width (for CHARS mode)
-
-

Returns: Size in pixels

-
-
- -
-
void wgtLayout(WidgetT *root, int32_t availW, int32_t availH, const BitmapFontT *font);
-
-

Execute the full two-pass layout algorithm. Pass 1 (bottom-up): compute minimum sizes. - Pass 2 (top-down): allocate space with weighted distribution. Normally called automatically; - exposed for cases where layout must be forced before the next paint.

-
-
root
Root widget
-
availW, availH
Available space
-
font
Bitmap font (for character-based sizing)
-
-
-
- -
-
void wgtPaint(WidgetT *root, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors);
-
-

Paint the entire widget tree by depth-first traversal. Each widget's clip rect is set - to its bounds. Overlays (popups, tooltips) are painted in a second pass on top.

-
-
root
Root widget
-
d
Display context
-
ops
Blit operations vtable
-
font
Bitmap font
-
colors
Color scheme
-
-
-
- +

wgtResolveSize

+
int32_t wgtResolveSize(int32_t taggedSize, int32_t parentSize, int32_t charWidth);
+

Decode a tagged size value (WGT_SIZE_PIXELS/CHARS/PERCENT) into a concrete +pixel count. Returns 0 for a raw 0 input (meaning "auto").

+
  Parameter     Description
+  ---------     -----------
+  taggedSize    Tagged size value
+  parentSize    Parent dimension (for PERCENT mode)
+  charWidth     Font character width (for CHARS mode)
+

Returns: Size in pixels.

+

wgtLayout

+
void wgtLayout(WidgetT *root, int32_t availW, int32_t availH, const BitmapFontT *font);
+

Execute the full two-pass layout algorithm. Pass 1 (bottom-up): compute +minimum sizes. Pass 2 (top-down): allocate space with weighted distribution. +Normally called automatically; exposed for cases where layout must be forced +before the next paint.

+
  Parameter     Description
+  ---------     -----------
+  root          Root widget
+  availW/H      Available space
+  font          Bitmap font (for character-based sizing)
+

wgtPaint

+
void wgtPaint(WidgetT *root, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors);
+

Paint the entire widget tree by depth-first traversal. Each widget's clip +rect is set to its bounds. Overlays (popups, tooltips) are painted in a +second pass on top.

+
  Parameter   Description
+  ---------   -----------
+  root        Root widget
+  d           Display context
+  ops         Blit operations vtable
+  font        Bitmap font
+  colors      Color scheme

Debug

- -
-
void wgtSetDebugLayout(AppContextT *ctx, bool enabled);
-
-

Draw colored borders around layout containers for debugging.

-
-
ctx
Application context
-
enabled
true = draw debug borders
-
-
-
- +

wgtSetDebugLayout

+
void wgtSetDebugLayout(AppContextT *ctx, bool enabled);
+

Draw colored borders around layout containers for debugging.

+
  Parameter   Description
+  ---------   -----------
+  ctx         Application context
+  enabled     true = draw debug borders

Dynamic Widget Registration

- -
-
int32_t wgtRegisterClass(const WidgetClassT *wclass);
-
-

Register a new widget class at runtime. Appends to widgetClassTable. The WidgetClassT - must remain valid for the lifetime of the process (typically static const in a DXE).

-
-
wclass
Widget class vtable to register
-
-

Returns: Assigned type ID

-
-
- -
-
void wgtRegisterApi(const char *name, const void *api);
-
-

Register a widget API struct under a name. Each widget DXE registers its API during - initialization. Callers retrieve it via wgtGetApi() and cast to the widget-specific type.

-
-
name
Widget type name (e.g. "button", "listbox")
-
api
Pointer to the widget's API struct
-
-
-
- -
-
const void *wgtGetApi(const char *name);
-
-

Retrieve a registered widget API struct by name.

-
-
name
Widget type name
-
-

Returns: Pointer to the API struct, or NULL if not found

-
-
- +

wgtRegisterClass

+
int32_t wgtRegisterClass(const WidgetClassT *wclass);
+

Register a new widget class at runtime. Appends to widgetClassTable. The +WidgetClassT must remain valid for the lifetime of the process (typically +static const in a DXE).

+
  Parameter   Description
+  ---------   -----------
+  wclass      Widget class vtable to register
+

Returns: Assigned type ID.

+

wgtRegisterApi

+
void wgtRegisterApi(const char *name, const void *api);
+

Register a widget API struct under a name. Each widget DXE registers its API +during initialization. Callers retrieve it via wgtGetApi() and cast to the +widget-specific type.

+
  Parameter   Description
+  ---------   -----------
+  name        Widget type name (e.g. "button", "listbox")
+  api         Pointer to the widget's API struct
+

wgtGetApi

+
const void *wgtGetApi(const char *name);
+

Retrieve a registered widget API struct by name.

+
  Parameter   Description
+  ---------   -----------
+  name        Widget type name
+

Returns: Pointer to the API struct, or NULL if not found.

Widget Interface Descriptors

- -
-
void wgtRegisterIface(const char *name, const WgtIfaceT *iface);
-
-

Register an interface descriptor for a widget type. Used by the BASIC form runtime and - IDE for generic property/method dispatch.

-
-
name
Widget type name
-
iface
Interface descriptor
-
+

wgtRegisterIface

+
void wgtRegisterIface(const char *name, const WgtIfaceT *iface);
+

Register an interface descriptor for a widget type. Used by the BASIC form +runtime and IDE for generic property/method dispatch.

+
  Parameter   Description
+  ---------   -----------
+  name        Widget type name
+  iface       Interface descriptor
+

wgtGetIface

+
const WgtIfaceT *wgtGetIface(const char *name);
+

Retrieve an interface descriptor by widget type name.

+
  Parameter   Description
+  ---------   -----------
+  name        Widget type name
+

Returns: Interface descriptor, or NULL.

+

wgtFindByBasName

+
const char *wgtFindByBasName(const char *basName);
+

Find a widget type name by its VB-style name (e.g. "CommandButton" -> +"button"). Case-insensitive search.

+
  Parameter   Description
+  ---------   -----------
+  basName     VB-style widget name
+

Returns: Internal type name, or NULL.

+

wgtIfaceCount

+
int32_t wgtIfaceCount(void);
+

Return the number of registered widget interfaces.

+

Returns: Count of registered interfaces.

+

wgtIfaceAt

+
const WgtIfaceT *wgtIfaceAt(int32_t idx, const char **outName);
+

Get a registered widget interface by index.

+
  Parameter   Description
+  ---------   -----------
+  idx         Index (0-based)
+  outName     Output: type name
+

Returns: Interface descriptor.

+

wgtIfaceGetPath

+
const char *wgtIfaceGetPath(const char *name);
+

Get the .wgt DXE file path for a registered widget.

+
  Parameter   Description
+  ---------   -----------
+  name        Widget type name
+

Returns: File path string.

+

wgtIfaceSetPath

+
void wgtIfaceSetPath(const char *name, const char *path);
+

Set the .wgt DXE file path for a registered widget (called by the loader).

+
  Parameter   Description
+  ---------   -----------
+  name        Widget type name
+  path        DXE file path
+

wgtIfaceGetPathIndex

+
int32_t wgtIfaceGetPathIndex(const char *name);
+

Get the 1-based index of this widget within its .wgt file. Used to construct +suffixed resource names (e.g. "name-2", "icon16-2").

+
  Parameter   Description
+  ---------   -----------
+  name        Widget type name
+

Returns: 1-based index within the DXE file.

+

Typed Dispatch Helpers

+

The following inline functions provide type-safe dispatch through the +WidgetClassT handler table. Each checks for a non-NULL handler before +calling.

+
  Function                                Method ID                          Description
+  --------                                ---------                          -----------
+  wclsHas(w, methodId)                    --                                 Check if handler exists
+  wclsPaint(w, d, ops, font, colors)      WGT_METHOD_PAINT                   Paint the widget
+  wclsPaintOverlay(w, d, ops, font, colors) WGT_METHOD_PAINT_OVERLAY         Paint overlay (popups)
+  wclsCalcMinSize(w, font)                WGT_METHOD_CALC_MIN_SIZE           Compute minimum size
+  wclsLayout(w, font)                     WGT_METHOD_LAYOUT                  Layout children
+  wclsGetLayoutMetrics(w, font, ...)      WGT_METHOD_GET_LAYOUT_METRICS      Get pad, gap, extraTop, borderW
+  wclsOnMouse(w, root, vx, vy)           WGT_METHOD_ON_MOUSE                Handle mouse event
+  wclsOnKey(w, key, mod)                  WGT_METHOD_ON_KEY                  Handle key event
+  wclsOnAccelActivate(w, root)            WGT_METHOD_ON_ACCEL_ACTIVATE       Handle accelerator
+  wclsDestroy(w)                          WGT_METHOD_DESTROY                 Destroy widget data
+  wclsOnChildChanged(parent, child)       WGT_METHOD_ON_CHILD_CHANGED        Notify parent of change
+  wclsGetText(w)                          WGT_METHOD_GET_TEXT                Get widget text
+  wclsSetText(w, text)                    WGT_METHOD_SET_TEXT                Set widget text
+  wclsClearSelection(w)                   WGT_METHOD_CLEAR_SELECTION         Clear text selection
+  wclsClosePopup(w)                       WGT_METHOD_CLOSE_POPUP             Close dropdown popup
+  wclsGetPopupRect(w, font, ...)          WGT_METHOD_GET_POPUP_RECT          Get popup screen rect
+  wclsOnDragUpdate(w, root, x, y)         WGT_METHOD_ON_DRAG_UPDATE          Update during drag
+  wclsOnDragEnd(w, root, x, y)            WGT_METHOD_ON_DRAG_END             End drag operation
+  wclsGetCursorShape(w, vx, vy)           WGT_METHOD_GET_CURSOR_SHAPE        Get cursor for position
+  wclsPoll(w, win)                        WGT_METHOD_POLL                    Periodic polling
+  wclsQuickRepaint(w, outY, outH)         WGT_METHOD_QUICK_REPAINT           Fast partial repaint
+  wclsScrollChildIntoView(parent, child)  WGT_METHOD_SCROLL_CHILD_INTO_VIEW  Scroll child visible
-
- -
-
const WgtIfaceT *wgtGetIface(const char *name);
-
-

Retrieve an interface descriptor by widget type name.

-
-
name
Widget type name
-
-

Returns: Interface descriptor, or NULL

-
-
- -
-
const char *wgtFindByBasName(const char *basName);
-
-

Find a widget type name by its VB-style name (e.g. "CommandButton" -> "button"). - Case-insensitive search.

-
-
basName
VB-style widget name
-
-

Returns: Internal type name, or NULL

-
-
- -
-
int32_t wgtIfaceCount(void);
-
-

Return the number of registered widget interfaces.

-

Returns: Count of registered interfaces

-
-
- -
-
const WgtIfaceT *wgtIfaceAt(int32_t idx, const char **outName);
-
-

Get a registered widget interface by index.

-
-
idx
Index (0-based)
-
outName
Output: type name
-
-

Returns: Interface descriptor

-
-
- -
-
const char *wgtIfaceGetPath(const char *name);
-
-

Get the .wgt DXE file path for a registered widget.

-
-
name
Widget type name
-
-

Returns: File path string

-
-
- -
-
void wgtIfaceSetPath(const char *name, const char *path);
-
-

Set the .wgt DXE file path for a registered widget (called by the loader).

-
-
name
Widget type name
-
path
DXE file path
-
-
-
- -
-
int32_t wgtIfaceGetPathIndex(const char *name);
-
-

Get the 1-based index of this widget within its .wgt file. Used to construct suffixed - resource names (e.g. "name-2", "icon16-2").

-
-
name
Widget type name
-
-

Returns: 1-based index within the DXE file

-
-
- -

Typed Dispatch Helpers (Inline)

- -

The following inline functions provide type-safe dispatch through the WidgetClassT -handler table. Each checks for a non-NULL handler before calling.

- - - - - - - - - - - - - - - - - - - - - - - - - -
FunctionMethod IDDescription
wclsHas(w, methodId)--Check if a handler exists for the given method ID
wclsPaint(w, d, ops, font, colors)WGT_METHOD_PAINTPaint the widget
wclsPaintOverlay(w, d, ops, font, colors)WGT_METHOD_PAINT_OVERLAYPaint overlay (popups, dropdowns)
wclsCalcMinSize(w, font)WGT_METHOD_CALC_MIN_SIZECompute minimum size
wclsLayout(w, font)WGT_METHOD_LAYOUTLayout children
wclsGetLayoutMetrics(w, font, ...)WGT_METHOD_GET_LAYOUT_METRICSGet pad, gap, extraTop, borderW
wclsOnMouse(w, root, vx, vy)WGT_METHOD_ON_MOUSEHandle mouse event
wclsOnKey(w, key, mod)WGT_METHOD_ON_KEYHandle key event
wclsOnAccelActivate(w, root)WGT_METHOD_ON_ACCEL_ACTIVATEHandle accelerator activation
wclsDestroy(w)WGT_METHOD_DESTROYDestroy widget-private data
wclsOnChildChanged(parent, child)WGT_METHOD_ON_CHILD_CHANGEDNotify parent of child change
wclsGetText(w)WGT_METHOD_GET_TEXTGet widget text
wclsSetText(w, text)WGT_METHOD_SET_TEXTSet widget text
wclsClearSelection(w)WGT_METHOD_CLEAR_SELECTIONClear text selection
wclsClosePopup(w)WGT_METHOD_CLOSE_POPUPClose dropdown popup
wclsGetPopupRect(w, font, ...)WGT_METHOD_GET_POPUP_RECTGet popup screen rect
wclsOnDragUpdate(w, root, x, y)WGT_METHOD_ON_DRAG_UPDATEUpdate during drag
wclsOnDragEnd(w, root, x, y)WGT_METHOD_ON_DRAG_ENDEnd drag operation
wclsGetCursorShape(w, vx, vy)WGT_METHOD_GET_CURSOR_SHAPEGet cursor shape for position
wclsPoll(w, win)WGT_METHOD_POLLPeriodic polling (comms, etc.)
wclsQuickRepaint(w, outY, outH)WGT_METHOD_QUICK_REPAINTFast partial repaint
wclsScrollChildIntoView(parent, child)WGT_METHOD_SCROLL_CHILD_INTO_VIEWScroll to make child visible
- -
- -
- -
- DVX GUI API Reference -- Generated from source headers in core/*.h -
- +
diff --git a/docs/dvx_architecture.html b/docs/dvx_architecture.html index 22a71bf..2035eab 100644 --- a/docs/dvx_architecture.html +++ b/docs/dvx_architecture.html @@ -1,195 +1,180 @@ - + - DVX Architecture Overview - + +
+

DVX Architecture Overview

-

DOS Visual eXecutive -- A Windowing GUI for DJGPP/DPMI

- -
-Contents +

DVX Architecture Overview

+

DOS Visual eXecutive -- A Windowing GUI for DJGPP/DPMI

+

DVX (DOS Visual eXecutive) is a complete windowing GUI compositor targeting +DJGPP/DPMI on DOS. It provides overlapping windows with Motif-style chrome, +a retained-mode widget toolkit, cooperative multitasking of DXE-loaded +applications, and a dirty-rectangle compositor optimized for 486/Pentium +hardware.

+

Key Design Constraints

+

No external font or cursor files -- all bitmaps are compiled in as static +const data.

+

The runtime environment consists of a bootstrap loader (dvx.exe) that loads +core DXE libraries, widget plugins, and the shell, which in turn loads and +manages DXE application modules.

+

Contents

+
    +
  • .link arch.overview System Overview
  • +
  • .link arch.layers Five-Layer Architecture
  • +
  • .link arch.pipeline Display Pipeline
  • +
  • .link arch.windows Window System
  • +
  • .link arch.widgets Widget System
  • +
  • .link arch.dxe DXE Module System
  • +
  • .link arch.events Event Model
  • +
  • .link arch.fonts Font System
  • +
  • .link arch.colors Color System
  • +
  • .link arch.platform Platform Layer
  • +
+

.link arch.build Build System

- - -

1. System Overview

- -

-DVX (DOS Visual eXecutive) is a complete windowing GUI compositor targeting -DJGPP/DPMI on DOS. It provides overlapping windows with -Motif-style chrome, a retained-mode widget toolkit, cooperative multitasking -of DXE-loaded applications, and a dirty-rectangle compositor optimized for -486/Pentium hardware. -

- -

Key design constraints:

-
    -
  • VESA VBE 2.0+ LFB only -- no bank switching. If the - hardware cannot provide a linear framebuffer, initialization fails.
  • -
  • 486 baseline -- all hot paths are written to be fast on - a 486, with Pentium-specific paths where the gain is significant.
  • -
  • Single-tasking cooperative model -- applications yield - the CPU via tsYield(); there is no preemptive scheduler.
  • -
  • 86Box is the trusted reference platform for testing. - DOSBox-X is not used; any bugs observed are treated as DVX bugs.
  • -
  • No external font or cursor files -- all bitmaps are - compiled in as static const data.
  • -
- -

The runtime environment consists of a bootstrap loader -(dvx.exe) that loads core DXE libraries, widget plugins, and -the shell, which in turn loads and manages DXE application modules.

- - -

2. Five-Layer Architecture

- -

DVX is organized into five layers, each implemented as a single -.h/.c pair. Every header includes -dvxTypes.h (the shared type definitions) to avoid circular -dependencies. The layers are strictly stacked: each layer depends only on the -layers below it.

- -
-

- Applications (DXE .app modules)
+
+

Five-Layer Architecture

+

Five-Layer Architecture

+

DVX is organized into five layers, each implemented as a single .h/.c pair. +Every header includes dvxTypes.h (the shared type definitions) to avoid +circular dependencies. The layers are strictly stacked: each layer depends +only on the layers below it.

+
 Applications (DXE .app modules)
  ==================================================
  |                                                |
  |  +------------------------------------------+  |
@@ -218,71 +203,27 @@ layers below it.

| | Shared Types (dvxTypes.h) | | | | DisplayT, WindowT, RectT, ColorSchemeT | | | +------------------------------------------+ | - ================================================== -
+ ==================================================
+

Layer Summary

+
  Layer               Header         Responsibility
+  -----               ------         --------------
+  1 - Video           dvxVideo.h     VESA VBE mode negotiation, LFB mapping via DPMI, backbuffer allocation, packColor() (RGB to native pixel format), display-wide clip rectangle.
+  2 - Draw            dvxDraw.h      All 2D drawing: rectFill, rectCopy, drawBevel, drawText/drawTextN, drawMaskedBitmap (cursor), drawTermRow (batch terminal row). Stateless beyond clip rect. Dispatches hot inner loops through BlitOpsT function pointers.
+  3 - Compositor      dvxComp.h      Dirty rectangle tracking (dirtyListAdd), pairwise merge of overlapping rects (dirtyListMerge), and flushRect to copy dirty regions from backBuf to LFB.
+  4 - Window Manager  dvxWm.h        Window lifecycle, Z-order stack, chrome drawing (title bars, bevels, close/minimize/maximize gadgets), hit testing, drag/resize, menu bars, scrollbars, system menu, keyboard move/resize, minimized icon bar.
+  5 - Application     dvxApp.h       Public API aggregating all layers into AppContextT. Provides dvxInit/dvxShutdown, dvxRun/dvxUpdate, window creation helpers, image loading, clipboard, accelerator tables, theme management, wallpaper, video mode switching, screenshot capture.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LayerHeaderResponsibility
1 - VideodvxVideo.hVESA VBE mode negotiation, LFB mapping via DPMI, backbuffer - allocation, packColor() (RGB to native pixel format), - display-wide clip rectangle.
2 - DrawdvxDraw.hAll 2D drawing operations: rectFill, rectCopy, - drawBevel, drawText/drawTextN, - drawMaskedBitmap (cursor), drawTermRow - (batch terminal row rendering). Stateless beyond the clip rect on - DisplayT. Dispatches hot inner loops through BlitOpsT - function pointers.
3 - CompositordvxComp.hDirty rectangle tracking (dirtyListAdd), pairwise merge - of overlapping rects (dirtyListMerge), and the - flushRect function that copies dirty regions from the - system RAM backbuffer to the LFB.
4 - Window ManagerdvxWm.hWindow lifecycle, Z-order stack, chrome drawing (title bars, bevels, - close/minimize/maximize gadgets), hit testing, drag/resize, menu bars, - scrollbars, system menu, keyboard move/resize mode, minimized icon - bar.
5 - ApplicationdvxApp.hPublic API aggregating all layers into AppContextT. - Provides dvxInit/dvxShutdown, - dvxRun/dvxUpdate, window creation - helpers, image loading, clipboard, accelerator tables, theme - management, wallpaper, video mode switching, screenshot capture.
- - -

3. Display Pipeline

- -

The double-buffer strategy is the single most important performance -decision in DVX. All drawing goes to a system RAM backbuffer -(DisplayT.backBuf); only dirty rectangles are flushed to the -linear framebuffer (DisplayT.lfb) in video -memory.

- -

This matters because writes to video memory over the PCI bus are -10-50x slower than writes to main RAM on 486/Pentium hardware for -random-access patterns.

- +
+

Display Pipeline

+

Display Pipeline

+

The double-buffer strategy is the single most important performance decision +in DVX. All drawing goes to a system RAM backbuffer (DisplayT.backBuf); only +dirty rectangles are flushed to the linear framebuffer (DisplayT.lfb) in +video memory.

+

This matters because writes to video memory over the PCI bus are 10-50x +slower than writes to main RAM on 486/Pentium hardware for random-access +patterns.

Per-Frame Compositing Pipeline

-
  1. Input poll (mouse, keyboard)
          |
   2. Event dispatch (focus window callbacks)
@@ -303,84 +244,54 @@ random-access patterns.

| 6. flushRect() -- copy each dirty rect from backBuf to LFB | - 7. Yield (platformYield) -
- + 7. Yield (platformYield)

Key Data Structures

- -
-
DisplayT
-
Central display context: width, height, pitch, pixel format, LFB pointer, - backbuffer pointer, palette, clip rectangle. Passed by pointer through - every layer -- no globals.
- -
BlitOpsT
-
Vtable of span fill/copy function pointers resolved at init time for the - active pixel depth. On DOS these dispatch to hand-written rep stosl - / rep movsd asm inner loops.
- -
DirtyListT
-
Fixed-capacity dynamic array of RectT. Linear scanning for - merge candidates is cache-friendly at typical sizes (under 128 rects). - If the list fills up, the compositor merges aggressively or falls back to - full-screen repaint.
-
- +

DisplayT -- Central display context: width, height, pitch, pixel format, LFB +pointer, backbuffer pointer, palette, clip rectangle. Passed by pointer +through every layer -- no globals.

+

BlitOpsT -- Vtable of span fill/copy function pointers resolved at init time +for the active pixel depth. On DOS these dispatch to hand-written rep stosl +/ rep movsd asm inner loops.

+

DirtyListT -- Fixed-capacity dynamic array of RectT. Linear scanning for +merge candidates is cache-friendly at typical sizes (under 128 rects). If +the list fills up, the compositor merges aggressively or falls back to +full-screen repaint.

Why This Works on a 486

    -
  • A full 640x480x32bpp frame is 1.2 MB -- far too much to flush every - frame over a slow PCI bus.
  • -
  • A typical dirty region during normal interaction (typing, menu open) - is a few KB.
  • -
  • Merging overlapping dirty rects into larger rects reduces per-rect - overhead and improves bus utilization.
  • -
  • Per-window content buffers persist across frames, so windows don't - repaint on expose -- only when their own content changes.
  • +
  • A full 640x480x32bpp frame is 1.2 MB -- far too much to flush every frame + over a slow PCI bus.
  • +
  • A typical dirty region during normal interaction (typing, menu open) is a + few KB.
  • +
  • Merging overlapping dirty rects into larger rects reduces per-rect + overhead and improves bus utilization.
- - -

4. Window System

- +

Per-window content buffers persist across frames, so windows don't repaint +on expose -- only when their own content changes.

+
+
+

Window System

+

Window System

WindowT Structure

- -

Each WindowT is the central object of the window manager. Key -fields:

- - - - - - - - - - - - - - - -
Field GroupPurpose
Geometry (x, y, w, h)Outer frame rectangle (including chrome).
Content area (contentX/Y/W/H)Computed from frame minus chrome. Where application content lives.
Content buffer (contentBuf, contentPitch)Per-window backbuffer in native pixel format. Persists across frames.
Chrome state (menuBar, vScroll, hScroll)Optional menu bar and scrollbars. Affect content area computation.
Widget tree (widgetRoot)Root of the retained-mode widget tree (NULL if using raw callbacks).
CallbacksonPaint, onKey, onKeyUp, - onMouse, - onResize, onClose, onMenu, - onScroll, onFocus, onBlur, - onCursorQuery.
- +

Each WindowT is the central object of the window manager. Key fields:

+
  Field Group                              Purpose
+  -----------                              -------
+  Geometry (x, y, w, h)                   Outer frame rectangle (including chrome).
+  Content area (contentX/Y/W/H)           Computed from frame minus chrome. Where application content lives.
+  Content buffer (contentBuf, contentPitch) Per-window backbuffer in native pixel format. Persists across frames.
+  Chrome state (menuBar, vScroll, hScroll) Optional menu bar and scrollbars. Affect content area computation.
+  Widget tree (widgetRoot)                 Root of the retained-mode widget tree (NULL if using raw callbacks).
+  Callbacks                                onPaint, onKey, onKeyUp, onMouse, onResize, onClose, onMenu, onScroll, onFocus, onBlur, onCursorQuery.

Window Stack (Z-Order)

- -

WindowStackT is an array of WindowT* ordered -front-to-back: index count-1 is the topmost window. This allows:

+

WindowStackT is an array of WindowT* ordered front-to-back: index count-1 is +the topmost window. This allows:

    -
  • Back-to-front iteration for painting (painter's algorithm).
  • -
  • Front-to-back iteration for hit testing (first hit wins).
  • -
  • Reordering by pointer swap (no copying of large WindowT structs).
  • +
  • Back-to-front iteration for painting (painter's algorithm).
  • +
  • Front-to-back iteration for hit testing (first hit wins).
- +

Reordering by pointer swap (no copying of large WindowT structs).

Only one drag/resize/scroll operation can be active system-wide at a time (single mouse), so that state lives on the stack, not on individual windows.

-

Chrome Layout

-
  +-------------------------------------------+
   |  4px outer border (raised bevel)          |
   |  +-------------------------------------+  |
@@ -399,207 +310,137 @@ front-to-back: index count-1 is the topmost window. This allows:

- + +-------------------------------------------+

Chrome constants are compile-time defines:

  CHROME_BORDER_WIDTH   = 4px
   CHROME_TITLE_HEIGHT   = 20px
   CHROME_INNER_BORDER   = 2px
   CHROME_MENU_HEIGHT    = 20px
   SCROLLBAR_WIDTH       = 16px
-  CHROME_CLOSE_BTN_SIZE = 16px
-
- + CHROME_CLOSE_BTN_SIZE = 16px

Hit Test Regions

-

-wmHitTest() iterates the stack front-to-back and returns a -hit-part identifier: HIT_CONTENT, HIT_TITLE, -HIT_CLOSE, HIT_RESIZE, HIT_MENU, -HIT_VSCROLL, HIT_HSCROLL, -HIT_MINIMIZE, HIT_MAXIMIZE. -Resize edge detection returns a bitmask of RESIZE_LEFT, -RESIZE_RIGHT, RESIZE_TOP, -RESIZE_BOTTOM (corners combine two edges). -

- +

wmHitTest() iterates the stack front-to-back and returns a hit-part +identifier: HIT_CONTENT, HIT_TITLE, HIT_CLOSE, HIT_RESIZE, HIT_MENU, +HIT_VSCROLL, HIT_HSCROLL, HIT_MINIMIZE, HIT_MAXIMIZE. Resize edge detection +returns a bitmask of RESIZE_LEFT, RESIZE_RIGHT, RESIZE_TOP, RESIZE_BOTTOM +(corners combine two edges).

Menu System

-

-Menus use fixed-size arrays with inline char buffers (no heap -strings). Up to 8 menus per bar, items dynamically allocated. Supports -cascading submenus via MenuItemT.subMenu pointer. Item types: -normal, checkbox, radio. Separators are non-interactive items. The popup -state (PopupStateT) tracks a stack of parent frames for -cascading submenu nesting. -

- +

Menus use fixed-size arrays with inline char buffers (no heap strings). Up +to 8 menus per bar, items dynamically allocated. Supports cascading submenus +via MenuItemT.subMenu pointer. Item types: normal, checkbox, radio. +Separators are non-interactive items. The popup state (PopupStateT) tracks a +stack of parent frames for cascading submenu nesting.

Minimized Windows

-

-Minimized windows display as 64x64 icons at the bottom of the screen with +

Minimized windows display as 64x64 icons at the bottom of the screen with beveled borders, similar to a classic desktop icon bar. Icons show a scaled-down preview of the window's content buffer, refreshed one per frame -in a round-robin fashion to amortize the scaling cost. -

- - -

5. Widget System

- -

The widget system (dvxWidget.h) is a retained-mode toolkit -layered on top of the window manager. Widgets form a tree rooted at a -per-window VBox container.

- +in a round-robin fashion to amortize the scaling cost.

+
+
+

Widget System

+

Widget System

+

The widget system (dvxWidget.h) is a retained-mode toolkit layered on top of +the window manager. Widgets form a tree rooted at a per-window VBox +container.

WidgetT Base Structure

-

Every widget shares the same WidgetT struct. The -type field is a runtime-assigned integer ID. -The wclass pointer references the widget's -WidgetClassT vtable. Widget-specific private data is stored in -w->data (opaque void*).

- -

Tree linkage: parent, firstChild, -lastChild, nextSibling. No -prevSibling -- this halves pointer overhead and removal is -still O(n) for typical tree depths of 5-10.

- +

Every widget shares the same WidgetT struct. The type field is a +runtime-assigned integer ID. The wclass pointer references the widget's +WidgetClassT vtable. Widget-specific private data is stored in w->data +(opaque void*).

+

Tree linkage: parent, firstChild, lastChild, nextSibling. No prevSibling -- +this halves pointer overhead and removal is still O(n) for typical tree +depths of 5-10.

Layout Engine

-

Two-pass flexbox-like algorithm:

-
    -
  1. Bottom-up (calcMinSize) -- compute minimum sizes for - every widget, starting from leaves.
  2. -
  3. Top-down (layout) -- allocate space within available - bounds, distributing extra space according to weight - values (0 = fixed, 100 = normal stretch).
  4. -
- -

Size hints use a tagged encoding: the top 2 bits of an int32_t -select the unit (pixels, character widths, or percentage of parent), the low -30 bits hold the value. Macros: wgtPixels(v), -wgtChars(v), wgtPercent(v).

- +
    +
  • Bottom-up (calcMinSize) -- compute minimum sizes for every widget, + starting from leaves.
  • +
+

Top-down (layout) -- allocate space within available bounds, distributing +extra space according to weight values (0 = fixed, 100 = normal stretch).

+

Size hints use a tagged encoding: the top 2 bits of an int32_t select the +unit (pixels, character widths, or percentage of parent), the low 30 bits +hold the value. Macros: wgtPixels(v), wgtChars(v), wgtPercent(v).

Widget Class Dispatch (WidgetClassT)

- -

Each widget type provides a WidgetClassT with a -handlers[] array indexed by stable method IDs. Method IDs are -never reordered or reused -- new methods append at the end. This provides -ABI-stable dispatch so that widget DXEs compiled against an older DVX -version continue to work.

- -

Methods include: PAINT, PAINT_OVERLAY, -CALC_MIN_SIZE, LAYOUT, ON_MOUSE, -ON_KEY, ON_ACCEL_ACTIVATE, DESTROY, -GET_TEXT, SET_TEXT, POLL, and more -(21 defined, room for 32).

- -

Class flags encode static properties:

- - - - - - - - - - -
FlagMeaning
WCLASS_FOCUSABLECan receive keyboard focus (Tab navigation)
WCLASS_HORIZ_CONTAINERLays out children horizontally (HBox)
WCLASS_PAINTS_CHILDRENWidget handles child rendering itself
WCLASS_SCROLLABLEAccepts mouse wheel events
WCLASS_SCROLL_CONTAINERScrollPane -- scrolling viewport
WCLASS_NEEDS_POLLNeeds periodic polling (e.g. AnsiTerm comms)
WCLASS_SWALLOWS_TABTab key goes to widget, not focus navigation
WCLASS_PRESS_RELEASEClick = press + release (buttons)
- +

Each widget type provides a WidgetClassT with a handlers[] array indexed by +stable method IDs. Method IDs are never reordered or reused -- new methods +append at the end. This provides ABI-stable dispatch so that widget DXEs +compiled against an older DVX version continue to work.

+

Methods include: PAINT, PAINT_OVERLAY, CALC_MIN_SIZE, LAYOUT, ON_MOUSE, +ON_KEY, ON_ACCEL_ACTIVATE, DESTROY, GET_TEXT, SET_TEXT, POLL, and more (21 +defined, room for 32).

+

Class Flags

+
  Flag                    Meaning
+  ----                    -------
+  WCLASS_FOCUSABLE        Can receive keyboard focus (Tab navigation)
+  WCLASS_HORIZ_CONTAINER  Lays out children horizontally (HBox)
+  WCLASS_PAINTS_CHILDREN  Widget handles child rendering itself
+  WCLASS_SCROLLABLE       Accepts mouse wheel events
+  WCLASS_SCROLL_CONTAINER ScrollPane -- scrolling viewport
+  WCLASS_NEEDS_POLL       Needs periodic polling (e.g. AnsiTerm comms)
+  WCLASS_SWALLOWS_TAB     Tab key goes to widget, not focus navigation
+  WCLASS_PRESS_RELEASE    Click = press + release (buttons)

Available Widget Types

- -

Each widget is a separate .wgt DXE module. 29 widget types -are included:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
WidgetDescription
Box (VBox/HBox)Vertical and horizontal layout containers
ButtonClickable push button with label
CanvasRaw drawing surface for custom painting
CheckboxBoolean toggle with checkmark
ComboBoxText input with dropdown list
DataCtrlData-bound control for database operations
DbGridDatabase grid (tabular data display)
DropdownDropdown selection list
ImageStatic image display
ImageButtonButton with bitmap icon
LabelStatic text label
ListBoxScrollable selection list
ListViewMulti-column list with headers and sorting
ProgressBarDeterminate progress indicator
RadioRadio button (mutual exclusion group)
ScrollPaneScrollable viewport container
SeparatorVisual divider line
SliderValue selection via draggable thumb
SpacerEmpty space for layout
SpinnerNumeric input with up/down arrows
SplitterResizable split pane
StatusBarWindow status bar with sections
TabControlTabbed page container
Terminal (AnsiTerm)ANSI terminal emulator widget
TextInputSingle-line text entry field
TimerPeriodic timer events
ToolbarToolbar with icon buttons
TreeViewHierarchical tree display
WrapBoxFlow layout (wrapping horizontal container)
- +

Each widget is a separate .wgt DXE module. 29 widget types are included:

+
  Widget                  Description
+  ------                  -----------
+  Box (VBox/HBox)         Vertical and horizontal layout containers
+  Button                  Clickable push button with label
+  Canvas                  Raw drawing surface for custom painting
+  Checkbox                Boolean toggle with checkmark
+  ComboBox                Text input with dropdown list
+  DataCtrl                Data-bound control for database operations
+  DbGrid                  Database grid (tabular data display)
+  Dropdown                Dropdown selection list
+  Image                   Static image display
+  ImageButton             Button with bitmap icon
+  Label                   Static text label
+  ListBox                 Scrollable selection list
+  ListView                Multi-column list with headers and sorting
+  ProgressBar             Determinate progress indicator
+  Radio                   Radio button (mutual exclusion group)
+  ScrollPane              Scrollable viewport container
+  Separator               Visual divider line
+  Slider                  Value selection via draggable thumb
+  Spacer                  Empty space for layout
+  Spinner                 Numeric input with up/down arrows
+  Splitter                Resizable split pane
+  StatusBar               Window status bar with sections
+  TabControl              Tabbed page container
+  Terminal (AnsiTerm)     ANSI terminal emulator widget
+  TextInput               Single-line text entry field
+  Timer                   Periodic timer events
+  Toolbar                 Toolbar with icon buttons
+  TreeView                Hierarchical tree display
+  WrapBox                 Flow layout (wrapping horizontal container)

Widget API Registry

-

Each widget DXE registers a small API struct under a name during -wgtRegister(). Callers retrieve it via -wgtGetApi("button") and cast to the widget-specific API type. -Per-widget headers provide typed accessors so callers avoid manual casts. -Adding a new widget requires zero changes to the core.

- +wgtRegister(). Callers retrieve it via wgtGetApi("button") and cast to the +widget-specific API type. Per-widget headers provide typed accessors so +callers avoid manual casts. Adding a new widget requires zero changes to the +core.

Widget Interface Descriptors (WgtIfaceT)

-

Each widget can register an interface descriptor that describes its -BASIC-facing properties, methods, and events. These descriptors are used -by the form runtime and IDE for generic dispatch and property panel -enumeration. Properties have typed getters/setters -(WGT_IFACE_STRING, WGT_IFACE_INT, -WGT_IFACE_BOOL, WGT_IFACE_ENUM).

- - -

6. DXE Module System

- -

DVX uses DJGPP's DXE3 (Dynamic eXtension) format for -all loadable modules. DXE3 supports RTLD_GLOBAL symbol -sharing -- symbols exported by one module are visible to all subsequently -loaded modules. This is critical: widget DXEs call core API functions -(e.g. rectFill, wgtInvalidate) that are exported -by the core library DXE.

- +BASIC-facing properties, methods, and events. These descriptors are used by +the form runtime and IDE for generic dispatch and property panel +enumeration. Properties have typed getters/setters (WGT_IFACE_STRING, +WGT_IFACE_INT, WGT_IFACE_BOOL, WGT_IFACE_ENUM).

+
+
+

DXE Module System

+

DXE Module System

+

DVX uses DJGPP's DXE3 (Dynamic eXtension) format for all loadable modules. +DXE3 supports RTLD_GLOBAL symbol sharing -- symbols exported by one module +are visible to all subsequently loaded modules. This is critical: widget +DXEs call core API functions (e.g. rectFill, wgtInvalidate) that are +exported by the core library DXE.

Module Types

- - - - - - - - - - - - - - - - - - - - - -
ExtensionDirectoryPurposeExamples
.libLIBS/Core libraries loaded first. Provide infrastructure APIs.libtasks.lib (task switcher), - libdvx.lib (GUI core), - dvxshell.lib (shell)
.wgtWIDGETS/Widget type plugins. Each exports a wgtRegister() - function called at load time.button.wgt, listview.wgt, - terminal.wgt
.appAPPS/*/Application modules. Each exports appDescriptor - and appMain(). Loaded on demand by the shell.progman.app, notepad.app, - cpanel.app
- +
  Extension  Directory   Purpose                                             Examples
+  ---------  ---------   -------                                             --------
+  .lib       LIBS/       Core libraries loaded first. Provide infrastructure APIs.  libtasks.lib, libdvx.lib, dvxshell.lib
+  .wgt       WIDGETS/    Widget type plugins. Each exports wgtRegister().    button.wgt, listview.wgt, terminal.wgt
+  .app       APPS/*/     Application modules. Each exports appDescriptor and appMain(). Loaded on demand by the shell.  progman.app, notepad.app, cpanel.app

Boot Sequence

-
  dvx.exe (loader)
      |
      +-- Enter VGA mode 13h, display splash screen with progress bar
@@ -619,68 +460,48 @@ by the core library DXE.

+-- Load desktop app (progman.app) | +-- Main loop: - dvxUpdate() -> tsYield() -> shellReapApps() -
- + dvxUpdate() -> tsYield() -> shellReapApps()

Application Lifecycle

-

Two kinds of DXE apps:

- -
-
Callback-only (hasMainLoop = false)
-
appMain() creates windows, registers callbacks, and returns. - The app lives through GUI callbacks driven by the shell's main loop. - Lifecycle ends when the last window is closed. No extra task stack - needed -- simpler and cheaper.
- -
Main-loop (hasMainLoop = true)
-
A dedicated cooperative task is created. appMain() runs in - that task with its own loop, calling tsYield() to share CPU. - Needed for apps with continuous work (terminal emulators, games). - Lifecycle ends when appMain() returns.
-
- +

Callback-only (hasMainLoop = false)

+

appMain() creates windows, registers callbacks, and returns. The app lives +through GUI callbacks driven by the shell's main loop. Lifecycle ends when +the last window is closed. No extra task stack needed -- simpler and +cheaper.

+

Main-loop (hasMainLoop = true)

+

A dedicated cooperative task is created. appMain() runs in that task with +its own loop, calling tsYield() to share CPU. Needed for apps with +continuous work (terminal emulators, games). Lifecycle ends when appMain() +returns.

Crash Recovery

-

-The platform layer installs signal handlers for SIGSEGV, -SIGFPE, SIGILL. On crash, the handler logs -platform-specific diagnostics (register dump on DJGPP), then -longjmps back to the shell's main loop. The crashed app is +

The platform layer installs signal handlers for SIGSEGV, SIGFPE, SIGILL. On +crash, the handler logs platform-specific diagnostics (register dump on +DJGPP), then longjmps back to the shell's main loop. The crashed app is killed; other apps and the shell survive. This provides Windows 3.1-style -fault tolerance. -

- +fault tolerance.

Per-App Memory Tracking

-

-All allocations route through dvxMalloc/dvxFree -wrappers that prepend a 16-byte header recording the owning app ID and -allocation size. The Task Manager displays per-app memory usage, and leaks -are detected at app termination. -

- - -

7. Event Model

- -

DVX uses a cooperative polling model. The main loop -(dvxRun / dvxUpdate) runs this cycle each frame:

- -
    -
  1. Poll mouse -- platformMousePoll() returns - position and button bitmask. Compare with previous frame for - press/release edge detection.
  2. -
  3. Poll keyboard -- platformKeyboardRead() - returns ASCII + scancode. Non-blocking; returns false if buffer is - empty.
  4. -
  5. Dispatch to focused window -- the event loop fires - window callbacks (onKey, onMouse, etc.) - on the focused window. If the window has a widget tree, the widget - system's installed handlers dispatch to individual widgets.
  6. -
  7. Compositor pass -- merge dirty rects, composite, - flush to LFB.
  8. -
  9. Yield -- platformYield() or idle - callback.
  10. -
- +

All allocations route through dvxMalloc/dvxFree wrappers that prepend a +16-byte header recording the owning app ID and allocation size. The Task +Manager displays per-app memory usage, and leaks are detected at app +termination.

+
+
+

Event Model

+

Event Model

+

DVX uses a cooperative polling model. The main loop (dvxRun / dvxUpdate) +runs this cycle each frame:

+
    +
  • Poll mouse -- platformMousePoll() returns position and button bitmask. + Compare with previous frame for press/release edge detection.
  • +
  • Poll keyboard -- platformKeyboardRead() returns ASCII + scancode. + Non-blocking; returns false if buffer is empty.
  • +
  • Dispatch to focused window -- the event loop fires window callbacks + (onKey, onMouse, etc.) on the focused window. If the window has a widget + tree, the widget system's installed handlers dispatch to individual + widgets.
  • +
  • Compositor pass -- merge dirty rects, composite, flush to LFB.
  • +
+

Yield -- platformYield() or idle callback.

Event Dispatch Chain

  Mouse/Keyboard Input
        |
@@ -698,42 +519,29 @@ are detected at app termination.
        |
   wclsOnMouse / wclsOnKey (vtable dispatch)
        |
-  Universal callbacks (onClick, onChange, etc.)
-
- + Universal callbacks (onClick, onChange, etc.)

Accelerator Tables

-

-Per-window accelerator tables map key + modifier combinations to command IDs. -The runtime normalizes key/modifier at registration time (uppercase key, -strip shift from modifiers) so matching at dispatch time is two integer -comparisons per entry. Matched accelerators fire the window's -onMenu callback with the command ID, unifying the menu and -hotkey code paths. -

- +

Per-window accelerator tables map key + modifier combinations to command +IDs. The runtime normalizes key/modifier at registration time (uppercase +key, strip shift from modifiers) so matching at dispatch time is two integer +comparisons per entry. Matched accelerators fire the window's onMenu +callback with the command ID, unifying the menu and hotkey code paths.

Mouse Cursor

-

-Software-rendered cursor using the classic AND/XOR mask approach. Seven +

Software-rendered cursor using the classic AND/XOR mask approach. Seven cursor shapes are compiled in: arrow, horizontal resize, vertical resize, NW-SE diagonal resize, NE-SW diagonal resize, busy (hourglass), and crosshair. The cursor is painted into the backbuffer on top of the -composited frame and the affected region is flushed to the LFB each frame. -

- +composited frame and the affected region is flushed to the LFB each frame.

Double-Click Detection

-

-Timestamp-based: two clicks on the same target (title bar, minimized icon, +

Timestamp-based: two clicks on the same target (title bar, minimized icon, close gadget) within the configurable double-click interval trigger the -double-click action. Separate tracking for each target type. -

- - -

8. Font System

- -

DVX uses fixed-width 8-pixel-wide bitmap fonts only. -One size is provided: 8x16, matching the standard VGA ROM font -and CP437 encoding (256 glyphs).

- +double-click action. Separate tracking for each target type.

+
+
+

Font System

+

Font System

+

DVX uses fixed-width 8-pixel-wide bitmap fonts only. One size is provided: +8x16, matching the standard VGA ROM font and CP437 encoding (256 glyphs).

BitmapFontT

  typedef struct {
       int32_t        charWidth;    // fixed width per glyph (always 8)
@@ -741,225 +549,143 @@ and CP437 encoding (256 glyphs).

int32_t firstChar; // typically 0 int32_t numChars; // typically 256 const uint8_t *glyphData; // packed 1bpp, charHeight bytes per glyph - } BitmapFontT; -
- + } BitmapFontT;

Design rationale:

    -
  • Character positions are pure multiplication (x = col * 8).
  • -
  • Glyph lookup is a single array index.
  • -
  • Each scanline of a glyph is exactly one byte (1bpp at 8 pixels wide).
  • -
  • No glyph-width tables, kerning, or per-character positioning needed.
  • -
  • 8-pixel width aligns with byte boundaries -- no bit shifting in - per-scanline rendering.
  • +
  • Character positions are pure multiplication (x = col * 8).
  • +
  • Glyph lookup is a single array index.
  • +
  • Each scanline of a glyph is exactly one byte (1bpp at 8 pixels wide).
  • +
  • No glyph-width tables, kerning, or per-character positioning needed.
- +

8-pixel width aligns with byte boundaries -- no bit shifting in per-scanline +rendering.

Text Rendering Functions

-
-
drawChar()
-
Renders a single character. Supports opaque (background fill) and - transparent modes.
- -
drawTextN()
-
Optimized batch rendering for a known character count. Clips once for - the entire run, fills background in a single rectFill, - then overlays glyph foreground pixels. Significantly faster than - per-character rendering for long runs.
- -
drawTermRow()
-
Renders an 80-column terminal row in a single pass, with per-cell - foreground/background from a 16-color palette, blink attribute support, - and cursor rendering. Exists because per-character terminal rendering - is unacceptably slow on target hardware.
- -
drawTextAccel()
-
Renders text with & accelerator markers. The character - after & is underlined to indicate the keyboard - shortcut.
-
- +

drawChar() -- Renders a single character. Supports opaque (background fill) +and transparent modes.

+

drawTextN() -- Optimized batch rendering for a known character count. Clips +once for the entire run, fills background in a single rectFill, then +overlays glyph foreground pixels. Significantly faster than per-character +rendering for long runs.

+

drawTermRow() -- Renders an 80-column terminal row in a single pass, with +per-cell foreground/background from a 16-color palette, blink attribute +support, and cursor rendering. Exists because per-character terminal +rendering is unacceptably slow on target hardware.

+

drawTextAccel() -- Renders text with & accelerator markers. The character +after & is underlined to indicate the keyboard shortcut.

Performance Optimization

-

-AppContextT stores a fixed-point 16.16 reciprocal of -font.charHeight (charHeightRecip) so that dividing -by charHeight (for pixel-to-row conversion in terminal/text widgets) becomes -a multiply+shift instead of an integer divide, which costs 40+ cycles on a -486. -

- - -

9. Color System

- +

AppContextT stores a fixed-point 16.16 reciprocal of font.charHeight +(charHeightRecip) so that dividing by charHeight (for pixel-to-row +conversion in terminal/text widgets) becomes a multiply+shift instead of an +integer divide, which costs 40+ cycles on a 486.

+
+
+

Color System

+

Color System

Pixel Format

-

-PixelFormatT describes the active VESA mode's pixel encoding. -Populated once from the VBE mode info block. Stores shift, mask, and bit -count for each channel so packColor() can convert RGB to native -format with shift-and-mask arithmetic -- no per-pixel computation. -

- +

PixelFormatT describes the active VESA mode's pixel encoding. Populated once +from the VBE mode info block. Stores shift, mask, and bit count for each +channel so packColor() can convert RGB to native format with shift-and-mask +arithmetic -- no per-pixel computation.

Supported depths:

- - - - - - -
DepthBytes/PixelNotes
8 bpp1Palette mode. Nearest-index via 6x6x6 color cube + grey ramp.
15 bpp25-5-5 RGB (1 bit unused).
16 bpp25-6-5 RGB.
32 bpp48-8-8 RGB (8 bits unused).
- +
  Depth    Bytes/Pixel  Notes
+  -----    -----------  -----
+  8 bpp    1            Palette mode. Nearest-index via 6x6x6 color cube + grey ramp.
+  15 bpp   2            5-5-5 RGB (1 bit unused).
+  16 bpp   2            5-6-5 RGB.
+  32 bpp   4            8-8-8 RGB (8 bits unused).

ColorSchemeT -- Theming

-

-All 20 UI colors are pre-packed into display pixel format at init -time. Every color is a uint32_t that can be written -directly to the framebuffer with zero per-pixel conversion. The scheme must -be regenerated on video mode change, but mode changes require re-init -anyway. -

- +

All 20 UI colors are pre-packed into display pixel format at init time. +Every color is a uint32_t that can be written directly to the framebuffer +with zero per-pixel conversion. The scheme must be regenerated on video mode +change, but mode changes require re-init anyway.

Color roles mirror classic Motif/Windows 3.x conventions:

    -
  • desktop -- desktop background
  • -
  • windowFace, windowHighlight, - windowShadow -- window chrome bevel triplet
  • -
  • activeTitleBg/Fg, inactiveTitleBg/Fg -- - focused vs. unfocused title bar
  • -
  • contentBg/Fg -- window content area
  • -
  • menuBg/Fg, menuHighlightBg/Fg -- menus
  • -
  • buttonFace -- button background
  • -
  • scrollbarBg/Fg/Trough -- scrollbar components
  • -
  • cursorFg/Bg -- mouse cursor colors
  • +
  • desktop -- desktop background
  • +
  • windowFace, windowHighlight, windowShadow -- window chrome bevel triplet
  • +
  • activeTitleBg/Fg, inactiveTitleBg/Fg -- focused vs. unfocused title bar
  • +
  • contentBg/Fg -- window content area
  • +
  • menuBg/Fg, menuHighlightBg/Fg -- menus
  • +
  • buttonFace -- button background
  • +
  • scrollbarBg/Fg/Trough -- scrollbar components
- -

Source RGB values are kept in AppContextT.colorRgb[] for -theme save/load. Themes are stored as INI files with a -[colors] section. The API provides -dvxLoadTheme(), dvxSaveTheme(), -dvxSetColor(), and dvxResetColorScheme().

- +

cursorFg/Bg -- mouse cursor colors

+

Source RGB values are kept in AppContextT.colorRgb[] for theme save/load. +Themes are stored as INI files with a [colors] section. The API provides +dvxLoadTheme(), dvxSaveTheme(), dvxSetColor(), and dvxResetColorScheme().

Bevel Styles

-

-Bevels are the defining visual element of the Motif aesthetic. Convenience +

Bevels are the defining visual element of the Motif aesthetic. Convenience macros create bevel style descriptors by swapping highlight and shadow -colors: -

+colors:

  BEVEL_RAISED(colorScheme, borderWidth)       -- raised 3D look
   BEVEL_SUNKEN(colorScheme, face, borderWidth) -- sunken/inset look
   BEVEL_TROUGH(colorScheme)                    -- 1px scrollbar trough
-  BEVEL_SB_BUTTON(colorScheme)                 -- scrollbar button
-
- - -

10. Platform Layer

- -

All OS-specific and CPU-specific code is isolated behind -dvxPlatform.h. To port DVX, implement a new -dvxPlatformXxx.c against this header.

- + BEVEL_SB_BUTTON(colorScheme) -- scrollbar button +
+
+

Platform Layer

+

Platform Layer

+

All OS-specific and CPU-specific code is isolated behind dvxPlatform.h. To +port DVX, implement a new dvxPlatformXxx.c against this header.

Implementations

- - - - - - - - -
FileTargetDetails
dvxPlatformDos.cDJGPP / DPMIReal VESA VBE, INT 33h mouse, INT 16h keyboard, - rep movsd/rep stosl asm spans, - DPMI physical memory mapping for LFB, INT 9 hook for key-up, - CuteMouse Wheel API.
- +
  File                Target        Details
+  ----                ------        -------
+  dvxPlatformDos.c    DJGPP/DPMI    Real VESA VBE, INT 33h mouse, INT 16h keyboard, rep movsd/rep stosl asm spans, DPMI physical memory mapping for LFB, INT 9 hook for key-up, CuteMouse Wheel API.

Abstraction Areas

- -
-
Video
-
platformVideoInit() -- mode probe and framebuffer setup.
- platformVideoShutdown() -- restore previous mode.
- platformVideoEnumModes() -- enumerate available modes.
- -
Framebuffer Flush
-
platformFlushRect() -- copy dirty rect from backBuf to LFB. - On DOS, each scanline uses rep movsd for near-optimal - aligned 32-bit writes over the PCI bus.
- -
Optimized Memory Spans
-
Six functions: platformSpanFill8/16/32() and - platformSpanCopy8/16/32(). Called once per scanline of - every rectangle fill, blit, and text draw. On DOS these use inline - assembly for critical inner loops - memset/memcpy.
- -
Mouse Input
-
Polling model. platformMousePoll() returns position and - button bitmask. Wheel support via CuteMouse API.
- -
Keyboard Input
-
platformKeyboardRead() -- non-blocking key read.
- platformKeyUpRead() -- key release detection (requires - INT 9 hook on DOS).
- platformAltScanToChar() -- scancode-to-ASCII lookup for - Alt+key combinations.
- -
Crash Recovery
-
platformInstallCrashHandler() -- signal handlers + - longjmp for fault tolerance.
- -
DXE Support
-
platformRegisterDxeExports() -- register C runtime and - platform symbols for DXE resolution.
- platformRegisterSymOverrides() -- register function - pointer overrides for module loader.
-
- - -

11. Build System

- +

Video

+

platformVideoInit() -- mode probe and framebuffer setup. +platformVideoShutdown() -- restore previous mode. platformVideoEnumModes() +-- enumerate available modes.

+

Framebuffer Flush

+

platformFlushRect() -- copy dirty rect from backBuf to LFB. On DOS, each +scanline uses rep movsd for near-optimal aligned 32-bit writes over the PCI +bus.

+

Optimized Memory Spans

+

Six functions: platformSpanFill8/16/32() and platformSpanCopy8/16/32(). +Called once per scanline of every rectangle fill, blit, and text draw. On +DOS these use inline assembly for critical inner loops.

+

Mouse Input

+

Polling model. platformMousePoll() returns position and button bitmask. +Wheel support via CuteMouse API.

+

Keyboard Input

+

platformKeyboardRead() -- non-blocking key read. platformKeyUpRead() -- key +release detection (requires INT 9 hook on DOS). platformAltScanToChar() -- +scancode-to-ASCII lookup for Alt+key combinations.

+

Crash Recovery

+

platformInstallCrashHandler() -- signal handlers + longjmp for fault +tolerance.

+

DXE Support

+

platformRegisterDxeExports() -- register C runtime and platform symbols for +DXE resolution. platformRegisterSymOverrides() -- register function pointer +overrides for module loader.

+
+
+

Build System

+

Build System

Cross-Compilation

-

DVX is cross-compiled from Linux using a DJGPP cross-compiler -(i586-pc-msdosdjgpp-gcc). The top-level Makefile -orchestrates building all subsystems in dependency order.

- +(i586-pc-msdosdjgpp-gcc). The top-level Makefile orchestrates building all +subsystems in dependency order.

  make               -- build everything
-  ./mkcd.sh          -- build + create ISO for 86Box
-
- + ./mkcd.sh -- build + create ISO for 86Box

Build Targets

- -
  all: core tasks loader texthelp listhelp tools widgets shell taskmgr serial sql apps
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
TargetOutputDescription
corebin/libs/libdvx.libGUI core library (draw, comp, wm, app, widget infrastructure)
tasksbin/libs/libtasks.libCooperative task switcher
loaderbin/dvx.exeBootstrap loader (the DOS executable)
widgetsbin/widgets/*.wgt29 widget type plugins
shellbin/libs/dvxshell.libDVX Shell (app management, desktop)
taskmgrbin/libs/taskmgr.libTask Manager (loaded as a separate DXE)
texthelpshared libraryShared text editing helpers (clipboard, word boundaries)
listhelpshared libraryShared dropdown/list helpers
appsbin/apps/*/*.appApplication modules (progman, notepad, clock, etc.)
toolsbin/dvxresResource compiler (runs on Linux, builds resource sections into DXEs)
serialserial DXE libsUART driver, HDLC packets, security, seclink
sqlSQL DXE libSQLite integration
- +
  all: core tasks loader texthelp listhelp tools widgets shell taskmgr serial sql apps
+
  Target     Output                    Description
+  ------     ------                    -----------
+  core       bin/libs/libdvx.lib       GUI core library (draw, comp, wm, app, widget infrastructure)
+  tasks      bin/libs/libtasks.lib     Cooperative task switcher
+  loader     bin/dvx.exe               Bootstrap loader (the DOS executable)
+  widgets    bin/widgets/*.wgt         29 widget type plugins
+  shell      bin/libs/dvxshell.lib     DVX Shell (app management, desktop)
+  taskmgr    bin/libs/taskmgr.lib      Task Manager (loaded as a separate DXE)
+  texthelp   shared library            Shared text editing helpers (clipboard, word boundaries)
+  listhelp   shared library            Shared dropdown/list helpers
+  apps       bin/apps/*/*.app          Application modules (progman, notepad, clock, etc.)
+  tools      bin/dvxres                Resource compiler (runs on Linux, builds resource sections into DXEs)
+  serial     serial DXE libs           UART driver, HDLC packets, security, seclink
+  sql        SQL DXE lib               SQLite integration

DXE3 Build Process

-

Each DXE module is compiled to an object file with GCC, then linked -with dxe3gen:

+

Each DXE module is compiled to an object file with GCC, then linked with +dxe3gen:

  # Compile
   i586-pc-msdosdjgpp-gcc -O2 -march=i486 -mtune=i586 -c -o widget.o widget.c
 
@@ -967,40 +693,27 @@ with dxe3gen:

dxe3gen -o widget.wgt -E _wgtRegister -U widget.o # Optionally append resources - dvxres build widget.wgt widget.res -
- -

The -E flag specifies exported symbols (prefixed with -underscore per DJGPP convention). -U marks unresolved symbols -as OK (they'll be resolved at load time from previously loaded DXEs).

- + dvxres build widget.wgt widget.res +

The -E flag specifies exported symbols (prefixed with underscore per DJGPP +convention). -U marks unresolved symbols as OK (they'll be resolved at load +time from previously loaded DXEs).

Deployment (mkcd.sh)

-
    -
  1. Runs make all.
  2. -
  3. Verifies critical outputs exist (dvx.exe, - libtasks.lib, libdvx.lib, - dvxshell.lib).
  4. -
  5. Counts widget modules.
  6. -
  7. Creates an ISO 9660 image from bin/ using - mkisofs: -
      -
    • -iso-level 1: strict 8.3 filenames for DOS
    • -
    • -J: Joliet extensions for long names
    • -
    • -V DVX: volume label
    • -
    -
  8. -
  9. Places the ISO at - ~/.var/app/net._86box._86Box/data/86Box/dvx.iso for - 86Box to mount as CD-ROM.
  10. -
- +
    +
  • Runs make all.
  • +
  • Verifies critical outputs exist (dvx.exe, libtasks.lib, libdvx.lib, + dvxshell.lib).
  • +
  • Counts widget modules.
  • +
  • Creates an ISO 9660 image from bin/ using mkisofs: -iso-level 1 (strict + 8.3 filenames for DOS), -J (Joliet extensions for long names), -V DVX + (volume label).
  • +
+

Places the ISO at ~/.var/app/net._86box._86Box/data/86Box/dvx.iso for 86Box +to mount as CD-ROM.

Compiler Flags

  -O2                  Optimization level 2
   -march=i486          486 instruction set baseline
   -mtune=i586          Optimize scheduling for Pentium
-  -Wall -Wextra        Full warnings
-
- + -Wall -Wextra Full warnings

Directory Layout

  dvxgui/
   +-- core/              Core library sources (dvxVideo, dvxDraw, dvxComp, dvxWm, dvxApp, widget infra)
@@ -1035,11 +748,8 @@ as OK (they'll be resolved at load time from previously loaded DXEs).

+-- sql/ SQLite integration +-- bin/ Build output (dvx.exe, libs/, widgets/, apps/, config/) +-- obj/ Intermediate object files - +-- docs/ Documentation -
- -
-

Generated 2026-04-06. Source: DVX GUI codebase headers and design documents.

- + +-- docs/ Documentation +
+
diff --git a/docs/dvx_help_sample.html b/docs/dvx_help_sample.html new file mode 100644 index 0000000..0d120db --- /dev/null +++ b/docs/dvx_help_sample.html @@ -0,0 +1,155 @@ + + + + +Welcome to DVX + + + + +
+
+

Welcome to DVX

+

Welcome to DVX

+

DVX is a graphical user interface environment for DOS, designed for +486-class hardware and above. It provides a windowing system with a +Motif-inspired visual style, cooperative multitasking, and a widget-based +application framework.

+

DVX features include:

+
    +
  • A window manager with drag, resize, and minimize support
  • +
  • Over 25 built-in widget types including buttons, lists, and trees
  • +
  • Dynamic application loading via DXE3 modules
  • +
  • Theme support with customizable color schemes
  • +
+

VESA VBE 2.0+ linear framebuffer rendering

+

See also: System Overview

+
+
Tip: Press F1 from any DVX application to open context-sensitive help.
+
+
+

System Overview

+

System Overview

+

DVX is built as a five-layer architecture, with each layer providing +services to the layer above it.

+

Video Layer

+

The video layer (dvxVideo) handles VESA VBE initialization, linear +framebuffer mapping, backbuffer allocation, and pixel format detection. It +supports 8-bit, 16-bit, and 32-bit color depths.

+

Drawing Layer

+

The drawing layer (dvxDraw) provides primitive rendering operations: filled +rectangles, beveled borders, text rendering, bitmap blitting, and clipped +drawing.

+

Compositor

+

The compositor (dvxComp) manages a dirty rectangle list. Only regions that +have changed since the last frame are flushed from the system RAM backbuffer +to the video card's linear framebuffer.

+

Window Manager

+

The window manager (dvxWm) handles the window stack, chrome rendering (title +bars, borders, close buttons), drag and resize interaction, focus +management, and menu bars.

+

Application Layer

+

The application layer (dvxApp) ties everything together with the event loop, +mouse and keyboard input, accelerator tables, and the public API used by +applications.

+

See also: Widget System

+
+
+

Widget System

+

Widget System

+

DVX provides a rich set of widgets (controls) for building application user +interfaces. Widgets are loaded as DXE3 plugin modules at startup.

+

Layout Widgets

+
    +
  • VBox -- Vertical box layout (stacks children vertically)
  • +
  • HBox -- Horizontal box layout (stacks children horizontally)
  • +
  • Frame -- Labeled group box with border
  • +
  • ScrollPane -- Scrollable container for oversized content
  • +
  • Splitter -- Resizable split between two panes
  • +
+

TabControl -- Tabbed container

+

Input Widgets

+
    +
  • Button -- Push button with text label
  • +
  • TextInput -- Single-line text entry field
  • +
  • TextArea -- Multi-line text editor with syntax highlighting
  • +
  • Checkbox -- Boolean toggle with label
  • +
  • Radio -- Mutually exclusive option selector
  • +
  • Dropdown -- Drop-down selection list
  • +
  • ComboBox -- Editable dropdown with text entry
  • +
  • Slider -- Horizontal or vertical value slider
  • +
+

Spinner -- Numeric up/down control

+

Display Widgets

+
    +
  • Label -- Single-line text display
  • +
  • Image -- Bitmap image display
  • +
  • ProgressBar -- Visual progress indicator
  • +
  • Canvas -- Custom drawing surface
  • +
+

Separator -- Horizontal or vertical divider line

+

Data Widgets

+
    +
  • ListBox -- Scrollable list of text items
  • +
  • ListView -- Multi-column sortable list with headers
  • +
+

TreeView -- Hierarchical tree with expand/collapse

+
+
+

Keyboard Shortcuts

+

Keyboard Shortcuts

+

The following keyboard shortcuts are available system-wide in DVX:

+
  Shortcut        Action
+  --------        ------
+  Alt+F4          Close active window
+  F10             Activate menu bar
+  Ctrl+Esc        Open task manager
+  Tab             Move focus to next widget
+  Shift+Tab       Move focus to previous widget
+  Enter           Activate focused button
+  Escape          Close dialog or cancel operation
+
+
+ + diff --git a/docs/dvx_widget_reference.html b/docs/dvx_widget_reference.html index 7f4a2c8..b7ab5f8 100644 --- a/docs/dvx_widget_reference.html +++ b/docs/dvx_widget_reference.html @@ -1,1553 +1,1313 @@ - + - -DVX Widget Reference + +Base WidgetT (Common Properties, Events, and Operations) - -

DVX Widget Reference

-

-Complete reference for the DVX GUI widget toolkit. All widgets are implemented -as dynamically loaded DXE modules. They are created via convenience macros -that wrap the per-widget API function tables. The base WidgetT -structure is defined in core/dvxWidget.h; individual widget -headers live in widgets/. -

- - - - -
-

Table of Contents

+ +
+
+

Base WidgetT (Common Properties, Events, and Operations)

+

DVX Widget Reference

+

Complete reference for the DVX GUI widget toolkit. All widgets are +implemented as dynamically loaded DXE modules. They are created via +convenience macros that wrap the per-widget API function tables. The base +WidgetT structure is defined in core/dvxWidget.h; individual widget headers +live in widgets/.

+

Base WidgetT (Common Properties, Events, and Operations)

+

Every widget inherits from the WidgetT structure defined in +core/dvxWidget.h. The fields and callbacks listed here are available on all +widget types.

+

Common Properties

+
  Field              Type                Description
+  -----              ----                -----------
+  name               char[32]            Widget name for lookup via wgtFind().
+  x, y, w, h         int32_t             Computed geometry relative to the window content area (set by layout).
+  minW, minH          int32_t (tagged)    Minimum size hints. Use wgtPixels(), wgtChars(), or wgtPercent(). 0 = auto.
+  maxW, maxH          int32_t (tagged)    Maximum size constraints. 0 = no limit.
+  prefW, prefH        int32_t (tagged)    Preferred size. 0 = auto.
+  weight             int32_t             Extra-space distribution weight. 0 = fixed, 100 = normal. A widget with weight=200 gets twice the extra space of one with weight=100.
+  align              WidgetAlignE        Main-axis alignment for children: AlignStartE, AlignCenterE, AlignEndE.
+  spacing            int32_t (tagged)    Spacing between children (containers only). 0 = default.
+  padding            int32_t (tagged)    Internal padding (containers only). 0 = default.
+  fgColor            uint32_t            Foreground color override. 0 = use color scheme default.
+  bgColor            uint32_t            Background color override. 0 = use color scheme default.
+  visible            bool                Visibility state.
+  enabled            bool                Enabled state. Disabled widgets are grayed out and ignore input.
+  readOnly           bool                Read-only mode: allows scrolling/selection but blocks editing.
+  swallowTab         bool                When true, Tab key goes to the widget instead of navigating focus.
+  accelKey           char                Lowercase accelerator character. 0 if none.
+  tooltip            const char *        Tooltip text. NULL = none. Caller owns the string.
+  contextMenu        MenuT *             Right-click context menu. NULL = none. Caller owns.
+  userData           void *              Application-defined user data pointer.
+

Size Specification Macros

+
  Macro              Description
+  -----              -----------
+  wgtPixels(v)       Size in pixels.
+  wgtChars(v)        Size in character widths (multiplied by font charWidth).
+  wgtPercent(v)      Size as a percentage of parent dimension.
+

Common Events (Callbacks)

+

These callback function pointers are available on every WidgetT. Set them +directly on the widget struct.

+
  Callback           Signature                                                   Description
+  --------           ---------                                                   -----------
+  onClick            void (*)(WidgetT *w)                                        Fires on mouse click / activation.
+  onDblClick         void (*)(WidgetT *w)                                        Fires on double-click.
+  onChange           void (*)(WidgetT *w)                                        Fires when the widget's value changes (text, selection, check state, etc.).
+  onFocus            void (*)(WidgetT *w)                                        Fires when the widget receives keyboard focus.
+  onBlur             void (*)(WidgetT *w)                                        Fires when the widget loses keyboard focus.
+  onKeyPress         void (*)(WidgetT *w, int32_t keyAscii)                      Fires on a printable key press (ASCII value).
+  onKeyDown          void (*)(WidgetT *w, int32_t keyCode, int32_t shift)        Fires on key down (scan code + shift state).
+  onKeyUp            void (*)(WidgetT *w, int32_t keyCode, int32_t shift)        Fires on key up.
+  onMouseDown        void (*)(WidgetT *w, int32_t button, int32_t x, int32_t y)  Fires on mouse button press.
+  onMouseUp          void (*)(WidgetT *w, int32_t button, int32_t x, int32_t y)  Fires on mouse button release.
+  onMouseMove        void (*)(WidgetT *w, int32_t button, int32_t x, int32_t y)  Fires on mouse movement over the widget.
+  onScroll           void (*)(WidgetT *w, int32_t delta)                         Fires on mouse wheel scroll.
+  onValidate         bool (*)(WidgetT *w)                                        Validation callback. Return false to cancel a pending write.
+

Common Operations

+
  Function                                                    Description
+  --------                                                    -----------
+  WidgetT *wgtInitWindow(AppContextT *ctx, WindowT *win)      Initialize widgets for a window. Returns the root VBox container.
+  AppContextT *wgtGetContext(const WidgetT *w)                 Walk up from any widget to retrieve the AppContextT.
+  void wgtInvalidate(WidgetT *w)                               Mark widget for re-layout and repaint. Propagates to ancestors.
+  void wgtInvalidatePaint(WidgetT *w)                          Mark widget for repaint only (no layout recalculation).
+  void wgtSetText(WidgetT *w, const char *text)                Set widget text (label, button, textinput, etc.).
+  const char *wgtGetText(const WidgetT *w)                     Get widget text.
+  void wgtSetEnabled(WidgetT *w, bool enabled)                 Enable or disable a widget.
+  void wgtSetReadOnly(WidgetT *w, bool readOnly)               Set read-only mode.
+  void wgtSetFocused(WidgetT *w)                               Set keyboard focus to a widget.
+  WidgetT *wgtGetFocused(void)                                 Get the currently focused widget.
+  void wgtSetVisible(WidgetT *w, bool visible)                 Show or hide a widget.
+  void wgtSetName(WidgetT *w, const char *name)                Set widget name for lookup.
+  WidgetT *wgtFind(WidgetT *root, const char *name)            Find a widget by name in the subtree.
+  void wgtDestroy(WidgetT *w)                                  Destroy a widget and all its children.
+  void wgtSetTooltip(WidgetT *w, const char *text)             Set tooltip text. Pass NULL to remove.
+
- - - - -
-

Base WidgetT (Common Properties, Events, and Operations)

-

-Every widget inherits from the WidgetT structure defined in -core/dvxWidget.h. The fields and callbacks listed here are -available on all widget types. -

- -

Common Properties

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeDescription
namechar[32]Widget name for lookup via wgtFind().
x, y, w, hint32_tComputed geometry relative to the window content area (set by layout).
minW, minHint32_t (tagged)Minimum size hints. Use wgtPixels(), wgtChars(), or wgtPercent(). 0 = auto.
maxW, maxHint32_t (tagged)Maximum size constraints. 0 = no limit.
prefW, prefHint32_t (tagged)Preferred size. 0 = auto.
weightint32_tExtra-space distribution weight. 0 = fixed, 100 = normal. A widget with weight=200 gets twice the extra space of one with weight=100.
alignWidgetAlignEMain-axis alignment for children: AlignStartE, AlignCenterE, AlignEndE.
spacingint32_t (tagged)Spacing between children (containers only). 0 = default.
paddingint32_t (tagged)Internal padding (containers only). 0 = default.
fgColoruint32_tForeground color override. 0 = use color scheme default.
bgColoruint32_tBackground color override. 0 = use color scheme default.
visibleboolVisibility state.
enabledboolEnabled state. Disabled widgets are grayed out and ignore input.
readOnlyboolRead-only mode: allows scrolling/selection but blocks editing.
swallowTabboolWhen true, Tab key goes to the widget instead of navigating focus.
accelKeycharLowercase accelerator character. 0 if none.
tooltipconst char *Tooltip text. NULL = none. Caller owns the string.
contextMenuMenuT *Right-click context menu. NULL = none. Caller owns.
userDatavoid *Application-defined user data pointer.
- -

Size Specification Macros

- - - - - -
MacroDescription
wgtPixels(v)Size in pixels.
wgtChars(v)Size in character widths (multiplied by font charWidth).
wgtPercent(v)Size as a percentage of parent dimension.
- -

Common Events (Callbacks)

-

These callback function pointers are available on every WidgetT. -Set them directly on the widget struct.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CallbackSignatureDescription
onClickvoid (*)(WidgetT *w)Fires on mouse click / activation.
onDblClickvoid (*)(WidgetT *w)Fires on double-click.
onChangevoid (*)(WidgetT *w)Fires when the widget's value changes (text, selection, check state, etc.).
onFocusvoid (*)(WidgetT *w)Fires when the widget receives keyboard focus.
onBlurvoid (*)(WidgetT *w)Fires when the widget loses keyboard focus.
onKeyPressvoid (*)(WidgetT *w, int32_t keyAscii)Fires on a printable key press (ASCII value).
onKeyDownvoid (*)(WidgetT *w, int32_t keyCode, int32_t shift)Fires on key down (scan code + shift state).
onKeyUpvoid (*)(WidgetT *w, int32_t keyCode, int32_t shift)Fires on key up.
onMouseDownvoid (*)(WidgetT *w, int32_t button, int32_t x, int32_t y)Fires on mouse button press.
onMouseUpvoid (*)(WidgetT *w, int32_t button, int32_t x, int32_t y)Fires on mouse button release.
onMouseMovevoid (*)(WidgetT *w, int32_t button, int32_t x, int32_t y)Fires on mouse movement over the widget.
onScrollvoid (*)(WidgetT *w, int32_t delta)Fires on mouse wheel scroll.
onValidatebool (*)(WidgetT *w)Validation callback. Return false to cancel a pending write.
- -

Common Operations

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FunctionDescription
WidgetT *wgtInitWindow(AppContextT *ctx, WindowT *win)Initialize widgets for a window. Returns the root VBox container.
AppContextT *wgtGetContext(const WidgetT *w)Walk up from any widget to retrieve the AppContextT.
void wgtInvalidate(WidgetT *w)Mark widget for re-layout and repaint. Propagates to ancestors.
void wgtInvalidatePaint(WidgetT *w)Mark widget for repaint only (no layout recalculation).
void wgtSetText(WidgetT *w, const char *text)Set widget text (label, button, textinput, etc.).
const char *wgtGetText(const WidgetT *w)Get widget text.
void wgtSetEnabled(WidgetT *w, bool enabled)Enable or disable a widget.
void wgtSetReadOnly(WidgetT *w, bool readOnly)Set read-only mode.
void wgtSetFocused(WidgetT *w)Set keyboard focus to a widget.
WidgetT *wgtGetFocused(void)Get the currently focused widget.
void wgtSetVisible(WidgetT *w, bool visible)Show or hide a widget.
void wgtSetName(WidgetT *w, const char *name)Set widget name for lookup.
WidgetT *wgtFind(WidgetT *root, const char *name)Find a widget by name in the subtree.
void wgtDestroy(WidgetT *w)Destroy a widget and all its children.
void wgtSetTooltip(WidgetT *w, const char *text)Set tooltip text. Pass NULL to remove.
-
- - - - -
-

AnsiTerm

-

-A VT100/ANSI-compatible terminal emulator widget designed for connecting to +

+

AnsiTerm

+

AnsiTerm

+

A VT100/ANSI-compatible terminal emulator widget designed for connecting to BBS systems over the serial link. Uses a traditional text-mode cell buffer (character + attribute byte pairs) with the CP437 character set and 16-color CGA palette. Supports cursor movement, screen/line erase, scrolling regions, SGR colors, and scrollback history. Communication is abstracted through read/write function pointers, allowing the terminal to work with raw serial -ports, the secLink encrypted channel, or any other byte-oriented transport. -

-

Header: widgets/widgetAnsiTerm.h

- -

Creation

-
WidgetT *term = wgtAnsiTerm(parent, 80, 25);
- -

Macros

- - - - - - - - - -
MacroDescription
wgtAnsiTerm(parent, cols, rows)Create an ANSI terminal widget with the given column and row dimensions.
wgtAnsiTermWrite(w, data, len)Write raw bytes into the terminal's ANSI parser. data is a const uint8_t * buffer, len is the byte count.
wgtAnsiTermClear(w)Clear the terminal screen and reset the cursor to the home position.
wgtAnsiTermSetComm(w, ctx, readFn, writeFn)Attach a communication channel. readFn and writeFn are I/O callbacks; ctx is passed as their first argument.
wgtAnsiTermSetScrollback(w, maxLines)Set the maximum number of scrollback lines. Lines scrolled off the top are saved in a circular buffer.
wgtAnsiTermPoll(w)Poll the communication channel for incoming data and feed it into the ANSI parser.
wgtAnsiTermRepaint(w, outY, outH)Fast repaint path that renders dirty rows directly into the window's content buffer, bypassing the widget pipeline. Returns the dirty region via outY/outH.
- -

Properties (BASIC Interface)

- - - - - -
PropertyTypeAccessDescription
ColsIntegerRead-onlyNumber of columns.
RowsIntegerRead-onlyNumber of rows.
ScrollbackIntegerWrite-onlyMaximum scrollback lines.
- -

Methods (BASIC Interface)

- - - - -
MethodDescription
ClearClear the terminal screen.
WriteWrite a string into the terminal.
- -

Events

+ports, the secLink encrypted channel, or any other byte-oriented transport.

+

Header: widgets/widgetAnsiTerm.h

+

Creation

+
WidgetT *term = wgtAnsiTerm(parent, 80, 25);
+

Macros

+
  Macro                                              Description
+  -----                                              -----------
+  wgtAnsiTerm(parent, cols, rows)                    Create an ANSI terminal widget with the given column and row dimensions.
+  wgtAnsiTermWrite(w, data, len)                     Write raw bytes into the terminal's ANSI parser. data is a const uint8_t * buffer, len is the byte count.
+  wgtAnsiTermClear(w)                                Clear the terminal screen and reset the cursor to the home position.
+  wgtAnsiTermSetComm(w, ctx, readFn, writeFn)        Attach a communication channel. readFn and writeFn are I/O callbacks; ctx is passed as their first argument.
+  wgtAnsiTermSetScrollback(w, maxLines)              Set the maximum number of scrollback lines. Lines scrolled off the top are saved in a circular buffer.
+  wgtAnsiTermPoll(w)                                 Poll the communication channel for incoming data and feed it into the ANSI parser.
+  wgtAnsiTermRepaint(w, outY, outH)                  Fast repaint path that renders dirty rows directly into the window's content buffer, bypassing the widget pipeline. Returns the dirty region via outY/outH.
+

Properties (BASIC Interface)

+
  Property     Type       Access       Description
+  --------     ----       ------       -----------
+  Cols         Integer    Read-only    Number of columns.
+  Rows         Integer    Read-only    Number of rows.
+  Scrollback   Integer    Write-only   Maximum scrollback lines.
+

Methods (BASIC Interface)

+
  Method       Description
+  ------       -----------
+  Clear        Clear the terminal screen.
+  Write        Write a string into the terminal.
+

Events

AnsiTerm uses the common events only. No widget-specific events are defined.

+
- - - - -
-

Box (VBox / HBox / Frame)

-

-Container widgets that arrange their children in a vertical column (VBox), +

+

Box (VBox / HBox / Frame)

+

Box (VBox / HBox / Frame)

+

Container widgets that arrange their children in a vertical column (VBox), horizontal row (HBox), or a titled group box (Frame). These are the primary layout building blocks. Children are laid out using a flexbox-like algorithm -with weight-based extra-space distribution. -

-

Header: widgets/widgetBox.h

- -

Creation

- - - - - -
MacroDescription
wgtVBox(parent)Create a vertical box container. Children are stacked top to bottom.
wgtHBox(parent)Create a horizontal box container. Children are placed left to right.
wgtFrame(parent, title)Create a titled group box (a VBox with a border and label).
- -

Properties

-

Box containers use the common WidgetT fields for layout control:

- - - - - - -
PropertyDescription
alignMain-axis alignment of children. HBox: Start=left, Center=center, End=right. VBox: Start=top, Center=center, End=bottom.
spacingGap between children (tagged size).
paddingInternal padding around children (tagged size).
weightControls how the box itself stretches within its parent.
- -

Events

+with weight-based extra-space distribution.

+

Header: widgets/widgetBox.h

+

Creation

+
  Macro                        Description
+  -----                        -----------
+  wgtVBox(parent)              Create a vertical box container. Children are stacked top to bottom.
+  wgtHBox(parent)              Create a horizontal box container. Children are placed left to right.
+  wgtFrame(parent, title)      Create a titled group box (a VBox with a border and label).
+

Properties

+

Box containers use the common WidgetT fields for layout control:

+
  Property     Description
+  --------     -----------
+  align        Main-axis alignment of children. HBox: Start=left, Center=center, End=right. VBox: Start=top, Center=center, End=bottom.
+  spacing      Gap between children (tagged size).
+  padding      Internal padding around children (tagged size).
+  weight       Controls how the box itself stretches within its parent.
+

Events

Containers use the common events only. No widget-specific events.

+
- - - - -
-

Button

-

-A push button with a text label. Fires onClick when pressed -and released. Supports keyboard activation via accelerator keys. -

-

Header: widgets/widgetButton.h

- -

Creation

-
WidgetT *btn = wgtButton(parent, "OK");
- -

Macro

- - - -
MacroDescription
wgtButton(parent, text)Create a push button with the given label text.
- -

Properties

-

Uses common WidgetT properties. Set accelKey for keyboard shortcut. Use wgtSetText() / wgtGetText() to change the label.

- -

Events

- - - -
CallbackDescription
onClickFires when the button is clicked (press + release).
+
+

Button

+

Button

+

A push button with a text label. Fires onClick when pressed and released. +Supports keyboard activation via accelerator keys.

+

Header: widgets/widgetButton.h

+

Creation

+
WidgetT *btn = wgtButton(parent, "OK");
+

Macro

+
  Macro                        Description
+  -----                        -----------
+  wgtButton(parent, text)      Create a push button with the given label text.
+

Properties

+

Uses common WidgetT properties. Set accelKey for keyboard shortcut. Use +wgtSetText() / wgtGetText() to change the label.

+

Events

+
  Callback     Description
+  --------     -----------
+  onClick      Fires when the button is clicked (press + release).
+
- - - - -
-

Label

-

-A static text label. Does not accept keyboard focus. Typically used to -describe other widgets. Supports text alignment and accelerator keys -(with WCLASS_FOCUS_FORWARD, the accelerator moves focus to the -next focusable sibling). -

-

Header: widgets/widgetLabel.h

- -

Creation

-
WidgetT *lbl = wgtLabel(parent, "Name:");
- -

Macros

- - - - -
MacroDescription
wgtLabel(parent, text)Create a text label.
wgtLabelSetAlign(w, align)Set the text alignment (AlignStartE, AlignCenterE, AlignEndE).
- -

Properties

-

Use wgtSetText() / wgtGetText() to change the text. Set accelKey for accelerator support (focus forwards to next focusable widget).

- -

Events

+
+

Label

+

Label

+

A static text label. Does not accept keyboard focus. Typically used to +describe other widgets. Supports text alignment and accelerator keys (with +WCLASS_FOCUS_FORWARD, the accelerator moves focus to the next focusable +sibling).

+

Header: widgets/widgetLabel.h

+

Creation

+
WidgetT *lbl = wgtLabel(parent, "Name:");
+

Macros

+
  Macro                        Description
+  -----                        -----------
+  wgtLabel(parent, text)       Create a text label.
+  wgtLabelSetAlign(w, align)   Set the text alignment (AlignStartE, AlignCenterE, AlignEndE).
+

Properties

+

Use wgtSetText() / wgtGetText() to change the text. Set accelKey for +accelerator support (focus forwards to next focusable widget).

+

Events

Labels use the common events only. Typically no callbacks are set on labels.

- -

Properties (BASIC Interface)

- - - -
PropertyTypeAccessDescription
AlignmentEnum (Left, Center, Right)Read/WriteText alignment within the label.
+

Properties (BASIC Interface)

+
  Property     Type                         Access       Description
+  --------     ----                         ------       -----------
+  Alignment    Enum (Left, Center, Right)   Read/Write   Text alignment within the label.
+
- - - - -
-

TextInput / TextArea

-

-Single-line text input, password input, masked input, and multi-line text area -with optional syntax colorization, line numbers, find/replace, and gutter -decorators. -

-

Header: widgets/widgetTextInput.h

- -

Creation

- - - - - - -
MacroDescription
wgtTextInput(parent, maxLen)Create a single-line text input. maxLen is the maximum number of characters.
wgtPasswordInput(parent, maxLen)Create a password input (characters displayed as bullets).
wgtMaskedInput(parent, mask)Create a masked input field. The mask string defines the input format.
wgtTextArea(parent, maxLen)Create a multi-line text area.
- -

Methods (TextArea-specific)

- - - - - - - - - - - - - - - - - - - - - - - - - - -
MacroDescription
wgtTextAreaSetColorize(w, fn, ctx)Set a syntax colorization callback. The callback receives each line and fills a color index array. Color indices: 0=default, 1=keyword, 2=string, 3=comment, 4=number, 5=operator, 6=type/builtin, 7=reserved.
wgtTextAreaGoToLine(w, line)Scroll to and place the cursor on the given line number.
wgtTextAreaSetAutoIndent(w, enable)Enable or disable automatic indentation on newline.
wgtTextAreaSetShowLineNumbers(w, show)Show or hide line numbers in the gutter.
wgtTextAreaSetCaptureTabs(w, capture)When true, Tab key inserts a tab/spaces instead of moving focus.
wgtTextAreaSetTabWidth(w, width)Set the tab stop width in characters.
wgtTextAreaSetUseTabChar(w, useChar)When true, insert literal tab characters; when false, insert spaces.
wgtTextAreaFindNext(w, needle, caseSens, fwd)Search for the next occurrence. Returns true if found.
wgtTextAreaReplaceAll(w, needle, repl, caseSens)Replace all occurrences. Returns the number of replacements made.
wgtTextAreaSetLineDecorator(w, fn, ctx)Set a gutter line decorator callback. The callback returns a color and receives the line number, a color output pointer, and the user context.
wgtTextAreaGetCursorLine(w)Get the current cursor line number.
wgtTextAreaSetGutterClick(w, fn)Set a callback for gutter clicks (e.g. for breakpoint toggling). Callback receives the widget and line number.
- -

Events

- - - - - -
CallbackDescription
onChangeFires when the text content changes.
onKeyPressFires on each key press (ASCII value).
onValidateCalled before committing a change. Return false to cancel.
+
+

TextInput / TextArea

+

TextInput / TextArea

+

Single-line text input, password input, masked input, and multi-line text +area with optional syntax colorization, line numbers, find/replace, and +gutter decorators.

+

Header: widgets/widgetTextInput.h

+

Creation

+
  Macro                            Description
+  -----                            -----------
+  wgtTextInput(parent, maxLen)     Create a single-line text input. maxLen is the maximum number of characters.
+  wgtPasswordInput(parent, maxLen) Create a password input (characters displayed as bullets).
+  wgtMaskedInput(parent, mask)     Create a masked input field. The mask string defines the input format.
+  wgtTextArea(parent, maxLen)      Create a multi-line text area.
+

Methods (TextArea-specific)

+
  Macro                                             Description
+  -----                                             -----------
+  wgtTextAreaSetColorize(w, fn, ctx)                Set a syntax colorization callback. The callback receives each line and fills a color index array. Color indices: 0=default, 1=keyword, 2=string, 3=comment, 4=number, 5=operator, 6=type/builtin, 7=reserved.
+  wgtTextAreaGoToLine(w, line)                      Scroll to and place the cursor on the given line number.
+  wgtTextAreaSetAutoIndent(w, enable)               Enable or disable automatic indentation on newline.
+  wgtTextAreaSetShowLineNumbers(w, show)            Show or hide line numbers in the gutter.
+  wgtTextAreaSetCaptureTabs(w, capture)             When true, Tab key inserts a tab/spaces instead of moving focus.
+  wgtTextAreaSetTabWidth(w, width)                  Set the tab stop width in characters.
+  wgtTextAreaSetUseTabChar(w, useChar)              When true, insert literal tab characters; when false, insert spaces.
+  wgtTextAreaFindNext(w, needle, caseSens, fwd)     Search for the next occurrence. Returns true if found.
+  wgtTextAreaReplaceAll(w, needle, repl, caseSens)  Replace all occurrences. Returns the number of replacements made.
+  wgtTextAreaSetLineDecorator(w, fn, ctx)           Set a gutter line decorator callback. The callback returns a color and receives the line number, a color output pointer, and the user context.
+  wgtTextAreaGetCursorLine(w)                       Get the current cursor line number.
+  wgtTextAreaSetGutterClick(w, fn)                  Set a callback for gutter clicks (e.g. for breakpoint toggling). Callback receives the widget and line number.
+

Events

+
  Callback     Description
+  --------     -----------
+  onChange     Fires when the text content changes.
+  onKeyPress   Fires on each key press (ASCII value).
+  onValidate   Called before committing a change. Return false to cancel.
+
- - - - -
-

Checkbox

-

-A toggle control with a text label. Clicking toggles between checked and -unchecked states. -

-

Header: widgets/widgetCheckbox.h

- -

Creation

-
WidgetT *cb = wgtCheckbox(parent, "Enable logging");
- -

Macros

- - - - - -
MacroDescription
wgtCheckbox(parent, text)Create a checkbox with the given label text.
wgtCheckboxIsChecked(w)Returns true if the checkbox is checked.
wgtCheckboxSetChecked(w, checked)Set the checked state programmatically.
- -

Events

- - - - -
CallbackDescription
onClickFires when clicked (after toggle).
onChangeFires when the checked state changes.
- -

Properties (BASIC Interface)

- - - -
PropertyTypeAccessDescription
ValueBooleanRead/WriteWhether the checkbox is checked.
+
+

Checkbox

+

Checkbox

+

A toggle control with a text label. Clicking toggles between checked and +unchecked states.

+

Header: widgets/widgetCheckbox.h

+

Creation

+
WidgetT *cb = wgtCheckbox(parent, "Enable logging");
+

Macros

+
  Macro                                  Description
+  -----                                  -----------
+  wgtCheckbox(parent, text)              Create a checkbox with the given label text.
+  wgtCheckboxIsChecked(w)                Returns true if the checkbox is checked.
+  wgtCheckboxSetChecked(w, checked)      Set the checked state programmatically.
+

Events

+
  Callback     Description
+  --------     -----------
+  onClick      Fires when clicked (after toggle).
+  onChange     Fires when the checked state changes.
+

Properties (BASIC Interface)

+
  Property     Type       Access       Description
+  --------     ----       ------       -----------
+  Value        Boolean    Read/Write   Whether the checkbox is checked.
+
- - - - -
-

Radio Button

-

-A mutually exclusive selection control. Radio buttons must be placed inside -a radio group container. Only one radio button within a group can be selected -at a time. -

-

Header: widgets/widgetRadio.h

- -

Creation

-
WidgetT *grp = wgtRadioGroup(parent);
-WidgetT *r1  = wgtRadio(grp, "Option A");
-WidgetT *r2  = wgtRadio(grp, "Option B");
- -

Macros

- - - - - - -
MacroDescription
wgtRadioGroup(parent)Create a radio group container.
wgtRadio(parent, text)Create a radio button inside a group.
wgtRadioGroupSetSelected(w, idx)Set the selected radio button by index within the group.
wgtRadioGetIndex(w)Get the index of the currently selected radio button.
- -

Events

- - - - -
CallbackDescription
onClickFires on the radio button when clicked.
onChangeFires when the selection changes.
- -

Properties (BASIC Interface)

- - - -
PropertyTypeAccessDescription
ValueIntegerRead-onlyIndex of the currently selected radio button in the group.
- -

Methods (BASIC Interface)

- - - -
MethodDescription
SetSelectedSet the selected radio button by index.
+
+

Radio Button

+

Radio Button

+

A mutually exclusive selection control. Radio buttons must be placed inside +a radio group container. Only one radio button within a group can be +selected at a time.

+

Header: widgets/widgetRadio.h

+

Creation

+
WidgetT *grp = wgtRadioGroup(parent);
+WidgetT *r1  = wgtRadio(grp, "Option A");
+WidgetT *r2  = wgtRadio(grp, "Option B");
+

Macros

+
  Macro                                Description
+  -----                                -----------
+  wgtRadioGroup(parent)                Create a radio group container.
+  wgtRadio(parent, text)               Create a radio button inside a group.
+  wgtRadioGroupSetSelected(w, idx)     Set the selected radio button by index within the group.
+  wgtRadioGetIndex(w)                  Get the index of the currently selected radio button.
+

Events

+
  Callback     Description
+  --------     -----------
+  onClick      Fires on the radio button when clicked.
+  onChange     Fires when the selection changes.
+

Properties (BASIC Interface)

+
  Property     Type       Access       Description
+  --------     ----       ------       -----------
+  Value        Integer    Read-only    Index of the currently selected radio button in the group.
+

Methods (BASIC Interface)

+
  Method          Description
+  ------          -----------
+  SetSelected     Set the selected radio button by index.
+
- - - - -
diff --git a/docs/dvxbasic_control_reference.html b/docs/dvxbasic_control_reference.html index 38c5241..71db7b6 100644 --- a/docs/dvxbasic_control_reference.html +++ b/docs/dvxbasic_control_reference.html @@ -1,836 +1,664 @@ - + - -DVX BASIC Control Reference + +Common Properties, Events, and Methods - -

DVX BASIC Control Reference

- -

-This document describes every VB-style control available in DVX BASIC. -Each control maps to an underlying DVX widget loaded dynamically via -.wgt DXE files. Properties and methods are dispatched through -interface descriptors registered by each widget. -

- -
-Table of Contents + +
+
+

Common Properties, Events, and Methods

+

Common Properties, Events, and Methods

+

Every control in DVX BASIC inherits a set of common properties, events, and +methods. These are handled by the form runtime before dispatching to +widget-specific interface descriptors.

+

Common Properties

+
  Property     Type      R/W   Description
+  ----------   -------   ---   -------------------------------------------
+  Name         String    R     The control's name (e.g. "Command1"). Read-only at runtime.
+  Left         Integer   R/W   X position in pixels relative to the parent container.
+  Top          Integer   R/W   Y position in pixels relative to the parent container.
+  Width        Integer   R/W   Current width in pixels. Setting this changes the minimum width constraint.
+  Height       Integer   R/W   Current height in pixels. Setting this changes the minimum height constraint.
+  MinWidth     Integer   R/W   Minimum width for layout. Alias for Width in the setter.
+  MinHeight    Integer   R/W   Minimum height for layout. Alias for Height in the setter.
+  MaxWidth     Integer   R/W   Maximum width cap (0 = no limit, stretch to fill).
+  MaxHeight    Integer   R/W   Maximum height cap (0 = no limit, stretch to fill).
+  Weight       Integer   R/W   Layout weight. 0 = fixed size, >0 = share extra space proportionally.
+  Visible      Boolean   R/W   Whether the control is visible.
+  Enabled      Boolean   R/W   Whether the control accepts user input.
+  BackColor    Long      R/W   Background color as a 32-bit ARGB value.
+  ForeColor    Long      R/W   Foreground (text) color as a 32-bit ARGB value.
+  TabIndex     Integer   R     Accepted for VB compatibility but ignored. DVX has no tab order.
+

Common Events

+

These events are wired on every control loaded from a .frm file. Controls +created dynamically at runtime via code only receive Click, DblClick, +Change, GotFocus, and LostFocus; the keyboard, mouse, and scroll events +below require the control to be defined in the .frm file.

+
  Event       Parameters                                    Description
+  ---------   -------------------------------------------   -------------------------------------------
+  Click       (none)                                        Fires when the control is clicked.
+  DblClick    (none)                                        Fires when the control is double-clicked.
+  Change      (none)                                        Fires when the control's value or text changes.
+  GotFocus    (none)                                        Fires when the control receives keyboard focus.
+  LostFocus   (none)                                        Fires when the control loses keyboard focus.
+  KeyPress    KeyAscii As Integer                           Fires when a printable key is pressed. KeyAscii is the ASCII code.
+  KeyDown     KeyCode As Integer, Shift As Integer          Fires when any key is pressed down. KeyCode is the scan code; Shift indicates modifier keys.
+  KeyUp       KeyCode As Integer, Shift As Integer          Fires when a key is released.
+  MouseDown   Button As Integer, X As Integer, Y As Integer Fires when a mouse button is pressed over the control.
+  MouseUp     Button As Integer, X As Integer, Y As Integer Fires when a mouse button is released over the control.
+  MouseMove   Button As Integer, X As Integer, Y As Integer Fires when the mouse moves over the control.
+  Scroll      Delta As Integer                              Fires when the control is scrolled (mouse wheel or scrollbar).
+

Common Methods

+
  Method     Parameters   Description
+  --------   ----------   -------------------------------------------
+  SetFocus   (none)       Gives keyboard focus to this control.
+  Refresh    (none)       Forces the control to repaint.
+

Form

+

Data Binding

+

FRM File Format

- - - -

Common Properties, Events, and Methods

- - -

-Every control in DVX BASIC inherits a set of common properties, events, -and methods. These are handled by the form runtime before dispatching -to widget-specific interface descriptors. -

- -

Common Properties

- - - - - - - - - - - - - - - - - - -
PropertyTypeR/WDescription
NameStringRThe control's name (e.g. "Command1"). Read-only at runtime.
LeftIntegerR/WX position in pixels relative to the parent container.
TopIntegerR/WY position in pixels relative to the parent container.
WidthIntegerR/WCurrent width in pixels. Setting this changes the minimum width constraint.
HeightIntegerR/WCurrent height in pixels. Setting this changes the minimum height constraint.
MinWidthIntegerR/WMinimum width for layout. Alias for Width in the setter.
MinHeightIntegerR/WMinimum height for layout. Alias for Height in the setter.
MaxWidthIntegerR/WMaximum width cap (0 = no limit, stretch to fill).
MaxHeightIntegerR/WMaximum height cap (0 = no limit, stretch to fill).
WeightIntegerR/WLayout weight. 0 = fixed size, >0 = share extra space proportionally.
VisibleBooleanR/WWhether the control is visible.
EnabledBooleanR/WWhether the control accepts user input.
BackColorLongR/WBackground color as a 32-bit ARGB value.
ForeColorLongR/WForeground (text) color as a 32-bit ARGB value.
TabIndexIntegerRAccepted for VB compatibility but ignored. DVX has no tab order.
- -

Common Events

- -

-These events are wired on every control loaded from a .frm -file. Controls created dynamically at runtime via code only receive -Click, DblClick, Change, GotFocus, and LostFocus; the keyboard, mouse, -and scroll events below require the control to be defined in the -.frm file. -

- - - - - - - - - - - - - - - -
EventParametersDescription
Click(none)Fires when the control is clicked.
DblClick(none)Fires when the control is double-clicked.
Change(none)Fires when the control's value or text changes.
GotFocus(none)Fires when the control receives keyboard focus.
LostFocus(none)Fires when the control loses keyboard focus.
KeyPressKeyAscii As IntegerFires when a printable key is pressed. KeyAscii is the ASCII code.
KeyDownKeyCode As Integer, Shift As IntegerFires when any key is pressed down. KeyCode is the scan code; Shift indicates modifier keys.
KeyUpKeyCode As Integer, Shift As IntegerFires when a key is released.
MouseDownButton As Integer, X As Integer, Y As IntegerFires when a mouse button is pressed over the control.
MouseUpButton As Integer, X As Integer, Y As IntegerFires when a mouse button is released over the control.
MouseMoveButton As Integer, X As Integer, Y As IntegerFires when the mouse moves over the control.
ScrollDelta As IntegerFires when the control is scrolled (mouse wheel or scrollbar).
- -

Common Methods

- - - - - -
MethodParametersDescription
SetFocus(none)Gives keyboard focus to this control.
Refresh(none)Forces the control to repaint.
- - - -

Form

- - -
-VB Equivalent: Form    -DVX Widget: Window + VBox/HBox root -
- -

-The Form is the top-level container representing a DVX window. It is declared -in the .frm file with Begin Form FormName. -All controls are children of the form's content box, which uses either VBox -(default) or HBox layout. -

- -

Form Properties

- - - - - - - - - - - - - -
PropertyTypeDefaultDescription
NameString"Form1"The form's name, used for event dispatch and Load statement.
CaptionString(same as Name)Window title bar text.
WidthInteger400Window width in pixels. Setting this disables AutoSize.
HeightInteger300Window height in pixels. Setting this disables AutoSize.
LeftInteger0Initial X position. Used when Centered is False.
TopInteger0Initial Y position. Used when Centered is False.
LayoutString"VBox"Content box layout: "VBox" (vertical) or "HBox" (horizontal).
AutoSizeBooleanTrueWhen True, the window shrink-wraps to fit its content.
ResizableBooleanTrueWhether the user can resize the window at runtime.
CenteredBooleanTrueWhen True, the window is centered on screen. When False, Left/Top are used.
- -

Form Events

- - - - - - - - - -
EventParametersDescription
Load(none)Fires after the form and all controls are created. This is the default event.
Unload(none)Fires when the form is being closed or unloaded.
QueryUnloadCancel As IntegerFires before Unload. Set Cancel = 1 to abort the close.
Resize(none)Fires when the window is resized by the user.
Activate(none)Fires when the window gains focus.
Deactivate(none)Fires when the window loses focus.
- -

Form Methods (called on the form object)

- - - - - - - - -
StatementDescription
Load FormNameLoad the form (creates the window and controls, fires Load event).
Unload FormNameUnload the form (fires Unload, destroys window).
FormName.ShowMake the form visible.
FormName.Show 1Show as modal dialog (blocks until closed).
FormName.HideHide the form without unloading it.
- -

Example

- -
-Sub Form_Load ()
-    Form1.Caption = "Hello World"
-    Print "Form loaded!"
+
+

Form

+

Form

+

VB Equivalent: Form -- DVX Widget: Window + VBox/HBox root

+

The Form is the top-level container representing a DVX window. It is +declared in the .frm file with Begin Form FormName. All controls are +children of the form's content box, which uses either VBox (default) or HBox +layout.

+

Form Properties

+
  Property    Type      Default          Description
+  ----------  -------   --------------   -------------------------------------------
+  Name        String    "Form1"          The form's name, used for event dispatch and Load statement.
+  Caption     String    (same as Name)   Window title bar text.
+  Width       Integer   400              Window width in pixels. Setting this disables AutoSize.
+  Height      Integer   300              Window height in pixels. Setting this disables AutoSize.
+  Left        Integer   0                Initial X position. Used when Centered is False.
+  Top         Integer   0                Initial Y position. Used when Centered is False.
+  Layout      String    "VBox"           Content box layout: "VBox" (vertical) or "HBox" (horizontal).
+  AutoSize    Boolean   True             When True, the window shrink-wraps to fit its content.
+  Resizable   Boolean   True             Whether the user can resize the window at runtime.
+  Centered    Boolean   True             When True, the window is centered on screen. When False, Left/Top are used.
+

Form Events

+
  Event         Parameters              Description
+  -----------   ---------------------   -------------------------------------------
+  Load          (none)                  Fires after the form and all controls are created. This is the default event.
+  Unload        (none)                  Fires when the form is being closed or unloaded.
+  QueryUnload   Cancel As Integer       Fires before Unload. Set Cancel = 1 to abort the close.
+  Resize        (none)                  Fires when the window is resized by the user.
+  Activate      (none)                  Fires when the window gains focus.
+  Deactivate    (none)                  Fires when the window loses focus.
+

Form Methods

+
  Statement           Description
+  ------------------  -------------------------------------------
+  Load FormName       Load the form (creates the window and controls, fires Load event).
+  Unload FormName     Unload the form (fires Unload, destroys window).
+  FormName.Show       Make the form visible.
+  FormName.Show 1     Show as modal dialog (blocks until closed).
+  FormName.Hide       Hide the form without unloading it.
+

Example

+
Sub Form_Load ()
+    Form1.Caption = "Hello World"
+    Print "Form loaded!"
 End Sub
 
 Sub Form_QueryUnload (Cancel As Integer)
-    If MsgBox("Really quit?", 4) <> 6 Then
+    If MsgBox("Really quit?", 4) <> 6 Then
         Cancel = 1
     End If
 End Sub
 
 Sub Form_Resize ()
-    Print "Window resized"
-End Sub
-
- - - -

CommandButton

- - -
-VB Equivalent: CommandButton    -DVX Widget: button | Name Prefix: Command + Print "Window resized" +End Sub
+

Common Properties, Events, and Methods

+

FRM File Format

- -

-A push button that triggers an action when clicked. Created with -wgtButton(parent, text). -

- -

Type-Specific Properties

- - - - -
PropertyTypeDescription
CaptionStringThe text displayed on the button. Use & for accelerator keys (e.g. "&OK").
- +
+

CommandButton

+

CommandButton

+

VB Equivalent: CommandButton -- DVX Widget: button | Name Prefix: Command

+

A push button that triggers an action when clicked. Created with +wgtButton(parent, text).

+

Type-Specific Properties

+
  Property   Type     Description
+  --------   ------   -------------------------------------------
+  Caption    String   The text displayed on the button. Use & for accelerator keys (e.g. "&OK").

No additional type-specific properties beyond common properties and Caption.

- -

Default Event: Click

- -

Example

- -
-Begin Form Form1
-    Caption = "Button Demo"
+

Default Event: Click

+

Example

+
Begin Form Form1
+    Caption = "Button Demo"
     Begin CommandButton Command1
-        Caption = "&Click Me!"
+        Caption = "&Click Me!"
     End
 End
 
 Sub Command1_Click ()
-    MsgBox "Button was clicked!"
-End Sub
-
- - - -

Label

- - -
-VB Equivalent: Label    -DVX Widget: label + MsgBox "Button was clicked!" +End Sub
+

Common Properties, Events, and Methods

- -

-A static text label. Supports left, center, and right alignment. -

- -

Type-Specific Properties

- - - - - -
PropertyTypeDescription
CaptionStringThe text displayed by the label.
AlignmentEnumText alignment: Left (default), Center, or Right.
- -

Default Event: Click

- -

Example

- -
-Begin Label Label1
-    Caption   = "Hello, World!"
-    Alignment = "Center"
-End
-
- - - -

TextBox

- - -
-VB Equivalent: TextBox    -DVX Widget: textbox (single-line text input, max 256 chars) +
+

Label

+

Label

+

VB Equivalent: Label -- DVX Widget: label

+

A static text label. Supports left, center, and right alignment.

+

Type-Specific Properties

+
  Property    Type   Description
+  ---------   ----   -------------------------------------------
+  Caption     String The text displayed by the label.
+  Alignment   Enum   Text alignment: Left (default), Center, or Right.
+

Default Event: Click

+

Example

+
Begin Label Label1
+    Caption   = "Hello, World!"
+    Alignment = "Center"
+End
+

Common Properties, Events, and Methods

- -

-A single-line text input field. Supports data binding via DataSource -and DataField properties. -

- -

Type-Specific Properties

- - - - - - -
PropertyTypeDescription
TextStringThe text content of the input field.
DataSourceStringName of a Data control for data binding.
DataFieldStringColumn name for data binding.
- -

Default Event: Change

- -

Example

- -
-Begin TextBox Text1
-    Text = "Enter text here"
+
+

TextBox

+

TextBox

+

VB Equivalent: TextBox -- DVX Widget: textbox (single-line text input, max +256 chars)

+

A single-line text input field. Supports data binding via DataSource and +DataField properties.

+

Type-Specific Properties

+
  Property     Type     Description
+  ----------   ------   -------------------------------------------
+  Text         String   The text content of the input field.
+  DataSource   String   Name of a Data control for data binding.
+  DataField    String   Column name for data binding.
+

Default Event: Change

+

Example

+
Begin TextBox Text1
+    Text = "Enter text here"
 End
 
 Sub Text1_Change ()
-    Label1.Caption = "You typed: " & Text1.Text
-End Sub
-
- - - -

TextArea

- - -
-VB Equivalent: TextArea (DVX extension)    -DVX Widget: textarea (multi-line text input, max 4096 chars) + Label1.Caption = "You typed: " & Text1.Text +End Sub
+

Common Properties, Events, and Methods

+

Data Binding

- -

-A multi-line text editing area. This is a DVX extension with no direct VB3 +

+

TextArea

+

TextArea

+

VB Equivalent: TextArea (DVX extension) -- DVX Widget: textarea (multi-line +text input, max 4096 chars)

+

A multi-line text editing area. This is a DVX extension with no direct VB3 equivalent (VB uses a TextBox with MultiLine=True). Supports syntax -colorization, line numbers, auto-indent, and find/replace via the C API. -

- -

Type-Specific Properties

- - - - -
PropertyTypeDescription
TextStringThe full text content.
- -

Default Event: Change

- - - -

CheckBox

- - -
-VB Equivalent: CheckBox    -DVX Widget: checkbox +colorization, line numbers, auto-indent, and find/replace via the C API.

+

Type-Specific Properties

+
  Property   Type     Description
+  --------   ------   -------------------------------------------
+  Text       String   The full text content.
+

Default Event: Change

+

Common Properties, Events, and Methods

- -

-A toggle control with a label. Checked state is exposed as a Boolean. -

- -

Type-Specific Properties

- - - - - -
PropertyTypeDescription
CaptionStringThe text displayed next to the checkbox.
ValueBooleanTrue if checked, False if unchecked.
- -

Default Event: Click

- -

Example

- -
-Begin CheckBox Check1
-    Caption = "Enable feature"
+
+

CheckBox

+

CheckBox

+

VB Equivalent: CheckBox -- DVX Widget: checkbox

+

A toggle control with a label. Checked state is exposed as a Boolean.

+

Type-Specific Properties

+
  Property   Type      Description
+  --------   -------   -------------------------------------------
+  Caption    String    The text displayed next to the checkbox.
+  Value      Boolean   True if checked, False if unchecked.
+

Default Event: Click

+

Example

+
Begin CheckBox Check1
+    Caption = "Enable feature"
 End
 
 Sub Check1_Click ()
     If Check1.Value Then
-        Label1.Caption = "Feature ON"
+        Label1.Caption = "Feature ON"
     Else
-        Label1.Caption = "Feature OFF"
+        Label1.Caption = "Feature OFF"
     End If
-End Sub
-
- - - -

OptionButton

- - -
-VB Equivalent: OptionButton    -DVX Widget: radio (radio group + radio button) | Name Prefix: Option +End Sub
+

Common Properties, Events, and Methods

- -

-A radio button for mutually exclusive choices. DVX uses a radio group -container; individual OptionButtons are children of the group. The -Value property returns the button's index within its group. -

- -

Type-Specific Properties

- - - - - -
PropertyTypeDescription
CaptionStringThe text displayed next to the radio button.
ValueIntegerThe index of this radio button within its group (read-only).
- -

Type-Specific Methods

- - - - -
MethodParametersDescription
SetSelectedIndex As IntegerSelect the radio button at the given index within the group.
- -

Default Event: Click

- - - -

Frame

- - -
-VB Equivalent: Frame    -DVX Widget: frame (titled VBox container) +
+

OptionButton

+

OptionButton

+

VB Equivalent: OptionButton -- DVX Widget: radio (radio group + radio +button) | Name Prefix: Option

+

A radio button for mutually exclusive choices. DVX uses a radio group +container; individual OptionButtons are children of the group. The Value +property returns the button's index within its group.

+

Type-Specific Properties

+
  Property   Type      Description
+  --------   -------   -------------------------------------------
+  Caption    String    The text displayed next to the radio button.
+  Value      Integer   The index of this radio button within its group (read-only).
+

Type-Specific Methods

+
  Method        Parameters          Description
+  -----------   -----------------   -------------------------------------------
+  SetSelected   Index As Integer    Select the radio button at the given index within the group.
+

Default Event: Click

+

Common Properties, Events, and Methods

- -

-A container with a titled border. Child controls are placed inside the frame -using VBox layout. In the .frm file, nest Begin/End -blocks inside the Frame block. -

- -

Type-Specific Properties

- - - - -
PropertyTypeDescription
CaptionStringThe title displayed in the frame border.
- -

Container: Yes

-

Default Event: Click

- -

Example

- -
-Begin Frame Frame1
-    Caption = "Options"
+
+

Frame

+

Frame

+

VB Equivalent: Frame -- DVX Widget: frame (titled VBox container)

+

A container with a titled border. Child controls are placed inside the frame +using VBox layout. In the .frm file, nest Begin/End blocks inside the Frame +block.

+

Type-Specific Properties

+
  Property   Type     Description
+  --------   ------   -------------------------------------------
+  Caption    String   The title displayed in the frame border.
+

Container: Yes

+

Default Event: Click

+

Example

+
Begin Frame Frame1
+    Caption = "Options"
     Begin CheckBox Check1
-        Caption = "Option A"
+        Caption = "Option A"
     End
     Begin CheckBox Check2
-        Caption = "Option B"
+        Caption = "Option B"
     End
-End
-
- - - -

VBox

- - -
-DVX Extension    -DVX Widget: vbox (vertical layout container) +End
+

Common Properties, Events, and Methods

- -

-A container that arranges its children vertically, top to bottom. No title -or border. Use Weight on children to distribute extra space. -

- -

Container: Yes

-

Default Event: Click

+
+

VBox

+

VBox

+

DVX Extension -- DVX Widget: vbox (vertical layout container)

+

A container that arranges its children vertically, top to bottom. No title +or border. Use Weight on children to distribute extra space.

+

Container: Yes

+

Default Event: Click

No type-specific properties.

- - - -

HBox

- - -
-DVX Extension    -DVX Widget: hbox (horizontal layout container) +

Common Properties, Events, and Methods

+

HBox

- -

-A container that arranges its children horizontally, left to right. Use -Weight on children to distribute extra space. -

- -

Container: Yes

-

Default Event: Click

+
+

HBox

+

HBox

+

DVX Extension -- DVX Widget: hbox (horizontal layout container)

+

A container that arranges its children horizontally, left to right. Use +Weight on children to distribute extra space.

+

Container: Yes

+

Default Event: Click

No type-specific properties.

- - - -

ListBox

- - -
-VB Equivalent: ListBox    -DVX Widget: listbox +

Common Properties, Events, and Methods

+

VBox

- -

-A scrollable list of selectable items. Items are managed via methods -(AddItem, RemoveItem, Clear). Supports single and multi-select modes. -

- -

Type-Specific Properties

- - - - - -
PropertyTypeDescription
ListIndexIntegerIndex of the currently selected item (-1 = no selection).
ListCountIntegerNumber of items in the list (read-only).
- -

Type-Specific Methods

- - - - - - - - - - - - - -
MethodParametersDescription
AddItemText As StringAdd an item to the end of the list.
RemoveItemIndex As IntegerRemove the item at the given index.
Clear(none)Remove all items from the list.
ListIndex As IntegerReturn the text of the item at the given index.
SelectAll(none)Select all items (multi-select mode).
ClearSelection(none)Deselect all items.
SetMultiSelectMulti As BooleanEnable or disable multi-select mode.
SetReorderableReorderable As BooleanEnable or disable drag-to-reorder.
IsItemSelectedIndex As IntegerReturns True if the item at Index is selected.
SetItemSelectedIndex As Integer, Selected As BooleanSelect or deselect a specific item.
- -

Default Event: Click

- -

Example

- -
-Sub Form_Load ()
-    List1.AddItem "Apple"
-    List1.AddItem "Banana"
-    List1.AddItem "Cherry"
+
+

ListBox

+

ListBox

+

VB Equivalent: ListBox -- DVX Widget: listbox

+

A scrollable list of selectable items. Items are managed via methods +(AddItem, RemoveItem, Clear). Supports single and multi-select modes.

+

Type-Specific Properties

+
  Property    Type      Description
+  ---------   -------   -------------------------------------------
+  ListIndex   Integer   Index of the currently selected item (-1 = no selection).
+  ListCount   Integer   Number of items in the list (read-only).
+

Type-Specific Methods

+
  Method            Parameters                                Description
+  ---------------   ---------------------------------------   -------------------------------------------
+  AddItem           Text As String                            Add an item to the end of the list.
+  RemoveItem        Index As Integer                          Remove the item at the given index.
+  Clear             (none)                                    Remove all items from the list.
+  List              Index As Integer                          Return the text of the item at the given index.
+  SelectAll         (none)                                    Select all items (multi-select mode).
+  ClearSelection    (none)                                    Deselect all items.
+  SetMultiSelect    Multi As Boolean                          Enable or disable multi-select mode.
+  SetReorderable    Reorderable As Boolean                    Enable or disable drag-to-reorder.
+  IsItemSelected    Index As Integer                          Returns True if the item at Index is selected.
+  SetItemSelected   Index As Integer, Selected As Boolean     Select or deselect a specific item.
+

Default Event: Click

+

Example

+
Sub Form_Load ()
+    List1.AddItem "Apple"
+    List1.AddItem "Banana"
+    List1.AddItem "Cherry"
 End Sub
 
 Sub List1_Click ()
     Dim idx As Integer
     idx = List1.ListIndex
     If idx >= 0 Then
-        Label1.Caption = "Selected: " & List1.List(idx)
+        Label1.Caption = "Selected: " & List1.List(idx)
     End If
-End Sub
-
- - - -

ComboBox

- - -
-VB Equivalent: ComboBox    -DVX Widget: combobox (editable text field + drop-down list, max 256 chars) +End Sub
+

Common Properties, Events, and Methods

+

ComboBox

+

DropDown

- -

-A combination of a text input and a drop-down list. The user can type -text or select from the list. Supports the same AddItem/RemoveItem/Clear/List -methods as ListBox. -

- -

Type-Specific Properties

- - - - - - -
PropertyTypeDescription
TextStringThe text in the editable field.
ListIndexIntegerIndex of the currently selected list item (-1 = none).
ListCountIntegerNumber of items in the drop-down list (read-only).
- -

Type-Specific Methods

- -

Same as ListBox: AddItem, RemoveItem, Clear, List.

- -

Default Event: Click

- - - - - - -
-DVX Extension    -DVX Widget: dropdown (non-editable drop-down list) +
+

ComboBox

+

ComboBox

+

VB Equivalent: ComboBox -- DVX Widget: combobox (editable text field + +drop-down list, max 256 chars)

+

A combination of a text input and a drop-down list. The user can type text +or select from the list. Supports the same AddItem/RemoveItem/Clear/List +methods as ListBox.

+

Type-Specific Properties

+
  Property    Type      Description
+  ---------   -------   -------------------------------------------
+  Text        String    The text in the editable field.
+  ListIndex   Integer   Index of the currently selected list item (-1 = none).
+  ListCount   Integer   Number of items in the drop-down list (read-only).
+

Type-Specific Methods

+

Same as .link ctrl.listbox ListBox : AddItem, RemoveItem, Clear, List.

+

Default Event: Click

+

Common Properties, Events, and Methods

- -

-A read-only drop-down list. Unlike ComboBox, the user cannot type free text; -they can only select from the provided items. Supports AddItem/RemoveItem/Clear/List. -

- -

Type-Specific Properties

- - - - - -
PropertyTypeDescription
ListIndexIntegerIndex of the currently selected item.
ListCountIntegerNumber of items (read-only).
- -

Type-Specific Methods

- -

Same as ListBox: AddItem, RemoveItem, Clear, List.

- -

Default Event: Click

- - - -

HScrollBar

- - -
-VB Equivalent: HScrollBar    -DVX Widget: slider | Name Prefix: HScroll +
+

DropDown

+

DropDown

+

DVX Extension -- DVX Widget: dropdown (non-editable drop-down list)

+

A read-only drop-down list. Unlike ComboBox, the user cannot type free text; +they can only select from the provided items. Supports +AddItem/RemoveItem/Clear/List.

+

Type-Specific Properties

+
  Property    Type      Description
+  ---------   -------   -------------------------------------------
+  ListIndex   Integer   Index of the currently selected item.
+  ListCount   Integer   Number of items (read-only).
+

Type-Specific Methods

+

Same as .link ctrl.listbox ListBox : AddItem, RemoveItem, Clear, List.

+

Default Event: Click

+

Common Properties, Events, and Methods

- -

-A horizontal slider/scrollbar control. The value ranges between a minimum -and maximum set at creation time (default 0 to 100). -

- -

Type-Specific Properties

- - - - -
PropertyTypeDescription
ValueIntegerThe current slider position (clamped to min/max range).
- -

Default Event: Change

- -

Example

- -
-Begin HScrollBar HScroll1
+
+

HScrollBar

+

HScrollBar

+

VB Equivalent: HScrollBar -- DVX Widget: slider | Name Prefix: HScroll

+

A horizontal slider/scrollbar control. The value ranges between a minimum +and maximum set at creation time (default 0 to 100).

+

Type-Specific Properties

+
  Property   Type      Description
+  --------   -------   -------------------------------------------
+  Value      Integer   The current slider position (clamped to min/max range).
+

Default Event: Change

+

Example

+
Begin HScrollBar HScroll1
     MinWidth = 200
 End
 
 Sub HScroll1_Change ()
-    Label1.Caption = "Value: " & Str$(HScroll1.Value)
-End Sub
-
- - - -

SpinButton

- - -
-DVX Extension    -DVX Widget: spinner | Name Prefix: Spin + Label1.Caption = "Value: " & Str$(HScroll1.Value) +End Sub
+

Common Properties, Events, and Methods

- -

-A numeric input with up/down buttons. Supports integer mode (default) and -real-number mode with configurable decimal places. -

- -

Type-Specific Properties

- - - - - - -
PropertyTypeDescription
ValueIntegerCurrent integer value (in integer mode).
RealModeBooleanTrue to use floating-point mode; False for integer mode.
DecimalsIntegerNumber of decimal places shown in real mode.
- -

Type-Specific Methods

- - - - - -
MethodParametersDescription
SetRangeMin As Integer, Max As IntegerSet the allowed value range.
SetStepStep As IntegerSet the increment per button click.
- -

Default Event: Change

- - - -

Timer

- - -
-VB Equivalent: Timer    -DVX Widget: timer (non-visual) +
+

SpinButton

+

SpinButton

+

DVX Extension -- DVX Widget: spinner | Name Prefix: Spin

+

A numeric input with up/down buttons. Supports integer mode (default) and +real-number mode with configurable decimal places.

+

Type-Specific Properties

+
  Property   Type      Description
+  --------   -------   -------------------------------------------
+  Value      Integer   Current integer value (in integer mode).
+  RealMode   Boolean   True to use floating-point mode; False for integer mode.
+  Decimals   Integer   Number of decimal places shown in real mode.
+

Type-Specific Methods

+
  Method     Parameters                       Description
+  --------   ------------------------------   -------------------------------------------
+  SetRange   Min As Integer, Max As Integer   Set the allowed value range.
+  SetStep    Step As Integer                  Set the increment per button click.
+

Default Event: Change

+

Common Properties, Events, and Methods

- -

-A non-visual control that fires its event at a regular interval. The Timer -widget is invisible at runtime -- it has no on-screen representation. -

- -

Type-Specific Properties

- - - - - -
PropertyTypeDescription
EnabledBooleanTrue to start the timer, False to stop it.
IntervalIntegerTimer interval in milliseconds (write-only from BASIC).
- -

Type-Specific Methods

- - - - - -
MethodParametersDescription
Start(none)Start the timer.
Stop(none)Stop the timer.
- -

Type-Specific Events

- - - - -
EventParametersDescription
Timer(none)Fires each time the interval elapses. This is the default event.
- -
-The Timer control fires the Timer event instead of Change. -The onChange callback on the underlying widget is remapped automatically. -
- -

Example

- -
-Begin Timer Timer1
+
+

Timer

+

Timer

+

VB Equivalent: Timer -- DVX Widget: timer (non-visual)

+

A non-visual control that fires its event at a regular interval. The Timer +widget is invisible at runtime -- it has no on-screen representation.

+

Type-Specific Properties

+
  Property   Type      Description
+  --------   -------   -------------------------------------------
+  Enabled    Boolean   True to start the timer, False to stop it.
+  Interval   Integer   Timer interval in milliseconds (write-only from BASIC).
+

Type-Specific Methods

+
  Method   Parameters   Description
+  ------   ----------   -------------------------------------------
+  Start    (none)       Start the timer.
+  Stop     (none)       Stop the timer.
+

Type-Specific Events

+
  Event   Parameters   Description
+  -----   ----------   -------------------------------------------
+  Timer   (none)       Fires each time the interval elapses. This is the default event.
+
Note: The Timer control fires the Timer event instead of Change. The onChange +callback on the underlying widget is remapped automatically.
+

Example

+
Begin Timer Timer1
     Interval = 1000
     Enabled  = True
 End
@@ -839,849 +667,566 @@ Dim counter As Integer
 
 Sub Timer1_Timer ()
     counter = counter + 1
-    Label1.Caption = "Ticks: " & Str$(counter)
-End Sub
-
- - - -

PictureBox

- - -
-VB Equivalent: PictureBox    -DVX Widget: canvas | Name Prefix: Picture + Label1.Caption = "Ticks: " & Str$(counter) +End Sub
+

Common Properties, Events, and Methods

- -

-A drawing surface (canvas). Supports drawing lines, rectangles, circles, +

+

PictureBox

+

PictureBox

+

VB Equivalent: PictureBox -- DVX Widget: canvas | Name Prefix: Picture

+

A drawing surface (canvas). Supports drawing lines, rectangles, circles, text, and individual pixels. Can save and load BMP images. The default -canvas size is 64x64 pixels. -

- -

Type-Specific Methods

- - - - -
MethodParametersDescription
ClearColor As IntegerFill the entire canvas with the specified color.
- -

-Additional drawing methods (DrawLine, DrawRect, -FillRect, FillCircle, SetPixel, -GetPixel, DrawText, Save, -Load) are available through the C API but not currently -exposed through BASIC interface descriptors. -

- -

Default Event: Click

- - - -

Image

- - -
-VB Equivalent: Image    -DVX Widget: image +canvas size is 64x64 pixels.

+

Type-Specific Methods

+
  Method   Parameters         Description
+  ------   ----------------   -------------------------------------------
+  Clear    Color As Integer   Fill the entire canvas with the specified color.
+

Additional drawing methods (DrawLine, DrawRect, FillRect, FillCircle, +SetPixel, GetPixel, DrawText, Save, Load) are available through the C API +but not currently exposed through BASIC interface descriptors.

+

Default Event: Click

+

Common Properties, Events, and Methods

- -

-A static image display control. Loads BMP images from file. Cannot be -placed via the designer toolbox (requires pixel data at creation time); -typically created in code or loaded via the Picture property. -

- -

Type-Specific Properties

- - - - - - -
PropertyTypeDescription
PictureStringPath to a BMP file to load (write-only).
ImageWidthIntegerWidth of the loaded image in pixels (read-only).
ImageHeightIntegerHeight of the loaded image in pixels (read-only).
- -

Default Event: Click

- - - -

ImageButton

- - -
-DVX Extension    -DVX Widget: imagebutton +
+

Image

+

Image

+

VB Equivalent: Image -- DVX Widget: image

+

A static image display control. Loads BMP images from file. Cannot be placed +via the designer toolbox (requires pixel data at creation time); typically +created in code or loaded via the Picture property.

+

Type-Specific Properties

+
  Property      Type      Description
+  -----------   -------   -------------------------------------------
+  Picture       String    Path to a BMP file to load (write-only).
+  ImageWidth    Integer   Width of the loaded image in pixels (read-only).
+  ImageHeight   Integer   Height of the loaded image in pixels (read-only).
+

Default Event: Click

+

Common Properties, Events, and Methods

- -

-A button that displays an image instead of text. Like Image, it requires -pixel data at creation time and is typically loaded via the -Picture property. -

- -

Type-Specific Properties

- - - - - - -
PropertyTypeDescription
PictureStringPath to a BMP file to load (write-only).
ImageWidthIntegerWidth of the loaded image in pixels (read-only).
ImageHeightIntegerHeight of the loaded image in pixels (read-only).
- -

Default Event: Click

- - - -

ProgressBar

- - -
-VB Equivalent: ProgressBar    -DVX Widget: progressbar +
+

ImageButton

+

ImageButton

+

DVX Extension -- DVX Widget: imagebutton

+

A button that displays an image instead of text. Like Image, it requires +pixel data at creation time and is typically loaded via the Picture +property.

+

Type-Specific Properties

+
  Property      Type      Description
+  -----------   -------   -------------------------------------------
+  Picture       String    Path to a BMP file to load (write-only).
+  ImageWidth    Integer   Width of the loaded image in pixels (read-only).
+  ImageHeight   Integer   Height of the loaded image in pixels (read-only).
+

Default Event: Click

+

Common Properties, Events, and Methods

- -

-A horizontal progress indicator bar. -

- -

Type-Specific Properties

- - - - -
PropertyTypeDescription
ValueIntegerCurrent progress value (0-100).
- +
+

ProgressBar

+

ProgressBar

+

VB Equivalent: ProgressBar -- DVX Widget: progressbar

+

A horizontal progress indicator bar.

+

Type-Specific Properties

+
  Property   Type      Description
+  --------   -------   -------------------------------------------
+  Value      Integer   Current progress value (0-100).

No type-specific events or methods. No default event.

- - - -

ListView

- - -
-VB Equivalent: ListView    -DVX Widget: listview +

Common Properties, Events, and Methods

- -

-A multi-column list with column headers. Supports sorting, multi-select, -and drag-to-reorder. Columns are configured via the C API (SetColumns, -SetData). -

- -

Type-Specific Properties

- - - - -
PropertyTypeDescription
ListIndexIntegerIndex of the currently selected row (-1 = none).
- -

Type-Specific Methods

- - - - - - - - - -
MethodParametersDescription
SelectAll(none)Select all rows.
ClearSelection(none)Deselect all rows.
SetMultiSelectMulti As BooleanEnable or disable multi-select.
SetReorderableReorderable As BooleanEnable or disable row reordering.
IsItemSelectedIndex As IntegerReturns True if the row at Index is selected.
SetItemSelectedIndex As Integer, Selected As BooleanSelect or deselect a specific row.
- -

Default Event: Click

- - - -

TreeView

- - -
-VB Equivalent: TreeView    -DVX Widget: treeview +
+

ListView

+

ListView

+

VB Equivalent: ListView -- DVX Widget: listview

+

A multi-column list with column headers. Supports sorting, multi-select, and +drag-to-reorder. Columns are configured via the C API (SetColumns, SetData).

+

Type-Specific Properties

+
  Property    Type      Description
+  ---------   -------   -------------------------------------------
+  ListIndex   Integer   Index of the currently selected row (-1 = none).
+

Type-Specific Methods

+
  Method            Parameters                                Description
+  ---------------   ---------------------------------------   -------------------------------------------
+  SelectAll         (none)                                    Select all rows.
+  ClearSelection    (none)                                    Deselect all rows.
+  SetMultiSelect    Multi As Boolean                          Enable or disable multi-select.
+  SetReorderable    Reorderable As Boolean                    Enable or disable row reordering.
+  IsItemSelected    Index As Integer                          Returns True if the row at Index is selected.
+  SetItemSelected   Index As Integer, Selected As Boolean     Select or deselect a specific row.
+

Default Event: Click

+

Common Properties, Events, and Methods

- -

-A hierarchical tree of expandable/collapsible nodes. Nodes are created -via the C API (wgtTreeItem). Supports multi-select and -drag-to-reorder. -

- -

Type-Specific Methods

- - - - - -
MethodParametersDescription
SetMultiSelectMulti As BooleanEnable or disable multi-select mode.
SetReorderableReorderable As BooleanEnable or disable node reordering.
- -

Default Event: Click

- - - -

TabStrip

- - -
-VB Equivalent: TabStrip    -DVX Widget: tabcontrol +
+

TreeView

+

TreeView

+

VB Equivalent: TreeView -- DVX Widget: treeview

+

A hierarchical tree of expandable/collapsible nodes. Nodes are created via +the C API (wgtTreeItem). Supports multi-select and drag-to-reorder.

+

Type-Specific Methods

+
  Method           Parameters               Description
+  --------------   ----------------------   -------------------------------------------
+  SetMultiSelect   Multi As Boolean         Enable or disable multi-select mode.
+  SetReorderable   Reorderable As Boolean   Enable or disable node reordering.
+

Default Event: Click

+

Common Properties, Events, and Methods

- -

-A tabbed container. Each tab page is a separate container that holds -child controls. Switching tabs shows one page and hides others. -

- -

Type-Specific Properties

- - - - -
PropertyTypeDescription
TabIndexIntegerIndex of the active tab (0-based). Note: this property name collides with the common VB-compatibility TabIndex property, which shadows it at runtime. Use the SetActive method instead to switch tabs.
- -

Type-Specific Methods

- - - - -
MethodParametersDescription
SetActiveIndex As IntegerSwitch to the tab at the given index. This is the recommended way to change tabs at runtime (the TabIndex property is shadowed by the common property handler).
- -

Container: Yes

-

Default Event: Click

- - - -

Splitter

- - -
-DVX Extension    -DVX Widget: splitter +
+

TabStrip

+

TabStrip

+

VB Equivalent: TabStrip -- DVX Widget: tabcontrol

+

A tabbed container. Each tab page is a separate container that holds child +controls. Switching tabs shows one page and hides others.

+

Type-Specific Properties

+
  Property   Type      Description
+  --------   -------   -------------------------------------------
+  TabIndex   Integer   Index of the active tab (0-based). Note: this property name collides with the common VB-compatibility TabIndex property, which shadows it at runtime. Use the SetActive method instead to switch tabs.
+

Type-Specific Methods

+
  Method      Parameters          Description
+  ---------   -----------------   -------------------------------------------
+  SetActive   Index As Integer    Switch to the tab at the given index. This is the recommended way to change tabs at runtime (the TabIndex property is shadowed by the common property handler).
+

Container: Yes

+

Default Event: Click

+
Warning: The TabIndex property is shadowed by the common property handler at runtime. +Use the SetActive method to change tabs programmatically.
+

Common Properties, Events, and Methods

- -

-A resizable split pane. Holds exactly two child widgets separated by a -draggable divider. Default orientation is vertical (top/bottom split). -

- -

Type-Specific Properties

- - - - -
PropertyTypeDescription
PositionIntegerPosition of the divider in pixels from the top (or left).
- -

Container: Yes

+
+

Splitter

+

Splitter

+

DVX Extension -- DVX Widget: splitter

+

A resizable split pane. Holds exactly two child widgets separated by a +draggable divider. Default orientation is vertical (top/bottom split).

+

Type-Specific Properties

+
  Property   Type      Description
+  --------   -------   -------------------------------------------
+  Position   Integer   Position of the divider in pixels from the top (or left).
+

Container: Yes

No default event.

- - - -

ScrollPane

- - -
-DVX Extension    -DVX Widget: scrollpane | Name Prefix: Scroll +

Common Properties, Events, and Methods

- -

-A scrollable container. Place child controls inside and the ScrollPane -automatically provides scrollbars when the content exceeds the visible area. -

- -

Type-Specific Properties

- - - - -
PropertyTypeDescription
NoBorderBooleanWhen True, suppresses the border around the scroll pane.
- -

Container: Yes

+
+

ScrollPane

+

ScrollPane

+

DVX Extension -- DVX Widget: scrollpane | Name Prefix: Scroll

+

A scrollable container. Place child controls inside and the ScrollPane +automatically provides scrollbars when the content exceeds the visible area.

+

Type-Specific Properties

+
  Property   Type      Description
+  --------   -------   -------------------------------------------
+  NoBorder   Boolean   When True, suppresses the border around the scroll pane.
+

Container: Yes

No default event.

- - - -

WrapBox

- - -
-DVX Extension    -DVX Widget: wrapbox +

Common Properties, Events, and Methods

- -

-A container that arranges children in a flowing layout, wrapping to the -next row when the available width is exceeded. Similar to CSS flexbox with -flex-wrap: wrap. -

- -

Type-Specific Properties

- - - - -
PropertyTypeDescription
AlignmentEnumHorizontal alignment of items: Left, Center, or Right.
- -

Container: Yes

-

Default Event: Click

- - - -

Line

- - -
-VB Equivalent: Line    -DVX Widget: separator +
+

WrapBox

+

WrapBox

+

DVX Extension -- DVX Widget: wrapbox

+

A container that arranges children in a flowing layout, wrapping to the next +row when the available width is exceeded. Similar to CSS flexbox with +flex-wrap: wrap.

+

Type-Specific Properties

+
  Property    Type   Description
+  ---------   ----   -------------------------------------------
+  Alignment   Enum   Horizontal alignment of items: Left, Center, or Right.
+

Container: Yes

+

Default Event: Click

+

Common Properties, Events, and Methods

- -

-A visual separator line. The underlying widget supports both horizontal -and vertical orientations. The default (via BASIC) is horizontal. -

- +
+

Line

+

Line

+

VB Equivalent: Line -- DVX Widget: separator

+

A visual separator line. The underlying widget supports both horizontal and +vertical orientations. The default (via BASIC) is horizontal.

No type-specific properties, events, or methods.

- - - -

Spacer

- - -
-DVX Extension    -DVX Widget: spacer +

Common Properties, Events, and Methods

- -

-An invisible layout spacer. Takes up space in the layout without rendering -anything. Useful for pushing controls apart. Give it a Weight -to absorb extra space. -

- +
+

Spacer

+

Spacer

+

DVX Extension -- DVX Widget: spacer

+

An invisible layout spacer. Takes up space in the layout without rendering +anything. Useful for pushing controls apart. Give it a Weight to absorb +extra space.

No type-specific properties, events, or methods.

- - - -

Toolbar

- - -
-VB Equivalent: Toolbar    -DVX Widget: toolbar +

Common Properties, Events, and Methods

- -

-A horizontal container styled as a toolbar, with compact padding and -spacing. Place buttons, labels, or other controls inside. -

- -

Container: Yes

+
+

Toolbar

+

Toolbar

+

VB Equivalent: Toolbar -- DVX Widget: toolbar

+

A horizontal container styled as a toolbar, with compact padding and +spacing. Place buttons, labels, or other controls inside.

+

Container: Yes

No type-specific properties, events, or methods.

- - - -

StatusBar

- - -
-VB Equivalent: StatusBar    -DVX Widget: statusbar +

Common Properties, Events, and Methods

- -

-A horizontal container styled as a status bar, typically placed at the -bottom of a form. At the C API level it accepts child widgets, but it -is not registered as a container in the form runtime, so child controls -cannot be nested inside it in .frm files. Set its -Caption property to display status text. -

- +
+

StatusBar

+

StatusBar

+

VB Equivalent: StatusBar -- DVX Widget: statusbar

+

A horizontal container styled as a status bar, typically placed at the +bottom of a form. At the C API level it accepts child widgets, but it is not +registered as a container in the form runtime, so child controls cannot be +nested inside it in .frm files. Set its Caption property to display status +text.

No type-specific properties, events, or methods.

- - - -

Terminal

- - -
-DVX Extension    -DVX Widget: ansiterm (ANSI terminal emulator) +

Common Properties, Events, and Methods

- -

-A VT100/ANSI terminal emulator widget. Supports ANSI escape sequences, -scrollback buffer, and serial communication. Default size is 80 columns -by 25 rows. -

- -

Type-Specific Properties

- - - - - - -
PropertyTypeDescription
ColsIntegerNumber of character columns (read-only).
RowsIntegerNumber of character rows (read-only).
ScrollbackIntegerNumber of scrollback lines (write-only).
- -

Type-Specific Methods

- - - - - -
MethodParametersDescription
Clear(none)Clear the terminal screen.
WriteText As StringWrite text (with ANSI escape processing) to the terminal.
- +
+

Terminal

+

Terminal

+

DVX Extension -- DVX Widget: ansiterm (ANSI terminal emulator)

+

A VT100/ANSI terminal emulator widget. Supports ANSI escape sequences, +scrollback buffer, and serial communication. Default size is 80 columns by +25 rows.

+

Type-Specific Properties

+
  Property     Type      Description
+  ----------   -------   -------------------------------------------
+  Cols         Integer   Number of character columns (read-only).
+  Rows         Integer   Number of character rows (read-only).
+  Scrollback   Integer   Number of scrollback lines (write-only).
+

Type-Specific Methods

+
  Method   Parameters        Description
+  ------   ---------------   -------------------------------------------
+  Clear    (none)            Clear the terminal screen.
+  Write    Text As String    Write text (with ANSI escape processing) to the terminal.

No default event.

- - - -

Data

- - -
-VB Equivalent: Data    -DVX Widget: data (database record navigator) +

Common Properties, Events, and Methods

- -

-A data access control that connects to a SQLite database and provides -record navigation. Other controls can bind to a Data control via their -DataSource and DataField properties. -See the Data Binding section for details. -

- -

Type-Specific Properties

- - - - - - - - - - - - -
PropertyTypeR/WDescription
DatabaseNameStringR/WPath to the SQLite database file.
RecordSourceStringR/WTable name or SQL SELECT query for the recordset.
KeyColumnStringR/WPrimary key column name (used for UPDATE/DELETE operations).
CaptionStringR/WText displayed on the navigator bar.
BOFBooleanRTrue if the current position is before the first record (read-only).
EOFBooleanRTrue if the current position is past the last record (read-only).
MasterSourceStringR/WName of a master Data control (for master-detail binding).
MasterFieldStringR/WColumn in the master recordset to filter by.
DetailFieldStringR/WColumn in this recordset that matches the master field.
- -

Type-Specific Methods

- - - - - - - - - - - -
MethodParametersDescription
MoveFirst(none)Navigate to the first record.
MoveLast(none)Navigate to the last record.
MoveNext(none)Navigate to the next record.
MovePrevious(none)Navigate to the previous record.
AddNew(none)Add a new blank record.
Delete(none)Delete the current record.
Refresh(none)Re-query the database and reload records.
Update(none)Write pending changes to the database.
- -

Type-Specific Events

- - - - - -
EventParametersDescription
Reposition(none)Fires after the current record changes (navigation). This is the default event.
ValidateCancel As IntegerFires before writing a record. Set Cancel = 1 to abort.
- - - -

DBGrid

- - -
-VB Equivalent: DBGrid    -DVX Widget: dbgrid +
+

Data

+

Data

+

VB Equivalent: Data -- DVX Widget: data (database record navigator)

+

A data access control that connects to a SQLite database and provides record +navigation. Other controls can bind to a Data control via their DataSource +and DataField properties. See .link ctrl.databinding Data Binding for +details.

+

Type-Specific Properties

+
  Property       Type      R/W   Description
+  ------------   -------   ---   -------------------------------------------
+  DatabaseName   String    R/W   Path to the SQLite database file.
+  RecordSource   String    R/W   Table name or SQL SELECT query for the recordset.
+  KeyColumn      String    R/W   Primary key column name (used for UPDATE/DELETE operations).
+  Caption        String    R/W   Text displayed on the navigator bar.
+  BOF            Boolean   R     True if the current position is before the first record (read-only).
+  EOF            Boolean   R     True if the current position is past the last record (read-only).
+  MasterSource   String    R/W   Name of a master Data control (for master-detail binding).
+  MasterField    String    R/W   Column in the master recordset to filter by.
+  DetailField    String    R/W   Column in this recordset that matches the master field.
+

Type-Specific Methods

+
  Method         Parameters   Description
+  ------------   ----------   -------------------------------------------
+  MoveFirst      (none)       Navigate to the first record.
+  MoveLast       (none)       Navigate to the last record.
+  MoveNext       (none)       Navigate to the next record.
+  MovePrevious   (none)       Navigate to the previous record.
+  AddNew         (none)       Add a new blank record.
+  Delete         (none)       Delete the current record.
+  Refresh        (none)       Re-query the database and reload records.
+  Update         (none)       Write pending changes to the database.
+

Type-Specific Events

+
  Event        Parameters          Description
+  ----------   -----------------   -------------------------------------------
+  Reposition   (none)              Fires after the current record changes (navigation). This is the default event.
+  Validate     Cancel As Integer   Fires before writing a record. Set Cancel = 1 to abort.
+

Common Properties, Events, and Methods

+

Data Binding

+

DBGrid

- -

-A data-bound grid that displays records from a Data control in a tabular -format. Columns are auto-generated from the query results. Bind it using -the DataSource property. -

- -

Type-Specific Properties

- - - - - -
PropertyTypeDescription
DataSourceStringName of the Data control that supplies records.
GridLinesBooleanShow or hide grid lines between cells.
- -

Type-Specific Methods

- - - - -
MethodParametersDescription
Refresh(none)Reload and redraw the grid from the Data control.
- -

Type-Specific Events

- - - - - -
EventParametersDescription
Click(none)Fires when a cell is clicked.
DblClick(none)Fires when a cell is double-clicked. This is the default event.
- - - -

Data Binding

- - -

-DVX BASIC provides VB3-style data binding through three properties that can -be set on most controls: -

- - - - - -
PropertySet OnDescription
DataSourceAny controlName of the Data control to bind to (e.g. "Data1").
DataFieldAny controlColumn name from the Data control's recordset to display.
- +
+

DBGrid

+

DBGrid

+

VB Equivalent: DBGrid -- DVX Widget: dbgrid

+

A data-bound grid that displays records from a Data control in a tabular +format. Columns are auto-generated from the query results. Bind it using the +DataSource property.

+

Type-Specific Properties

+
  Property     Type      Description
+  ----------   -------   -------------------------------------------
+  DataSource   String    Name of the Data control that supplies records.
+  GridLines    Boolean   Show or hide grid lines between cells.
+

Type-Specific Methods

+
  Method    Parameters   Description
+  -------   ----------   -------------------------------------------
+  Refresh   (none)       Reload and redraw the grid from the Data control.
+

Type-Specific Events

+
  Event      Parameters   Description
+  --------   ----------   -------------------------------------------
+  Click      (none)       Fires when a cell is clicked.
+  DblClick   (none)       Fires when a cell is double-clicked. This is the default event.
+

Common Properties, Events, and Methods

+

Data

+

Data Binding

+
+
+

Data Binding

+

Data Binding

+

DVX BASIC provides VB3-style data binding through three properties that can +be set on most controls:

+
  Property     Set On        Description
+  ----------   -----------   -------------------------------------------
+  DataSource   Any control   Name of the Data control to bind to (e.g. "Data1").
+  DataField    Any control   Column name from the Data control's recordset to display.

How It Works

- -
    -
  1. Place a Data control on the form and set its DatabaseName - and RecordSource properties.
  2. +
      +
    • Place a Data control on the form and set its DatabaseName and RecordSource + properties.
    • Place one or more display/edit controls (TextBox, Label, etc.) and set - their DataSource to the Data control's name and - DataField to a column name.
    • -
    • When the form loads, the Data control auto-refreshes: it opens the database, - runs the query, and navigates to the first record.
    • + their DataSource to the Data control's name and DataField to a column + name. +
    • When the form loads, the Data control auto-refreshes: it opens the + database, runs the query, and navigates to the first record.
    • Bound controls are updated automatically each time the Data control - repositions (the Reposition event fires, and the runtime - pushes the current record's field values into all bound controls).
    • -
    • When a bound control loses focus (LostFocus), its current - text is written back to the Data control's record cache, and - Update is called automatically to persist changes.
    • -
- + repositions (the Reposition event fires, and the runtime pushes the + current record's field values into all bound controls). + +

When a bound control loses focus (LostFocus), its current text is written +back to the Data control's record cache, and Update is called automatically +to persist changes.

Master-Detail Binding

- -

-For hierarchical data (e.g. orders and order items), use two Data controls: -

- -
    -
  1. A master Data control bound to the parent table.
  2. -
  3. A detail Data control with its MasterSource - set to the master's name, MasterField set to the key column - in the master, and DetailField set to the foreign key column - in the detail table.
  4. -
- -

-When the master record changes, the detail Data control automatically +

For hierarchical data (e.g. orders and order items), use two Data controls:

+
    +
  • A master Data control bound to the parent table.
  • +
+

A detail Data control with its MasterSource set to the master's name, +MasterField set to the key column in the master, and DetailField set to the +foreign key column in the detail table.

+

When the master record changes, the detail Data control automatically re-queries using the master's current value for filtering. All controls -bound to the detail are refreshed. -

- +bound to the detail are refreshed.

DBGrid Binding

- -

-Set the DBGrid's DataSource to a Data control name. The grid -auto-populates columns from the query results and refreshes whenever the -Data control refreshes. -

- -

Example

- -
-VERSION DVX 1.00
+

Set the DBGrid's DataSource to a Data control name. The grid auto-populates +columns from the query results and refreshes whenever the Data control +refreshes.

+

Example

+
VERSION DVX 1.00
 Begin Form frmData
-    Caption      = "Data Binding Example"
+    Caption      = "Data Binding Example"
     AutoSize     = False
     Width        = 400
     Height       = 280
     Begin Data Data1
-        DatabaseName = "myapp.db"
-        RecordSource = "customers"
+        DatabaseName = "myapp.db"
+        RecordSource = "customers"
     End
     Begin Label lblName
-        Caption = "Name:"
+        Caption = "Name:"
     End
     Begin TextBox txtName
-        DataSource = "Data1"
-        DataField  = "name"
+        DataSource = "Data1"
+        DataField  = "name"
     End
     Begin Label lblEmail
-        Caption = "Email:"
+        Caption = "Email:"
     End
     Begin TextBox txtEmail
-        DataSource = "Data1"
-        DataField  = "email"
+        DataSource = "Data1"
+        DataField  = "email"
     End
 End
 
 Sub Data1_Reposition ()
-    Print "Current record changed"
+    Print "Current record changed"
 End Sub
 
 Sub Data1_Validate (Cancel As Integer)
-    If txtName.Text = "" Then
-        MsgBox "Name cannot be empty!"
+    If txtName.Text = "" Then
+        MsgBox "Name cannot be empty!"
         Cancel = 1
     End If
-End Sub
-
- - - - - - -

-Menus are defined in the .frm file using Begin Menu -blocks. Each menu item has a name, caption, and nesting level. Menu items -fire Click events dispatched as -MenuName_Click. -

- +End Sub
+

Data

+

DBGrid

+
+
+

Menu System

+

Menu System

+

Menus are defined in the .frm file using Begin Menu blocks. Each menu item +has a name, caption, and nesting level. Menu items fire Click events +dispatched as MenuName_Click.

FRM Syntax

- -
-Begin Form Form1
-    Caption = "Menu Demo"
+
Begin Form Form1
+    Caption = "Menu Demo"
 
     Begin Menu mnuFile
-        Caption = "&File"
+        Caption = "&File"
         Begin Menu mnuOpen
-            Caption = "&Open"
+            Caption = "&Open"
         End
         Begin Menu mnuSave
-            Caption = "&Save"
+            Caption = "&Save"
         End
         Begin Menu mnuSep1
-            Caption = "-"
+            Caption = "-"
         End
         Begin Menu mnuExit
-            Caption = "E&xit"
+            Caption = "E&xit"
         End
     End
 
     Begin Menu mnuEdit
-        Caption = "&Edit"
+        Caption = "&Edit"
         Begin Menu mnuCopy
-            Caption = "&Copy"
+            Caption = "&Copy"
         End
         Begin Menu mnuPaste
-            Caption = "&Paste"
+            Caption = "&Paste"
         End
     End
-End
-
- +End

Menu Item Properties

- - - - - - -
PropertyTypeDescription
CaptionStringThe text displayed. Use & for accelerator key. Set to "-" for a separator.
CheckedBooleanWhether the menu item shows a checkmark.
EnabledBooleanWhether the menu item is enabled (default True).
- +
  Property   Type      Description
+  --------   -------   -------------------------------------------
+  Caption    String    The text displayed. Use & for accelerator key. Set to "-" for a separator.
+  Checked    Boolean   Whether the menu item shows a checkmark.
+  Enabled    Boolean   Whether the menu item is enabled (default True).

Nesting

- -

-Menu items are nested by placing Begin Menu blocks inside -other Begin Menu blocks: -

- +

Menu items are nested by placing Begin Menu blocks inside other Begin Menu +blocks:

    -
  • Level 0: top-level menu bar headers (e.g. "File", "Edit").
  • +
  • Level 0: top-level menu bar headers (e.g. "File", "Edit").
  • Level 1: items within a top-level menu.
  • -
  • Level 2+: submenu items.
- -

-A level-0 menu that contains children becomes a top-level menu header. -A non-level-0 menu that contains children becomes a submenu. -

- +

Level 2+: submenu items.

+

A level-0 menu that contains children becomes a top-level menu header. A +non-level-0 menu that contains children becomes a submenu.

Event Dispatch

- -

-Each clickable menu item (not headers, not separators) receives a unique -numeric ID at load time. When clicked, the form's onMenu -handler maps the ID to the menu item's name and fires -MenuName_Click. -

- -
-Sub mnuOpen_Click ()
-    MsgBox "Open was clicked"
+

Each clickable menu item (not headers, not separators) receives a unique +numeric ID at load time. When clicked, the form's onMenu handler maps the ID +to the menu item's name and fires MenuName_Click.

+
Sub mnuOpen_Click ()
+    MsgBox "Open was clicked"
 End Sub
 
 Sub mnuExit_Click ()
     Unload Form1
-End Sub
-
- - - -

Control Arrays

- - -

-DVX BASIC supports VB-style control arrays. Multiple controls can share -the same name, differentiated by an Index property. When an -event fires on a control array element, the element's index is passed as -the first parameter. -

- +End Sub
+

Form

+

FRM File Format

+
+
+

Control Arrays

+

Control Arrays

+

DVX BASIC supports VB-style control arrays. Multiple controls can share the +same name, differentiated by an Index property. When an event fires on a +control array element, the element's index is passed as the first parameter.

Defining Control Arrays in FRM

- -
-Begin CommandButton Command1
-    Caption = "Button A"
+
Begin CommandButton Command1
+    Caption = "Button A"
     Index   = 0
 End
 Begin CommandButton Command1
-    Caption = "Button B"
+    Caption = "Button B"
     Index   = 1
 End
 Begin CommandButton Command1
-    Caption = "Button C"
+    Caption = "Button C"
     Index   = 2
-End
-
- +End

Event Handler Convention

- -

-When a control has an Index property (>= 0), the event handler -receives Index As Integer as the first parameter, before any -event-specific parameters. -

- -
-Sub Command1_Click (Index As Integer)
+

When a control has an Index property (>= 0), the event handler receives +Index As Integer as the first parameter, before any event-specific +parameters.

+
Sub Command1_Click (Index As Integer)
     Select Case Index
         Case 0
-            MsgBox "Button A clicked"
+            MsgBox "Button A clicked"
         Case 1
-            MsgBox "Button B clicked"
+            MsgBox "Button B clicked"
         Case 2
-            MsgBox "Button C clicked"
+            MsgBox "Button C clicked"
     End Select
-End Sub
-
- +End Sub

Accessing Array Elements in Code

- -

-Use the indexed form ControlName(Index) to access -a specific element: -

- -
-Command1(0).Caption = "New Text"
-Command1(1).Enabled = False
-
- -
-Control array elements share the same event handler Sub. The runtime -prepends the Index argument automatically. If you define parameters on -the Sub, Index comes first, followed by the event's own parameters -(e.g. KeyPress would be -Sub Ctrl1_KeyPress (Index As Integer, KeyAscii As Integer)). +

Use the indexed form ControlName(Index) to access a specific element:

+
Command1(0).Caption = "New Text"
+Command1(1).Enabled = False
+
Note: Control array elements share the same event handler Sub. The runtime +prepends the Index argument automatically. If you define parameters on the +Sub, Index comes first, followed by the event's own parameters (e.g. +KeyPress would be Sub Ctrl1_KeyPress (Index As Integer, KeyAscii As +Integer)).
+

Common Properties, Events, and Methods

+

FRM File Format

- - - -

FRM File Format

- - -

-The .frm file is a text file that describes a form's layout, -controls, menus, and code. It follows a format compatible with VB3 .frm -files, with DVX-specific extensions. -

- +
+

FRM File Format

+

FRM File Format

+

The .frm file is a text file that describes a form's layout, controls, +menus, and code. It follows a format compatible with VB3 .frm files, with +DVX-specific extensions.

Structure

- -
-VERSION DVX 1.00
+
VERSION DVX 1.00
 Begin Form FormName
-    form-level properties...
+    form-level properties...
 
     Begin Menu mnuFile
-        Caption = "&File"
+        Caption = "&File"
         Begin Menu mnuOpen
-            Caption = "&Open"
+            Caption = "&Open"
         End
     End
 
-    Begin TypeName ControlName
-        property = value
+    Begin TypeName ControlName
+        property = value
         ...
     End
 
     Begin Frame Frame1
-        Caption = "Group"
-        Begin TypeName ChildName
+        Caption = "Group"
+        Begin TypeName ChildName
             ...
         End
     End
 End
 
-BASIC code follows...
+BASIC code follows...
 
 Sub FormName_Load ()
     ...
-End Sub
-
- +End Sub

Rules

-
    -
  • The VERSION line is optional. VERSION DVX 1.00 marks a native DVX form. - VB forms with version <= 2.0 are accepted for import.
  • -
  • The form block begins with Begin Form Name and ends with End.
  • -
  • Controls are nested with Begin TypeName Name / End.
  • -
  • Container controls (Frame, VBox, HBox, Toolbar, TabStrip, ScrollPane, Splitter, WrapBox) - can have child controls nested inside them.
  • -
  • Properties are assigned as Key = Value. String values are optionally quoted.
  • -
  • Everything after the form's closing End is BASIC source code.
  • -
  • Comments in the form section use ' (single quote).
  • -
  • Blank lines are ignored in the form section.
  • +
  • The VERSION line is optional. VERSION DVX 1.00 marks a native DVX form. VB + forms with version <= 2.0 are accepted for import.
  • +
  • The form block begins with Begin Form Name and ends with End.
  • +
  • Controls are nested with Begin TypeName Name / End.
  • +
  • Container controls (Frame, VBox, HBox, Toolbar, TabStrip, ScrollPane, + Splitter, WrapBox) can have child controls nested inside them.
  • +
  • Properties are assigned as Key = Value. String values are optionally + quoted.
  • +
  • Everything after the form's closing End is BASIC source code.
  • +
  • Comments in the form section use ' (single quote).
- +

Blank lines are ignored in the form section.

Common FRM Properties

- - - - - - - - - - - - - - - - - - - - - - - -
PropertyApplies ToDescription
CaptionForm, controlsDisplay text or window title.
TextTextBox, ComboBoxInitial text content.
MinWidth / WidthControlsMinimum width. Both names are accepted.
MinHeight / HeightControlsMinimum height. Both names are accepted.
MaxWidthControlsMaximum width (0 = no cap).
MaxHeightControlsMaximum height (0 = no cap).
WeightControlsLayout weight for flexible sizing.
LeftForm, controlsX position (used by Form when Centered=False; informational for controls).
TopForm, controlsY position.
IndexControlsControl array index (-1 or absent = not in array).
VisibleControlsInitial visibility.
EnabledControlsInitial enabled state.
LayoutForm"VBox" or "HBox".
AutoSizeFormAuto-fit window to content.
ResizableFormAllow runtime resizing.
CenteredFormCenter window on screen.
DatabaseNameDataSQLite database file path.
RecordSourceDataTable name or SQL query.
DataSourceBound controlsName of the Data control.
DataFieldBound controlsColumn name in the recordset.
- - -
-

-DVX BASIC Control Reference -- Generated from source code analysis of -formrt.c, ideProperties.c, ideDesigner.c, and widget DXE interface descriptors. -

- +
  Property                  Applies To        Description
+  -----------------------   ---------------   -------------------------------------------
+  Caption                   Form, controls    Display text or window title.
+  Text                      TextBox, ComboBox Initial text content.
+  MinWidth / Width          Controls          Minimum width. Both names are accepted.
+  MinHeight / Height        Controls          Minimum height. Both names are accepted.
+  MaxWidth                  Controls          Maximum width (0 = no cap).
+  MaxHeight                 Controls          Maximum height (0 = no cap).
+  Weight                    Controls          Layout weight for flexible sizing.
+  Left                      Form, controls    X position (used by Form when Centered=False; informational for controls).
+  Top                       Form, controls    Y position.
+  Index                     Controls          Control array index (-1 or absent = not in array).
+  Visible                   Controls          Initial visibility.
+  Enabled                   Controls          Initial enabled state.
+  Layout                    Form              "VBox" or "HBox".
+  AutoSize                  Form              Auto-fit window to content.
+  Resizable                 Form              Allow runtime resizing.
+  Centered                  Form              Center window on screen.
+  DatabaseName              Data              SQLite database file path.
+  RecordSource              Data              Table name or SQL query.
+  DataSource                Bound controls    Name of the Data control.
+  DataField                 Bound controls    Column name in the recordset.
+

Form

+

Common Properties, Events, and Methods

+

Menu System

+

Control Arrays

+
+ diff --git a/docs/dvxbasic_ide_guide.html b/docs/dvxbasic_ide_guide.html index 4a82f00..c68683f 100644 --- a/docs/dvxbasic_ide_guide.html +++ b/docs/dvxbasic_ide_guide.html @@ -1,895 +1,868 @@ - + - + DVX BASIC IDE Guide - + +
+

DVX BASIC IDE Guide

-

-DVX BASIC is a Visual BASIC development environment for the DVX GUI System. -It provides a VB3-style integrated development environment with a code editor, -form designer, project system, and a full interactive debugger -- all running -natively on DOS under the DVX windowing system. -

-

-This guide covers every feature of the IDE: menus, toolbar, editor, form -designer, project management, debugger, and auxiliary windows. -

- -
-Table of Contents +

DVX BASIC IDE Guide

+

DVX BASIC is a Visual BASIC development environment for the DVX GUI System. +It provides a VB3-style integrated development environment with a code +editor, form designer, project system, and a full interactive debugger -- +all running natively on DOS under the DVX windowing system.

+

This guide covers every feature of the IDE: menus, toolbar, editor, form +designer, project management, debugger, and auxiliary windows.

+

IDE Windows

+

The DVX BASIC IDE is modeled after Visual Basic 3.0. It consists of several +floating windows arranged on the DVX desktop:

    -
  • 1. Overview
  • -
  • 2. Menu Reference
  • -
  • 3. Toolbar
  • -
  • 4. Code Editor
  • -
  • 5. Form Designer
  • -
  • 6. Project System
  • -
  • 7. Properties Panel
  • -
  • 8. Toolbox
  • -
  • 9. Debugger
  • -
  • 10. Debug Windows
  • -
  • 11. Immediate Window
  • -
  • 12. Output Window
  • -
  • 13. Find / Replace
  • -
  • 14. Preferences
  • +
  • Main Toolbar Window -- anchored at the top of the screen. Contains the + menu bar, toolbar buttons, and status bar.
  • +
  • Code Editor -- the primary editing surface for BASIC source code, with + Object/Event dropdowns, syntax highlighting, and line numbers.
  • +
  • Form Designer -- a visual design surface for .frm files, showing a WYSIWYG + preview of the form with grab handles for resizing controls.
  • +
  • Project Explorer -- a tree view listing all files in the project.
  • +
  • Toolbox -- a palette of available controls for placing on forms.
  • +
  • Properties Panel -- a tree of controls and a list of editable properties + for the selected control.
  • +
  • Output Window -- displays PRINT output and runtime errors.
  • +
  • Immediate Window -- an interactive REPL for evaluating expressions and + modifying variables at runtime.
+

Debug Windows -- Locals, Call Stack, Watch, and Breakpoints windows that +appear automatically when debugging.

+

The IDE compiles BASIC source into bytecode and runs it in an integrated +virtual machine (VM). Programs execute in cooperative slices (10,000 VM +steps per slice), yielding to the DVX event loop between slices so the GUI +remains responsive.

+

File Menu

+

Edit Menu

+

Run Menu

+

View Menu

+

Window Menu

+

Tools Menu

+

Help Menu

+

Toolbar

+

Code Editor

+

Form Designer

+

Project System

+

Properties Panel

+

Toolbox

+

Debugger

+

Locals Window

+

Call Stack Window

+

Watch Window

+

Breakpoints Window

+

Immediate Window

+

Output Window

+

Find / Replace

+

Preferences

+

Keyboard Shortcuts

- - -

1. Overview

- -

-The DVX BASIC IDE is modeled after Visual Basic 3.0. It consists of several -floating windows arranged on the DVX desktop: -

-
    -
  • Main Toolbar Window -- anchored at the top of the screen. - Contains the menu bar, toolbar buttons, and status bar.
  • -
  • Code Editor -- the primary editing surface for BASIC source code, - with Object/Event dropdowns, syntax highlighting, and line numbers.
  • -
  • Form Designer -- a visual design surface for .frm files, - showing a WYSIWYG preview of the form with grab handles for resizing controls.
  • -
  • Project Explorer -- a tree view listing all files in the project.
  • -
  • Toolbox -- a palette of available controls for placing on forms.
  • -
  • Properties Panel -- a tree of controls and a list of editable properties - for the selected control.
  • -
  • Output Window -- displays PRINT output and runtime errors.
  • -
  • Immediate Window -- an interactive REPL for evaluating expressions - and modifying variables at runtime.
  • -
  • Debug Windows -- Locals, Call Stack, Watch, and Breakpoints windows - that appear automatically when debugging.
  • -
- -

-The IDE compiles BASIC source into bytecode and runs it in an integrated virtual -machine (VM). Programs execute in cooperative slices (10,000 VM steps per slice), -yielding to the DVX event loop between slices so the GUI remains responsive. -

- - - - -

File Menu

- - - - - - - - - - - - - - - - -
Menu ItemShortcutDescription
New Project...Create a new DVX BASIC project.
Open Project...Open an existing .dbp project file.
Save ProjectSave the current project file to disk.
Close ProjectClose the current project (prompts to save unsaved changes).

Project Properties...Edit project metadata (name, author, version, startup form, icon, etc.).

Add File...Ctrl+OAdd a .bas or .frm file to the project. If no project is open, creates an implicit project from the file.
Save FileCtrl+SSave the active file to disk.
Save AllSave all modified files in the project.

Remove FileRemove the selected file from the project (prompts to save if modified).

ExitClose the IDE (prompts to save unsaved changes).
- -

Edit Menu

- - - - - - - - - - - - - -
Menu ItemShortcutDescription
CutCtrl+XCut selected text to the clipboard.
CopyCtrl+CCopy selected text to the clipboard.
PasteCtrl+VPaste text from the clipboard.

Select AllCtrl+ASelect all text in the active editor.

DeleteDelDelete the selected text or control (in the form designer).

Find...Ctrl+FOpen the Find/Replace dialog.
Find NextF3Find the next occurrence of the search text.
Replace...Ctrl+HOpen the Find/Replace dialog with replace enabled.
- -

Run Menu

- - - - - - - - - - - - - - - - - -
Menu ItemShortcutDescription
RunF5Compile and run the program. If paused at a breakpoint, resumes execution with debugging disabled (runs free).
DebugShift+F5Compile and run with the debugger active. Breakpoints are active but execution does not pause at the first statement. If paused, resumes to the next breakpoint.
Run Without RecompileCtrl+F5Re-run the last compiled module without recompiling.
StopEscStop the running program immediately.

Step IntoF8Execute one statement, stepping into SUB/FUNCTION calls. If idle, starts a debug session and breaks at the first statement.
Step OverShift+F8Execute one statement, stepping over SUB/FUNCTION calls.
Step OutCtrl+Shift+F8Run until the current SUB/FUNCTION returns.
Run to CursorCtrl+F8Run until execution reaches the line where the cursor is positioned.

Toggle BreakpointF9Toggle a breakpoint on the current editor line.

Clear OutputClear the Output window.

Save on RunCheckbox: when enabled, all modified files are saved automatically before compiling. Persisted in preferences.
- -

View Menu

- - - - - - - - - -
Menu ItemShortcutDescription
CodeF7Switch to Code view for the active file (or the file selected in the Project Explorer).
DesignerShift+F7Switch to Design view for the active form file.

ToolbarCheckbox: show or hide the toolbar. Persisted in preferences.
Status BarCheckbox: show or hide the status bar. Persisted in preferences.

Menu Editor...Ctrl+EOpen the Menu Editor dialog for the active form. Allows designing menu bars with captions, names, levels, checked state, and enabled state.
- -

Window Menu

- - - - - - - - - - - - - -
Menu ItemDescription
Code EditorShow or raise the Code Editor window.
OutputShow or raise the Output window.
ImmediateShow or raise the Immediate window.
LocalsShow or raise the Locals debug window.
Call StackShow or raise the Call Stack debug window.
WatchShow or raise the Watch debug window.
BreakpointsShow or raise the Breakpoints window.

Project ExplorerShow or raise the Project Explorer window.
ToolboxShow or raise the Toolbox window.
PropertiesShow or raise the Properties panel.
- -

Tools Menu

- - - - - -
Menu ItemDescription
Preferences...Open the Preferences dialog (editor settings and project defaults).

Debug LayoutCheckbox: toggle a debug overlay that shows widget layout boundaries. Useful for diagnosing widget layout issues.
- -

Help Menu

- - - -
Menu ItemDescription
About DVX BASIC...Show the About dialog with version and copyright information.
- - -

3. Toolbar

- -

-The toolbar is organized into four groups separated by vertical dividers. -Each button has a tooltip showing its name and keyboard shortcut. -

- +
+

File Menu

+

File Menu

+
  Menu Item              Shortcut   Description
+  ---------              --------   -----------
+  New Project...                    Create a new DVX BASIC project.
+  Open Project...                   Open an existing .dbp project file.
+  Save Project                      Save the current project file to disk.
+  Close Project                     Close the current project (prompts to save unsaved changes).
+  ---
+  Project Properties...             Edit project metadata (name, author, version, startup form, icon, etc.).
+  ---
+  Add File...            Ctrl+O     Add a .bas or .frm file to the project. If no project is open, creates an implicit project from the file.
+  Save File              Ctrl+S     Save the active file to disk.
+  Save All                          Save all modified files in the project.
+  ---
+  Remove File                       Remove the selected file from the project (prompts to save if modified).
+  ---
+  Exit                              Close the IDE (prompts to save unsaved changes).
+

Edit Menu

+

Back to Overview

+
+
+

Edit Menu

+

Edit Menu

+
  Menu Item    Shortcut   Description
+  ---------    --------   -----------
+  Cut          Ctrl+X     Cut selected text to the clipboard.
+  Copy         Ctrl+C     Copy selected text to the clipboard.
+  Paste        Ctrl+V     Paste text from the clipboard.
+  ---
+  Select All   Ctrl+A     Select all text in the active editor.
+  ---
+  Delete       Del        Delete the selected text or control (in the form designer).
+  ---
+  Find...      Ctrl+F     Open the Find/Replace dialog.
+  Find Next    F3         Find the next occurrence of the search text.
+  Replace...   Ctrl+H     Open the Find/Replace dialog with replace enabled.
+

Run Menu

+

Back to Overview

+
+
+

Run Menu

+

Run Menu

+
  Menu Item                Shortcut         Description
+  ---------                --------         -----------
+  Run                      F5               Compile and run the program. If paused at a breakpoint, resumes execution with debugging disabled (runs free).
+  Debug                    Shift+F5         Compile and run with the debugger active. Breakpoints are active but execution does not pause at the first statement. If paused, resumes to the next breakpoint.
+  Run Without Recompile    Ctrl+F5          Re-run the last compiled module without recompiling.
+  Stop                     Esc              Stop the running program immediately.
+  ---
+  Step Into                F8               Execute one statement, stepping into SUB/FUNCTION calls. If idle, starts a debug session and breaks at the first statement.
+  Step Over                Shift+F8         Execute one statement, stepping over SUB/FUNCTION calls.
+  Step Out                 Ctrl+Shift+F8    Run until the current SUB/FUNCTION returns.
+  Run to Cursor            Ctrl+F8          Run until execution reaches the line where the cursor is positioned.
+  ---
+  Toggle Breakpoint        F9               Toggle a breakpoint on the current editor line.
+  ---
+  Clear Output                              Clear the Output window.
+  ---
+  Save on Run                               Checkbox: when enabled, all modified files are saved automatically before compiling. Persisted in preferences.
+

View Menu

+

Back to Overview

+
+
+

View Menu

+

View Menu

+
  Menu Item        Shortcut   Description
+  ---------        --------   -----------
+  Code             F7         Switch to Code view for the active file (or the file selected in the Project Explorer).
+  Designer         Shift+F7   Switch to Design view for the active form file.
+  ---
+  Toolbar                     Checkbox: show or hide the toolbar. Persisted in preferences.
+  Status Bar                  Checkbox: show or hide the status bar. Persisted in preferences.
+  ---
+  Menu Editor...   Ctrl+E     Open the Menu Editor dialog for the active form. Allows designing menu bars with captions, names, levels, checked state, and enabled state.
+

Window Menu

+

Back to Overview

+
+
+

Window Menu

+

Window Menu

+
  Menu Item          Description
+  ---------          -----------
+  Code Editor        Show or raise the Code Editor window.
+  Output             Show or raise the Output window.
+  Immediate          Show or raise the Immediate window.
+  Locals             Show or raise the Locals debug window.
+  Call Stack         Show or raise the Call Stack debug window.
+  Watch              Show or raise the Watch debug window.
+  Breakpoints        Show or raise the Breakpoints window.
+  ---
+  Project Explorer   Show or raise the Project Explorer window.
+  Toolbox            Show or raise the Toolbox window.
+  Properties         Show or raise the Properties panel.
+

Tools Menu

+

Back to Overview

+
+
+

Tools Menu

+

Tools Menu

+
  Menu Item        Description
+  ---------        -----------
+  Preferences...   Open the Preferences dialog (editor settings and project defaults).
+  ---
+  Debug Layout     Checkbox: toggle a debug overlay that shows widget layout boundaries. Useful for diagnosing widget layout issues.
+

Help Menu

+

Back to Overview

+
+
+

Help Menu

+

Help Menu

+
  Menu Item            Description
+  ---------            -----------
+  About DVX BASIC...   Show the About dialog with version and copyright information.
+

Back to Overview

+
+
+

Toolbar

+

Toolbar

+

The toolbar is organized into four groups separated by vertical dividers. +Each button has a tooltip showing its name and keyboard shortcut.

File Group

- - - - -
ButtonShortcutAction
OpenCtrl+OAdd a file to the project (same as File > Add File).
SaveCtrl+SSave the active file.
- +
  Button   Shortcut   Action
+  ------   --------   ------
+  Open     Ctrl+O     Add a file to the project (same as File > Add File).
+  Save     Ctrl+S     Save the active file.

Run Group

- - - - -
ButtonShortcutAction
RunF5Compile and run the program.
StopEscStop the running program.
- +
  Button   Shortcut   Action
+  ------   --------   ------
+  Run      F5         Compile and run the program.
+  Stop     Esc        Stop the running program.

Debug Group

- - - - - - - -
ButtonShortcutAction
DebugShift+F5Start or resume a debug session.
Step IntoF8Step into the next statement.
Step OverShift+F8Step over the next statement.
Step OutCtrl+Shift+F8Step out of the current procedure.
Run to CursorCtrl+F8Run to the cursor position.
- +
  Button          Shortcut         Action
+  ------          --------         ------
+  Debug           Shift+F5         Start or resume a debug session.
+  Step Into       F8               Step into the next statement.
+  Step Over       Shift+F8         Step over the next statement.
+  Step Out        Ctrl+Shift+F8    Step out of the current procedure.
+  Run to Cursor   Ctrl+F8          Run to the cursor position.

View Group

- - - - -
ButtonShortcutAction
CodeF7Switch to Code view.
DesignShift+F7Switch to Design view.
- - -

4. Code Editor

- -

-The Code Editor is the primary editing window for BASIC source code. It +

  Button   Shortcut   Action
+  ------   --------   ------
+  Code     F7         Switch to Code view.
+  Design   Shift+F7   Switch to Design view.
+

Back to Overview

+
+
+

Code Editor

+

Code Editor

+

The Code Editor is the primary editing window for BASIC source code. It occupies the center of the screen, below the toolbar and above the Output -and Immediate windows. -

- +and Immediate windows.

Object and Function Dropdowns

-

-At the top of the Code Editor are two dropdown lists: -

+

At the top of the Code Editor are two dropdown lists:

    -
  • Object -- lists (General) plus all objects - (form name, control names, menu item names). Selecting an object filters - the Function dropdown.
  • -
  • Function -- lists all event handlers (procedures) for - the selected object. Implemented handlers are listed first (plain text); - unimplemented handlers follow in brackets (e.g., [Click]). - Selecting an unimplemented event creates a new event handler stub.
  • +
  • Object -- lists (General) plus all objects (form name, control names, menu + item names). Selecting an object filters the Function dropdown.
-

-The editor shows one procedure at a time. Each procedure has its own buffer, -and switching between them is instantaneous. The (General) section -contains module-level declarations and code. -

- +

Function -- lists all event handlers (procedures) for the selected object. +Implemented handlers are listed first (plain text); unimplemented handlers +follow in brackets (e.g., [Click]). Selecting an unimplemented event creates +a new event handler stub.

+

The editor shows one procedure at a time. Each procedure has its own buffer, +and switching between them is instantaneous. The (General) section contains +module-level declarations and code.

Syntax Highlighting

-

-The editor applies real-time syntax coloring as you type. The following -categories are highlighted in distinct colors: -

- - - - - - - - -
CategoryExamples
KeywordsIF, THEN, FOR, NEXT, SUB, FUNCTION, DIM, PRINT, SELECT, CASE, DO, LOOP, WHILE, WEND, END, EXIT, CALL, GOSUB, GOTO, RETURN, DECLARE, CONST, TYPE, AND, OR, NOT, XOR, MOD, etc.
Type namesINTEGER, LONG, SINGLE, DOUBLE, STRING, BOOLEAN, BYTE, TRUE, FALSE
String literals"Hello, World!"
Comments' This is a comment, REM This is a comment
Numbers42, 3.14
Operators=, <, >, +, -, *, /, \, &
- +

The editor applies real-time syntax coloring as you type. The following +categories are highlighted in distinct colors:

+
  Category          Examples
+  --------          --------
+  Keywords          IF, THEN, FOR, NEXT, SUB, FUNCTION, DIM, PRINT, SELECT, CASE, DO, LOOP, WHILE, WEND, END, EXIT, CALL, GOSUB, GOTO, RETURN, DECLARE, CONST, TYPE, AND, OR, NOT, XOR, MOD, etc.
+  Type names        INTEGER, LONG, SINGLE, DOUBLE, STRING, BOOLEAN, BYTE, TRUE, FALSE
+  String literals   "Hello, World!"
+  Comments          ' This is a comment, REM This is a comment
+  Numbers           42, 3.14
+  Operators         =, <, >, +, -, *, /, \, &

Editor Features

    -
  • Line numbers -- displayed in the gutter on the left side.
  • -
  • Auto-indent -- new lines are automatically indented to match - the previous line.
  • -
  • Tab handling -- the Tab key is captured by the editor. - Tab width and whether to insert spaces or tab characters are configurable - in Preferences (default: 3 spaces).
  • -
  • Gutter click -- clicking in the line number gutter toggles - a breakpoint on that line.
  • -
  • Line decorations -- breakpoint lines show a red dot in the - gutter. The current debug line (when paused) is highlighted with a yellow - background.
  • +
  • Line numbers -- displayed in the gutter on the left side.
  • +
  • Auto-indent -- new lines are automatically indented to match the previous + line.
  • +
  • Tab handling -- the Tab key is captured by the editor. Tab width and + whether to insert spaces or tab characters are configurable in + Preferences (default: 3 spaces).
  • +
  • Gutter click -- clicking in the line number gutter toggles a breakpoint on + that line.
- - -

5. Form Designer

- -

-The Form Designer provides a visual design surface for editing .frm files. -Switch to it with Shift+F7 or the Design toolbar button. It opens -in a separate window showing a WYSIWYG preview of the form. -

- +

Line decorations -- breakpoint lines show a red dot in the gutter. The +current debug line (when paused) is highlighted with a yellow background.

+

Back to Overview

+
+
+

Form Designer

+

Form Designer

+

The Form Designer provides a visual design surface for editing .frm files. +Switch to it with Shift+F7 or the Design toolbar button. It opens in a +separate window showing a WYSIWYG preview of the form.

Design Surface

    -
  • Grid snapping -- controls snap to an 8-pixel grid - (DSGN_GRID_SIZE) when placed or resized.
  • -
  • Selection -- click a control to select it. The selected - control is highlighted with grab handles.
  • -
  • Grab handles -- 6x6 pixel handles appear on the right edge (E), - bottom edge (S), and bottom-right corner (SE) of the selected control. - Drag a handle to resize the control.
  • -
  • Reordering -- drag a control vertically to reorder it - within the form's layout (VBox/HBox).
  • -
  • Placing controls -- select a control type in the Toolbox, - then click on the form to place a new instance. The control is auto-named - (e.g., Command1, Command2). Clicking the same - tool again deselects it (toggles back to pointer mode).
  • -
  • Menu bar preview -- if the form has menu items (defined via the - Menu Editor), a preview menu bar is rendered on the design window.
  • -
  • Delete key -- removes the selected control from the form.
  • +
  • Grid snapping -- controls snap to an 8-pixel grid (DSGN_GRID_SIZE) when + placed or resized.
  • +
  • Selection -- click a control to select it. The selected control is + highlighted with grab handles.
  • +
  • Grab handles -- 6x6 pixel handles appear on the right edge (E), bottom + edge (S), and bottom-right corner (SE) of the selected control. Drag a + handle to resize the control.
  • +
  • Reordering -- drag a control vertically to reorder it within the form's + layout (VBox/HBox).
  • +
  • Placing controls -- select a control type in the Toolbox, then click on + the form to place a new instance. The control is auto-named (e.g., + Command1, Command2). Clicking the same tool again deselects it (toggles + back to pointer mode).
  • +
  • Menu bar preview -- if the form has menu items (defined via the Menu + Editor), a preview menu bar is rendered on the design window.
- +

Delete key -- removes the selected control from the form.

Form Properties

-

-Forms have the following design-time properties: Name, Caption, Width, Height, -Left, Top, Layout (VBox or HBox), Centered, AutoSize, and Resizable. -

- - -

6. Project System

- +

Forms have the following design-time properties: Name, Caption, Width, +Height, Left, Top, Layout (VBox or HBox), Centered, AutoSize, and Resizable.

+

Properties Panel

+

Toolbox

+

Back to Overview

+
+
+

Project System

+

Project System

Project Files (.dbp)

-

-A DVX BASIC project is stored as a .dbp file (DVX BASIC Project). -The project file records: -

+

A DVX BASIC project is stored as a .dbp file (DVX BASIC Project). The +project file records:

    -
  • Name -- the project display name (up to 32 characters).
  • -
  • Startup Form -- which form to show automatically when the - program starts.
  • -
  • Metadata -- Author, Company, Version, Copyright, Description, - and Icon Path (for compiled binaries).
  • -
  • File list -- relative paths (8.3 DOS names) of all .bas and .frm - files in the project. Each entry tracks whether it is a form file.
  • +
  • Name -- the project display name (up to 32 characters).
  • +
  • Startup Form -- which form to show automatically when the program starts.
  • +
  • Metadata -- Author, Company, Version, Copyright, Description, and Icon + Path (for compiled binaries).
- +

File list -- relative paths (8.3 DOS names) of all .bas and .frm files in +the project. Each entry tracks whether it is a form file.

Source Map

-

-When the project is compiled, all files are concatenated into a single source -stream. A source map tracks which lines belong to which file, enabling accurate -error reporting and debugger navigation across multiple files. For .frm files, -an injected BEGINFORM directive is prepended to the code section. -

- +

When the project is compiled, all files are concatenated into a single +source stream. A source map tracks which lines belong to which file, +enabling accurate error reporting and debugger navigation across multiple +files. For .frm files, an injected BEGINFORM directive is prepended to the +code section.

Project Operations

- - - - - - - - - -
OperationDescription
New ProjectCreates a blank project with a name and directory. A default .frm file is added automatically.
Open ProjectOpens a .dbp file and loads all referenced files into memory.
Save ProjectWrites the .dbp file to disk.
Close ProjectCloses the project, prompting to save unsaved changes.
Add FileAdds a .bas or .frm file to the project. Opening a file without a project auto-creates an implicit project.
Remove FileRemoves a file from the project (prompts to save if modified).
Project PropertiesOpens a dialog for editing project metadata (name, author, company, version, copyright, description, icon, startup form).
- +
  Operation             Description
+  ---------             -----------
+  New Project           Creates a blank project with a name and directory. A default .frm file is added automatically.
+  Open Project          Opens a .dbp file and loads all referenced files into memory.
+  Save Project          Writes the .dbp file to disk.
+  Close Project         Closes the project, prompting to save unsaved changes.
+  Add File              Adds a .bas or .frm file to the project. Opening a file without a project auto-creates an implicit project.
+  Remove File           Removes a file from the project (prompts to save if modified).
+  Project Properties    Opens a dialog for editing project metadata (name, author, company, version, copyright, description, icon, startup form).

Project Explorer

-

-The Project Explorer is a tree view window listing all project files. Double-click -a file to open it: .bas files open in Code view, .frm files open in Design view. -The selected file in the Project Explorer determines the target for View > Code -and View > Designer commands. -

- - -

7. Properties Panel

- -

-The Properties panel (Window > Properties) has two sections: -

+

The Project Explorer is a tree view window listing all project files. +Double-click a file to open it: .bas files open in Code view, .frm files +open in Design view. The selected file in the Project Explorer determines +the target for View > Code and View > Designer commands.

+

Back to Overview

+
+
+

Properties Panel

+

Properties Panel

+

The Properties panel (Window > Properties) has two sections:

    -
  • Control tree -- a TreeView at the top listing the form and all - its controls in layout order. Click a control name to select it in both the - Properties panel and the Form Designer. Drag items in the tree to reorder - controls in the form's layout.
  • -
  • Property list -- a two-column ListView below the tree showing - property names and values for the selected control. Double-click a property - value to edit it via an InputBox dialog. Changes take effect immediately in - the designer preview.
  • +
  • Control tree -- a TreeView at the top listing the form and all its + controls in layout order. Click a control name to select it in both the + Properties panel and the Form Designer. Drag items in the tree to + reorder controls in the form's layout.
-

-Each control type exposes different properties (e.g., Caption, Text, Width, Height, -MaxWidth, MaxHeight, Weight, Alignment, Enabled, Visible, and type-specific -properties like DataSource and DataField for data-bound controls). -

- - -

8. Toolbox

- -

-The Toolbox (Window > Toolbox) is a floating palette of -buttons, one for each available control type. Controls are loaded dynamically -from the widget plugin registry -- any widget DXE that provides a -basName appears in the toolbox. -

-

-Click a tool to select it (the active tool name is stored in the designer +

Property list -- a two-column ListView below the tree showing property names +and values for the selected control. Double-click a property value to edit +it via an InputBox dialog. Changes take effect immediately in the designer +preview.

+

Each control type exposes different properties (e.g., Caption, Text, Width, +Height, MaxWidth, MaxHeight, Weight, Alignment, Enabled, Visible, and +type-specific properties like DataSource and DataField for data-bound +controls).

+

Form Designer

+

Back to Overview

+
+
+

Toolbox

+

Toolbox

+

The Toolbox (Window > Toolbox) is a floating palette of buttons, one for +each available control type. Controls are loaded dynamically from the widget +plugin registry -- any widget DXE that provides a basName appears in the +toolbox.

+

Click a tool to select it (the active tool name is stored in the designer state), then click on the form to place a new instance. Click the same tool -again to deselect it and return to pointer mode. -

- +again to deselect it and return to pointer mode.

Available Controls

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
VB NameDescription
CommandButtonPush button that triggers a Click event.
LabelStatic text label.
TextBoxSingle-line text input field.
TextAreaMulti-line text editor.
CheckBoxOn/off checkbox.
OptionButtonRadio button (mutually exclusive within a group).
ListBoxScrollable list of items.
ComboBoxDrop-down combo box.
DropDownSimple drop-down list.
PictureBoxCanvas for drawing and images.
ImageStatic image display.
ImageButtonClickable image button.
FrameGrouping container with a labeled border.
VBoxVertical layout container.
HBoxHorizontal layout container.
WrapBoxFlow layout container that wraps items to the next row.
SplitterResizable split between two child panes.
ScrollPaneScrollable container for large content.
TabStripTabbed container with multiple pages.
ListViewMulti-column list with headers.
TreeViewHierarchical tree control.
ProgressBarProgress indicator bar.
HScrollBarHorizontal slider/scrollbar.
SpinButtonNumeric up/down spinner.
LineHorizontal or vertical separator line.
SpacerInvisible spacing element for layout.
TimerNon-visual timer that fires periodic events.
ToolbarToolbar container for buttons.
StatusBarStatus bar at the bottom of a form.
TerminalANSI terminal emulator control.
DataData control for binding to a database.
DBGridData-bound grid for displaying database query results.
- - -

9. Debugger

- -

-The DVX BASIC IDE includes a full interactive debugger. The debugger operates -as a state machine with three states: -

- - - - - -
StateDescription
DBG_IDLENo program loaded or running.
DBG_RUNNINGProgram is executing (VM running in slices).
DBG_PAUSEDExecution is paused at a breakpoint or step point. The IDE GUI is fully interactive.
- +
  VB Name         Description
+  -------         -----------
+  CommandButton   Push button that triggers a Click event.
+  Label           Static text label.
+  TextBox         Single-line text input field.
+  TextArea        Multi-line text editor.
+  CheckBox        On/off checkbox.
+  OptionButton    Radio button (mutually exclusive within a group).
+  ListBox         Scrollable list of items.
+  ComboBox        Drop-down combo box.
+  DropDown        Simple drop-down list.
+  PictureBox      Canvas for drawing and images.
+  Image           Static image display.
+  ImageButton     Clickable image button.
+  Frame           Grouping container with a labeled border.
+  VBox            Vertical layout container.
+  HBox            Horizontal layout container.
+  WrapBox         Flow layout container that wraps items to the next row.
+  Splitter        Resizable split between two child panes.
+  ScrollPane      Scrollable container for large content.
+  TabStrip        Tabbed container with multiple pages.
+  ListView        Multi-column list with headers.
+  TreeView        Hierarchical tree control.
+  ProgressBar     Progress indicator bar.
+  HScrollBar      Horizontal slider/scrollbar.
+  SpinButton      Numeric up/down spinner.
+  Line            Horizontal or vertical separator line.
+  Spacer          Invisible spacing element for layout.
+  Timer           Non-visual timer that fires periodic events.
+  Toolbar         Toolbar container for buttons.
+  StatusBar       Status bar at the bottom of a form.
+  Terminal        ANSI terminal emulator control.
+  Data            Data control for binding to a database.
+  DBGrid          Data-bound grid for displaying database query results.
+

Form Designer

+

Back to Overview

+
+
+

Debugger

+

Debugger

+

The DVX BASIC IDE includes a full interactive debugger. The debugger +operates as a state machine with three states:

+
  State          Description
+  -----          -----------
+  DBG_IDLE       No program loaded or running.
+  DBG_RUNNING    Program is executing (VM running in slices).
+  DBG_PAUSED     Execution is paused at a breakpoint or step point. The IDE GUI is fully interactive.

Starting a Debug Session

    -
  • Shift+F5 (Debug) -- compiles the project and starts - execution in debug mode. Breakpoints are active but execution does not pause - at the first statement.
  • -
  • F8 (Step Into) -- if idle, starts a debug session - and breaks at the first statement.
  • -
  • F5 (Run) -- compiles and runs without the debugger. - No breakpoints are active. If already paused, resumes execution with debugging - disabled.
  • +
  • Shift+F5 (Debug) -- compiles the project and starts execution in debug + mode. Breakpoints are active but execution does not pause at the first + statement.
  • +
  • F8 (Step Into) -- if idle, starts a debug session and breaks at the first + statement.
- +

F5 (Run) -- compiles and runs without the debugger. No breakpoints are +active. If already paused, resumes execution with debugging disabled.

Breakpoints

-

Setting Breakpoints

    -
  • Press F9 to toggle a breakpoint on the current editor line.
  • -
  • Click in the line number gutter to toggle a breakpoint on that line.
  • +
  • Press F9 to toggle a breakpoint on the current editor line.
- +

Click in the line number gutter to toggle a breakpoint on that line.

Breakpoint Validation

-

-Not every line can have a breakpoint. The IDE validates the line content and -silently refuses to set breakpoints on: -

+

Not every line can have a breakpoint. The IDE validates the line content and +silently refuses to set breakpoints on:

    -
  • Blank lines
  • -
  • Comment lines (' or REM)
  • -
  • SUB and FUNCTION declaration lines
  • -
  • END SUB and END FUNCTION lines
  • +
  • Blank lines
  • +
  • Comment lines (' or REM)
  • +
  • SUB and FUNCTION declaration lines
- +

END SUB and END FUNCTION lines

Breakpoint Storage

-

-Each breakpoint records the project file index, the code line number within the -file, the procedure index, and the procedure name (as Object.Event). -When the project is compiled, breakpoints are converted to concatenated source -line numbers that match the VM's OP_LINE opcodes. -

- +

Each breakpoint records the project file index, the code line number within +the file, the procedure index, and the procedure name (as Object.Event). +When the project is compiled, breakpoints are converted to concatenated +source line numbers that match the VM's OP_LINE opcodes.

Visual Indicators

    -
  • Breakpoint lines show a red dot in the gutter.
  • -
  • The current debug line (when paused) has a yellow background.
  • +
  • Breakpoint lines show a red dot in the gutter.
- +

The current debug line (when paused) has a yellow background.

Breakpoint Adjustment on Edit

-

-When lines are added or removed in the editor, breakpoints below the edit -point are automatically shifted to stay on the correct line. -

- +

When lines are added or removed in the editor, breakpoints below the edit +point are automatically shifted to stay on the correct line.

Stepping

- - - - - - -
ActionShortcutBehavior
Step IntoF8Execute one statement. If the statement is a SUB/FUNCTION call, step into it.
Step OverShift+F8Execute one statement. If the statement is a SUB/FUNCTION call, execute the entire call and break at the next line in the current scope.
Step OutCtrl+Shift+F8Run until the current SUB/FUNCTION returns to its caller.
Run to CursorCtrl+F8Run until execution reaches the line under the cursor.
- +
  Action          Shortcut         Behavior
+  ------          --------         --------
+  Step Into       F8               Execute one statement. If the statement is a SUB/FUNCTION call, step into it.
+  Step Over       Shift+F8         Execute one statement. If the statement is a SUB/FUNCTION call, execute the entire call and break at the next line in the current scope.
+  Step Out        Ctrl+Shift+F8    Run until the current SUB/FUNCTION returns to its caller.
+  Run to Cursor   Ctrl+F8          Run until execution reaches the line under the cursor.

The Debug Run Loop

-

-When a program is running in debug mode, the IDE enters a cooperative loop: -

-
    -
  1. The VM executes up to 10,000 steps per slice.
  2. -
  3. If the VM hits a breakpoint (BAS_VM_BREAKPOINT), the state - transitions to DBG_PAUSED. The IDE navigates the code editor - to the breakpoint line, highlights it in yellow, auto-opens the Locals - and Call Stack windows, and updates all debug windows.
  4. -
  5. While paused, the IDE pumps dvxUpdate() continuously, - keeping the GUI responsive. The user can inspect variables, modify them - in the Immediate window, step, continue, or stop.
  6. -
  7. When the user resumes (F5/Shift+F5/F8/etc.), the state transitions back - to DBG_RUNNING and the loop continues.
  8. -
- +

When a program is running in debug mode, the IDE enters a cooperative loop:

+
    +
  • The VM executes up to 10,000 steps per slice.
  • +
  • If the VM hits a breakpoint (BAS_VM_BREAKPOINT), the state transitions to + DBG_PAUSED. The IDE navigates the code editor to the breakpoint line, + highlights it in yellow, auto-opens the Locals and Call Stack windows, + and updates all debug windows.
  • +
  • While paused, the IDE pumps dvxUpdate() continuously, keeping the GUI + responsive. The user can inspect variables, modify them in the Immediate + window, step, continue, or stop.
  • +
+

When the user resumes (F5/Shift+F5/F8/etc.), the state transitions back to +DBG_RUNNING and the loop continues.

Stopping

-

-Press Esc or click the Stop toolbar button at any time to halt execution. -The VM is destroyed, debug state resets to DBG_IDLE, and the IDE -restores the designer windows that were hidden at run start. -

- - -

10. Debug Windows

- -

-When the debugger pauses, the Locals and Call Stack windows are auto-opened +

Press Esc or click the Stop toolbar button at any time to halt execution. +The VM is destroyed, debug state resets to DBG_IDLE, and the IDE restores +the designer windows that were hidden at run start.

+

Locals Window

+

Call Stack Window

+

Watch Window

+

Breakpoints Window

+

Back to Overview

+
+
+

Locals Window

+

Locals Window

+

When the debugger pauses, the Locals and Call Stack windows are auto-opened (if not already visible). The Watch and Breakpoints windows can be opened -manually from the Window menu. -

- -

Locals Window

-

-Shows variables for the current execution scope. Displayed as a three-column -ListView: -

- - - - - -
ColumnContent
NameVariable name (internal mangled names like static variable placeholders are filtered out).
TypeData type: Integer, Long, Single, Double, String, Boolean, Array, UDT. Array types show the element type (e.g., Integer()).
ValueCurrent value. Strings are shown in quotes. Booleans as True/False. Arrays show bounds and element count (e.g., Integer(0 To 9) [10]). Uninitialized arrays show (uninitialized).
-

-The Locals window displays: -

+manually from the Window menu.

+

Shows variables for the current execution scope. Displayed as a three-column +ListView:

+
  Column   Content
+  ------   -------
+  Name     Variable name (internal mangled names like static variable placeholders are filtered out).
+  Type     Data type: Integer, Long, Single, Double, String, Boolean, Array, UDT. Array types show the element type (e.g., Integer()).
+  Value    Current value. Strings are shown in quotes. Booleans as True/False. Arrays show bounds and element count (e.g., Integer(0 To 9) [10]). Uninitialized arrays show (uninitialized).
+

The Locals window displays:

    -
  • Local variables for the current procedure (matched by proc index).
  • -
  • Global (module-level) variables.
  • -
  • Form-scoped variables for the current form (if the program is executing - within a form context).
  • +
  • Local variables for the current procedure (matched by proc index).
  • +
  • Global (module-level) variables.
-

-Up to 64 variables are displayed. The window is resizable. -

- -

Call Stack Window

-

-Shows the current call chain as a two-column ListView: -

- - - - -
ColumnContent
ProcedureProcedure name (or (module) for module-level code).
LineLine number where execution is paused (shown for the topmost frame).
-

-The current location is shown first, followed by each caller in the call stack -(walking from the deepest frame back to the module entry point). Up to 32 -frames are displayed. -

- -

Watch Window

-

-Allows monitoring arbitrary expressions while debugging. The window has -a text input at the top and a two-column ListView below: -

- - - - -
ColumnContent
ExpressionThe watch expression text.
ValueEvaluated result (or <error> if evaluation fails). Blank when not paused.
- -

Adding Watch Expressions

-

-Type an expression in the text input and press Enter. -Up to 16 watch expressions can be active at once. -

- -

Watch Expression Syntax

-

-Watch expressions support: -

+

Form-scoped variables for the current form (if the program is executing +within a form context).

+

Up to 64 variables are displayed. The window is resizable.

+

Call Stack Window

+

Back to Overview

+
+
+

Call Stack Window

+

Call Stack Window

+

Shows the current call chain as a two-column ListView:

+
  Column      Content
+  ------      -------
+  Procedure   Procedure name (or (module) for module-level code).
+  Line        Line number where execution is paused (shown for the topmost frame).
+

The current location is shown first, followed by each caller in the call +stack (walking from the deepest frame back to the module entry point). Up to +32 frames are displayed.

+

Watch Window

+

Back to Overview

+
+
+

Watch Window

+

Watch Window

+

Allows monitoring arbitrary expressions while debugging. The window has a +text input at the top and a two-column ListView below:

+
  Column       Content
+  ------       -------
+  Expression   The watch expression text.
+  Value        Evaluated result (or <error> if evaluation fails). Blank when not paused.
+

Adding Watch Expressions

+

Type an expression in the text input and press Enter. Up to 16 watch +expressions can be active at once.

+

Watch Expression Syntax

+

Watch expressions support:

    -
  • Simple variable names: x, count
  • -
  • Array subscripts: arr(5), matrix(2, 3)
  • -
  • UDT field access: player.name
  • -
  • Combined: items(i).price
  • -
  • Arbitrary BASIC expressions (compiled and evaluated against the - paused VM's state): x + y * 2, Len(name$)
  • +
  • Simple variable names: x, count
  • +
  • Array subscripts: arr(5), matrix(2, 3)
  • +
  • UDT field access: player.name
  • +
  • Combined: items(i).price
- -

Editing and Deleting

+

Arbitrary BASIC expressions (compiled and evaluated against the paused VM's +state): x + y * 2, Len(name$)

+

Editing and Deleting

    -
  • Double-click or press Enter on a watch entry to - move it back into the input box for editing.
  • -
  • Press Delete to remove the selected watch expression.
  • +
  • Double-click or press Enter on a watch entry to move it back into the + input box for editing.
- -

Breakpoints Window

-

-Lists all set breakpoints as a three-column ListView: -

- - - - - -
ColumnContent
FileProject file path.
ProcedureProcedure name (Object.Event format, or (General)).
LineCode line number within the file.
+

Press Delete to remove the selected watch expression.

+

Breakpoints Window

+

Back to Overview

+
+
+

Breakpoints Window

+

Breakpoints Window

+

Lists all set breakpoints as a three-column ListView:

+
  Column      Content
+  ------      -------
+  File        Project file path.
+  Procedure   Procedure name (Object.Event format, or (General)).
+  Line        Code line number within the file.
    -
  • Double-click a breakpoint to navigate the code editor to that location.
  • -
  • Press Delete to remove selected breakpoints (multi-select is supported).
  • +
  • Double-click a breakpoint to navigate the code editor to that location.
- - -

11. Immediate Window

- -

-The Immediate window is an interactive REPL at the bottom-right of the screen. -Type a line of BASIC and press Enter to evaluate it. Results appear -inline below your input. -

- +

Press Delete to remove selected breakpoints (multi-select is supported).

+

Debugger

+

Back to Overview

+
+
+

Immediate Window

+

Immediate Window

+

The Immediate window is an interactive REPL at the bottom-right of the +screen. Type a line of BASIC and press Enter to evaluate it. Results appear +inline below your input.

Expression Evaluation

-

-If the input is not a recognized statement keyword, it is automatically wrapped -in a PRINT statement. For example, typing 2 + 2 -evaluates as PRINT 2 + 2 and displays 4. -

-

-You can also type full statements: -

+

If the input is not a recognized statement keyword, it is automatically +wrapped in a PRINT statement. For example, typing 2 + 2 evaluates as PRINT 2 ++ 2 and displays 4.

+

You can also type full statements:

    -
  • PRINT x * 2 -- evaluate and print an expression.
  • -
  • DIM tmp As Integer -- declare a temporary variable.
  • -
  • LET x = 42 -- explicit assignment (see below).
  • +
  • PRINT x * 2 -- evaluate and print an expression.
  • +
  • DIM tmp As Integer -- declare a temporary variable.
-

-Parse or runtime errors are displayed inline with an Error: prefix. -

- +

LET x = 42 -- explicit assignment (see below).

+

Parse or runtime errors are displayed inline with an Error: prefix.

Inspecting Variables While Paused

-

-When the debugger is paused at a breakpoint, the Immediate window has access -to the running VM's state. Global variable values are copied into the evaluation -VM, so expressions like count or name$ & " test" -display live values. -

- +

When the debugger is paused at a breakpoint, the Immediate window has access +to the running VM's state. Global variable values are copied into the +evaluation VM, so expressions like count or name$ & " test" display live +values.

Assigning Variables While Paused

-

-When paused, you can modify variables in the running program directly from the -Immediate window using assignment syntax: -

+

When paused, you can modify variables in the running program directly from +the Immediate window using assignment syntax:

variableName = newValue
-

-The optional LET keyword is also accepted: -

+

The optional LET keyword is also accepted:

LET variableName = newValue
-

-Assignment works for: -

+

Assignment works for:

    -
  • Scalar variables -- x = 42, name$ = "test"
  • -
  • Array elements -- arr(5) = 100, matrix(2, 3) = 7.5
  • -
  • UDT fields -- player.score = 1000
  • -
  • Combined -- items(0).price = 9.99
  • +
  • Scalar variables -- x = 42, name$ = "test"
  • +
  • Array elements -- arr(5) = 100, matrix(2, 3) = 7.5
  • +
  • UDT fields -- player.score = 1000
-

-The new value is written directly into the VM's live variable slot (local, +

Combined -- items(0).price = 9.99

+

The new value is written directly into the VM's live variable slot (local, global, or form scope). A confirmation message is displayed, and the Locals -and Watch windows update automatically to reflect the change. -

-

-If the assignment target cannot be resolved (unknown variable, out-of-bounds -index, wrong type), an error message is displayed. -

- - -

12. Output Window

- -

-The Output window is a read-only TextArea at the bottom-left of the screen. -It displays: -

+and Watch windows update automatically to reflect the change.

+

If the assignment target cannot be resolved (unknown variable, out-of-bounds +index, wrong type), an error message is displayed.

+

Back to Overview

+
+
+

Output Window

+

Output Window

+

The Output window is a read-only TextArea at the bottom-left of the screen. +It displays:

    -
  • PRINT output -- all PRINT statement output from - the running program is appended here.
  • -
  • Runtime errors -- if the VM encounters a runtime error - (division by zero, out-of-bounds, etc.), the error message and line number - are displayed in the output with an Error on line N: prefix.
  • -
  • Compile errors -- if compilation fails, the error message - and location are shown.
  • +
  • PRINT output -- all PRINT statement output from the running program is + appended here.
  • +
  • Runtime errors -- if the VM encounters a runtime error (division by zero, + out-of-bounds, etc.), the error message and line number are displayed in + the output with an Error on line N: prefix.
-

-The output buffer holds up to 32,768 characters. Use Run > Clear Output -to clear it. -

-

-INPUT statements prompt the user via a modal InputBox dialog; the -prompt text is also echoed to the Output window. -

- - -

13. Find / Replace

- -

-Open with Ctrl+F (Find) or Ctrl+H (Replace). The -Find/Replace dialog is modeless -- it stays open while you continue editing. -

- +

Compile errors -- if compilation fails, the error message and location are +shown.

+

The output buffer holds up to 32,768 characters. Use Run > Clear Output to +clear it.

+

INPUT statements prompt the user via a modal InputBox dialog; the prompt +text is also echoed to the Output window.

+

Back to Overview

+
+
+

Find / Replace

+

Find / Replace

+

Open with Ctrl+F (Find) or Ctrl+H (Replace). The Find/Replace dialog is +modeless -- it stays open while you continue editing.

Dialog Controls

- - - - - - - -
ControlDescription
Find inputThe text to search for.
Replace checkbox + inputEnable replacement mode and enter replacement text.
ScopeRadio group: Function, Object, File, or Project. Default is Project.
DirectionRadio group: Forward or Backward.
Match CaseCheckbox: case-sensitive search.
- +
  Control                    Description
+  -------                    -----------
+  Find input                 The text to search for.
+  Replace checkbox + input   Enable replacement mode and enter replacement text.
+  Scope                      Radio group: Function, Object, File, or Project. Default is Project.
+  Direction                  Radio group: Forward or Backward.
+  Match Case                 Checkbox: case-sensitive search.

Buttons

- - - - - - -
ButtonAction
Find NextFind the next occurrence. Wraps across procedures, files, and the entire project depending on the scope setting.
ReplaceReplace the current match and find the next one.
Replace AllReplace all occurrences within the selected scope.
CloseClose the dialog.
- +
  Button        Action
+  ------        ------
+  Find Next     Find the next occurrence. Wraps across procedures, files, and the entire project depending on the scope setting.
+  Replace       Replace the current match and find the next one.
+  Replace All   Replace all occurrences within the selected scope.
+  Close         Close the dialog.

Keyboard Shortcut

-

-F3 repeats the last search (Find Next) without opening the dialog. -

- - -

14. Preferences

- -

-Open via Tools > Preferences. Settings are saved to -dvxbasic.ini in the app's config directory. -

- +

F3 repeats the last search (Find Next) without opening the dialog.

+

Back to Overview

+
+
+

Preferences

+

Preferences

+

Open via Tools > Preferences. Settings are saved to dvxbasic.ini in the +app's config directory.

Editor Section

- - - - - - -
SettingDescriptionDefault
Skip comments/strings when renamingWhen renaming a control or form, skip occurrences inside comments and string literals.On
Require variable declaration (OPTION EXPLICIT)When enabled, variables must be declared with DIM before use.Off
Tab widthNumber of spaces per tab stop (1-8).3
Insert spaces instead of tabsWhen enabled, pressing Tab inserts spaces. When disabled, inserts a real tab character.On
- +
  Setting                                      Description                                                                               Default
+  -------                                      -----------                                                                               -------
+  Skip comments/strings when renaming          When renaming a control or form, skip occurrences inside comments and string literals.     On
+  Require variable declaration (OPTION EXPLICIT)   When enabled, variables must be declared with DIM before use.                          Off
+  Tab width                                    Number of spaces per tab stop (1-8).                                                      3
+  Insert spaces instead of tabs                When enabled, pressing Tab inserts spaces. When disabled, inserts a real tab character.     On

New Project Defaults Section

-

-These fields set the default values for new project metadata: -

- - - - - - - -
FieldDescriptionDefault
AuthorDefault author name.(empty)
CompanyDefault company name.(empty)
VersionDefault version string.1.0
CopyrightDefault copyright notice.(empty)
DescriptionDefault project description (multi-line).(empty)
- -
- -

Keyboard Shortcut Summary

- - - - - - - - - - - - - - - - - - - - - - - - - -
ShortcutAction
Ctrl+OAdd File
Ctrl+SSave File
Ctrl+ASelect All
Ctrl+XCut
Ctrl+CCopy
Ctrl+VPaste
Ctrl+FFind
Ctrl+HReplace
Ctrl+EMenu Editor
F3Find Next
F5Run
Shift+F5Debug
Ctrl+F5Run Without Recompile
EscStop
F7Code View
Shift+F7Design View
F8Step Into
Shift+F8Step Over
Ctrl+Shift+F8Step Out
Ctrl+F8Run to Cursor
F9Toggle Breakpoint
DelDelete
- -
-

DVX BASIC 1.0 -- Copyright 2026 Scott Duensing

- +

These fields set the default values for new project metadata:

+
  Field         Description                              Default
+  -----         -----------                              -------
+  Author        Default author name.                     (empty)
+  Company       Default company name.                    (empty)
+  Version       Default version string.                  1.0
+  Copyright     Default copyright notice.                (empty)
+  Description   Default project description (multi-line).   (empty)
+

Back to Overview

+
+
+

Keyboard Shortcuts

+

Keyboard Shortcuts

+
  Shortcut         Action
+  --------         ------
+  Ctrl+O           Add File
+  Ctrl+S           Save File
+  Ctrl+A           Select All
+  Ctrl+X           Cut
+  Ctrl+C           Copy
+  Ctrl+V           Paste
+  Ctrl+F           Find
+  Ctrl+H           Replace
+  Ctrl+E           Menu Editor
+  F3               Find Next
+  F5               Run
+  Shift+F5         Debug
+  Ctrl+F5          Run Without Recompile
+  Esc              Stop
+  F7               Code View
+  Shift+F7         Design View
+  F8               Step Into
+  Shift+F8         Step Over
+  Ctrl+Shift+F8    Step Out
+  Ctrl+F8          Run to Cursor
+  F9               Toggle Breakpoint
+  Del              Delete
+
+

DVX BASIC 1.0 -- Copyright 2026 Scott Duensing

+
+
diff --git a/docs/dvxbasic_language_reference.html b/docs/dvxbasic_language_reference.html index 2b3f7cd..7cc5f4b 100644 --- a/docs/dvxbasic_language_reference.html +++ b/docs/dvxbasic_language_reference.html @@ -1,1973 +1,1084 @@ - + - -DVX BASIC Language Reference + +Data Types - -

DVX BASIC Language Reference

- -

Complete reference for the DVX BASIC language as implemented in the -DVX BASIC compiler and runtime. DVX BASIC is a QuickBASIC/Visual Basic -compatible dialect targeting the DVX GUI environment.

- - - - - -

1. Data Types

- - + +
  • File I/O
  • +
  • Built-in Functions + +
  • +
  • Form and Control Statements
  • +
  • SQL Functions
  • +
  • App Object
  • +
  • INI Functions
  • +
  • Predefined Constants
  • + +

    Index

    + + +
    +
    +

    Data Types

    +

    Data Types

    DVX BASIC supports the following data types. Each type has a corresponding type suffix character that can be appended to variable names.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeSizeSuffixRange / Description
    Integer2 bytes%-32768 to 32767
    Long4 bytes&-2147483648 to 2147483647
    Single4 bytes!32-bit float, approximately 7 digits precision
    Double8 bytes#64-bit float, approximately 15 digits precision
    Stringvariable$Variable-length, reference-counted, dynamic string
    Boolean2 bytesTrue (-1) or False (0)
    - -

    Internal Types (not directly declarable)

    - - - - - - - - - - - - - - - - - - - - - - -
    Internal TypeDescription
    ArrayReference-counted multi-dimensional array (up to 8 dimensions)
    UDTUser-defined type instance (created with TYPE...END TYPE)
    ObjectOpaque host object (form reference, control reference)
    RefByRef pointer to a variable slot (used for ByRef parameters)
    - +

    Primary Types

    +
      Type       Size       Suffix   Range / Description
    +  ----       ----       ------   -------------------
    +  Integer    2 bytes    %        -32768 to 32767
    +  Long       4 bytes    &        -2147483648 to 2147483647
    +  Single     4 bytes    !        32-bit float, approximately 7 digits precision
    +  Double     8 bytes    #        64-bit float, approximately 15 digits precision
    +  String     variable   $        Variable-length, reference-counted, dynamic string
    +  Boolean    2 bytes    (none)   True (-1) or False (0)
    +

    Internal Types

    +

    These types are not directly declarable but are used internally by the +runtime.

    +
      Internal Type   Description
    +  -------------   -----------
    +  Array           Reference-counted multi-dimensional array (up to 8 dimensions)
    +  UDT             User-defined type instance (created with TYPE...END TYPE)
    +  Object          Opaque host object (form reference, control reference)
    +  Ref             ByRef pointer to a variable slot (used for ByRef parameters)

    Type Suffixes

    -

    Type suffixes can be appended to variable names to declare their type implicitly:

    - -
    -count%  = 42         ' Integer
    +
    count%  = 42         ' Integer
     total&  = 100000     ' Long
     rate!   = 3.14       ' Single
     pi#     = 3.14159265 ' Double
    -name$   = "Hello"    ' String
    -
    - +name$ = "Hello" ' String

    Numeric Literals

    - - - - - - - - - -
    FormExampleDescription
    Decimal integer42Values -32768..32767 are Integer; larger values are Long
    Hex integer&HFFHexadecimal literal
    Long suffix42&, &HFF&Force Long type
    Floating-point3.14, 1.5E10Double by default
    Single suffix3.14!Force Single type
    Double suffix3.14#Force Double type
    - +
      Form               Example          Description
    +  ----               -------          -----------
    +  Decimal integer    42               Values -32768..32767 are Integer; larger are Long
    +  Hex integer        &HFF             Hexadecimal literal
    +  Long suffix        42&, &HFF&       Force Long type
    +  Floating-point     3.14, 1.5E10     Double by default
    +  Single suffix      3.14!            Force Single type
    +  Double suffix      3.14#            Force Double type

    Type Promotion

    -

    When mixing types in expressions, values are automatically promoted to a -common type: Integer -> Long -> Single -> Double. Strings are -not automatically converted to numbers (use VAL and -STR$).

    - - - -

    2. Operators

    - - +common type: Integer -> Long -> Single -> Double. Strings are not +automatically converted to numbers (use VAL and STR$).

    +

    See also: Conversion Functions

    +
    +
    +

    Operators

    +

    Operators

    Operators listed from highest precedence (evaluated first) to lowest precedence (evaluated last).

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    PrecedenceOperatorDescription
    1 (highest)^Exponentiation
    2- (unary)Negation
    3*   /   \ -   MODMultiplication, float division, integer division, modulus
    4+   -Addition, subtraction
    5&String concatenation
    6=   <>   < -   >   <=   - >=Comparison (returns Boolean)
    7NOTLogical/bitwise NOT
    8ANDLogical/bitwise AND
    9XORLogical/bitwise XOR
    10ORLogical/bitwise OR
    11EQVLogical/bitwise equivalence
    12 (lowest)IMPLogical/bitwise implication
    - +
      Precedence     Operator                  Description
    +  ----------     --------                  -----------
    +  1 (highest)    ^                         Exponentiation
    +  2              - (unary)                 Negation
    +  3              *  /  \  MOD              Multiply, float div, integer div, modulus
    +  4              +  -                      Addition, subtraction
    +  5              &                         String concatenation
    +  6              =  <>  <  >  <=  >=       Comparison (returns Boolean)
    +  7              NOT                       Logical/bitwise NOT
    +  8              AND                       Logical/bitwise AND
    +  9              XOR                       Logical/bitwise XOR
    +  10             OR                        Logical/bitwise OR
    +  11             EQV                       Logical/bitwise equivalence
    +  12 (lowest)    IMP                       Logical/bitwise implication

    String Concatenation

    - -

    Use & to concatenate strings. The + operator -also concatenates when both operands are strings.

    - -
    -result$ = "Hello" & " " & "World"
    -result$ = firstName$ & " " & lastName$
    -
    - - - -

    3. Statements

    - - -

    Multiple statements can appear on one line separated by :. -Lines can be continued with _ at the end. Comments start with -' or REM.

    - - - -

    DIM

    - +

    Use & to concatenate strings. The + operator also concatenates when both +operands are strings.

    +
    result$ = "Hello" & " " & "World"
    +result$ = firstName$ & " " & lastName$
    +
    +
    +

    Statements Overview

    +

    Statements

    +

    Multiple statements can appear on one line separated by :. Lines can be +continued with _ at the end. Comments start with ' or REM.

    +

    Declaration Statements (DIM, REDIM, CONST, TYPE)

    +

    Conditional Statements (IF, SELECT CASE)

    +

    Loop Statements (FOR, DO, WHILE)

    +

    Procedures (SUB, FUNCTION, DEF FN)

    +

    Flow Control (EXIT, CALL, GOTO, GOSUB, ON)

    +

    Input/Output (PRINT, INPUT, DATA/READ)

    +

    Miscellaneous Statements

    +
    +
    +

    Declaration Statements

    +

    Declaration Statements

    +

    DIM

    Declares variables and arrays with an explicit type.

    - -
    -DIM variable AS type
    -DIM variable(upperBound) AS type
    -DIM variable(lower TO upper) AS type
    -DIM variable(dim1, dim2, ...) AS type
    -DIM variable AS UdtName
    -DIM variable AS STRING * n
    -DIM SHARED variable AS type
    -
    - +
    DIM variable AS type
    +DIM variable(upperBound) AS type
    +DIM variable(lower TO upper) AS type
    +DIM variable(dim1, dim2, ...) AS type
    +DIM variable AS UdtName
    +DIM variable AS STRING * n
    +DIM SHARED variable AS type

    Examples:

    - -
    -Dim name As String
    +
    Dim name As String
     Dim count As Integer
     Dim values(100) As Double
     Dim matrix(1 To 10, 1 To 10) As Single
     Dim Shared globalFlag As Boolean
     Dim record As PersonType
    -Dim fixedStr As String * 20
    -
    - -
    -DIM SHARED makes a variable accessible from all procedures -without passing it as a parameter. -
    - - - -

    REDIM

    - +Dim fixedStr As String * 20
    +
    Note: DIM SHARED makes a variable accessible from all procedures without passing +it as a parameter.
    +

    REDIM

    Reallocates a dynamic array, optionally preserving existing data.

    - -
    -REDIM array(newBounds) AS type
    -REDIM PRESERVE array(newBounds) AS type
    -
    - -
    -ReDim items(newSize) As String
    -ReDim Preserve scores(1 To newCount) As Integer
    -
    - - - -

    CONST

    - +
    REDIM array(newBounds) AS type
    +REDIM PRESERVE array(newBounds) AS type
    +
    ReDim items(newSize) As String
    +ReDim Preserve scores(1 To newCount) As Integer
    +

    CONST

    Declares a named constant. The value must be a literal (integer, float, string, or boolean).

    - -
    -CONST name = value
    -
    - -
    -Const MAX_SIZE = 100
    +
    CONST name = value
    +
    Const MAX_SIZE = 100
     Const PI = 3.14159265
    -Const APP_NAME = "DVX App"
    -Const DEBUG_MODE = True
    -
    - - - -

    TYPE...END TYPE

    - +Const APP_NAME = "DVX App" +Const DEBUG_MODE = True
    +

    TYPE...END TYPE

    Defines a user-defined type (record/structure).

    - -
    -TYPE TypeName
    -    fieldName AS type
    +
    TYPE TypeName
    +    fieldName AS type
         ...
    -END TYPE
    -
    - -
    -Type PersonType
    +END TYPE
    +
    Type PersonType
         firstName As String
         lastName  As String
         age       As Integer
     End Type
     
     Dim p As PersonType
    -p.firstName = "Scott"
    -p.age = 30
    -
    - +p.firstName = "Scott" +p.age = 30

    UDT fields can themselves be UDTs (nested types).

    - - - -

    IF...THEN...ELSE...END IF

    - +

    DECLARE

    +

    Forward-declares a SUB or FUNCTION. Required when a procedure is called +before it is defined.

    +
    DECLARE SUB name ([BYVAL] param AS type, ...)
    +DECLARE FUNCTION name ([BYVAL] param AS type, ...) AS returnType
    +

    DECLARE LIBRARY

    +

    Declares external native functions from a dynamically loaded library. This +allows BASIC programs to call functions exported by DXE libraries.

    +
    DECLARE LIBRARY "libraryName"
    +    DECLARE SUB name ([BYVAL] param AS type, ...)
    +    DECLARE FUNCTION name ([BYVAL] param AS type, ...) AS returnType
    +END DECLARE
    +
    Declare Library "rs232"
    +    Declare Function ComOpen(ByVal port As Integer) As Integer
    +    Declare Sub ComClose(ByVal port As Integer)
    +    Declare Sub ComSend(ByVal port As Integer, ByVal data$ As String)
    +End Declare
    +

    STATIC

    +

    Declares a local variable that retains its value between calls.

    +
    STATIC variable AS type
    +
    Sub Counter()
    +    Static count As Integer
    +    count = count + 1
    +    Print count
    +End Sub
    +

    OPTION

    +

    Sets compiler options. Must appear before any executable code.

    +
    OPTION BASE 0          ' Arrays start at index 0 (default)
    +OPTION BASE 1          ' Arrays start at index 1
    +OPTION COMPARE BINARY  ' Case-sensitive string comparisons (default)
    +OPTION COMPARE TEXT    ' Case-insensitive string comparisons
    +OPTION EXPLICIT        ' All variables must be declared with DIM
    +

    DEFtype Statements

    +

    Set the default type for variables based on their first letter.

    +
    DEFINT letterRange
    +DEFLNG letterRange
    +DEFSNG letterRange
    +DEFDBL letterRange
    +DEFSTR letterRange
    +
    DefInt I-N     ' Variables starting with I through N default to Integer
    +DefStr S       ' Variables starting with S default to String
    +

    Assignment

    +

    Assigns a value to a variable, array element, or UDT field.

    +
    variable = expression
    +array(index) = expression
    +udt.field = expression
    +LET variable = expression
    +

    The LET keyword is optional and supported for compatibility.

    +

    SWAP

    +

    Exchanges the values of two variables.

    +
    SWAP variable1, variable2
    +
    Swap a, b
    +

    ERASE

    +

    Frees the memory of an array and resets it.

    +
    ERASE arrayName
    +
    +
    +

    Conditional Statements

    +

    Conditional Statements

    +

    IF...THEN...ELSE...END IF

    Conditional execution. Supports single-line and multi-line forms.

    - -

    Single-line form:

    - -
    -IF condition THEN statement
    -IF condition THEN statement ELSE statement
    -
    - -

    Multi-line form:

    - -
    -IF condition THEN
    -    statements
    -ELSEIF condition THEN
    -    statements
    +

    Single-line form

    +
    IF condition THEN statement
    +IF condition THEN statement ELSE statement
    +

    Multi-line form

    +
    IF condition THEN
    +    statements
    +ELSEIF condition THEN
    +    statements
     ELSE
    -    statements
    -END IF
    -
    - -
    -If x > 10 Then
    -    Print "Large"
    -ElseIf x > 5 Then
    -    Print "Medium"
    +    statements
    +END IF
    +
    If x > 10 Then
    +    Print "Large"
    +ElseIf x > 5 Then
    +    Print "Medium"
     Else
    -    Print "Small"
    +    Print "Small"
     End If
     
    -If ready Then Print "Go!"
    -
    - - - -

    SELECT CASE

    - +If ready Then Print "Go!"
    +

    SELECT CASE

    Multi-way branch based on an expression value.

    - -
    -SELECT CASE expression
    -    CASE value
    -        statements
    -    CASE value1, value2
    -        statements
    -    CASE low TO high
    -        statements
    -    CASE IS operator value
    -        statements
    +
    SELECT CASE expression
    +    CASE value
    +        statements
    +    CASE value1, value2
    +        statements
    +    CASE low TO high
    +        statements
    +    CASE IS operator value
    +        statements
         CASE ELSE
    -        statements
    -END SELECT
    -
    - -
    -Select Case grade
    +        statements
    +END SELECT
    +
    Select Case grade
         Case 90 To 100
    -        Print "A"
    +        Print "A"
         Case 80 To 89
    -        Print "B"
    -    Case Is >= 70
    -        Print "C"
    +        Print "B"
    +    Case Is >= 70
    +        Print "C"
         Case 60, 65
    -        Print "D (borderline)"
    +        Print "D (borderline)"
         Case Else
    -        Print "F"
    -End Select
    -
    - -

    CASE items can be combined with commas. The IS keyword allows -comparison operators: <, >, -<=, >=, =, -<>.

    - - - -

    FOR...NEXT

    - + Print "F" +End Select
    +

    CASE items can be combined with commas. The IS keyword allows comparison +operators: <, >, <=, >=, =, <>.

    +
    +
    +

    Loop Statements

    +

    Loop Statements

    +

    FOR...NEXT

    Counted loop with an optional step value.

    - -
    -FOR variable = start TO limit [STEP step]
    -    statements
    -NEXT [variable]
    -
    - -
    -For i = 1 To 10
    +
    FOR variable = start TO limit [STEP step]
    +    statements
    +NEXT [variable]
    +
    For i = 1 To 10
         Print i
     Next i
     
     For x = 10 To 0 Step -2
         Print x
    -Next
    -
    - -

    The variable name after NEXT is optional. Use -EXIT FOR to break out early.

    - - - -

    DO...LOOP

    - +Next
    +

    The variable name after NEXT is optional. Use EXIT FOR to break out early.

    +

    DO...LOOP

    General-purpose loop with pre-test, post-test, or infinite forms.

    - -
    -DO [WHILE condition | UNTIL condition]
    -    statements
    -LOOP [WHILE condition | UNTIL condition]
    -
    - -
    -' Pre-test
    -Do While count < 10
    +
    DO [WHILE condition | UNTIL condition]
    +    statements
    +LOOP [WHILE condition | UNTIL condition]
    +
    ' Pre-test
    +Do While count < 10
         count = count + 1
     Loop
     
     ' Post-test
     Do
         line$ = ReadLine()
    -Loop Until line$ = "quit"
    +Loop Until line$ = "quit"
     
     ' Infinite loop (exit with EXIT DO)
     Do
         DoEvents
         If done Then Exit Do
    -Loop
    -
    - - - -

    WHILE...WEND

    - -

    Simple pre-test loop (legacy form; prefer DO...LOOP).

    - -
    -WHILE condition
    -    statements
    -WEND
    -
    - -
    -While Not EOF(1)
    +Loop
    +

    WHILE...WEND

    +

    Simple pre-test loop (legacy form; prefer DO...LOOP).

    +
    WHILE condition
    +    statements
    +WEND
    +
    While Not EOF(1)
         Line Input #1, line$
         Print line$
    -Wend
    -
    - - - -

    SUB...END SUB

    - +Wend
    +
    +
    +

    Procedures

    +

    Procedures

    +

    SUB...END SUB

    Defines a subroutine (no return value).

    - -
    -SUB name ([BYVAL] param AS type, ...)
    -    statements
    -END SUB
    -
    - -
    -Sub Greet(ByVal name As String)
    -    Print "Hello, " & name
    -End Sub
    -
    - -

    Parameters are passed ByRef by default. Use -ByVal for value semantics. Use EXIT SUB to -return early.

    - - - -

    FUNCTION...END FUNCTION

    - +
    SUB name ([BYVAL] param AS type, ...)
    +    statements
    +END SUB
    +
    Sub Greet(ByVal name As String)
    +    Print "Hello, " & name
    +End Sub
    +

    Parameters are passed ByRef by default. Use ByVal for value semantics. Use +EXIT SUB to return early.

    +

    FUNCTION...END FUNCTION

    Defines a function with a return value.

    - -
    -FUNCTION name ([BYVAL] param AS type, ...) AS returnType
    -    statements
    -    name = returnValue
    -END FUNCTION
    -
    - -
    -Function Square(ByVal n As Double) As Double
    +
    FUNCTION name ([BYVAL] param AS type, ...) AS returnType
    +    statements
    +    name = returnValue
    +END FUNCTION
    +
    Function Square(ByVal n As Double) As Double
         Square = n * n
    -End Function
    -
    - -

    Assign to the function name to set the return value. Use -EXIT FUNCTION to return early.

    - - - -

    DEF FN

    - +End Function
    +

    Assign to the function name to set the return value. Use EXIT FUNCTION to +return early.

    +

    DEF FN

    Defines a single-expression function.

    - -
    -DEF FNname(params) = expression
    -
    - -
    -Def FnSquare(x) = x * x
    -Print FnSquare(5)     ' prints 25
    -
    - - - -

    EXIT

    - +
    DEF FNname(params) = expression
    +
    Def FnSquare(x) = x * x
    +Print FnSquare(5)     ' prints 25
    +
    +
    +

    Flow Control

    +

    Flow Control

    +

    EXIT

    Exits the current block early.

    - -
    -EXIT FOR
    +
    EXIT FOR
     EXIT DO
     EXIT SUB
    -EXIT FUNCTION
    -
    - - - -

    CALL

    - +EXIT FUNCTION
    +

    CALL

    Explicitly calls a subroutine or function. The return value (if any) is discarded.

    - -
    -CALL name
    -CALL name(args)
    -
    - -

    Normally you can omit CALL and just use the name directly.

    - - - -

    GOTO / GOSUB / RETURN

    - -
    -GOTO label
    -GOSUB label
    -RETURN
    -
    - -

    GOSUB pushes the return address, executes code at the label, -and RETURN jumps back. At module level, RETURN -returns from a GOSUB. Inside a SUB/FUNCTION, RETURN returns -from the procedure.

    - -
    -GoSub Initialize
    -Print "Done"
    +
    CALL name
    +CALL name(args)
    +

    Normally you can omit CALL and just use the name directly.

    +

    GOTO / GOSUB / RETURN

    +
    GOTO label
    +GOSUB label
    +RETURN
    +

    GOSUB pushes the return address, executes code at the label, and RETURN +jumps back. At module level, RETURN returns from a GOSUB. Inside a +SUB/FUNCTION, RETURN returns from the procedure.

    +
    GoSub Initialize
    +Print "Done"
     End
     
     Initialize:
         count = 0
    -    name$ = ""
    -Return
    -
    - - - -

    ON...GOTO / ON...GOSUB

    - + name$ = "" +Return
    +

    ON...GOTO / ON...GOSUB

    Computed branch based on an integer expression.

    - -
    -ON expression GOTO label1, label2, ...
    -ON expression GOSUB label1, label2, ...
    -
    - +
    ON expression GOTO label1, label2, ...
    +ON expression GOSUB label1, label2, ...

    If the expression evaluates to 1, control goes to the first label; 2, the second; and so on. If out of range, execution falls through.

    - - - -

    PRINT

    - +
    +
    +

    Input/Output Statements

    +

    Input/Output Statements

    +

    PRINT

    Outputs text to the console or to a file channel.

    - -
    -PRINT [expression] [{; | ,} expression] ...
    -PRINT #channel, expression
    -PRINT USING format$; expression [; expression] ...
    -
    - +
    PRINT [expression] [{; | ,} expression] ...
    +PRINT #channel, expression
    +PRINT USING format$; expression [; expression] ...
      -
    • ; between items -- no separator (items are concatenated)
    • -
    • , between items -- advance to the next 14-column tab zone
    • -
    • Trailing ; or , suppresses the newline
    • -
    • ? is an alias for PRINT
    • +
    • ; between items -- no separator (items are concatenated)
    • +
    • , between items -- advance to the next 14-column tab zone
    • +
    • Trailing ; or , suppresses the newline
    - +

    ? is an alias for PRINT

    Special functions inside PRINT:

    -
      -
    • SPC(n) -- print n spaces
    • -
    • TAB(n) -- advance to column n
    • +
    • SPC(n) -- print n spaces
    - -
    -Print "Name:"; Tab(20); name$
    -Print Using "###.##"; total
    -Print #1, "Written to file"
    -
    - - - -

    INPUT

    - +

    TAB(n) -- advance to column n

    +
    Print "Name:"; Tab(20); name$
    +Print Using "###.##"; total
    +Print #1, "Written to file"
    +

    INPUT

    Reads a line of text from the user or from a file channel.

    - -
    -INPUT variable
    -INPUT "prompt"; variable
    -INPUT #channel, variable
    -
    - -
    -Input "Enter your name: "; name$
    -Input #1, line$
    -
    - - - -

    DATA / READ / RESTORE

    - +
    INPUT variable
    +INPUT "prompt"; variable
    +INPUT #channel, variable
    +
    Input "Enter your name: "; name$
    +Input #1, line$
    +

    DATA / READ / RESTORE

    Inline data pool for constants.

    - -
    -DATA value1, value2, "string", ...
    -READ variable1, variable2, ...
    -RESTORE
    -
    - -

    DATA statements define a pool of values. READ -reads the next value from the pool into a variable. RESTORE -resets the read pointer to the beginning.

    - -
    -Data 10, 20, 30, "Hello"
    +
    DATA value1, value2, "string", ...
    +READ variable1, variable2, ...
    +RESTORE
    +

    DATA statements define a pool of values. READ reads the next value from the +pool into a variable. RESTORE resets the read pointer to the beginning.

    +
    Data 10, 20, 30, "Hello"
     Read a, b, c, msg$
     Print a; b; c; msg$
    -Restore
    -
    - - - -

    Assignment

    - -

    Assigns a value to a variable, array element, or UDT field.

    - -
    -variable = expression
    -array(index) = expression
    -udt.field = expression
    -LET variable = expression
    -
    - -

    The LET keyword is optional and supported for -compatibility.

    - - - -

    SWAP

    - -

    Exchanges the values of two variables.

    - -
    -SWAP variable1, variable2
    -
    - -
    -Swap a, b
    -
    - - - -

    ERASE

    - -

    Frees the memory of an array and resets it.

    - -
    -ERASE arrayName
    -
    - - - -

    OPTION

    - -

    Sets compiler options. Must appear before any executable code.

    - -
    -OPTION BASE 0          ' Arrays start at index 0 (default)
    -OPTION BASE 1          ' Arrays start at index 1
    -OPTION COMPARE BINARY  ' Case-sensitive string comparisons (default)
    -OPTION COMPARE TEXT    ' Case-insensitive string comparisons
    -OPTION EXPLICIT        ' All variables must be declared with DIM
    -
    - - - -

    DEFtype Statements

    - -

    Set the default type for variables based on their first letter.

    - -
    -DEFINT letterRange
    -DEFLNG letterRange
    -DEFSNG letterRange
    -DEFDBL letterRange
    -DEFSTR letterRange
    -
    - -
    -DefInt I-N     ' Variables starting with I through N default to Integer
    -DefStr S       ' Variables starting with S default to String
    -
    - - - -

    STATIC

    - -

    Declares a local variable that retains its value between calls.

    - -
    -STATIC variable AS type
    -
    - -
    -Sub Counter()
    -    Static count As Integer
    -    count = count + 1
    -    Print count
    -End Sub
    -
    - - - -

    Error Handling

    - -
    -ON ERROR GOTO label     ' Enable error handler
    +Restore
    +
    +
    +

    Miscellaneous Statements

    +

    Miscellaneous Statements

    +

    Error Handling

    +
    ON ERROR GOTO label     ' Enable error handler
     ON ERROR GOTO 0          ' Disable error handler
     RESUME                   ' Retry the statement that caused the error
     RESUME NEXT              ' Continue at the next statement after the error
    -ERROR n                  ' Raise a runtime error with error number n
    -
    - -

    The ERR keyword returns the current error number in -expressions.

    - -
    -On Error GoTo ErrorHandler
    -Open "missing.txt" For Input As #1
    +ERROR n                  ' Raise a runtime error with error number n
    +

    The ERR keyword returns the current error number in expressions.

    +
    On Error GoTo ErrorHandler
    +Open "missing.txt" For Input As #1
     Exit Sub
     
     ErrorHandler:
    -    Print "Error number:"; Err
    -    Resume Next
    -
    - - - -

    SHELL

    - + Print "Error number:"; Err + Resume Next
    +

    SHELL

    Executes an operating system command.

    - -
    -SHELL "command"
    -
    - +
    SHELL "command"

    When used as a function, returns the exit code of the command.

    - -
    -Shell "DIR /B"
    -exitCode = Shell("COPY A.TXT B.TXT")
    -
    - - - -

    SLEEP

    - +
    Shell "DIR /B"
    +exitCode = Shell("COPY A.TXT B.TXT")
    +

    SLEEP

    Pauses execution for a specified number of seconds.

    - -
    -SLEEP seconds
    -
    - - - -

    RANDOMIZE

    - +
    SLEEP seconds
    +

    RANDOMIZE

    Seeds the random number generator.

    - -
    -RANDOMIZE seed
    -RANDOMIZE TIMER          ' Seed from system clock
    -
    - - - -

    END

    - +
    RANDOMIZE seed
    +RANDOMIZE TIMER          ' Seed from system clock
    +

    END

    Terminates program execution immediately.

    - -
    -END
    -
    - - - -

    DECLARE

    - -

    Forward-declares a SUB or FUNCTION. Required when a procedure is called -before it is defined.

    - -
    -DECLARE SUB name ([BYVAL] param AS type, ...)
    -DECLARE FUNCTION name ([BYVAL] param AS type, ...) AS returnType
    -
    - - - -

    DECLARE LIBRARY

    - -

    Declares external native functions from a dynamically loaded library. -This allows BASIC programs to call functions exported by DXE libraries.

    - -
    -DECLARE LIBRARY "libraryName"
    -    DECLARE SUB name ([BYVAL] param AS type, ...)
    -    DECLARE FUNCTION name ([BYVAL] param AS type, ...) AS returnType
    -END DECLARE
    -
    - -
    -Declare Library "rs232"
    -    Declare Function ComOpen(ByVal port As Integer) As Integer
    -    Declare Sub ComClose(ByVal port As Integer)
    -    Declare Sub ComSend(ByVal port As Integer, ByVal data$ As String)
    -End Declare
    -
    - - - -

    4. File I/O

    - - +
    END
    +
    +
    +

    File I/O

    +

    File I/O

    OPEN

    -

    Opens a file for reading, writing, or appending.

    - -
    -OPEN filename$ FOR INPUT AS #channel
    -OPEN filename$ FOR OUTPUT AS #channel
    -OPEN filename$ FOR APPEND AS #channel
    -OPEN filename$ FOR RANDOM AS #channel [LEN = recordSize]
    -OPEN filename$ FOR BINARY AS #channel
    -
    - - - - - - - - -
    ModeDescription
    INPUTOpen for sequential reading. File must exist.
    OUTPUTOpen for sequential writing. Creates or truncates.
    APPENDOpen for sequential writing at end of file.
    RANDOMOpen for random-access record I/O.
    BINARYOpen for raw binary I/O.
    - - +
    OPEN filename$ FOR INPUT AS #channel
    +OPEN filename$ FOR OUTPUT AS #channel
    +OPEN filename$ FOR APPEND AS #channel
    +OPEN filename$ FOR RANDOM AS #channel [LEN = recordSize]
    +OPEN filename$ FOR BINARY AS #channel
    +
      Mode      Description
    +  ----      -----------
    +  INPUT     Open for sequential reading. File must exist.
    +  OUTPUT    Open for sequential writing. Creates or truncates.
    +  APPEND    Open for sequential writing at end of file.
    +  RANDOM    Open for random-access record I/O.
    +  BINARY    Open for raw binary I/O.

    CLOSE

    - -
    -CLOSE #channel
    -
    - - +

    Closes an open file channel.

    +
    CLOSE #channel

    PRINT #

    -

    Writes text to a file.

    - -
    -PRINT #channel, expression
    -
    - - +
    PRINT #channel, expression

    INPUT #

    -

    Reads comma-delimited data from a file.

    - -
    -INPUT #channel, variable
    -
    - - +
    INPUT #channel, variable

    LINE INPUT #

    -

    Reads an entire line from a file into a string variable.

    - -
    -LINE INPUT #channel, variable$
    -
    - - +
    LINE INPUT #channel, variable$

    WRITE #

    -

    Writes comma-delimited data to a file. Strings are enclosed in quotes, numbers are undecorated. Each statement writes a newline at the end.

    - -
    -WRITE #channel, expr1, expr2, ...
    -
    - -
    -Write #1, "Scott", 42, 3.14
    -' Output: "Scott",42,3.14
    -
    - - +
    WRITE #channel, expr1, expr2, ...
    +
    Write #1, "Scott", 42, 3.14
    +' Output: "Scott",42,3.14

    GET / PUT

    -

    Read and write records in RANDOM or BINARY mode files.

    - -
    -GET #channel, [recordNum], variable
    -PUT #channel, [recordNum], variable
    -
    - - +
    GET #channel, [recordNum], variable
    +PUT #channel, [recordNum], variable

    SEEK

    -

    Sets the file position. As a function, returns the current position.

    - -
    -SEEK #channel, position      ' Statement: set position
    -pos = SEEK(channel)           ' Function: get current position
    -
    - - - -

    5. Built-in Functions

    - - - - -

    String Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FunctionArgsReturnsDescription
    ASC(s$)1IntegerReturns the ASCII code of the first character of s$.
    CHR$(n)1StringReturns the character with ASCII code n.
    FORMAT$(value, fmt$)2StringFormats a numeric value using the format string fmt$.
    HEX$(n)1StringReturns the hexadecimal representation of n.
    INSTR(s$, find$)2-3IntegerReturns the position of find$ in s$ (1-based). Optionally - takes a starting position as the first argument: - INSTR(start, s$, find$). Returns 0 if - not found.
    LCASE$(s$)1StringConverts s$ to lowercase.
    LEFT$(s$, n)2StringReturns the leftmost n characters of s$.
    LEN(s$)1IntegerReturns the length of s$.
    LTRIM$(s$)1StringRemoves leading spaces from s$.
    MID$(s$, start [, length])2-3StringReturns a substring starting at position start (1-based). If - length is omitted, returns from start to end.
    RIGHT$(s$, n)2StringReturns the rightmost n characters of s$.
    RTRIM$(s$)1StringRemoves trailing spaces from s$.
    SPACE$(n)1StringReturns a string of n spaces.
    STR$(n)1StringConverts number n to its string representation.
    STRING$(n, char)2StringReturns a string of n copies of char (ASCII code or - single-character string).
    TRIM$(s$)1StringRemoves leading and trailing spaces from s$.
    UCASE$(s$)1StringConverts s$ to uppercase.
    VAL(s$)1DoubleConverts the string s$ to a numeric value.
    - -

    MID$ Assignment

    - -

    MID$ can also be used on the left side of an assignment to -replace a portion of a string:

    - -
    -Mid$(s$, 3, 2) = "XY"    ' Replace 2 characters starting at position 3
    -
    - - - -

    Math Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FunctionArgsReturnsDescription
    ABS(n)1DoubleAbsolute value of n.
    ATN(n)1DoubleArctangent of n (in radians).
    COS(n)1DoubleCosine of n (radians).
    EXP(n)1DoubleReturns e raised to the power n.
    FIX(n)1IntegerTruncates n toward zero (removes the fractional part).
    INT(n)1IntegerReturns the largest integer less than or equal to n (floor).
    LOG(n)1DoubleNatural logarithm (base e) of n.
    RND[(n)]0-1DoubleReturns a random number between 0 (inclusive) and 1 (exclusive). - With a negative argument, seeds and returns. With 0, returns the - previous value.
    SGN(n)1IntegerReturns the sign of n: -1, 0, or 1.
    SIN(n)1DoubleSine of n (radians).
    SQR(n)1DoubleSquare root of n.
    TAN(n)1DoubleTangent of n (radians).
    TIMER0DoubleReturns the number of seconds since midnight.
    - - - -

    Conversion Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FunctionArgsReturnsDescription
    CDBL(n)1DoubleConverts n to Double.
    CINT(n)1IntegerConverts n to Integer (with banker's rounding).
    CLNG(n)1LongConverts n to Long.
    CSNG(n)1SingleConverts n to Single.
    CSTR(n)1StringConverts n to its String representation.
    - - - -

    File I/O Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FunctionArgsReturnsDescription
    EOF(channel)1BooleanReturns True if the file pointer is at end of file.
    FREEFILE0IntegerReturns the next available file channel number.
    INPUT$(n, #channel)2StringReads n characters from the file and returns them as a string.
    LOC(channel)1LongReturns the current read/write position in the file.
    LOF(channel)1LongReturns the length of the file in bytes.
    SEEK(channel)1LongReturns the current file position (function form of SEEK).
    LBOUND(array [, dim])1-2IntegerReturns the lower bound of an array dimension.
    UBOUND(array [, dim])1-2IntegerReturns the upper bound of an array dimension.
    - - - -

    Miscellaneous Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FunctionArgsReturnsDescription
    DATE$0StringReturns the current date as "MM-DD-YYYY".
    TIME$0StringReturns the current time as "HH:MM:SS".
    ENVIRON$(name$)1StringReturns the value of the environment variable name$.
    ERR0IntegerReturns the current runtime error number (0 if no error).
    - - - -

    6. Form and Control Statements

    - - +
    SEEK #channel, position      ' Statement: set position
    +pos = SEEK(channel)           ' Function: get current position
    +
    +
    +

    String Functions

    +

    String Functions

    +
      Function                          Returns   Description
    +  --------                          -------   -----------
    +  ASC(s$)                           Integer   ASCII code of first character of s$
    +  CHR$(n)                           String    Character with ASCII code n
    +  FORMAT$(value, fmt$)              String    Formats a numeric value using format string
    +  HEX$(n)                           String    Hexadecimal representation of n
    +  INSTR(s$, find$)                  Integer   Position of find$ in s$ (1-based), 0 if not found
    +  INSTR(start, s$, find$)          Integer   Search starting at position start
    +  LCASE$(s$)                        String    Converts s$ to lowercase
    +  LEFT$(s$, n)                      String    Leftmost n characters of s$
    +  LEN(s$)                           Integer   Length of s$
    +  LTRIM$(s$)                        String    Removes leading spaces from s$
    +  MID$(s$, start [, length])        String    Substring from position start (1-based)
    +  RIGHT$(s$, n)                     String    Rightmost n characters of s$
    +  RTRIM$(s$)                        String    Removes trailing spaces from s$
    +  SPACE$(n)                         String    String of n spaces
    +  STR$(n)                           String    Converts number n to string
    +  STRING$(n, char)                  String    String of n copies of char
    +  TRIM$(s$)                         String    Removes leading and trailing spaces from s$
    +  UCASE$(s$)                        String    Converts s$ to uppercase
    +  VAL(s$)                           Double    Converts string s$ to a numeric value
    +

    MID$ Assignment

    +

    MID$ can also be used on the left side of an assignment to replace a portion +of a string:

    +
    Mid$(s$, 3, 2) = "XY"    ' Replace 2 characters starting at position 3
    +
    +
    +

    Math Functions

    +

    Math Functions

    +
      Function   Returns   Description
    +  --------   -------   -----------
    +  ABS(n)     Double    Absolute value of n
    +  ATN(n)     Double    Arctangent of n (in radians)
    +  COS(n)     Double    Cosine of n (radians)
    +  EXP(n)     Double    e raised to the power n
    +  FIX(n)     Integer   Truncates n toward zero (removes fractional part)
    +  INT(n)     Integer   Largest integer less than or equal to n (floor)
    +  LOG(n)     Double    Natural logarithm (base e) of n
    +  RND[(n)]   Double    Random number between 0 (inclusive) and 1 (exclusive)
    +  SGN(n)     Integer   Sign of n: -1, 0, or 1
    +  SIN(n)     Double    Sine of n (radians)
    +  SQR(n)     Double    Square root of n
    +  TAN(n)     Double    Tangent of n (radians)
    +  TIMER      Double    Number of seconds since midnight
    +
    Note: RND with a negative argument seeds and returns. RND(0) returns the previous +value. Use RANDOMIZE to seed the generator.
    +
    +
    +

    Conversion Functions

    +

    Conversion Functions

    +
      Function   Returns   Description
    +  --------   -------   -----------
    +  CDBL(n)    Double    Converts n to Double
    +  CINT(n)    Integer   Converts n to Integer (with banker's rounding)
    +  CLNG(n)    Long      Converts n to Long
    +  CSNG(n)    Single    Converts n to Single
    +  CSTR(n)    String    Converts n to its String representation
    +
    +
    +

    File I/O Functions

    +

    File I/O Functions

    +
      Function                    Returns   Description
    +  --------                    -------   -----------
    +  EOF(channel)                Boolean   True if file pointer is at end of file
    +  FREEFILE                    Integer   Next available file channel number
    +  INPUT$(n, #channel)         String    Reads n characters from the file
    +  LOC(channel)                Long      Current read/write position in the file
    +  LOF(channel)                Long      Length of the file in bytes
    +  SEEK(channel)               Long      Current file position (function form)
    +  LBOUND(array [, dim])       Integer   Lower bound of an array dimension
    +  UBOUND(array [, dim])       Integer   Upper bound of an array dimension
    +
    +
    +

    Miscellaneous Functions

    +

    Miscellaneous Functions

    +
      Function          Returns   Description
    +  --------          -------   -----------
    +  DATE$             String    Current date as "MM-DD-YYYY"
    +  TIME$             String    Current time as "HH:MM:SS"
    +  ENVIRON$(name$)   String    Value of environment variable name$
    +  ERR               Integer   Current runtime error number (0 if no error)
    +
    +
    +

    Form and Control Statements

    +

    Form and Control Statements

    DVX BASIC supports Visual Basic-style forms and controls for building -graphical user interfaces. Forms are defined in .frm files and -loaded at runtime.

    - +graphical user interfaces. Forms are defined in .frm files and loaded at +runtime.

    Loading and Unloading Forms

    - -
    -LOAD FormName
    -UNLOAD FormName
    -
    - -

    LOAD creates the form and its controls in memory. -UNLOAD destroys the form and frees its resources.

    - +
    LOAD FormName
    +UNLOAD FormName
    +

    LOAD creates the form and its controls in memory. UNLOAD destroys the form +and frees its resources.

    Showing and Hiding Forms

    - -
    -FormName.Show [modal]
    -FormName.Hide
    -Me.Show [modal]
    -Me.Hide
    -
    - -

    Pass vbModal (1) to Show for a modal dialog.

    - -
    -Form2.Show vbModal
    -Me.Hide
    -
    - +
    FormName.Show [modal]
    +FormName.Hide
    +Me.Show [modal]
    +Me.Hide
    +

    Pass vbModal (1) to Show for a modal dialog.

    +
    Form2.Show vbModal
    +Me.Hide

    Property Access

    -

    Read and write control properties using dot notation:

    - -
    -ControlName.Property = value
    -value = ControlName.Property
    -
    - -
    -Text1.Text = "Hello"
    -label1.Caption = "Name: " & name$
    -x = Text1.Left
    -
    - +
    ControlName.Property = value
    +value = ControlName.Property
    +
    Text1.Text = "Hello"
    +label1.Caption = "Name: " & name$
    +x = Text1.Left

    Method Calls

    - -
    -ControlName.Method [args]
    -
    - -
    -List1.AddItem "New entry"
    -List1.Clear
    -
    - +
    ControlName.Method [args]
    +
    List1.AddItem "New entry"
    +List1.Clear

    Me Keyword

    - -

    Me refers to the current form. Use it to access the form's -own properties, controls, and methods from within event handlers.

    - -
    -Me.Caption = "Updated Title"
    -Me.Text1.Text = ""
    -Me.Hide
    -
    - +

    Me refers to the current form. Use it to access the form's own properties, +controls, and methods from within event handlers.

    +
    Me.Caption = "Updated Title"
    +Me.Text1.Text = ""
    +Me.Hide

    Control Arrays

    -

    Multiple controls can share a name with unique indices. Access individual controls with parenthesized indices:

    - -
    -Option1(0).Value = True
    -Label1(idx).Caption = "Item " & Str$(idx)
    -Me.Label1(i).Visible = True
    -
    - +
    Option1(0).Value = True
    +Label1(idx).Caption = "Item " & Str$(idx)
    +Me.Label1(i).Visible = True

    DoEvents

    -

    Yields control to the DVX event loop, allowing the GUI to process pending events. Call this in long-running loops to keep the UI responsive.

    - -
    -DOEVENTS
    -
    - -
    -For i = 1 To 10000
    +
    DOEVENTS
    +
    For i = 1 To 10000
         ' process data
         If i Mod 100 = 0 Then DoEvents
    -Next
    -
    - +Next

    MsgBox

    - -

    Displays a message box dialog. Can be used as a statement (discards -result) or as a function (returns the button clicked).

    - -
    -MSGBOX message$ [, flags]
    -result = MSGBOX(message$ [, flags])
    -
    - -
    -MsgBox "Operation complete"
    -answer = MsgBox("Continue?", vbYesNo + vbQuestion)
    +

    Displays a message box dialog. Can be used as a statement (discards result) +or as a function (returns the button clicked).

    +
    MSGBOX message$ [, flags]
    +result = MSGBOX(message$ [, flags])
    +
    MsgBox "Operation complete"
    +answer = MsgBox("Continue?", vbYesNo + vbQuestion)
     If answer = vbYes Then
         ' proceed
    -End If
    -
    - +End If

    InputBox$

    -

    Displays an input dialog and returns the user's text entry.

    - -
    -result$ = INPUTBOX$(prompt$ [, title$ [, default$]])
    -
    - -
    -name$ = InputBox$("Enter your name:", "Name Entry", "")
    -
    - +
    result$ = INPUTBOX$(prompt$ [, title$ [, default$]])
    +
    name$ = InputBox$("Enter your name:", "Name Entry", "")

    Event Handler Convention

    - -

    Event handlers are named ControlName_EventName -and defined as SUBs:

    - -
    -Sub Command1_Click()
    -    MsgBox "Button clicked!"
    +

    Event handlers are named ControlName_EventName and defined as SUBs:

    +
    Sub Command1_Click()
    +    MsgBox "Button clicked!"
     End Sub
     
     Sub Form_Load()
    -    Me.Caption = "My App"
    +    Me.Caption = "My App"
     End Sub
     
     Sub Text1_Change()
    -    Label1.Caption = "You typed: " & Text1.Text
    -End Sub
    -
    - -

    Common events:

    - - - - - - - - - - - - - - - - - - -
    EventDescription
    ClickControl was clicked
    DblClickControl was double-clicked
    ChangeControl value/text changed
    KeyPressKey was pressed (receives key code)
    KeyDownKey went down (receives key code and shift state)
    KeyUpKey was released
    MouseDownMouse button pressed
    MouseUpMouse button released
    MouseMoveMouse moved over control
    GotFocusControl received input focus
    LostFocusControl lost input focus
    Form_LoadForm is being loaded
    Form_UnloadForm is being unloaded
    Form_ResizeForm was resized
    TimerTimer interval elapsed
    - - - -

    7. SQL Functions

    - - + Label1.Caption = "You typed: " & Text1.Text +End Sub
    +

    Common Events

    +
      Event          Description
    +  -----          -----------
    +  Click          Control was clicked
    +  DblClick       Control was double-clicked
    +  Change         Control value/text changed
    +  KeyPress       Key was pressed (receives key code)
    +  KeyDown        Key went down (receives key code and shift state)
    +  KeyUp          Key was released
    +  MouseDown      Mouse button pressed
    +  MouseUp        Mouse button released
    +  MouseMove      Mouse moved over control
    +  GotFocus       Control received input focus
    +  LostFocus      Control lost input focus
    +  Form_Load      Form is being loaded
    +  Form_Unload    Form is being unloaded
    +  Form_Resize    Form was resized
    +  Timer          Timer interval elapsed
    +
    +
    +

    SQL Functions

    +

    SQL Functions

    DVX BASIC includes built-in SQLite database support through a set of SQL functions. All functions use database handles and result set handles -(integers) returned by SQLOpen and SQLQuery.

    - +(integers) returned by SQLOpen and SQLQuery.

    Opening and Closing Databases

    -

    SQLOpen

    -

    Opens a SQLite database file and returns a database handle.

    - -
    -db = SQLOPEN(path$)
    -
    - -
    -db = SQLOpen(App.Data & "\mydata.db")
    -
    - +
    db = SQLOPEN(path$)
    +
    db = SQLOpen(App.Data & "\mydata.db")

    SQLClose

    -

    Closes an open database.

    - -
    -SQLCLOSE db
    -
    - - +
    SQLCLOSE db

    Executing SQL

    -

    SQLExec

    - -

    Executes a SQL statement that does not return data (INSERT, UPDATE, -DELETE, CREATE TABLE, etc.). Can be used as a statement or as a function -returning a Boolean success flag.

    - -
    -SQLEXEC db, sql$
    -ok = SQLEXEC(db, sql$)
    -
    - -
    -SQLExec db, "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)"
    -SQLExec db, "INSERT INTO users (name) VALUES ('Scott')"
    -ok = SQLExec(db, "DELETE FROM users WHERE id = 5")
    -
    - +

    Executes a SQL statement that does not return data (INSERT, UPDATE, DELETE, +CREATE TABLE, etc.). Can be used as a statement or as a function returning a +Boolean success flag.

    +
    SQLEXEC db, sql$
    +ok = SQLEXEC(db, sql$)
    +
    SQLExec db, "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)"
    +SQLExec db, "INSERT INTO users (name) VALUES ('Scott')"
    +ok = SQLExec(db, "DELETE FROM users WHERE id = 5")

    SQLAffected

    -

    Returns the number of rows affected by the last INSERT, UPDATE, or DELETE.

    - -
    -count = SQLAFFECTED(db)
    -
    - - +
    count = SQLAFFECTED(db)

    Querying Data

    -

    SQLQuery

    -

    Executes a SELECT query and returns a result set handle.

    - -
    -rs = SQLQUERY(db, sql$)
    -
    - -
    -rs = SQLQuery(db, "SELECT id, name FROM users ORDER BY name")
    -
    - +
    rs = SQLQUERY(db, sql$)
    +
    rs = SQLQuery(db, "SELECT id, name FROM users ORDER BY name")

    SQLNext

    - -

    Advances to the next row in the result set. Can be used as a statement or -as a function returning True if a row is available.

    - -
    -SQLNEXT rs
    -hasRow = SQLNEXT(rs)
    -
    - +

    Advances to the next row in the result set. Can be used as a statement or as +a function returning True if a row is available.

    +
    SQLNEXT rs
    +hasRow = SQLNEXT(rs)

    SQLEof

    -

    Returns True if there are no more rows in the result set.

    - -
    -done = SQLEOF(rs)
    -
    - - +
    done = SQLEOF(rs)

    Reading Fields

    -

    SQLField$

    -

    Returns a field value as a string. The field can be specified by column index (0-based) or by column name.

    - -
    -value$ = SQLFIELD$(rs, columnIndex)
    -value$ = SQLFIELD$(rs, "columnName")
    -
    - -
    -name$ = SQLField$(rs, "name")
    -first$ = SQLField$(rs, 0)
    -
    - +
    value$ = SQLFIELD$(rs, columnIndex)
    +value$ = SQLFIELD$(rs, "columnName")
    +
    name$ = SQLField$(rs, "name")
    +first$ = SQLField$(rs, 0)

    SQLFieldInt

    -

    Returns a field value as an integer.

    - -
    -value = SQLFIELDINT(rs, columnIndex)
    -
    - +
    value = SQLFIELDINT(rs, columnIndex)

    SQLFieldDbl

    -

    Returns a field value as a double.

    - -
    -value# = SQLFIELDDBL(rs, columnIndex)
    -
    - +
    value# = SQLFIELDDBL(rs, columnIndex)

    SQLFieldCount

    -

    Returns the number of columns in the result set.

    - -
    -count = SQLFIELDCOUNT(rs)
    -
    - - +
    count = SQLFIELDCOUNT(rs)

    Result Set Cleanup

    -

    SQLFreeResult

    -

    Frees a result set. Always call this when done iterating a query.

    - -
    -SQLFREERESULT rs
    -
    - - +
    SQLFREERESULT rs

    Error Information

    -

    SQLError$

    -

    Returns the last error message for the database.

    - -
    -msg$ = SQLERROR$(db)
    -
    - - +
    msg$ = SQLERROR$(db)

    Complete SQL Example

    - -
    -Dim db As Long
    +
    Dim db As Long
     Dim rs As Long
     
    -db = SQLOpen(App.Data & "\contacts.db")
    -SQLExec db, "CREATE TABLE IF NOT EXISTS contacts (name TEXT, phone TEXT)"
    -SQLExec db, "INSERT INTO contacts VALUES ('Alice', '555-1234')"
    +db = SQLOpen(App.Data & "\contacts.db")
    +SQLExec db, "CREATE TABLE IF NOT EXISTS contacts (name TEXT, phone TEXT)"
    +SQLExec db, "INSERT INTO contacts VALUES ('Alice', '555-1234')"
     
    -rs = SQLQuery(db, "SELECT name, phone FROM contacts")
    +rs = SQLQuery(db, "SELECT name, phone FROM contacts")
     Do While Not SQLEof(rs)
         SQLNext rs
    -    Print SQLField$(rs, "name"); Tab(20); SQLField$(rs, "phone")
    +    Print SQLField$(rs, "name"); Tab(20); SQLField$(rs, "phone")
     Loop
     SQLFreeResult rs
    -SQLClose db
    -
    - - - -

    8. App Object

    - - -

    The App object provides read-only properties for the -application's directory paths.

    - - - - - - - - - - - - - - - - - - - - - - -
    PropertyReturnsDescription
    App.PathStringThe directory containing the application's executable.
    App.ConfigStringThe directory for application configuration files.
    App.DataStringThe directory for application data files (databases, etc.).
    - -
    -configFile$ = App.Config & "\settings.ini"
    -dbPath$ = App.Data & "\myapp.db"
    -Print "Running from: " & App.Path
    -
    - - - -

    9. INI Functions

    - - +SQLClose db
    +
    +
    +

    App Object

    +

    App Object

    +

    The App object provides read-only properties for the application's directory +paths.

    +
      Property      Returns   Description
    +  --------      -------   -----------
    +  App.Path      String    Directory containing the application's executable
    +  App.Config    String    Directory for application configuration files
    +  App.Data      String    Directory for application data files (databases, etc.)
    +
    configFile$ = App.Config & "\settings.ini"
    +dbPath$ = App.Data & "\myapp.db"
    +Print "Running from: " & App.Path
    +
    +
    +

    INI Functions

    +

    INI Functions

    DVX BASIC provides built-in functions for reading and writing standard INI configuration files.

    -

    IniRead

    - -

    Reads a value from an INI file. Returns the default value if the key is -not found.

    - -
    -value$ = INIREAD(file$, section$, key$, default$)
    -
    - -
    -name$ = IniRead(App.Config & "\app.ini", "User", "Name", "Unknown")
    -fontSize = Val(IniRead(App.Config & "\app.ini", "Display", "FontSize", "12"))
    -
    - +

    Reads a value from an INI file. Returns the default value if the key is not +found.

    +
    value$ = INIREAD(file$, section$, key$, default$)
    +
    name$ = IniRead(App.Config & "\app.ini", "User", "Name", "Unknown")
    +fontSize = Val(IniRead(App.Config & "\app.ini", "Display", "FontSize", "12"))

    IniWrite

    - -

    Writes a value to an INI file. Creates the file, section, or key if they -do not exist.

    - -
    -INIWRITE file$, section$, key$, value$
    -
    - -
    -IniWrite App.Config & "\app.ini", "User", "Name", "Scott"
    -IniWrite App.Config & "\app.ini", "Display", "FontSize", Str$(fontSize)
    -
    - - - -

    10. Predefined Constants

    - - +

    Writes a value to an INI file. Creates the file, section, or key if they do +not exist.

    +
    INIWRITE file$, section$, key$, value$
    +
    IniWrite App.Config & "\app.ini", "User", "Name", "Scott"
    +IniWrite App.Config & "\app.ini", "Display", "FontSize", Str$(fontSize)
    +
    +
    +

    Predefined Constants

    +

    Predefined Constants

    The following constants are predefined by the compiler and available in all programs.

    -

    MsgBox Button Style Flags

    - - - - - - - - -
    ConstantValueDescription
    vbOKOnly0OK button only (default)
    vbOKCancel1OK and Cancel buttons
    vbYesNo2Yes and No buttons
    vbYesNoCancel3Yes, No, and Cancel buttons
    vbRetryCancel4Retry and Cancel buttons
    - +
      Constant        Value   Description
    +  --------        -----   -----------
    +  vbOKOnly        0       OK button only (default)
    +  vbOKCancel      1       OK and Cancel buttons
    +  vbYesNo         2       Yes and No buttons
    +  vbYesNoCancel   3       Yes, No, and Cancel buttons
    +  vbRetryCancel   4       Retry and Cancel buttons

    MsgBox Icon Flags

    - -

    Add an icon flag to the button style to display an icon in the message -box.

    - - - - - - - -
    ConstantValueDescription
    vbInformation&H10Information icon
    vbExclamation&H20Warning icon
    vbCritical&H30Error/critical icon
    vbQuestion&H40Question mark icon
    - +

    Add an icon flag to the button style to display an icon in the message box.

    +
      Constant        Value   Description
    +  --------        -----   -----------
    +  vbInformation   &H10    Information icon
    +  vbExclamation   &H20    Warning icon
    +  vbCritical      &H30    Error/critical icon
    +  vbQuestion      &H40    Question mark icon

    MsgBox Return Values

    - - - - - - - - -
    ConstantValueDescription
    vbOK1User clicked OK
    vbCancel2User clicked Cancel
    vbYes3User clicked Yes
    vbNo4User clicked No
    vbRetry5User clicked Retry
    - +
      Constant   Value   Description
    +  --------   -----   -----------
    +  vbOK       1       User clicked OK
    +  vbCancel   2       User clicked Cancel
    +  vbYes      3       User clicked Yes
    +  vbNo       4       User clicked No
    +  vbRetry    5       User clicked Retry

    Show Mode Flags

    - - - - -
    ConstantValueDescription
    vbModal1Show form as modal dialog
    - +
      Constant   Value   Description
    +  --------   -----   -----------
    +  vbModal    1       Show form as modal dialog

    Boolean Constants

    - - - - - -
    ConstantValueDescription
    True-1Boolean true
    False0Boolean false
    - - -
    -

    DVX BASIC Language Reference -- Generated from compiler source code. -Covers the lexer, parser, and VM opcode set as implemented.

    - +
      Constant   Value   Description
    +  --------   -----   -----------
    +  True       -1      Boolean true
    +  False      0       Boolean false
    +
    +
    diff --git a/docs/src/dvx_api_reference.dvxhelp b/docs/src/dvx_api_reference.dvxhelp new file mode 100644 index 0000000..f7dc2c9 --- /dev/null +++ b/docs/src/dvx_api_reference.dvxhelp @@ -0,0 +1,3499 @@ +.topic api.overview +.title DVX GUI API Reference +.toc 0 DVX GUI API Reference +.default +.index DVX API +.index API Reference + +.h1 DVX GUI API Reference + +DOS Visual eXecutive -- Complete public API documentation generated from source headers. + +The DVX GUI is built as a five-layer architecture. Each layer is defined in its own header file. This reference covers every public function, type, and constant. + +.h2 Layers + +.list +.item dvxTypes.h -- Shared type definitions +.item dvxCursor.h -- Cursor definitions +.item dvxVideo.h -- Layer 1: VESA VBE Video Backend +.item dvxDraw.h -- Layer 2: Drawing Primitives +.item dvxComp.h -- Layer 3: Dirty Rectangle Compositor +.item dvxWm.h -- Layer 4: Window Manager +.item dvxApp.h -- Layer 5: Application API +.item dvxWidget.h -- Widget System +.endlist + +.link api.types dvxTypes.h -- Shared Type Definitions +.link api.cursor dvxCursor.h -- Cursor Definitions +.link api.video dvxVideo.h -- Layer 1: VESA VBE Video Backend +.link api.draw dvxDraw.h -- Layer 2: Drawing Primitives +.link api.comp dvxComp.h -- Layer 3: Dirty Rectangle Compositor +.link api.wm dvxWm.h -- Layer 4: Window Manager +.link api.app dvxApp.h -- Layer 5: Application API +.link api.widget dvxWidget.h -- Widget System + +.topic api.types +.title dvxTypes.h -- Shared Type Definitions +.toc 0 dvxTypes.h -- Shared Type Definitions +.index dvxTypes.h +.index PixelFormatT +.index DisplayT +.index RectT +.index BlitOpsT +.index BevelStyleT +.index BitmapFontT +.index ColorSchemeT +.index ColorIdE +.index DirtyListT +.index WindowT +.index WindowStackT +.index MenuT +.index MenuItemT +.index MenuBarT +.index ScrollbarT +.index AccelTableT +.index AccelEntryT +.index VideoModeInfoT +.index CursorT + +.h1 dvxTypes.h -- Shared Type Definitions + +Central type definitions shared across all five layers of the DVX GUI stack. Every header includes this file. Contains no function definitions -- only structs, enums, typedefs, and compile-time constants. + +.h2 Core Structures + +.h3 PixelFormatT + +Describes the pixel encoding for the active VESA video mode. Populated once at startup from the VBE mode info block, then treated as read-only. + +.table + Field Description + ----- ----------- + int32_t bitsPerPixel 8, 15, 16, or 32 + int32_t bytesPerPixel 1, 2, 2, or 4 + uint32_t redMask, greenMask, blueMask Bitmasks for each color channel + int32_t redShift, greenShift, blueShift Bit position of each color field + int32_t redBits, greenBits, blueBits Number of bits per channel +.endtable + +.h3 DisplayT + +Single display context passed by pointer through every layer. All drawing targets the backBuf; only dirty rects are flushed to lfb. + +.table + Field Description + ----- ----------- + int32_t width, height Screen dimensions in pixels + int32_t pitch Bytes per scanline + PixelFormatT format Active pixel format + uint8_t *lfb Mapped linear framebuffer (VESA LFB) + uint8_t *backBuf System RAM backbuffer + uint8_t *palette 768 bytes for 8-bit mode, NULL otherwise + int32_t clipX, clipY, clipW, clipH Current clip rectangle +.endtable + +.h3 RectT + +Rectangle in origin + extent form. Used throughout the compositor, window manager, and widget layout engine. + +.table + Field Description + ----- ----------- + int32_t x, y Top-left corner + int32_t w, h Width and height +.endtable + +.h3 BlitOpsT + +Vtable for hot-path span operations. Resolved at init time based on pixel depth. On DOS, these dispatch to hand-written asm (rep stosl / rep movsd). + +.table + Field Description + ----- ----------- + SpanFillFnT spanFill Fill a horizontal span with a solid color + SpanCopyFnT spanCopy Copy a horizontal span between buffers + int32_t bytesPerPixel Bytes per pixel for the active mode + int32_t pitch Bytes per scanline +.endtable + +.h3 BevelStyleT + +Bevel drawing parameters. Swapping highlight/shadow flips raised vs. sunken appearance. + +.table + Field Description + ----- ----------- + uint32_t highlight Lighter color (top/left edges) + uint32_t shadow Darker color (bottom/right edges) + uint32_t face Interior fill color (0 = no fill) + int32_t width Border thickness in pixels (typically 2) +.endtable + +.h3 BitmapFontT + +Fixed-width 8-pixel-wide bitmap font descriptor. One size provided: 8x16 (standard VGA ROM font, CP437 encoding). + +.table + Field Description + ----- ----------- + int32_t charWidth Fixed width per glyph (always 8) + int32_t charHeight Glyph height (14 or 16) + int32_t firstChar ASCII code of first glyph (typically 0) + int32_t numChars Number of glyphs (typically 256) + const uint8_t *glyphData Packed 1bpp data, charHeight bytes per glyph +.endtable + +.h3 ColorSchemeT + +All UI colors pre-packed into display pixel format at init time. Theme support is achieved by swapping this struct. + +.table + Field Description + ----- ----------- + uint32_t desktop Desktop background color + uint32_t windowFace Window body / chrome face + uint32_t windowHighlight Bevel highlight (top/left edge) + uint32_t windowShadow Bevel shadow (bottom/right edge) + uint32_t activeTitleBg, activeTitleFg Focused window title bar + uint32_t inactiveTitleBg, inactiveTitleFg Unfocused window title bar + uint32_t contentBg, contentFg Window content area default colors + uint32_t menuBg, menuFg Menu bar and popup background/text + uint32_t menuHighlightBg, menuHighlightFg Menu item highlight + uint32_t buttonFace Button face color + uint32_t scrollbarBg, scrollbarFg, scrollbarTrough Scrollbar element colors + uint32_t cursorFg, cursorBg Mouse cursor colors +.endtable + +.h3 ColorIdE + +Enum for addressing individual colors in ColorSchemeT. Order matches struct field order. + +Values: ColorDesktopE, ColorWindowFaceE, ColorWindowHighlightE, ColorWindowShadowE, ColorActiveTitleBgE, ColorActiveTitleFgE, ColorInactiveTitleBgE, ColorInactiveTitleFgE, ColorContentBgE, ColorContentFgE, ColorMenuBgE, ColorMenuFgE, ColorMenuHighlightBgE, ColorMenuHighlightFgE, ColorButtonFaceE, ColorScrollbarBgE, ColorScrollbarFgE, ColorScrollbarTroughE, ColorCursorFgE, ColorCursorBgE, ColorCountE. + +.h3 DirtyListT + +Fixed-capacity list of dirty rectangles. Dynamic array, grows on demand. + +.table + Field Description + ----- ----------- + RectT *rects Dynamic array of dirty rectangles + int32_t count Current number of dirty rects + int32_t cap Allocated capacity +.endtable + +.h3 WindowT + +Central window object. Each window owns a persistent content backbuffer and receives events through callback function pointers. + +.table + Field Description + ----- ----------- + int32_t id Unique window identifier + int32_t appId Shell app ID (0 = shell itself) + int32_t x, y, w, h Outer frame position and dimensions + int32_t contentX, contentY, contentW, contentH Content area inset from frame + char title[MAX_TITLE_LEN] Window title text (max 128 chars) + bool visible, focused, minimized, maximized, resizable, modal Window state flags + bool contentDirty true when contentBuf has changed + bool needsPaint true until first onPaint call + int32_t maxW, maxH Maximum dimensions + int32_t preMaxX, preMaxY, preMaxW, preMaxH Saved geometry before maximize + uint8_t *contentBuf Per-window content backbuffer + int32_t contentPitch Content buffer bytes per row + uint8_t *iconData Icon pixel data, NULL if none + int32_t iconW, iconH, iconPitch Icon image dimensions and pitch + MenuBarT *menuBar Menu bar (NULL if no menus) + ScrollbarT *vScroll, *hScroll Scrollbars (NULL if not present) + struct WidgetT *widgetRoot Widget tree root (NULL if none) + MenuT *contextMenu Right-click context menu + AccelTableT *accelTable Keyboard accelerator table + void *userData Application-defined data pointer +.endtable + +Callbacks: + +.table + Callback Description + -------- ----------- + onPaint(WindowT *win, RectT *dirtyArea) Content repaint requested + onKey(WindowT *win, int32_t key, int32_t mod) Key press + onKeyUp(WindowT *win, int32_t scancode, int32_t mod) Key release + onMouse(WindowT *win, int32_t x, int32_t y, int32_t btn) Mouse event (content-relative) + onResize(WindowT *win, int32_t newW, int32_t newH) Window resized + onClose(WindowT *win) Close requested + onMenu(WindowT *win, int32_t menuId) Menu item or accelerator activated + onScroll(WindowT *win, ScrollbarOrientE orient, int32_t val) Scrollbar value changed + onCursorQuery(WindowT *win, int32_t x, int32_t y) Return CURSOR_* for hit position + onFocus(WindowT *win) Window gained focus + onBlur(WindowT *win) Window lost focus +.endtable + +.h3 WindowStackT + +Z-ordered window stack (front-to-back: index count-1 is topmost). Owns system-wide drag/resize/scroll interaction state. + +.table + Field Description + ----- ----------- + WindowT **windows Dynamic array of window pointers + int32_t count, cap Current count and allocated capacity + int32_t focusedIdx Stack index of focused window + int32_t dragWindow, dragOffX, dragOffY Active drag state + int32_t resizeWindow, resizeEdge Active resize state + int32_t scrollWindow, scrollOrient, scrollDragOff Active scroll drag state +.endtable + +.h3 MenuT / MenuItemT / MenuBarT + +Menu system types. Fixed-size label buffers (MAX_MENU_LABEL = 32). Cascading submenus supported via MenuItemT.subMenu pointer. + +.table + Field Description + ----- ----------- + MenuItemT.label Item text (supports & accelerator markers) + MenuItemT.id Application-defined command ID + MenuItemT.type MenuItemNormalE, MenuItemCheckE, or MenuItemRadioE + MenuItemT.separator true = horizontal divider line + MenuItemT.enabled, checked Item state + MenuItemT.subMenu Child menu for cascading (NULL if leaf) + MenuBarT.activeIdx Open popup index (-1 = none) +.endtable + +.h3 ScrollbarT + +Window-level scrollbar state. Managed by the WM layer, drawn after content. + +.table + Field Description + ----- ----------- + ScrollbarOrientE orient ScrollbarVerticalE or ScrollbarHorizontalE + int32_t min, max Scroll range + int32_t value Current position + int32_t pageSize Visible portion (for proportional thumb sizing) + int32_t x, y, length Computed screen position and track length +.endtable + +.h3 AccelTableT / AccelEntryT + +Per-window keyboard accelerator table. Entries are matched against keystrokes in the event loop and fire onMenu(cmdId) on match. + +.table + Field Description + ----- ----------- + AccelEntryT.key ASCII character or KEY_Fxx constant + AccelEntryT.modifiers Bitmask of ACCEL_CTRL, ACCEL_SHIFT, ACCEL_ALT + AccelEntryT.cmdId Command ID passed to onMenu +.endtable + +.h3 VideoModeInfoT + +Describes an available video mode (enumerated at init). + +.table + Field Description + ----- ----------- + int32_t w, h Resolution + int32_t bpp Bits per pixel +.endtable + +.h3 CursorT + +Software-rendered 16x16 cursor using AND/XOR mask encoding. + +.table + Field Description + ----- ----------- + int32_t width, height Cursor dimensions (always 16x16) + int32_t hotX, hotY Hot spot coordinates + const uint16_t *andMask AND mask (0 = draw pixel, 1 = transparent) + const uint16_t *xorData XOR data (0 = black, 1 = white where AND = 0) +.endtable + +.h2 Bevel Convenience Macros + +.table + Macro Description + ----- ----------- + BEVEL_RAISED(cs, bw) Raised bevel style from ColorSchemeT ptr and border width + BEVEL_SUNKEN(cs, face, bw) Sunken bevel style with explicit face color + BEVEL_TROUGH(cs) 1px sunken trough (for scrollbar tracks) + BEVEL_SB_BUTTON(cs) 1px raised scrollbar button +.endtable + +.h2 Chrome Constants + +.table + Define Value Description + ------ ----- ----------- + CHROME_BORDER_WIDTH 4 Outer frame border width + CHROME_TITLE_HEIGHT 20 Title bar height + CHROME_TITLE_PAD 4 Title text padding + CHROME_INNER_BORDER 2 Inner chrome border + CHROME_MENU_HEIGHT 20 Menu bar height + CHROME_TOTAL_TOP 26 Total inset from top of frame to content + CHROME_TOTAL_SIDE 6 Total inset from side of frame to content + CHROME_TOTAL_BOTTOM 6 Total inset from bottom of frame to content + CHROME_CLOSE_BTN_SIZE 16 Close button gadget size +.endtable + +.h2 Hit Test Constants + +.table + Define Value Description + ------ ----- ----------- + HIT_CONTENT 0 Content area + HIT_TITLE 1 Title bar + HIT_CLOSE 2 Close gadget + HIT_RESIZE 3 Resize border + HIT_MENU 4 Menu bar + HIT_VSCROLL 5 Vertical scrollbar + HIT_HSCROLL 6 Horizontal scrollbar + HIT_MINIMIZE 7 Minimize gadget + HIT_MAXIMIZE 8 Maximize gadget + HIT_NONE -1 No window hit (desktop) +.endtable + +.h2 Mouse Button Flags + +.table + Define Value Description + ------ ----- ----------- + MOUSE_LEFT 1 Left mouse button + MOUSE_RIGHT 2 Right mouse button + MOUSE_MIDDLE 4 Middle mouse button +.endtable + +.h2 Accelerator Modifier Flags + +.table + Define Value Description + ------ ----- ----------- + ACCEL_SHIFT 0x03 Shift key (matches BIOS shift state bits) + ACCEL_CTRL 0x04 Ctrl key + ACCEL_ALT 0x08 Alt key +.endtable + +.h2 Extended Key Codes + +.table + Define Description + ------ ----------- + KEY_F1 .. KEY_F12 Function keys (scancode | 0x100) + KEY_INSERT Insert key + KEY_DELETE Delete key + KEY_HOME Home key + KEY_END End key + KEY_PGUP Page Up key + KEY_PGDN Page Down key +.endtable + +.h2 Resize Edge Flags + +.table + Define Value Description + ------ ----- ----------- + RESIZE_NONE 0 No resize edge + RESIZE_LEFT 1 Left edge + RESIZE_RIGHT 2 Right edge + RESIZE_TOP 4 Top edge + RESIZE_BOTTOM 8 Bottom edge (combinable via OR for corners) +.endtable + +.h2 Utility Macros + +.table + Macro Description + ----- ----------- + DVX_MIN(a, b) Return the smaller of two values + DVX_MAX(a, b) Return the larger of two values +.endtable + +.topic api.cursor +.title dvxCursor.h -- Cursor Definitions +.toc 0 dvxCursor.h -- Cursor Definitions +.index dvxCursor.h +.index Cursor Shapes +.index CURSOR_ARROW +.index CURSOR_BUSY + +.h1 dvxCursor.h -- Cursor Definitions + +Embedded 16x16 mouse cursor bitmaps compiled as static const data. No external cursor files. Uses the standard AND/XOR mask encoding from the IBM VGA hardware cursor spec. + +.h2 Cursor Shape IDs + +.table + Define Value Description + ------ ----- ----------- + CURSOR_ARROW 0 Standard arrow (hot spot at tip) + CURSOR_RESIZE_H 1 Horizontal resize (left/right arrows) + CURSOR_RESIZE_V 2 Vertical resize (up/down arrows) + CURSOR_RESIZE_DIAG_NWSE 3 NW-SE diagonal resize + CURSOR_RESIZE_DIAG_NESW 4 NE-SW diagonal resize + CURSOR_BUSY 5 Hourglass (wait) + CURSOR_CROSSHAIR 6 Crosshair for placement + CURSOR_COUNT 7 Total number of cursor shapes +.endtable + +.h2 Data + +.h3 dvxCursors[CURSOR_COUNT] + +Static const array of CursorT structs, indexed by CURSOR_xxx constants. Each entry includes the AND mask, XOR data, dimensions, and hot spot coordinates. + +.topic api.video +.title dvxVideo.h -- Layer 1: VESA VBE Video Backend +.toc 0 dvxVideo.h -- Layer 1: Video Backend +.index dvxVideo.h +.index videoInit +.index videoShutdown +.index packColor +.index setClipRect +.index resetClipRect +.index VESA +.index LFB + +.h1 dvxVideo.h -- Layer 1: VESA VBE Video Backend + +The lowest layer. Responsible for VESA VBE mode negotiation, LFB mapping via DPMI, system RAM backbuffer allocation, pixel format discovery, and color packing. LFB-only design: bank switching is deliberately unsupported. + +.h2 videoInit + +.code +int32_t videoInit(DisplayT *d, int32_t requestedW, int32_t requestedH, int32_t preferredBpp); +.endcode + +Probe VBE for a mode matching the requested resolution and depth, enable it, map the LFB into DPMI linear address space, and allocate a system RAM backbuffer. preferredBpp is a hint; the closest available depth is used if an exact match is not found. + +.table + Parameter Description + --------- ----------- + d Display context to initialize + requestedW/H Desired screen resolution + preferredBpp Preferred bits per pixel (8, 15, 16, or 32) +.endtable + +Returns: 0 on success, negative on failure. + +.h2 videoShutdown + +.code +void videoShutdown(DisplayT *d); +.endcode + +Restore VGA text mode (mode 3), unmap the LFB, and free the backbuffer. Safe to call even if videoInit() failed. + +.table + Parameter Description + --------- ----------- + d Display context to shut down +.endtable + +.h2 packColor + +.code +uint32_t packColor(const DisplayT *d, uint8_t r, uint8_t g, uint8_t b); +.endcode + +Pack an RGB triplet into the display's native pixel format. For direct-color modes (15/16/32 bpp), returns a packed pixel value using shift/mask fields. For 8-bit mode, returns the nearest palette index via Euclidean distance in RGB space. + +.table + Parameter Description + --------- ----------- + d Display context (provides pixel format) + r, g, b Color components (0-255) +.endtable + +Returns: Native pixel value suitable for direct framebuffer write. + +.h2 setClipRect + +.code +void setClipRect(DisplayT *d, int32_t x, int32_t y, int32_t w, int32_t h); +.endcode + +Set the clip rectangle on the display. All subsequent draw operations clip to this rectangle. The caller must save and restore the clip rect around scoped operations. + +.table + Parameter Description + --------- ----------- + d Display context + x, y, w, h Clip rectangle in screen coordinates +.endtable + +.h2 resetClipRect + +.code +void resetClipRect(DisplayT *d); +.endcode + +Reset the clip rectangle to the full display dimensions. + +.table + Parameter Description + --------- ----------- + d Display context +.endtable + +.topic api.draw +.title dvxDraw.h -- Layer 2: Drawing Primitives +.toc 0 dvxDraw.h -- Layer 2: Drawing Primitives +.index dvxDraw.h +.index drawInit +.index rectFill +.index rectCopy +.index rectCopyGrayscale +.index drawBevel +.index drawChar +.index drawText +.index drawTextN +.index textWidth +.index accelParse +.index drawTextAccel +.index textWidthAccel +.index drawMaskedBitmap +.index drawTermRow +.index drawFocusRect +.index drawHLine +.index drawVLine + +.h1 dvxDraw.h -- Layer 2: Drawing Primitives + +All 2D drawing operations: rectangle fills, bitmap blits, text rendering, bevels, lines, and cursor rendering. Every function draws into the display's backbuffer and clips to the current clip rectangle. This layer is stateless beyond the clip rect on DisplayT. + +.h2 drawInit + +.code +void drawInit(BlitOpsT *ops, const DisplayT *d); +.endcode + +Populate a BlitOpsT with the correct span functions for the display's pixel depth. Must be called once after videoInit(). + +.table + Parameter Description + --------- ----------- + ops BlitOpsT to populate + d Initialized display context +.endtable + +.h2 rectFill + +.code +void rectFill(DisplayT *d, const BlitOpsT *ops, int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color); +.endcode + +Fill a rectangle with a solid color. Clips to the display clip rect. Workhorse for backgrounds, window fills, and clear operations. + +.table + Parameter Description + --------- ----------- + d Display context + ops Blit operations vtable + x, y, w, h Rectangle to fill + color Packed pixel color +.endtable + +.h2 rectCopy + +.code +void rectCopy(DisplayT *d, const BlitOpsT *ops, int32_t dstX, int32_t dstY, const uint8_t *srcBuf, int32_t srcPitch, int32_t srcX, int32_t srcY, int32_t w, int32_t h); +.endcode + +Copy a rectangle from an arbitrary source buffer into the backbuffer. Used to blit per-window content buffers during compositing. + +.table + Parameter Description + --------- ----------- + d Display context + ops Blit operations vtable + dstX, dstY Destination position in backbuffer + srcBuf Source pixel buffer + srcPitch Source buffer bytes per row + srcX, srcY Origin within source buffer + w, h Rectangle dimensions to copy +.endtable + +.h2 rectCopyGrayscale + +.code +void rectCopyGrayscale(DisplayT *d, const BlitOpsT *ops, int32_t dstX, int32_t dstY, const uint8_t *srcBuf, int32_t srcPitch, int32_t srcX, int32_t srcY, int32_t w, int32_t h); +.endcode + +Copy a rectangle with grayscale conversion. Each pixel's RGB is converted to luminance (0.299R + 0.587G + 0.114B) for a disabled/grayed appearance. + +.table + Parameter Description + --------- ----------- + d Display context + ops Blit operations vtable + dstX, dstY Destination position + srcBuf, srcPitch Source buffer and pitch + srcX, srcY Source origin + w, h Rectangle dimensions +.endtable + +.h2 drawBevel + +.code +void drawBevel(DisplayT *d, const BlitOpsT *ops, int32_t x, int32_t y, int32_t w, int32_t h, const BevelStyleT *style); +.endcode + +Draw a beveled frame. Top/left edges in highlight color, bottom/right in shadow. Interior filled with face color if non-zero. + +.table + Parameter Description + --------- ----------- + d Display context + ops Blit operations vtable + x, y, w, h Outer bevel rectangle + style Bevel colors and width +.endtable + +.h2 drawChar + +.code +int32_t drawChar(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, int32_t x, int32_t y, char ch, uint32_t fg, uint32_t bg, bool opaque); +.endcode + +Draw a single character glyph. When opaque is true, the background fills the entire cell; when false, only foreground pixels are drawn (transparent background). + +.table + Parameter Description + --------- ----------- + d Display context + ops Blit operations vtable + font Bitmap font + x, y Character position + ch Character to draw + fg, bg Foreground and background packed colors + opaque true = fill background, false = transparent +.endtable + +Returns: Advance width (always charWidth). + +.h2 drawText + +.code +void drawText(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, int32_t x, int32_t y, const char *text, uint32_t fg, uint32_t bg, bool opaque); +.endcode + +Draw a null-terminated string. Calls drawChar per character. + +.table + Parameter Description + --------- ----------- + d Display context + ops Blit operations vtable + font Bitmap font + x, y Start position + text Null-terminated string + fg, bg Foreground and background packed colors + opaque true = fill background, false = transparent +.endtable + +.h2 drawTextN + +.code +void drawTextN(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, int32_t x, int32_t y, const char *text, int32_t count, uint32_t fg, uint32_t bg, bool opaque); +.endcode + +Optimized batch text rendering for a known character count. Computes clip bounds once, fills background in a single rectFill, then overlays glyph foreground pixels. Significantly faster than per-character drawChar for long runs (terminal rows, list items). + +.table + Parameter Description + --------- ----------- + d Display context + ops Blit operations vtable + font Bitmap font + x, y Start position + text Character buffer (not required to be null-terminated) + count Number of characters to render + fg, bg Foreground and background packed colors + opaque true = fill background, false = transparent +.endtable + +.h2 textWidth + +.code +int32_t textWidth(const BitmapFontT *font, const char *text); +.endcode + +Return the pixel width of a null-terminated string (strlen(text) * charWidth). + +.table + Parameter Description + --------- ----------- + font Bitmap font + text Null-terminated string +.endtable + +Returns: Width in pixels. + +.h2 accelParse + +.code +char accelParse(const char *text); +.endcode + +Scan text for an & prefix and return the following character as a lowercase accelerator key. "&File" returns 'f', "E&xit" returns 'x'. + +.table + Parameter Description + --------- ----------- + text Text with optional & accelerator marker +.endtable + +Returns: Lowercase accelerator character, or 0 if none. + +.h2 drawTextAccel + +.code +void drawTextAccel(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, int32_t x, int32_t y, const char *text, uint32_t fg, uint32_t bg, bool opaque); +.endcode + +Draw text with & accelerator markers. The character after & is drawn underlined to indicate the keyboard shortcut. && produces a literal &. Used for menu items and button labels. + +.table + Parameter Description + --------- ----------- + d Display context + ops Blit operations vtable + font Bitmap font + x, y Start position + text Text with & markers + fg, bg Foreground and background packed colors + opaque true = fill background, false = transparent +.endtable + +.h2 textWidthAccel + +.code +int32_t textWidthAccel(const BitmapFontT *font, const char *text); +.endcode + +Measure text width excluding & markers (so "&File" measures as 4 chars). + +.table + Parameter Description + --------- ----------- + font Bitmap font + text Text with optional & markers +.endtable + +Returns: Width in pixels. + +.h2 drawMaskedBitmap + +.code +void drawMaskedBitmap(DisplayT *d, const BlitOpsT *ops, int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *andMask, const uint16_t *xorData, uint32_t fgColor, uint32_t bgColor); +.endcode + +Draw a 1-bit AND/XOR masked bitmap. Used for software-rendered mouse cursors. + +.table + Parameter Description + --------- ----------- + d Display context + ops Blit operations vtable + x, y Screen position + w, h Bitmap dimensions + andMask AND transparency mask (one uint16_t per row) + xorData XOR color data + fgColor, bgColor Cursor foreground and background packed colors +.endtable + +.h2 drawTermRow + +.code +void drawTermRow(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, int32_t x, int32_t y, int32_t cols, const uint8_t *lineData, const uint32_t *palette, bool blinkVisible, int32_t cursorCol); +.endcode + +Render an entire row of terminal character cells (ch/attr byte pairs) in a single pass. Colors looked up from a 16-color palette. Attribute bit 7 controls blink. + +.table + Parameter Description + --------- ----------- + d Display context + ops Blit operations vtable + font Bitmap font + x, y Row start position + cols Number of columns + lineData Packed ch/attr byte pairs (2 bytes per cell) + palette 16-entry packed color palette + blinkVisible false = hide blinking characters + cursorCol Column for inverted text cursor (-1 = none) +.endtable + +.h2 drawFocusRect + +.code +void drawFocusRect(DisplayT *d, const BlitOpsT *ops, int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color); +.endcode + +Draw a 1px dotted rectangle (alternating pixels). Used for keyboard focus indicators, matching the Windows 3.x focus rectangle convention. + +.table + Parameter Description + --------- ----------- + d Display context + ops Blit operations vtable + x, y, w, h Focus rectangle bounds + color Dot color (packed) +.endtable + +.h2 drawHLine + +.code +void drawHLine(DisplayT *d, const BlitOpsT *ops, int32_t x, int32_t y, int32_t w, uint32_t color); +.endcode + +Draw a horizontal line (1px tall). + +.table + Parameter Description + --------- ----------- + d Display context + ops Blit operations vtable + x, y Start position + w Width in pixels + color Packed pixel color +.endtable + +.h2 drawVLine + +.code +void drawVLine(DisplayT *d, const BlitOpsT *ops, int32_t x, int32_t y, int32_t h, uint32_t color); +.endcode + +Draw a vertical line (1px wide). + +.table + Parameter Description + --------- ----------- + d Display context + ops Blit operations vtable + x, y Start position + h Height in pixels + color Packed pixel color +.endtable + +.topic api.comp +.title dvxComp.h -- Layer 3: Dirty Rectangle Compositor +.toc 0 dvxComp.h -- Layer 3: Compositor +.index dvxComp.h +.index dirtyListInit +.index dirtyListAdd +.index dirtyListMerge +.index dirtyListClear +.index flushRect +.index rectIntersect +.index rectIsEmpty + +.h1 dvxComp.h -- Layer 3: Dirty Rectangle Compositor + +Tracks changed screen regions and ensures only dirty regions are redrawn and flushed to video memory. The compositing pipeline: mark dirty, merge overlapping rects, redraw desktop + windows (back-to-front, painter's algorithm), flush to LFB. + +.h2 dirtyListInit + +.code +void dirtyListInit(DirtyListT *dl); +.endcode + +Zero the dirty rect count. Called at the start of each frame. + +.table + Parameter Description + --------- ----------- + dl Dirty list to initialize +.endtable + +.h2 dirtyListAdd + +.code +void dirtyListAdd(DirtyListT *dl, int32_t x, int32_t y, int32_t w, int32_t h); +.endcode + +Enqueue a dirty rectangle. Grows dynamically; triggers merge at a soft capacity limit. + +.table + Parameter Description + --------- ----------- + dl Dirty list + x, y, w, h Dirty rectangle in screen coordinates +.endtable + +.h2 dirtyListMerge + +.code +void dirtyListMerge(DirtyListT *dl); +.endcode + +Consolidate the dirty list by merging overlapping and adjacent rects. Uses iterative pairwise merge: if combining two rects does not increase total area beyond a threshold, they are merged. Reduces compositor passes and LFB flush operations. + +.table + Parameter Description + --------- ----------- + dl Dirty list to merge +.endtable + +.h2 dirtyListClear + +.code +void dirtyListClear(DirtyListT *dl); +.endcode + +Reset the dirty list to empty (sets count to 0). + +.table + Parameter Description + --------- ----------- + dl Dirty list to clear +.endtable + +.h2 flushRect + +.code +void flushRect(DisplayT *d, const RectT *r); +.endcode + +Copy a rectangle from the system RAM backbuffer to the LFB (video memory). This is the only place the real framebuffer is written. Uses platform-specific fast copy (rep movsd on DOS) for each scanline. + +.table + Parameter Description + --------- ----------- + d Display context + r Rectangle to flush +.endtable + +.h2 rectIntersect + +.code +bool rectIntersect(const RectT *a, const RectT *b, RectT *result); +.endcode + +Compute the intersection of two rectangles. + +.table + Parameter Description + --------- ----------- + a, b Input rectangles + result Output: intersection rectangle (valid only when return is true) +.endtable + +Returns: true if the rectangles overlap, false if disjoint. + +.h2 rectIsEmpty + +.code +bool rectIsEmpty(const RectT *r); +.endcode + +Test whether a rectangle has zero or negative area. + +.table + Parameter Description + --------- ----------- + r Rectangle to test +.endtable + +Returns: true if w <= 0 or h <= 0. + +.topic api.wm +.title dvxWm.h -- Layer 4: Window Manager +.toc 0 dvxWm.h -- Layer 4: Window Manager +.index dvxWm.h +.index wmInit +.index wmCreateWindow +.index wmDestroyWindow +.index wmRaiseWindow +.index wmSetFocus +.index wmUpdateContentRect +.index wmReallocContentBuf +.index wmMinWindowSize +.index wmAddMenuBar +.index wmAddMenu +.index wmAddMenuItem +.index wmAddSubMenu +.index wmCreateMenu +.index wmDrawChrome +.index wmHitTest +.index wmDragBegin +.index wmResizeBegin +.index wmMaximize +.index wmMinimize +.index wmRestore + +.h1 dvxWm.h -- Layer 4: Window Manager + +Manages the window lifecycle, Z-order stack, chrome drawing, hit testing, and interactive operations (drag, resize, scroll). The WM owns window geometry and chrome; content is owned by the application via callbacks or the widget system. + +.h2 Initialization + +.h3 wmInit + +.code +void wmInit(WindowStackT *stack); +.endcode + +Zero the window stack. Must be called before any other WM function. + +.table + Parameter Description + --------- ----------- + stack Window stack to initialize +.endtable + +.h2 Window Lifecycle + +.h3 wmCreateWindow + +.code +WindowT *wmCreateWindow(WindowStackT *stack, DisplayT *d, const char *title, int32_t x, int32_t y, int32_t w, int32_t h, bool resizable); +.endcode + +Allocate a new window, initialize its geometry and content buffer, and push it to the top of the Z-order stack. Returns with all callbacks NULL; the caller should set onPaint/onKey/etc. before the next event loop iteration. + +.table + Parameter Description + --------- ----------- + stack Window stack + d Display context + title Window title text + x, y Initial position + w, h Initial outer frame dimensions + resizable true = allow user resize +.endtable + +Returns: Pointer to new WindowT, or NULL on failure. + +.h3 wmDestroyWindow + +.code +void wmDestroyWindow(WindowStackT *stack, WindowT *win); +.endcode + +Free the window's content buffer and all attached resources (menu bar, scrollbars, widget tree), remove it from the stack, and dirty the vacated region. + +.table + Parameter Description + --------- ----------- + stack Window stack + win Window to destroy +.endtable + +.h2 Z-Order and Focus + +.h3 wmRaiseWindow + +.code +void wmRaiseWindow(WindowStackT *stack, DirtyListT *dl, int32_t idx); +.endcode + +Move window at stack index idx to the top of the Z-order. Dirties both old and new top positions so overlapping windows get repainted. + +.table + Parameter Description + --------- ----------- + stack Window stack + dl Dirty list for repaint marking + idx Stack index of window to raise +.endtable + +.h3 wmSetFocus + +.code +void wmSetFocus(WindowStackT *stack, DirtyListT *dl, int32_t idx); +.endcode + +Transfer keyboard focus to the window at stack index idx. Unfocuses the previously focused window and dirties both title bars. + +.table + Parameter Description + --------- ----------- + stack Window stack + dl Dirty list + idx Stack index of window to focus +.endtable + +.h2 Geometry + +.h3 wmUpdateContentRect + +.code +void wmUpdateContentRect(WindowT *win); +.endcode + +Recompute contentX/Y/W/H from the window's outer frame dimensions, accounting for chrome borders, title bar, menu bar, and scrollbars. Must be called after any change to frame size or chrome configuration. + +.table + Parameter Description + --------- ----------- + win Window to update +.endtable + +.h3 wmReallocContentBuf + +.code +int32_t wmReallocContentBuf(WindowT *win, const DisplayT *d); +.endcode + +Reallocate the per-window content backbuffer to match current contentW/H. Old buffer contents are lost; caller should trigger a full repaint via onPaint afterward. + +.table + Parameter Description + --------- ----------- + win Window to reallocate + d Display context (for bytes-per-pixel) +.endtable + +Returns: 0 on success, -1 on allocation failure. + +.h3 wmMinWindowSize + +.code +void wmMinWindowSize(const WindowT *win, int32_t *minW, int32_t *minH); +.endcode + +Get the minimum window size. Accounts for chrome, gadgets, and menu bar. + +.table + Parameter Description + --------- ----------- + win Window + minW, minH Output: minimum width and height +.endtable + +.h2 Menu Bar + +.h3 wmAddMenuBar + +.code +MenuBarT *wmAddMenuBar(WindowT *win); +.endcode + +Allocate and attach a menu bar to a window. Adjusts content area to make room (CHROME_MENU_HEIGHT pixels). One menu bar per window. + +.table + Parameter Description + --------- ----------- + win Window to add menu bar to +.endtable + +Returns: Pointer to the new MenuBarT. + +.h3 wmDestroyMenuBar + +.code +void wmDestroyMenuBar(WindowT *win); +.endcode + +Free the menu bar and reclaim the content area. + +.table + Parameter Description + --------- ----------- + win Window to remove menu bar from +.endtable + +.h3 wmAddMenu + +.code +MenuT *wmAddMenu(MenuBarT *bar, const char *label); +.endcode + +Append a dropdown menu to the menu bar. The label supports & accelerator markers (e.g. "&File"). + +.table + Parameter Description + --------- ----------- + bar Menu bar + label Menu label text +.endtable + +Returns: Pointer to the new MenuT to populate with items. + +.h3 wmAddMenuItem + +.code +void wmAddMenuItem(MenuT *menu, const char *label, int32_t id); +.endcode + +Append a clickable item to a menu. The id is passed to the window's onMenu callback when selected. + +.table + Parameter Description + --------- ----------- + menu Menu to append to + label Item label (supports & markers) + id Application-defined command ID +.endtable + +.h3 wmAddMenuCheckItem + +.code +void wmAddMenuCheckItem(MenuT *menu, const char *label, int32_t id, bool checked); +.endcode + +Add a checkbox-style menu item. Check state toggles on click; rendered with a checkmark glyph. + +.table + Parameter Description + --------- ----------- + menu Menu to append to + label Item label + id Command ID + checked Initial checked state +.endtable + +.h3 wmAddMenuRadioItem + +.code +void wmAddMenuRadioItem(MenuT *menu, const char *label, int32_t id, bool checked); +.endcode + +Add a radio-style menu item. Radio groups are defined implicitly by consecutive radio items; selecting one unchecks the others in the group. + +.table + Parameter Description + --------- ----------- + menu Menu to append to + label Item label + id Command ID + checked Initial checked state +.endtable + +.h3 wmAddMenuSeparator + +.code +void wmAddMenuSeparator(MenuT *menu); +.endcode + +Insert a horizontal separator line. Separators are not interactive. + +.table + Parameter Description + --------- ----------- + menu Menu to append separator to +.endtable + +.h3 wmMenuItemIsChecked + +.code +bool wmMenuItemIsChecked(MenuBarT *bar, int32_t id); +.endcode + +Query the checked state of a menu item by command ID. Searches all menus in the bar. + +.table + Parameter Description + --------- ----------- + bar Menu bar + id Command ID to query +.endtable + +Returns: true if checked. + +.h3 wmMenuItemSetChecked + +.code +void wmMenuItemSetChecked(MenuBarT *bar, int32_t id, bool checked); +.endcode + +Set the checked state of a menu item by command ID. For radio items, setting checked=true also unchecks other radio items in the same group. + +.table + Parameter Description + --------- ----------- + bar Menu bar + id Command ID + checked New checked state +.endtable + +.h3 wmMenuItemSetEnabled + +.code +void wmMenuItemSetEnabled(MenuBarT *bar, int32_t id, bool enabled); +.endcode + +Enable or disable a menu item by command ID. + +.table + Parameter Description + --------- ----------- + bar Menu bar + id Command ID + enabled true = enabled, false = grayed out +.endtable + +.h3 wmAddSubMenu + +.code +MenuT *wmAddSubMenu(MenuT *parentMenu, const char *label); +.endcode + +Create a cascading submenu attached to a parent menu. The child MenuT is heap-allocated and freed when the parent window is destroyed. + +.table + Parameter Description + --------- ----------- + parentMenu Parent menu to attach submenu to + label Submenu label text +.endtable + +Returns: Pointer to the child MenuT, or NULL on allocation failure. + +.h3 wmCreateMenu + +.code +MenuT *wmCreateMenu(void); +.endcode + +Allocate a heap-resident MenuT for use as a context menu (right-click). Unlike menu bar menus, context menus are standalone allocations. Free with wmFreeMenu(). + +Returns: Pointer to the new MenuT. + +.h3 wmFreeMenu + +.code +void wmFreeMenu(MenuT *menu); +.endcode + +Free a standalone menu allocated with wmCreateMenu(). Also frees any heap-allocated submenu children recursively. + +.table + Parameter Description + --------- ----------- + menu Menu to free +.endtable + +.h2 Scrollbars + +.h3 wmAddVScrollbar + +.code +ScrollbarT *wmAddVScrollbar(WindowT *win, int32_t min, int32_t max, int32_t pageSize); +.endcode + +Attach a vertical scrollbar to the right edge of the window's content area. Shrinks contentW by SCROLLBAR_WIDTH pixels. + +.table + Parameter Description + --------- ----------- + win Window + min, max Scroll value range + pageSize Visible portion (controls thumb size) +.endtable + +Returns: Pointer to the new ScrollbarT. + +.h3 wmAddHScrollbar + +.code +ScrollbarT *wmAddHScrollbar(WindowT *win, int32_t min, int32_t max, int32_t pageSize); +.endcode + +Attach a horizontal scrollbar to the bottom edge. Shrinks contentH by SCROLLBAR_WIDTH pixels. + +.table + Parameter Description + --------- ----------- + win Window + min, max Scroll value range + pageSize Visible portion +.endtable + +Returns: Pointer to the new ScrollbarT. + +.h2 Drawing + +.h3 wmDrawChrome + +.code +void wmDrawChrome(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors, WindowT *win, const RectT *clipTo); +.endcode + +Draw the window frame: outer bevel, title bar with text, close/minimize/maximize gadgets, and menu bar if present. Drawing is clipped to the intersection with clipTo. + +.table + Parameter Description + --------- ----------- + d Display context + ops Blit operations vtable + font Bitmap font for title text + colors Color scheme + win Window to draw chrome for + clipTo Dirty rectangle to clip drawing to +.endtable + +.h3 wmDrawContent + +.code +void wmDrawContent(DisplayT *d, const BlitOpsT *ops, WindowT *win, const RectT *clipTo); +.endcode + +Blit the window's content backbuffer into the display backbuffer, clipped to the dirty rect. Pure copy operation (no drawing). + +.table + Parameter Description + --------- ----------- + d Display context + ops Blit operations vtable + win Window + clipTo Dirty rectangle +.endtable + +.h3 wmDrawScrollbars + +.code +void wmDrawScrollbars(DisplayT *d, const BlitOpsT *ops, const ColorSchemeT *colors, WindowT *win, const RectT *clipTo); +.endcode + +Draw scrollbars (track, arrows, proportional thumb) for a window. Drawn after content so scrollbars overlay the content area edge. + +.table + Parameter Description + --------- ----------- + d Display context + ops Blit operations vtable + colors Color scheme + win Window + clipTo Dirty rectangle +.endtable + +.h3 wmDrawMinimizedIcons + +.code +void wmDrawMinimizedIcons(DisplayT *d, const BlitOpsT *ops, const ColorSchemeT *colors, const WindowStackT *stack, const RectT *clipTo); +.endcode + +Draw icons for all minimized windows along the bottom of the screen. Each icon shows a scaled preview of the window's content with a beveled border. + +.table + Parameter Description + --------- ----------- + d Display context + ops Blit operations vtable + colors Color scheme + stack Window stack + clipTo Dirty rectangle +.endtable + +.h2 Hit Testing + +.h3 wmHitTest + +.code +int32_t wmHitTest(const WindowStackT *stack, int32_t mx, int32_t my, int32_t *hitPart); +.endcode + +Determine which window and chrome region is under the given screen coordinates. Iterates front-to-back (highest Z first) so the topmost window wins. + +.table + Parameter Description + --------- ----------- + stack Window stack + mx, my Screen coordinates + hitPart Output: HIT_CONTENT, HIT_TITLE, HIT_CLOSE, etc. +.endtable + +Returns: Stack index of hit window, or -1 for desktop. + +.h3 wmResizeEdgeHit + +.code +int32_t wmResizeEdgeHit(const WindowT *win, int32_t mx, int32_t my); +.endcode + +Determine which edge(s) of a window's border zone are targeted for resize. + +.table + Parameter Description + --------- ----------- + win Window + mx, my Screen coordinates +.endtable + +Returns: Bitmask of RESIZE_LEFT / RESIZE_RIGHT / RESIZE_TOP / RESIZE_BOTTOM. + +.h3 wmMinimizedIconHit + +.code +int32_t wmMinimizedIconHit(const WindowStackT *stack, const DisplayT *d, int32_t mx, int32_t my); +.endcode + +Hit-test minimized icons at the bottom of the screen. + +.table + Parameter Description + --------- ----------- + stack Window stack + d Display context + mx, my Screen coordinates +.endtable + +Returns: Stack index of the minimized window, or -1. + +.h2 Drag and Resize + +.h3 wmDragBegin + +.code +void wmDragBegin(WindowStackT *stack, int32_t idx, int32_t mouseX, int32_t mouseY); +.endcode + +Begin a window drag operation. Records the mouse offset from the window origin. + +.table + Parameter Description + --------- ----------- + stack Window stack + idx Stack index of window to drag + mouseX/Y Current mouse position +.endtable + +.h3 wmDragMove + +.code +void wmDragMove(WindowStackT *stack, DirtyListT *dl, int32_t mouseX, int32_t mouseY, int32_t screenW, int32_t screenH); +.endcode + +Update window position during an active drag. Dirties both old and new positions. + +.table + Parameter Description + --------- ----------- + stack Window stack + dl Dirty list + mouseX/Y Current mouse position + screenW/H Screen dimensions (for clamping) +.endtable + +.h3 wmDragEnd + +.code +void wmDragEnd(WindowStackT *stack); +.endcode + +End the current drag operation. Clears dragWindow state. + +.table + Parameter Description + --------- ----------- + stack Window stack +.endtable + +.h3 wmResizeBegin + +.code +void wmResizeBegin(WindowStackT *stack, int32_t idx, int32_t edge, int32_t mouseX, int32_t mouseY); +.endcode + +Begin a window resize operation. Records which edge(s) are being dragged. + +.table + Parameter Description + --------- ----------- + stack Window stack + idx Stack index + edge Bitmask of RESIZE_xxx flags + mouseX/Y Current mouse position +.endtable + +.h3 wmResizeMove + +.code +void wmResizeMove(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, int32_t *mouseX, int32_t *mouseY); +.endcode + +Update window dimensions during an active resize. Enforces MIN_WINDOW_W/H and maxW/maxH constraints. Reallocates content buffer and calls onResize if size changed. mouseX/mouseY are in/out: clamped on return for cursor warping. + +.table + Parameter Description + --------- ----------- + stack Window stack + dl Dirty list + d Display context + mouseX/Y In/out: mouse position (clamped on return) +.endtable + +.h3 wmResizeEnd + +.code +void wmResizeEnd(WindowStackT *stack); +.endcode + +End the current resize operation. Clears resizeWindow state. + +.table + Parameter Description + --------- ----------- + stack Window stack +.endtable + +.h2 Scrollbar Interaction + +.h3 wmScrollbarClick + +.code +void wmScrollbarClick(WindowStackT *stack, DirtyListT *dl, int32_t idx, int32_t orient, int32_t mx, int32_t my); +.endcode + +Handle an initial click on a scrollbar. Determines what was hit (arrows, trough, or thumb) and either adjusts the value immediately or begins a thumb drag. + +.table + Parameter Description + --------- ----------- + stack Window stack + dl Dirty list + idx Stack index of window + orient SCROLL_VERTICAL or SCROLL_HORIZONTAL + mx, my Click screen coordinates +.endtable + +.h3 wmScrollbarDrag + +.code +void wmScrollbarDrag(WindowStackT *stack, DirtyListT *dl, int32_t mx, int32_t my); +.endcode + +Update the scroll value during an active thumb drag. Maps mouse position along the track to a proportional scroll value. + +.table + Parameter Description + --------- ----------- + stack Window stack + dl Dirty list + mx, my Current mouse position +.endtable + +.h3 wmScrollbarEnd + +.code +void wmScrollbarEnd(WindowStackT *stack); +.endcode + +End an active scrollbar thumb drag. + +.table + Parameter Description + --------- ----------- + stack Window stack +.endtable + +.h2 Minimize / Maximize / Restore + +.h3 wmMaximize + +.code +void wmMaximize(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, WindowT *win); +.endcode + +Maximize a window. Saves current geometry, then expands to screen or maxW/maxH bounds. + +.table + Parameter Description + --------- ----------- + stack Window stack + dl Dirty list + d Display context + win Window to maximize +.endtable + +.h3 wmMinimize + +.code +void wmMinimize(WindowStackT *stack, DirtyListT *dl, WindowT *win); +.endcode + +Minimize a window. Hides the window and shows an icon at the bottom of the screen. + +.table + Parameter Description + --------- ----------- + stack Window stack + dl Dirty list + win Window to minimize +.endtable + +.h3 wmRestore + +.code +void wmRestore(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, WindowT *win); +.endcode + +Restore a maximized window to its pre-maximize geometry. + +.table + Parameter Description + --------- ----------- + stack Window stack + dl Dirty list + d Display context + win Maximized window to restore +.endtable + +.h3 wmRestoreMinimized + +.code +void wmRestoreMinimized(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, WindowT *win); +.endcode + +Restore a minimized window (show it again and remove the icon). + +.table + Parameter Description + --------- ----------- + stack Window stack + dl Dirty list + d Display context + win Minimized window to restore +.endtable + +.h2 Minimized Icon Layout + +.h3 wmMinimizedIconPos + +.code +void wmMinimizedIconPos(const DisplayT *d, int32_t index, int32_t *x, int32_t *y); +.endcode + +Compute the screen position of a minimized icon by ordinal index. Icons wrap into rows from bottom to top when the screen fills up. + +.table + Parameter Description + --------- ----------- + d Display context + index Ordinal index of the minimized icon + x, y Output: screen position +.endtable + +.h3 wmMinimizedIconRect + +.code +void wmMinimizedIconRect(const WindowStackT *stack, const DisplayT *d, int32_t *y, int32_t *h); +.endcode + +Compute the screen rect covering all minimized icon rows. Used to dirty the icon area when windows are minimized or restored. + +.table + Parameter Description + --------- ----------- + stack Window stack + d Display context + y, h Output: vertical extent of icon area +.endtable + +.h2 Miscellaneous + +.h3 wmSetTitle + +.code +void wmSetTitle(WindowT *win, DirtyListT *dl, const char *title); +.endcode + +Set the window title and dirty the title bar for repaint. + +.table + Parameter Description + --------- ----------- + win Window + dl Dirty list + title New title text +.endtable + +.h3 wmSetIcon + +.code +int32_t wmSetIcon(WindowT *win, const char *path, const DisplayT *d); +.endcode + +Load an icon image for a window from a file. Converts to display pixel format. + +.table + Parameter Description + --------- ----------- + win Window + path Image file path + d Display context +.endtable + +Returns: 0 on success, -1 on failure. + +.topic api.app +.title dvxApp.h -- Layer 5: Application API +.toc 0 dvxApp.h -- Layer 5: Application API +.index dvxApp.h +.index AppContextT +.index dvxInit +.index dvxShutdown +.index dvxRun +.index dvxUpdate +.index dvxQuit +.index dvxCreateWindow +.index dvxCreateWindowCentered +.index dvxDestroyWindow +.index dvxRaiseWindow +.index dvxFitWindow +.index dvxResizeWindow +.index dvxMinimizeWindow +.index dvxMaximizeWindow +.index dvxHideWindow +.index dvxShowWindow +.index dvxInvalidateRect +.index dvxInvalidateWindow +.index dvxSetTitle +.index dvxSetWindowIcon +.index dvxSetBusy +.index dvxGetFont +.index dvxGetColors +.index dvxGetDisplay +.index dvxGetBlitOps +.index dvxGetVideoModes +.index dvxSetColor +.index dvxGetColor +.index dvxApplyColorScheme +.index dvxResetColorScheme +.index dvxLoadTheme +.index dvxSaveTheme +.index dvxColorName +.index dvxColorLabel +.index dvxSetWallpaper +.index dvxSetWallpaperMode +.index dvxSetMouseConfig +.index dvxCreateAccelTable +.index dvxFreeAccelTable +.index dvxAddAccel +.index dvxCascadeWindows +.index dvxTileWindows +.index dvxLoadImage +.index dvxFreeImage +.index dvxImageInfo +.index dvxSaveImage +.index dvxScreenshot +.index dvxWindowScreenshot +.index dvxClipboardCopy +.index dvxClipboardGet +.index dvxResLoadIcon +.index dvxResLoadText +.index dvxResLoadData +.index dvxTextHash +.index dvxChangeVideoMode + +.h1 dvxApp.h -- Layer 5: Application API + +The topmost layer and the public-facing API. Aggregates all lower layers into a single AppContextT. Applications interact exclusively through dvx*() functions and window callbacks. The event loop follows a cooperative model: poll, dispatch, composite, yield. + +.h2 AppContextT + +Single monolithic context that owns all GUI state. Contains the display, window stack, dirty list, blit ops, font, color scheme, popup state, cursor state, mouse/keyboard state, tooltip state, wallpaper buffer, video mode list, and various configuration fields. Allocated on the caller's stack or statically. + +.h2 Initialization and Shutdown + +.h3 dvxInit + +.code +int32_t dvxInit(AppContextT *ctx, int32_t requestedW, int32_t requestedH, int32_t preferredBpp); +.endcode + +Initialize the entire GUI stack: video mode, input devices, font, color scheme, cursor shapes, and internal state. Single entry point for starting a DVX application. + +.table + Parameter Description + --------- ----------- + ctx Application context to initialize + requestedW/H Desired screen resolution + preferredBpp Preferred bits per pixel +.endtable + +Returns: 0 on success, negative on failure. + +.h3 dvxShutdown + +.code +void dvxShutdown(AppContextT *ctx); +.endcode + +Tear down the GUI stack in reverse order: destroy all windows, restore text mode, release input devices. Safe to call after a failed dvxInit(). + +.table + Parameter Description + --------- ----------- + ctx Application context +.endtable + +.h3 dvxChangeVideoMode + +.code +int32_t dvxChangeVideoMode(AppContextT *ctx, int32_t requestedW, int32_t requestedH, int32_t preferredBpp); +.endcode + +Switch to a new video mode live. Reallocates the backbuffer, all window content buffers, repacks colors, rescales wallpaper, and repositions off-screen windows. + +.table + Parameter Description + --------- ----------- + ctx Application context + requestedW/H New resolution + preferredBpp New bits per pixel +.endtable + +Returns: 0 on success, -1 on failure (old mode restored). + +.h2 Event Loop + +.h3 dvxRun + +.code +void dvxRun(AppContextT *ctx); +.endcode + +Enter the main event loop. Polls input, dispatches events, composites dirty regions, and yields on each iteration. Returns when ctx->running becomes false. + +.table + Parameter Description + --------- ----------- + ctx Application context +.endtable + +.h3 dvxUpdate + +.code +bool dvxUpdate(AppContextT *ctx); +.endcode + +Process exactly one frame of the event loop. For applications that integrate the GUI into their own main loop (e.g. polling serial ports between frames). + +.table + Parameter Description + --------- ----------- + ctx Application context +.endtable + +Returns: false when the GUI wants to exit. + +.h3 dvxQuit + +.code +void dvxQuit(AppContextT *ctx); +.endcode + +Request exit from the main event loop (sets ctx->running = false). + +.table + Parameter Description + --------- ----------- + ctx Application context +.endtable + +.h2 Window Management + +.h3 dvxCreateWindow + +.code +WindowT *dvxCreateWindow(AppContextT *ctx, const char *title, int32_t x, int32_t y, int32_t w, int32_t h, bool resizable); +.endcode + +Create a window at an explicit screen position. The window is raised to the top, focused, and its entire region is dirtied. + +.table + Parameter Description + --------- ----------- + ctx Application context + title Window title + x, y Screen position + w, h Outer frame dimensions + resizable true = allow user resize +.endtable + +Returns: Pointer to new WindowT. + +.h3 dvxCreateWindowCentered + +.code +WindowT *dvxCreateWindowCentered(AppContextT *ctx, const char *title, int32_t w, int32_t h, bool resizable); +.endcode + +Convenience wrapper that centers the window on screen. + +.table + Parameter Description + --------- ----------- + ctx Application context + title Window title + w, h Outer frame dimensions + resizable true = allow user resize +.endtable + +Returns: Pointer to new WindowT. + +.h3 dvxDestroyWindow + +.code +void dvxDestroyWindow(AppContextT *ctx, WindowT *win); +.endcode + +Destroy a window, free all its resources, and dirty its former region. + +.table + Parameter Description + --------- ----------- + ctx Application context + win Window to destroy +.endtable + +.h3 dvxRaiseWindow + +.code +void dvxRaiseWindow(AppContextT *ctx, WindowT *win); +.endcode + +Raise a window to the top of the Z-order and give it focus. + +.table + Parameter Description + --------- ----------- + ctx Application context + win Window to raise +.endtable + +.h3 dvxFitWindow + +.code +void dvxFitWindow(AppContextT *ctx, WindowT *win); +.endcode + +Resize a window to exactly fit its widget tree's computed minimum size (plus chrome). Used for dialog boxes and fixed-layout windows. + +.table + Parameter Description + --------- ----------- + ctx Application context + win Window to fit +.endtable + +.h3 dvxFitWindowW + +.code +void dvxFitWindowW(AppContextT *ctx, WindowT *win); +.endcode + +Resize window width only to fit widget tree's minimum width (plus chrome). + +.table + Parameter Description + --------- ----------- + ctx Application context + win Window to fit +.endtable + +.h3 dvxFitWindowH + +.code +void dvxFitWindowH(AppContextT *ctx, WindowT *win); +.endcode + +Resize window height only to fit widget tree's minimum height (plus chrome). + +.table + Parameter Description + --------- ----------- + ctx Application context + win Window to fit +.endtable + +.h3 dvxResizeWindow + +.code +void dvxResizeWindow(AppContextT *ctx, WindowT *win, int32_t newW, int32_t newH); +.endcode + +Programmatically resize a window to the specified outer dimensions. + +.table + Parameter Description + --------- ----------- + ctx Application context + win Window to resize + newW, newH New outer frame dimensions +.endtable + +.h3 dvxMinimizeWindow + +.code +void dvxMinimizeWindow(AppContextT *ctx, WindowT *win); +.endcode + +Minimize a window (show as icon at bottom of screen). + +.table + Parameter Description + --------- ----------- + ctx Application context + win Window to minimize +.endtable + +.h3 dvxMaximizeWindow + +.code +void dvxMaximizeWindow(AppContextT *ctx, WindowT *win); +.endcode + +Maximize a window (expand to fill screen or maxW/maxH). + +.table + Parameter Description + --------- ----------- + ctx Application context + win Window to maximize +.endtable + +.h3 dvxHideWindow + +.code +void dvxHideWindow(AppContextT *ctx, WindowT *win); +.endcode + +Hide a window without destroying it. Marks the exposed region dirty. + +.table + Parameter Description + --------- ----------- + ctx Application context + win Window to hide +.endtable + +.h3 dvxShowWindow + +.code +void dvxShowWindow(AppContextT *ctx, WindowT *win); +.endcode + +Show a previously hidden window. Marks its region dirty for repaint. + +.table + Parameter Description + --------- ----------- + ctx Application context + win Window to show +.endtable + +.h2 Invalidation + +.h3 dvxInvalidateRect + +.code +void dvxInvalidateRect(AppContextT *ctx, WindowT *win, int32_t x, int32_t y, int32_t w, int32_t h); +.endcode + +Mark a sub-region of a window's content area as needing repaint. Coordinates are relative to the content area, not the screen. Triggers onPaint during the next composite pass. + +.table + Parameter Description + --------- ----------- + ctx Application context + win Window + x, y, w, h Dirty rectangle in content-relative coordinates +.endtable + +.h3 dvxInvalidateWindow + +.code +void dvxInvalidateWindow(AppContextT *ctx, WindowT *win); +.endcode + +Mark the entire window content area as dirty. + +.table + Parameter Description + --------- ----------- + ctx Application context + win Window to invalidate +.endtable + +.h2 Window Properties + +.h3 dvxSetTitle + +.code +void dvxSetTitle(AppContextT *ctx, WindowT *win, const char *title); +.endcode + +Set a window's title text and dirty the title bar. + +.table + Parameter Description + --------- ----------- + ctx Application context + win Window + title New title text +.endtable + +.h3 dvxSetWindowIcon + +.code +int32_t dvxSetWindowIcon(AppContextT *ctx, WindowT *win, const char *path); +.endcode + +Load an icon for a window from an image file. + +.table + Parameter Description + --------- ----------- + ctx Application context + win Window + path Image file path +.endtable + +Returns: 0 on success, -1 on failure. + +.h3 dvxSetBusy + +.code +void dvxSetBusy(AppContextT *ctx, bool busy); +.endcode + +Set or clear busy state. While busy, the hourglass cursor is shown and input is blocked. + +.table + Parameter Description + --------- ----------- + ctx Application context + busy true = show hourglass, false = normal +.endtable + +.h2 Accessors + +.h3 dvxGetFont + +.code +const BitmapFontT *dvxGetFont(const AppContextT *ctx); +.endcode + +Get a pointer to the default font. + +.table + Parameter Description + --------- ----------- + ctx Application context +.endtable + +Returns: Pointer to the active BitmapFontT. + +.h3 dvxGetColors + +.code +const ColorSchemeT *dvxGetColors(const AppContextT *ctx); +.endcode + +Get a pointer to the current color scheme. + +.table + Parameter Description + --------- ----------- + ctx Application context +.endtable + +Returns: Pointer to the active ColorSchemeT. + +.h3 dvxGetDisplay + +.code +DisplayT *dvxGetDisplay(AppContextT *ctx); +.endcode + +Get a pointer to the display context. + +.table + Parameter Description + --------- ----------- + ctx Application context +.endtable + +Returns: Pointer to the DisplayT. + +.h3 dvxGetBlitOps + +.code +const BlitOpsT *dvxGetBlitOps(const AppContextT *ctx); +.endcode + +Get a pointer to the blit operations vtable. + +.table + Parameter Description + --------- ----------- + ctx Application context +.endtable + +Returns: Pointer to the active BlitOpsT. + +.h3 dvxGetVideoModes + +.code +const VideoModeInfoT *dvxGetVideoModes(const AppContextT *ctx, int32_t *count); +.endcode + +Return the list of available video modes enumerated at init time. + +.table + Parameter Description + --------- ----------- + ctx Application context + count Output: number of mode entries +.endtable + +Returns: Pointer to the VideoModeInfoT array. + +.h2 Color Scheme + +.h3 dvxSetColor + +.code +void dvxSetColor(AppContextT *ctx, ColorIdE id, uint8_t r, uint8_t g, uint8_t b); +.endcode + +Set a single color by ID. Repacks to native pixel format and invalidates the entire screen. + +.table + Parameter Description + --------- ----------- + ctx Application context + id Color ID (ColorIdE) + r, g, b RGB values (0-255) +.endtable + +.h3 dvxGetColor + +.code +void dvxGetColor(const AppContextT *ctx, ColorIdE id, uint8_t *r, uint8_t *g, uint8_t *b); +.endcode + +Get a color's RGB values by ID. + +.table + Parameter Description + --------- ----------- + ctx Application context + id Color ID (ColorIdE) + r, g, b Output: RGB values +.endtable + +.h3 dvxApplyColorScheme + +.code +void dvxApplyColorScheme(AppContextT *ctx); +.endcode + +Apply all colors from ctx->colorRgb[] at once (repack + full repaint). + +.table + Parameter Description + --------- ----------- + ctx Application context +.endtable + +.h3 dvxResetColorScheme + +.code +void dvxResetColorScheme(AppContextT *ctx); +.endcode + +Reset all colors to the built-in defaults and repaint. + +.table + Parameter Description + --------- ----------- + ctx Application context +.endtable + +.h3 dvxLoadTheme + +.code +bool dvxLoadTheme(AppContextT *ctx, const char *filename); +.endcode + +Load a theme file (INI format with [colors] section) and apply it. + +.table + Parameter Description + --------- ----------- + ctx Application context + filename Path to theme INI file +.endtable + +Returns: true on success. + +.h3 dvxSaveTheme + +.code +bool dvxSaveTheme(const AppContextT *ctx, const char *filename); +.endcode + +Save the current color scheme to a theme file. + +.table + Parameter Description + --------- ----------- + ctx Application context + filename Output file path +.endtable + +Returns: true on success. + +.h3 dvxColorName + +.code +const char *dvxColorName(ColorIdE id); +.endcode + +Return the INI key name for a color ID (e.g. "desktop", "windowFace"). + +.table + Parameter Description + --------- ----------- + id Color ID +.endtable + +Returns: Static string. + +.h3 dvxColorLabel + +.code +const char *dvxColorLabel(ColorIdE id); +.endcode + +Return a human-readable display label (e.g. "Desktop", "Cursor Color"). + +.table + Parameter Description + --------- ----------- + id Color ID +.endtable + +Returns: Static string. + +.h2 Wallpaper + +.h3 dvxSetWallpaper + +.code +bool dvxSetWallpaper(AppContextT *ctx, const char *path); +.endcode + +Load and apply a wallpaper image using the current wallpaperMode (stretch/tile/center). Pass NULL to clear the wallpaper. + +.table + Parameter Description + --------- ----------- + ctx Application context + path Image file path, or NULL to clear +.endtable + +Returns: true on success. + +.h3 dvxSetWallpaperMode + +.code +void dvxSetWallpaperMode(AppContextT *ctx, WallpaperModeE mode); +.endcode + +Change the wallpaper display mode and re-render. No effect if no wallpaper is loaded. + +.table + Parameter Description + --------- ----------- + ctx Application context + mode WallpaperStretchE, WallpaperTileE, or WallpaperCenterE +.endtable + +.h2 Mouse Configuration + +.h3 dvxSetMouseConfig + +.code +void dvxSetMouseConfig(AppContextT *ctx, int32_t wheelDir, int32_t dblClickMs, int32_t accelThreshold); +.endcode + +Configure mouse behavior. + +.table + Parameter Description + --------- ----------- + ctx Application context + wheelDir 1 = normal, -1 = reversed + dblClickMs Double-click speed in milliseconds (e.g. 500) + accelThreshold Double-speed threshold in mickeys/sec (0 = don't change) +.endtable + +.h2 Accelerators + +.h3 dvxCreateAccelTable + +.code +AccelTableT *dvxCreateAccelTable(void); +.endcode + +Allocate a new accelerator table. Attach to a window via win->accelTable. + +Returns: Pointer to new AccelTableT. + +.h3 dvxFreeAccelTable + +.code +void dvxFreeAccelTable(AccelTableT *table); +.endcode + +Free an accelerator table and its entries. + +.table + Parameter Description + --------- ----------- + table Table to free +.endtable + +.h3 dvxAddAccel + +.code +void dvxAddAccel(AccelTableT *table, int32_t key, int32_t modifiers, int32_t cmdId); +.endcode + +Register a keyboard shortcut. On match, fires the window's onMenu callback with cmdId. + +.table + Parameter Description + --------- ----------- + table Accelerator table + key ASCII character or KEY_Fxx constant + modifiers Bitmask of ACCEL_CTRL / ACCEL_SHIFT / ACCEL_ALT + cmdId Command ID passed to onMenu +.endtable + +.h2 Window Arrangement + +.h3 dvxCascadeWindows + +.code +void dvxCascadeWindows(AppContextT *ctx); +.endcode + +Cascade all visible, non-minimized windows. Each is offset diagonally by the title bar height. + +.table + Parameter Description + --------- ----------- + ctx Application context +.endtable + +.h3 dvxTileWindows + +.code +void dvxTileWindows(AppContextT *ctx); +.endcode + +Arrange visible windows in an NxM grid filling the screen. + +.table + Parameter Description + --------- ----------- + ctx Application context +.endtable + +.h3 dvxTileWindowsH + +.code +void dvxTileWindowsH(AppContextT *ctx); +.endcode + +Tile windows horizontally (side by side, equal width, full height). + +.table + Parameter Description + --------- ----------- + ctx Application context +.endtable + +.h3 dvxTileWindowsV + +.code +void dvxTileWindowsV(AppContextT *ctx); +.endcode + +Tile windows vertically (stacked, full width, equal height). + +.table + Parameter Description + --------- ----------- + ctx Application context +.endtable + +.h2 Image I/O + +.h3 dvxLoadImage + +.code +uint8_t *dvxLoadImage(const AppContextT *ctx, const char *path, int32_t *outW, int32_t *outH, int32_t *outPitch); +.endcode + +Load an image file (BMP, PNG, JPEG, GIF) and convert to the display's native pixel format. Caller must free with dvxFreeImage(). + +.table + Parameter Description + --------- ----------- + ctx Application context + path Image file path + outW, outH Output: image dimensions + outPitch Output: row pitch in bytes +.endtable + +Returns: Pixel buffer, or NULL on failure. + +.h3 dvxLoadImageFromMemory + +.code +uint8_t *dvxLoadImageFromMemory(const AppContextT *ctx, const uint8_t *data, int32_t dataLen, int32_t *outW, int32_t *outH, int32_t *outPitch); +.endcode + +Load an image from a memory buffer. Same output format as dvxLoadImage(). Caller must free with dvxFreeImage(). + +.table + Parameter Description + --------- ----------- + ctx Application context + data Image data buffer + dataLen Buffer size in bytes + outW, outH Output: image dimensions + outPitch Output: row pitch in bytes +.endtable + +Returns: Pixel buffer, or NULL on failure. + +.h3 dvxFreeImage + +.code +void dvxFreeImage(uint8_t *data); +.endcode + +Free a pixel buffer returned by dvxLoadImage() or dvxLoadImageFromMemory(). + +.table + Parameter Description + --------- ----------- + data Buffer to free +.endtable + +.h3 dvxImageInfo + +.code +bool dvxImageInfo(const char *path, int32_t *outW, int32_t *outH); +.endcode + +Query image dimensions without decoding the full file. + +.table + Parameter Description + --------- ----------- + path Image file path + outW, outH Output: image dimensions +.endtable + +Returns: true on success. + +.h3 dvxSaveImage + +.code +int32_t dvxSaveImage(const AppContextT *ctx, const uint8_t *data, int32_t w, int32_t h, int32_t pitch, const char *path); +.endcode + +Save native-format pixel data to a PNG file. + +.table + Parameter Description + --------- ----------- + ctx Application context + data Pixel data in display native format + w, h Image dimensions + pitch Row pitch in bytes + path Output file path +.endtable + +Returns: 0 on success, -1 on failure. + +.h2 Screenshots + +.h3 dvxScreenshot + +.code +int32_t dvxScreenshot(AppContextT *ctx, const char *path); +.endcode + +Save the entire screen (backbuffer contents) to a PNG file. Converts from native pixel format to RGB. + +.table + Parameter Description + --------- ----------- + ctx Application context + path Output PNG file path +.endtable + +Returns: 0 on success, -1 on failure. + +.h3 dvxWindowScreenshot + +.code +int32_t dvxWindowScreenshot(AppContextT *ctx, WindowT *win, const char *path); +.endcode + +Save a window's content to a PNG file. + +.table + Parameter Description + --------- ----------- + ctx Application context + win Window + path Output PNG file path +.endtable + +Returns: 0 on success, -1 on failure. + +.h2 Clipboard + +.h3 dvxClipboardCopy + +.code +void dvxClipboardCopy(const char *text, int32_t len); +.endcode + +Copy text to the process-wide clipboard buffer. Simple static buffer (not inter-process). + +.table + Parameter Description + --------- ----------- + text Text to copy + len Length in bytes +.endtable + +.h3 dvxClipboardGet + +.code +const char *dvxClipboardGet(int32_t *outLen); +.endcode + +Retrieve the current clipboard contents. Returns a pointer to the internal buffer (valid until the next dvxClipboardCopy), or NULL if empty. + +.table + Parameter Description + --------- ----------- + outLen Output: length of clipboard text +.endtable + +Returns: Clipboard text, or NULL. + +.h2 Resource Loading + +.h3 dvxResLoadIcon + +.code +uint8_t *dvxResLoadIcon(AppContextT *ctx, const char *dxePath, const char *resName, int32_t *outW, int32_t *outH, int32_t *outPitch); +.endcode + +Load an icon/image resource from a DXE file and decode to native pixel format. Caller must free with dvxFreeImage(). + +.table + Parameter Description + --------- ----------- + ctx Application context + dxePath Path to DXE file + resName Resource name within the DXE + outW, outH Output: image dimensions + outPitch Output: row pitch +.endtable + +Returns: Pixel buffer, or NULL if not found. + +.h3 dvxResLoadText + +.code +bool dvxResLoadText(const char *dxePath, const char *resName, char *buf, int32_t bufSize); +.endcode + +Load a text resource from a DXE file into a caller-provided buffer. Null-terminated and truncated to fit bufSize. + +.table + Parameter Description + --------- ----------- + dxePath Path to DXE file + resName Resource name + buf Output buffer + bufSize Buffer capacity +.endtable + +Returns: true on success. + +.h3 dvxResLoadData + +.code +void *dvxResLoadData(const char *dxePath, const char *resName, uint32_t *outSize); +.endcode + +Load a raw binary resource from a DXE file. Returns a malloc'd buffer that the caller must free. + +.table + Parameter Description + --------- ----------- + dxePath Path to DXE file + resName Resource name + outSize Output: data size in bytes +.endtable + +Returns: Data buffer, or NULL if not found. + +.h2 Utilities + +.h3 dvxTextHash + +.code +uint32_t dvxTextHash(const char *text); +.endcode + +Compute a djb2-xor hash for cheap dirty detection. Compare at save time with the current hash to detect changes without a shadow copy. Not cryptographic. + +.table + Parameter Description + --------- ----------- + text Null-terminated string to hash +.endtable + +Returns: 32-bit hash value. + +.topic api.widget +.title dvxWidget.h -- Widget System +.toc 0 dvxWidget.h -- Widget System +.index dvxWidget.h +.index WidgetT +.index WidgetClassT +.index wgtInitWindow +.index wgtGetContext +.index wgtInvalidate +.index wgtInvalidatePaint +.index wgtSetText +.index wgtGetText +.index wgtSetEnabled +.index wgtSetReadOnly +.index wgtSetFocused +.index wgtGetFocused +.index wgtSetVisible +.index wgtSetName +.index wgtFind +.index wgtDestroy +.index wgtSetTooltip +.index wgtResolveSize +.index wgtLayout +.index wgtPaint +.index wgtSetDebugLayout +.index wgtRegisterClass +.index wgtRegisterApi +.index wgtGetApi +.index wgtRegisterIface +.index wgtGetIface +.index wgtFindByBasName +.index wgtPixels +.index wgtChars +.index wgtPercent + +.h1 dvxWidget.h -- Widget System + +Retained-mode widget toolkit layered on the DVX window manager. Widgets form a tree (parent-child) rooted at a per-window VBox container. Layout is automatic: measure minimum sizes bottom-up, then allocate space top-down with flexbox-like weighted distribution. Widget types are registered dynamically at runtime via DXE plugins. + +.h2 WidgetT Structure + +Core widget structure. Generic across all widget types; type-specific data lives in the void *data pointer managed by each widget's DXE. + +.table + Field Description + ----- ----------- + int32_t type Widget type ID (assigned by wgtRegisterClass) + const WidgetClassT *wclass Vtable for this widget type + char name[MAX_WIDGET_NAME] Widget name for lookup via wgtFind + parent, firstChild, lastChild, nextSibling Tree linkage pointers + WindowT *window Owning window + int32_t x, y, w, h Computed geometry (relative to content area) + int32_t calcMinW, calcMinH Computed minimum size (from layout pass) + int32_t minW, minH, maxW, maxH, prefW, prefH Size hints (tagged sizes) + int32_t weight Extra-space distribution weight (0=fixed, 100=normal) + WidgetAlignE align Main-axis alignment for children + int32_t spacing, padding Tagged sizes for child spacing and padding + uint32_t fgColor, bgColor Custom colors (0 = use scheme defaults) + bool visible, enabled, readOnly State flags + bool swallowTab Tab key goes to widget, not focus navigation + char accelKey Accelerator character (0 = none) + void *userData, *data Application data and widget-private data + const char *tooltip Tooltip text (NULL = none) + MenuT *contextMenu Right-click menu (NULL = none) +.endtable + +Universal Callbacks: + +.table + Callback Description + -------- ----------- + onClick(WidgetT *w) Widget clicked + onDblClick(WidgetT *w) Widget double-clicked + onChange(WidgetT *w) Value changed + onFocus(WidgetT *w) Widget gained focus + onBlur(WidgetT *w) Widget lost focus + onKeyPress(WidgetT *w, int32_t keyAscii) ASCII key press + onKeyDown(WidgetT *w, int32_t keyCode, int32_t shift) Key down + onKeyUp(WidgetT *w, int32_t keyCode, int32_t shift) Key up + onMouseDown(WidgetT *w, int32_t btn, int32_t x, int32_t y) Mouse button pressed + onMouseUp(WidgetT *w, int32_t btn, int32_t x, int32_t y) Mouse button released + onMouseMove(WidgetT *w, int32_t btn, int32_t x, int32_t y) Mouse moved + onScroll(WidgetT *w, int32_t delta) Mouse wheel + onValidate(WidgetT *w) Return false to cancel a write +.endtable + +.h2 Size Specification Macros + +.table + Macro Description + ----- ----------- + wgtPixels(v) Size in pixels + wgtChars(v) Size in character widths (multiplied by charWidth at layout) + wgtPercent(v) Size as percentage of parent dimension +.endtable + +.h2 Widget Class Flags + +.table + Flag Description + ---- ----------- + WCLASS_FOCUSABLE Can receive keyboard focus (Tab navigation) + WCLASS_HORIZ_CONTAINER Lays out children horizontally (vs. vertical) + WCLASS_PAINTS_CHILDREN Widget handles child rendering itself + WCLASS_NO_HIT_RECURSE Hit testing stops here, no child recursion + WCLASS_FOCUS_FORWARD Accel hit forwards focus to next focusable sibling + WCLASS_HAS_POPUP Has dropdown popup overlay + WCLASS_SCROLLABLE Accepts mouse wheel events + WCLASS_SCROLL_CONTAINER Scroll container (ScrollPane) + WCLASS_NEEDS_POLL Needs periodic polling + WCLASS_SWALLOWS_TAB Tab key goes to widget, not focus navigation + WCLASS_RELAYOUT_ON_SCROLL Full relayout on scrollbar drag + WCLASS_PRESS_RELEASE Click = press + release (Button, ImageButton) + WCLASS_ACCEL_WHEN_HIDDEN Accelerator matching works even when invisible +.endtable + +.h2 Window Integration + +.h3 wgtInitWindow + +.code +WidgetT *wgtInitWindow(AppContextT *ctx, WindowT *win); +.endcode + +Initialize the widget system for a window. Creates a root VBox container that fills the content area, and installs callback handlers (onPaint, onMouse, onKey, onResize) for widget-based event dispatch. The window's userData is set to the AppContextT pointer. + +.table + Parameter Description + --------- ----------- + ctx Application context + win Window to initialize +.endtable + +Returns: Root VBox widget (add children to this). + +.h2 Widget Operations + +.h3 wgtGetContext + +.code +AppContextT *wgtGetContext(const WidgetT *w); +.endcode + +Walk from any widget up the tree to the root, then retrieve the AppContextT stored in the window's userData. Lets any widget access the full application context. + +.table + Parameter Description + --------- ----------- + w Any widget in the tree +.endtable + +Returns: Pointer to the AppContextT. + +.h3 wgtInvalidate + +.code +void wgtInvalidate(WidgetT *w); +.endcode + +Mark a widget as needing both re-layout (measure + position) and repaint. Propagates upward to ancestors. Use after structural changes (adding/removing children, text changes that affect size). + +.table + Parameter Description + --------- ----------- + w Widget to invalidate +.endtable + +.h3 wgtInvalidatePaint + +.code +void wgtInvalidatePaint(WidgetT *w); +.endcode + +Mark a widget as needing repaint only, without re-layout. Use for visual-only changes (checkbox toggle, selection highlight, cursor blink). + +.table + Parameter Description + --------- ----------- + w Widget to repaint +.endtable + +.h3 wgtSetText + +.code +void wgtSetText(WidgetT *w, const char *text); +.endcode + +Set widget text content (dispatches to the widget class's SET_TEXT handler). + +.table + Parameter Description + --------- ----------- + w Widget + text New text +.endtable + +.h3 wgtGetText + +.code +const char *wgtGetText(const WidgetT *w); +.endcode + +Get the widget's current text content. + +.table + Parameter Description + --------- ----------- + w Widget +.endtable + +Returns: Text string (empty string if no handler). + +.h3 wgtSetEnabled + +.code +void wgtSetEnabled(WidgetT *w, bool enabled); +.endcode + +Enable or disable a widget. Disabled widgets are grayed out and do not receive input. + +.table + Parameter Description + --------- ----------- + w Widget + enabled true = enabled, false = disabled +.endtable + +.h3 wgtSetReadOnly + +.code +void wgtSetReadOnly(WidgetT *w, bool readOnly); +.endcode + +Set read-only mode. Allows scrolling and selection but blocks editing. + +.table + Parameter Description + --------- ----------- + w Widget + readOnly true = read-only +.endtable + +.h3 wgtSetFocused + +.code +void wgtSetFocused(WidgetT *w); +.endcode + +Set keyboard focus to a widget. + +.table + Parameter Description + --------- ----------- + w Widget to focus +.endtable + +.h3 wgtGetFocused + +.code +WidgetT *wgtGetFocused(void); +.endcode + +Get the currently focused widget. + +Returns: Focused widget, or NULL. + +.h3 wgtSetVisible + +.code +void wgtSetVisible(WidgetT *w, bool visible); +.endcode + +Show or hide a widget. + +.table + Parameter Description + --------- ----------- + w Widget + visible true = visible, false = hidden +.endtable + +.h3 wgtSetName + +.code +void wgtSetName(WidgetT *w, const char *name); +.endcode + +Set a widget's name for lookup via wgtFind(). + +.table + Parameter Description + --------- ----------- + w Widget + name Name string (max MAX_WIDGET_NAME chars) +.endtable + +.h3 wgtFind + +.code +WidgetT *wgtFind(WidgetT *root, const char *name); +.endcode + +Find a widget by name. Searches the subtree rooted at root. + +.table + Parameter Description + --------- ----------- + root Root of subtree to search + name Widget name to find +.endtable + +Returns: Matching widget, or NULL. + +.h3 wgtDestroy + +.code +void wgtDestroy(WidgetT *w); +.endcode + +Destroy a widget and all its children. Removes from parent's child list. + +.table + Parameter Description + --------- ----------- + w Widget to destroy +.endtable + +.h3 wgtSetTooltip + +.code +void wgtSetTooltip(WidgetT *w, const char *text); +.endcode + +Set tooltip text for a widget. Pass NULL to remove. Caller owns the string and it must outlive the widget. + +.table + Parameter Description + --------- ----------- + w Widget + text Tooltip text, or NULL +.endtable + +.h3 widgetOnResize + +.code +void widgetOnResize(WindowT *win, int32_t newW, int32_t newH); +.endcode + +Default window resize handler installed by wgtInitWindow(). Re-evaluates scrollbars and relayouts the widget tree. Call from custom onResize handlers to chain to the widget system. + +.table + Parameter Description + --------- ----------- + win Window being resized + newW, newH New content dimensions +.endtable + +.h2 Layout + +.h3 wgtResolveSize + +.code +int32_t wgtResolveSize(int32_t taggedSize, int32_t parentSize, int32_t charWidth); +.endcode + +Decode a tagged size value (WGT_SIZE_PIXELS/CHARS/PERCENT) into a concrete pixel count. Returns 0 for a raw 0 input (meaning "auto"). + +.table + Parameter Description + --------- ----------- + taggedSize Tagged size value + parentSize Parent dimension (for PERCENT mode) + charWidth Font character width (for CHARS mode) +.endtable + +Returns: Size in pixels. + +.h3 wgtLayout + +.code +void wgtLayout(WidgetT *root, int32_t availW, int32_t availH, const BitmapFontT *font); +.endcode + +Execute the full two-pass layout algorithm. Pass 1 (bottom-up): compute minimum sizes. Pass 2 (top-down): allocate space with weighted distribution. Normally called automatically; exposed for cases where layout must be forced before the next paint. + +.table + Parameter Description + --------- ----------- + root Root widget + availW/H Available space + font Bitmap font (for character-based sizing) +.endtable + +.h3 wgtPaint + +.code +void wgtPaint(WidgetT *root, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors); +.endcode + +Paint the entire widget tree by depth-first traversal. Each widget's clip rect is set to its bounds. Overlays (popups, tooltips) are painted in a second pass on top. + +.table + Parameter Description + --------- ----------- + root Root widget + d Display context + ops Blit operations vtable + font Bitmap font + colors Color scheme +.endtable + +.h2 Debug + +.h3 wgtSetDebugLayout + +.code +void wgtSetDebugLayout(AppContextT *ctx, bool enabled); +.endcode + +Draw colored borders around layout containers for debugging. + +.table + Parameter Description + --------- ----------- + ctx Application context + enabled true = draw debug borders +.endtable + +.h2 Dynamic Widget Registration + +.h3 wgtRegisterClass + +.code +int32_t wgtRegisterClass(const WidgetClassT *wclass); +.endcode + +Register a new widget class at runtime. Appends to widgetClassTable. The WidgetClassT must remain valid for the lifetime of the process (typically static const in a DXE). + +.table + Parameter Description + --------- ----------- + wclass Widget class vtable to register +.endtable + +Returns: Assigned type ID. + +.h3 wgtRegisterApi + +.code +void wgtRegisterApi(const char *name, const void *api); +.endcode + +Register a widget API struct under a name. Each widget DXE registers its API during initialization. Callers retrieve it via wgtGetApi() and cast to the widget-specific type. + +.table + Parameter Description + --------- ----------- + name Widget type name (e.g. "button", "listbox") + api Pointer to the widget's API struct +.endtable + +.h3 wgtGetApi + +.code +const void *wgtGetApi(const char *name); +.endcode + +Retrieve a registered widget API struct by name. + +.table + Parameter Description + --------- ----------- + name Widget type name +.endtable + +Returns: Pointer to the API struct, or NULL if not found. + +.h2 Widget Interface Descriptors + +.h3 wgtRegisterIface + +.code +void wgtRegisterIface(const char *name, const WgtIfaceT *iface); +.endcode + +Register an interface descriptor for a widget type. Used by the BASIC form runtime and IDE for generic property/method dispatch. + +.table + Parameter Description + --------- ----------- + name Widget type name + iface Interface descriptor +.endtable + +.h3 wgtGetIface + +.code +const WgtIfaceT *wgtGetIface(const char *name); +.endcode + +Retrieve an interface descriptor by widget type name. + +.table + Parameter Description + --------- ----------- + name Widget type name +.endtable + +Returns: Interface descriptor, or NULL. + +.h3 wgtFindByBasName + +.code +const char *wgtFindByBasName(const char *basName); +.endcode + +Find a widget type name by its VB-style name (e.g. "CommandButton" -> "button"). Case-insensitive search. + +.table + Parameter Description + --------- ----------- + basName VB-style widget name +.endtable + +Returns: Internal type name, or NULL. + +.h3 wgtIfaceCount + +.code +int32_t wgtIfaceCount(void); +.endcode + +Return the number of registered widget interfaces. + +Returns: Count of registered interfaces. + +.h3 wgtIfaceAt + +.code +const WgtIfaceT *wgtIfaceAt(int32_t idx, const char **outName); +.endcode + +Get a registered widget interface by index. + +.table + Parameter Description + --------- ----------- + idx Index (0-based) + outName Output: type name +.endtable + +Returns: Interface descriptor. + +.h3 wgtIfaceGetPath + +.code +const char *wgtIfaceGetPath(const char *name); +.endcode + +Get the .wgt DXE file path for a registered widget. + +.table + Parameter Description + --------- ----------- + name Widget type name +.endtable + +Returns: File path string. + +.h3 wgtIfaceSetPath + +.code +void wgtIfaceSetPath(const char *name, const char *path); +.endcode + +Set the .wgt DXE file path for a registered widget (called by the loader). + +.table + Parameter Description + --------- ----------- + name Widget type name + path DXE file path +.endtable + +.h3 wgtIfaceGetPathIndex + +.code +int32_t wgtIfaceGetPathIndex(const char *name); +.endcode + +Get the 1-based index of this widget within its .wgt file. Used to construct suffixed resource names (e.g. "name-2", "icon16-2"). + +.table + Parameter Description + --------- ----------- + name Widget type name +.endtable + +Returns: 1-based index within the DXE file. + +.h2 Typed Dispatch Helpers + +The following inline functions provide type-safe dispatch through the WidgetClassT handler table. Each checks for a non-NULL handler before calling. + +.table + Function Method ID Description + -------- --------- ----------- + wclsHas(w, methodId) -- Check if handler exists + wclsPaint(w, d, ops, font, colors) WGT_METHOD_PAINT Paint the widget + wclsPaintOverlay(w, d, ops, font, colors) WGT_METHOD_PAINT_OVERLAY Paint overlay (popups) + wclsCalcMinSize(w, font) WGT_METHOD_CALC_MIN_SIZE Compute minimum size + wclsLayout(w, font) WGT_METHOD_LAYOUT Layout children + wclsGetLayoutMetrics(w, font, ...) WGT_METHOD_GET_LAYOUT_METRICS Get pad, gap, extraTop, borderW + wclsOnMouse(w, root, vx, vy) WGT_METHOD_ON_MOUSE Handle mouse event + wclsOnKey(w, key, mod) WGT_METHOD_ON_KEY Handle key event + wclsOnAccelActivate(w, root) WGT_METHOD_ON_ACCEL_ACTIVATE Handle accelerator + wclsDestroy(w) WGT_METHOD_DESTROY Destroy widget data + wclsOnChildChanged(parent, child) WGT_METHOD_ON_CHILD_CHANGED Notify parent of change + wclsGetText(w) WGT_METHOD_GET_TEXT Get widget text + wclsSetText(w, text) WGT_METHOD_SET_TEXT Set widget text + wclsClearSelection(w) WGT_METHOD_CLEAR_SELECTION Clear text selection + wclsClosePopup(w) WGT_METHOD_CLOSE_POPUP Close dropdown popup + wclsGetPopupRect(w, font, ...) WGT_METHOD_GET_POPUP_RECT Get popup screen rect + wclsOnDragUpdate(w, root, x, y) WGT_METHOD_ON_DRAG_UPDATE Update during drag + wclsOnDragEnd(w, root, x, y) WGT_METHOD_ON_DRAG_END End drag operation + wclsGetCursorShape(w, vx, vy) WGT_METHOD_GET_CURSOR_SHAPE Get cursor for position + wclsPoll(w, win) WGT_METHOD_POLL Periodic polling + wclsQuickRepaint(w, outY, outH) WGT_METHOD_QUICK_REPAINT Fast partial repaint + wclsScrollChildIntoView(parent, child) WGT_METHOD_SCROLL_CHILD_INTO_VIEW Scroll child visible +.endtable diff --git a/docs/src/dvx_architecture.dvxhelp b/docs/src/dvx_architecture.dvxhelp new file mode 100644 index 0000000..210253b --- /dev/null +++ b/docs/src/dvx_architecture.dvxhelp @@ -0,0 +1,776 @@ +.topic arch.overview +.title DVX Architecture Overview +.toc 0 System Overview +.default +.index DVX +.index Architecture +.index DJGPP +.index DPMI + +.h1 DVX Architecture Overview + +DOS Visual eXecutive -- A Windowing GUI for DJGPP/DPMI + +DVX (DOS Visual eXecutive) is a complete windowing GUI compositor targeting DJGPP/DPMI on DOS. It provides overlapping windows with Motif-style chrome, a retained-mode widget toolkit, cooperative multitasking of DXE-loaded applications, and a dirty-rectangle compositor optimized for 486/Pentium hardware. + +.h2 Key Design Constraints + +.list +.item VESA VBE 2.0+ LFB only -- no bank switching. If the hardware cannot provide a linear framebuffer, initialization fails. +.item 486 baseline -- all hot paths are written to be fast on a 486, with Pentium-specific paths where the gain is significant. +.item Single-tasking cooperative model -- applications yield the CPU via tsYield(); there is no preemptive scheduler. +.item 86Box is the trusted reference platform for testing. DOSBox-X is not used; any bugs observed are treated as DVX bugs. +.item No external font or cursor files -- all bitmaps are compiled in as static const data. +.endlist + +The runtime environment consists of a bootstrap loader (dvx.exe) that loads core DXE libraries, widget plugins, and the shell, which in turn loads and manages DXE application modules. + +.h2 Contents + +.list +.item .link arch.overview System Overview +.item .link arch.layers Five-Layer Architecture +.item .link arch.pipeline Display Pipeline +.item .link arch.windows Window System +.item .link arch.widgets Widget System +.item .link arch.dxe DXE Module System +.item .link arch.events Event Model +.item .link arch.fonts Font System +.item .link arch.colors Color System +.item .link arch.platform Platform Layer +.item .link arch.build Build System +.endlist + +.topic arch.layers +.title Five-Layer Architecture +.toc 0 Five-Layer Architecture +.index Layers +.index dvxVideo +.index dvxDraw +.index dvxComp +.index dvxWm +.index dvxApp + +.h1 Five-Layer Architecture + +DVX is organized into five layers, each implemented as a single .h/.c pair. Every header includes dvxTypes.h (the shared type definitions) to avoid circular dependencies. The layers are strictly stacked: each layer depends only on the layers below it. + +.code + Applications (DXE .app modules) + ================================================== + | | + | +------------------------------------------+ | + | | Layer 5: dvxApp (Application API) | | dvxApp.h / dvxApp.c + | | Event loop, window creation, public API | | + | +------------------------------------------+ | + | | Layer 4: dvxWm (Window Manager) | | dvxWm.h / dvxWm.c + | | Window stack, chrome, drag, resize | | + | +------------------------------------------+ | + | | Layer 3: dvxComp (Compositor) | | dvxComp.h / dvxComp.c + | | Dirty rect tracking, merge, LFB flush | | + | +------------------------------------------+ | + | | Layer 2: dvxDraw (Drawing Primitives) | | dvxDraw.h / dvxDraw.c + | | Rects, bevels, text, blits, cursors | | + | +------------------------------------------+ | + | | Layer 1: dvxVideo (Video Backend) | | dvxVideo.h / dvxVideo.c + | | VESA VBE, LFB mapping, pixel format | | + | +------------------------------------------+ | + | | + | +------------------------------------------+ | + | | Platform Layer (dvxPlatform.h) | | dvxPlatformDos.c + | | OS-specific: video, input, asm spans | | + | +------------------------------------------+ | + | | + | +------------------------------------------+ | + | | Shared Types (dvxTypes.h) | | + | | DisplayT, WindowT, RectT, ColorSchemeT | | + | +------------------------------------------+ | + ================================================== +.endcode + +.h2 Layer Summary + +.table + Layer Header Responsibility + ----- ------ -------------- + 1 - Video dvxVideo.h VESA VBE mode negotiation, LFB mapping via DPMI, backbuffer allocation, packColor() (RGB to native pixel format), display-wide clip rectangle. + 2 - Draw dvxDraw.h All 2D drawing: rectFill, rectCopy, drawBevel, drawText/drawTextN, drawMaskedBitmap (cursor), drawTermRow (batch terminal row). Stateless beyond clip rect. Dispatches hot inner loops through BlitOpsT function pointers. + 3 - Compositor dvxComp.h Dirty rectangle tracking (dirtyListAdd), pairwise merge of overlapping rects (dirtyListMerge), and flushRect to copy dirty regions from backBuf to LFB. + 4 - Window Manager dvxWm.h Window lifecycle, Z-order stack, chrome drawing (title bars, bevels, close/minimize/maximize gadgets), hit testing, drag/resize, menu bars, scrollbars, system menu, keyboard move/resize, minimized icon bar. + 5 - Application dvxApp.h Public API aggregating all layers into AppContextT. Provides dvxInit/dvxShutdown, dvxRun/dvxUpdate, window creation helpers, image loading, clipboard, accelerator tables, theme management, wallpaper, video mode switching, screenshot capture. +.endtable + +.topic arch.pipeline +.title Display Pipeline +.toc 0 Display Pipeline +.index Display Pipeline +.index Backbuffer +.index Linear Framebuffer +.index LFB +.index Dirty Rects +.index Double Buffer +.index Compositing + +.h1 Display Pipeline + +The double-buffer strategy is the single most important performance decision in DVX. All drawing goes to a system RAM backbuffer (DisplayT.backBuf); only dirty rectangles are flushed to the linear framebuffer (DisplayT.lfb) in video memory. + +This matters because writes to video memory over the PCI bus are 10-50x slower than writes to main RAM on 486/Pentium hardware for random-access patterns. + +.h2 Per-Frame Compositing Pipeline + +.code + 1. Input poll (mouse, keyboard) + | + 2. Event dispatch (focus window callbacks) + | + 3. Layers call dirtyListAdd() for changed regions + | + 4. dirtyListMerge() consolidates overlapping rects + | + 5. For each merged dirty rect: + a. Clip and redraw desktop background (or wallpaper) + b. For each window (back-to-front, painter's algorithm): + - wmDrawChrome() -- frame, title bar, gadgets, menu bar + - wmDrawContent() -- blit per-window content buffer + - wmDrawScrollbars() + c. Draw minimized window icons + d. Draw popup menus / tooltips (overlay pass) + e. Draw software mouse cursor + | + 6. flushRect() -- copy each dirty rect from backBuf to LFB + | + 7. Yield (platformYield) +.endcode + +.h2 Key Data Structures + +.index DisplayT +.index BlitOpsT +.index DirtyListT + +DisplayT -- Central display context: width, height, pitch, pixel format, LFB pointer, backbuffer pointer, palette, clip rectangle. Passed by pointer through every layer -- no globals. + +BlitOpsT -- Vtable of span fill/copy function pointers resolved at init time for the active pixel depth. On DOS these dispatch to hand-written rep stosl / rep movsd asm inner loops. + +DirtyListT -- Fixed-capacity dynamic array of RectT. Linear scanning for merge candidates is cache-friendly at typical sizes (under 128 rects). If the list fills up, the compositor merges aggressively or falls back to full-screen repaint. + +.h2 Why This Works on a 486 + +.list +.item A full 640x480x32bpp frame is 1.2 MB -- far too much to flush every frame over a slow PCI bus. +.item A typical dirty region during normal interaction (typing, menu open) is a few KB. +.item Merging overlapping dirty rects into larger rects reduces per-rect overhead and improves bus utilization. +.item Per-window content buffers persist across frames, so windows don't repaint on expose -- only when their own content changes. +.endlist + +.topic arch.windows +.title Window System +.toc 0 Window System +.index Window +.index WindowT +.index Z-Order +.index Chrome +.index Hit Testing +.index Menu System +.index Minimized Windows + +.h1 Window System + +.h2 WindowT Structure + +Each WindowT is the central object of the window manager. Key fields: + +.table + Field Group Purpose + ----------- ------- + Geometry (x, y, w, h) Outer frame rectangle (including chrome). + Content area (contentX/Y/W/H) Computed from frame minus chrome. Where application content lives. + Content buffer (contentBuf, contentPitch) Per-window backbuffer in native pixel format. Persists across frames. + Chrome state (menuBar, vScroll, hScroll) Optional menu bar and scrollbars. Affect content area computation. + Widget tree (widgetRoot) Root of the retained-mode widget tree (NULL if using raw callbacks). + Callbacks onPaint, onKey, onKeyUp, onMouse, onResize, onClose, onMenu, onScroll, onFocus, onBlur, onCursorQuery. +.endtable + +.h2 Window Stack (Z-Order) + +.index Window Stack + +WindowStackT is an array of WindowT* ordered front-to-back: index count-1 is the topmost window. This allows: + +.list +.item Back-to-front iteration for painting (painter's algorithm). +.item Front-to-back iteration for hit testing (first hit wins). +.item Reordering by pointer swap (no copying of large WindowT structs). +.endlist + +Only one drag/resize/scroll operation can be active system-wide at a time (single mouse), so that state lives on the stack, not on individual windows. + +.h2 Chrome Layout + +.code + +-------------------------------------------+ + | 4px outer border (raised bevel) | + | +-------------------------------------+ | + | | [X] Title Bar Text [_] [^] [X] | | 20px title height + | +-------------------------------------+ | + | | 2px inner border | | + | +-------------------------------------+ | + | | Menu Bar (optional, 20px) | | + | +-------------------------------------+ | + | | | | + | | Content Area | | + | | | | + | | | S | | S = vertical scrollbar + | | | B | | (16px wide) + | +-------------------------------------+ | + | | Horizontal Scrollbar (optional) | | 16px tall + | +-------------------------------------+ | + | 4px outer border | + +-------------------------------------------+ +.endcode + +Chrome constants are compile-time defines: + +.code + CHROME_BORDER_WIDTH = 4px + CHROME_TITLE_HEIGHT = 20px + CHROME_INNER_BORDER = 2px + CHROME_MENU_HEIGHT = 20px + SCROLLBAR_WIDTH = 16px + CHROME_CLOSE_BTN_SIZE = 16px +.endcode + +.h2 Hit Test Regions + +wmHitTest() iterates the stack front-to-back and returns a hit-part identifier: HIT_CONTENT, HIT_TITLE, HIT_CLOSE, HIT_RESIZE, HIT_MENU, HIT_VSCROLL, HIT_HSCROLL, HIT_MINIMIZE, HIT_MAXIMIZE. Resize edge detection returns a bitmask of RESIZE_LEFT, RESIZE_RIGHT, RESIZE_TOP, RESIZE_BOTTOM (corners combine two edges). + +.h2 Menu System + +.index Menus +.index Submenus + +Menus use fixed-size arrays with inline char buffers (no heap strings). Up to 8 menus per bar, items dynamically allocated. Supports cascading submenus via MenuItemT.subMenu pointer. Item types: normal, checkbox, radio. Separators are non-interactive items. The popup state (PopupStateT) tracks a stack of parent frames for cascading submenu nesting. + +.h2 Minimized Windows + +Minimized windows display as 64x64 icons at the bottom of the screen with beveled borders, similar to a classic desktop icon bar. Icons show a scaled-down preview of the window's content buffer, refreshed one per frame in a round-robin fashion to amortize the scaling cost. + +.topic arch.widgets +.title Widget System +.toc 0 Widget System +.index Widgets +.index WidgetT +.index WidgetClassT +.index Layout Engine +.index Widget API + +.h1 Widget System + +The widget system (dvxWidget.h) is a retained-mode toolkit layered on top of the window manager. Widgets form a tree rooted at a per-window VBox container. + +.h2 WidgetT Base Structure + +Every widget shares the same WidgetT struct. The type field is a runtime-assigned integer ID. The wclass pointer references the widget's WidgetClassT vtable. Widget-specific private data is stored in w->data (opaque void*). + +Tree linkage: parent, firstChild, lastChild, nextSibling. No prevSibling -- this halves pointer overhead and removal is still O(n) for typical tree depths of 5-10. + +.h2 Layout Engine + +.index Layout +.index Flexbox + +Two-pass flexbox-like algorithm: + +.list +.item Bottom-up (calcMinSize) -- compute minimum sizes for every widget, starting from leaves. +.item Top-down (layout) -- allocate space within available bounds, distributing extra space according to weight values (0 = fixed, 100 = normal stretch). +.endlist + +Size hints use a tagged encoding: the top 2 bits of an int32_t select the unit (pixels, character widths, or percentage of parent), the low 30 bits hold the value. Macros: wgtPixels(v), wgtChars(v), wgtPercent(v). + +.h2 Widget Class Dispatch (WidgetClassT) + +Each widget type provides a WidgetClassT with a handlers[] array indexed by stable method IDs. Method IDs are never reordered or reused -- new methods append at the end. This provides ABI-stable dispatch so that widget DXEs compiled against an older DVX version continue to work. + +Methods include: PAINT, PAINT_OVERLAY, CALC_MIN_SIZE, LAYOUT, ON_MOUSE, ON_KEY, ON_ACCEL_ACTIVATE, DESTROY, GET_TEXT, SET_TEXT, POLL, and more (21 defined, room for 32). + +.h3 Class Flags + +.table + Flag Meaning + ---- ------- + WCLASS_FOCUSABLE Can receive keyboard focus (Tab navigation) + WCLASS_HORIZ_CONTAINER Lays out children horizontally (HBox) + WCLASS_PAINTS_CHILDREN Widget handles child rendering itself + WCLASS_SCROLLABLE Accepts mouse wheel events + WCLASS_SCROLL_CONTAINER ScrollPane -- scrolling viewport + WCLASS_NEEDS_POLL Needs periodic polling (e.g. AnsiTerm comms) + WCLASS_SWALLOWS_TAB Tab key goes to widget, not focus navigation + WCLASS_PRESS_RELEASE Click = press + release (buttons) +.endtable + +.h2 Available Widget Types + +Each widget is a separate .wgt DXE module. 29 widget types are included: + +.table + Widget Description + ------ ----------- + Box (VBox/HBox) Vertical and horizontal layout containers + Button Clickable push button with label + Canvas Raw drawing surface for custom painting + Checkbox Boolean toggle with checkmark + ComboBox Text input with dropdown list + DataCtrl Data-bound control for database operations + DbGrid Database grid (tabular data display) + Dropdown Dropdown selection list + Image Static image display + ImageButton Button with bitmap icon + Label Static text label + ListBox Scrollable selection list + ListView Multi-column list with headers and sorting + ProgressBar Determinate progress indicator + Radio Radio button (mutual exclusion group) + ScrollPane Scrollable viewport container + Separator Visual divider line + Slider Value selection via draggable thumb + Spacer Empty space for layout + Spinner Numeric input with up/down arrows + Splitter Resizable split pane + StatusBar Window status bar with sections + TabControl Tabbed page container + Terminal (AnsiTerm) ANSI terminal emulator widget + TextInput Single-line text entry field + Timer Periodic timer events + Toolbar Toolbar with icon buttons + TreeView Hierarchical tree display + WrapBox Flow layout (wrapping horizontal container) +.endtable + +.h2 Widget API Registry + +Each widget DXE registers a small API struct under a name during wgtRegister(). Callers retrieve it via wgtGetApi("button") and cast to the widget-specific API type. Per-widget headers provide typed accessors so callers avoid manual casts. Adding a new widget requires zero changes to the core. + +.h2 Widget Interface Descriptors (WgtIfaceT) + +.index WgtIfaceT + +Each widget can register an interface descriptor that describes its BASIC-facing properties, methods, and events. These descriptors are used by the form runtime and IDE for generic dispatch and property panel enumeration. Properties have typed getters/setters (WGT_IFACE_STRING, WGT_IFACE_INT, WGT_IFACE_BOOL, WGT_IFACE_ENUM). + +.topic arch.dxe +.title DXE Module System +.toc 0 DXE Module System +.index DXE +.index DXE3 +.index Modules +.index Dynamic Loading + +.h1 DXE Module System + +DVX uses DJGPP's DXE3 (Dynamic eXtension) format for all loadable modules. DXE3 supports RTLD_GLOBAL symbol sharing -- symbols exported by one module are visible to all subsequently loaded modules. This is critical: widget DXEs call core API functions (e.g. rectFill, wgtInvalidate) that are exported by the core library DXE. + +.h2 Module Types + +.table + Extension Directory Purpose Examples + --------- --------- ------- -------- + .lib LIBS/ Core libraries loaded first. Provide infrastructure APIs. libtasks.lib, libdvx.lib, dvxshell.lib + .wgt WIDGETS/ Widget type plugins. Each exports wgtRegister(). button.wgt, listview.wgt, terminal.wgt + .app APPS/*/ Application modules. Each exports appDescriptor and appMain(). Loaded on demand by the shell. progman.app, notepad.app, cpanel.app +.endtable + +.h2 Boot Sequence + +.index Boot Sequence + +.code + dvx.exe (loader) + | + +-- Enter VGA mode 13h, display splash screen with progress bar + | + +-- Scan LIBS/ for *.lib, WIDGETS/ for *.wgt + | + +-- Read .dep files for each module (dependency base names) + | + +-- Topological sort: load modules in dependency order + | - dlopen() with RTLD_GLOBAL + | - Each .wgt that exports wgtRegister() has it called + | + +-- Find and call shellMain() (exported by dvxshell.lib) + | + +-- dvxInit() -- video mode, input, font, colors, cursors + | + +-- Load desktop app (progman.app) + | + +-- Main loop: + dvxUpdate() -> tsYield() -> shellReapApps() +.endcode + +.h2 Application Lifecycle + +Two kinds of DXE apps: + +.h3 Callback-only (hasMainLoop = false) + +appMain() creates windows, registers callbacks, and returns. The app lives through GUI callbacks driven by the shell's main loop. Lifecycle ends when the last window is closed. No extra task stack needed -- simpler and cheaper. + +.h3 Main-loop (hasMainLoop = true) + +A dedicated cooperative task is created. appMain() runs in that task with its own loop, calling tsYield() to share CPU. Needed for apps with continuous work (terminal emulators, games). Lifecycle ends when appMain() returns. + +.h2 Crash Recovery + +.index Crash Recovery + +The platform layer installs signal handlers for SIGSEGV, SIGFPE, SIGILL. On crash, the handler logs platform-specific diagnostics (register dump on DJGPP), then longjmps back to the shell's main loop. The crashed app is killed; other apps and the shell survive. This provides Windows 3.1-style fault tolerance. + +.h2 Per-App Memory Tracking + +.index Memory Tracking + +All allocations route through dvxMalloc/dvxFree wrappers that prepend a 16-byte header recording the owning app ID and allocation size. The Task Manager displays per-app memory usage, and leaks are detected at app termination. + +.topic arch.events +.title Event Model +.toc 0 Event Model +.index Events +.index Input +.index Mouse +.index Keyboard +.index Polling +.index Cooperative + +.h1 Event Model + +DVX uses a cooperative polling model. The main loop (dvxRun / dvxUpdate) runs this cycle each frame: + +.list +.item Poll mouse -- platformMousePoll() returns position and button bitmask. Compare with previous frame for press/release edge detection. +.item Poll keyboard -- platformKeyboardRead() returns ASCII + scancode. Non-blocking; returns false if buffer is empty. +.item Dispatch to focused window -- the event loop fires window callbacks (onKey, onMouse, etc.) on the focused window. If the window has a widget tree, the widget system's installed handlers dispatch to individual widgets. +.item Compositor pass -- merge dirty rects, composite, flush to LFB. +.item Yield -- platformYield() or idle callback. +.endlist + +.h2 Event Dispatch Chain + +.index Event Dispatch + +.code + Mouse/Keyboard Input + | + Global handlers (Ctrl+Esc, modal filter) + | + Accelerator table check (focused window) + | + Window callback (onMouse / onKey) + | + [If widget tree installed:] + | + widgetOnMouse / widgetOnKey + | + Widget hit test (widgetHitTest) + | + wclsOnMouse / wclsOnKey (vtable dispatch) + | + Universal callbacks (onClick, onChange, etc.) +.endcode + +.h2 Accelerator Tables + +.index Accelerator Tables + +Per-window accelerator tables map key + modifier combinations to command IDs. The runtime normalizes key/modifier at registration time (uppercase key, strip shift from modifiers) so matching at dispatch time is two integer comparisons per entry. Matched accelerators fire the window's onMenu callback with the command ID, unifying the menu and hotkey code paths. + +.h2 Mouse Cursor + +.index Cursor + +Software-rendered cursor using the classic AND/XOR mask approach. Seven cursor shapes are compiled in: arrow, horizontal resize, vertical resize, NW-SE diagonal resize, NE-SW diagonal resize, busy (hourglass), and crosshair. The cursor is painted into the backbuffer on top of the composited frame and the affected region is flushed to the LFB each frame. + +.h2 Double-Click Detection + +.index Double-Click + +Timestamp-based: two clicks on the same target (title bar, minimized icon, close gadget) within the configurable double-click interval trigger the double-click action. Separate tracking for each target type. + +.topic arch.fonts +.title Font System +.toc 0 Font System +.index Fonts +.index Bitmap Font +.index BitmapFontT +.index Text Rendering +.index CP437 + +.h1 Font System + +DVX uses fixed-width 8-pixel-wide bitmap fonts only. One size is provided: 8x16, matching the standard VGA ROM font and CP437 encoding (256 glyphs). + +.h2 BitmapFontT + +.code + typedef struct { + int32_t charWidth; // fixed width per glyph (always 8) + int32_t charHeight; // 16 + int32_t firstChar; // typically 0 + int32_t numChars; // typically 256 + const uint8_t *glyphData; // packed 1bpp, charHeight bytes per glyph + } BitmapFontT; +.endcode + +Design rationale: + +.list +.item Character positions are pure multiplication (x = col * 8). +.item Glyph lookup is a single array index. +.item Each scanline of a glyph is exactly one byte (1bpp at 8 pixels wide). +.item No glyph-width tables, kerning, or per-character positioning needed. +.item 8-pixel width aligns with byte boundaries -- no bit shifting in per-scanline rendering. +.endlist + +.h2 Text Rendering Functions + +drawChar() -- Renders a single character. Supports opaque (background fill) and transparent modes. + +drawTextN() -- Optimized batch rendering for a known character count. Clips once for the entire run, fills background in a single rectFill, then overlays glyph foreground pixels. Significantly faster than per-character rendering for long runs. + +drawTermRow() -- Renders an 80-column terminal row in a single pass, with per-cell foreground/background from a 16-color palette, blink attribute support, and cursor rendering. Exists because per-character terminal rendering is unacceptably slow on target hardware. + +drawTextAccel() -- Renders text with & accelerator markers. The character after & is underlined to indicate the keyboard shortcut. + +.h2 Performance Optimization + +AppContextT stores a fixed-point 16.16 reciprocal of font.charHeight (charHeightRecip) so that dividing by charHeight (for pixel-to-row conversion in terminal/text widgets) becomes a multiply+shift instead of an integer divide, which costs 40+ cycles on a 486. + +.topic arch.colors +.title Color System +.toc 0 Color System +.index Colors +.index Pixel Format +.index PixelFormatT +.index ColorSchemeT +.index Theming +.index Bevel + +.h1 Color System + +.h2 Pixel Format + +PixelFormatT describes the active VESA mode's pixel encoding. Populated once from the VBE mode info block. Stores shift, mask, and bit count for each channel so packColor() can convert RGB to native format with shift-and-mask arithmetic -- no per-pixel computation. + +Supported depths: + +.table + Depth Bytes/Pixel Notes + ----- ----------- ----- + 8 bpp 1 Palette mode. Nearest-index via 6x6x6 color cube + grey ramp. + 15 bpp 2 5-5-5 RGB (1 bit unused). + 16 bpp 2 5-6-5 RGB. + 32 bpp 4 8-8-8 RGB (8 bits unused). +.endtable + +.h2 ColorSchemeT -- Theming + +All 20 UI colors are pre-packed into display pixel format at init time. Every color is a uint32_t that can be written directly to the framebuffer with zero per-pixel conversion. The scheme must be regenerated on video mode change, but mode changes require re-init anyway. + +Color roles mirror classic Motif/Windows 3.x conventions: + +.list +.item desktop -- desktop background +.item windowFace, windowHighlight, windowShadow -- window chrome bevel triplet +.item activeTitleBg/Fg, inactiveTitleBg/Fg -- focused vs. unfocused title bar +.item contentBg/Fg -- window content area +.item menuBg/Fg, menuHighlightBg/Fg -- menus +.item buttonFace -- button background +.item scrollbarBg/Fg/Trough -- scrollbar components +.item cursorFg/Bg -- mouse cursor colors +.endlist + +Source RGB values are kept in AppContextT.colorRgb[] for theme save/load. Themes are stored as INI files with a [colors] section. The API provides dvxLoadTheme(), dvxSaveTheme(), dvxSetColor(), and dvxResetColorScheme(). + +.h2 Bevel Styles + +Bevels are the defining visual element of the Motif aesthetic. Convenience macros create bevel style descriptors by swapping highlight and shadow colors: + +.code + BEVEL_RAISED(colorScheme, borderWidth) -- raised 3D look + BEVEL_SUNKEN(colorScheme, face, borderWidth) -- sunken/inset look + BEVEL_TROUGH(colorScheme) -- 1px scrollbar trough + BEVEL_SB_BUTTON(colorScheme) -- scrollbar button +.endcode + +.topic arch.platform +.title Platform Layer +.toc 0 Platform Layer +.index Platform Layer +.index dvxPlatform +.index VESA +.index VBE +.index INT 33h +.index INT 16h +.index Assembly +.index rep stosl +.index rep movsd + +.h1 Platform Layer + +All OS-specific and CPU-specific code is isolated behind dvxPlatform.h. To port DVX, implement a new dvxPlatformXxx.c against this header. + +.h2 Implementations + +.table + File Target Details + ---- ------ ------- + dvxPlatformDos.c DJGPP/DPMI Real VESA VBE, INT 33h mouse, INT 16h keyboard, rep movsd/rep stosl asm spans, DPMI physical memory mapping for LFB, INT 9 hook for key-up, CuteMouse Wheel API. +.endtable + +.h2 Abstraction Areas + +.h3 Video + +platformVideoInit() -- mode probe and framebuffer setup. platformVideoShutdown() -- restore previous mode. platformVideoEnumModes() -- enumerate available modes. + +.h3 Framebuffer Flush + +platformFlushRect() -- copy dirty rect from backBuf to LFB. On DOS, each scanline uses rep movsd for near-optimal aligned 32-bit writes over the PCI bus. + +.h3 Optimized Memory Spans + +Six functions: platformSpanFill8/16/32() and platformSpanCopy8/16/32(). Called once per scanline of every rectangle fill, blit, and text draw. On DOS these use inline assembly for critical inner loops. + +.h3 Mouse Input + +Polling model. platformMousePoll() returns position and button bitmask. Wheel support via CuteMouse API. + +.h3 Keyboard Input + +platformKeyboardRead() -- non-blocking key read. platformKeyUpRead() -- key release detection (requires INT 9 hook on DOS). platformAltScanToChar() -- scancode-to-ASCII lookup for Alt+key combinations. + +.h3 Crash Recovery + +platformInstallCrashHandler() -- signal handlers + longjmp for fault tolerance. + +.h3 DXE Support + +platformRegisterDxeExports() -- register C runtime and platform symbols for DXE resolution. platformRegisterSymOverrides() -- register function pointer overrides for module loader. + +.topic arch.build +.title Build System +.toc 0 Build System +.index Build +.index Makefile +.index Cross-Compilation +.index dxe3gen +.index mkcd.sh +.index ISO + +.h1 Build System + +.h2 Cross-Compilation + +DVX is cross-compiled from Linux using a DJGPP cross-compiler (i586-pc-msdosdjgpp-gcc). The top-level Makefile orchestrates building all subsystems in dependency order. + +.code + make -- build everything + ./mkcd.sh -- build + create ISO for 86Box +.endcode + +.h2 Build Targets + +.code + all: core tasks loader texthelp listhelp tools widgets shell taskmgr serial sql apps +.endcode + +.table + Target Output Description + ------ ------ ----------- + core bin/libs/libdvx.lib GUI core library (draw, comp, wm, app, widget infrastructure) + tasks bin/libs/libtasks.lib Cooperative task switcher + loader bin/dvx.exe Bootstrap loader (the DOS executable) + widgets bin/widgets/*.wgt 29 widget type plugins + shell bin/libs/dvxshell.lib DVX Shell (app management, desktop) + taskmgr bin/libs/taskmgr.lib Task Manager (loaded as a separate DXE) + texthelp shared library Shared text editing helpers (clipboard, word boundaries) + listhelp shared library Shared dropdown/list helpers + apps bin/apps/*/*.app Application modules (progman, notepad, clock, etc.) + tools bin/dvxres Resource compiler (runs on Linux, builds resource sections into DXEs) + serial serial DXE libs UART driver, HDLC packets, security, seclink + sql SQL DXE lib SQLite integration +.endtable + +.h2 DXE3 Build Process + +Each DXE module is compiled to an object file with GCC, then linked with dxe3gen: + +.code + # Compile + i586-pc-msdosdjgpp-gcc -O2 -march=i486 -mtune=i586 -c -o widget.o widget.c + + # Link as DXE with exported symbols + dxe3gen -o widget.wgt -E _wgtRegister -U widget.o + + # Optionally append resources + dvxres build widget.wgt widget.res +.endcode + +The -E flag specifies exported symbols (prefixed with underscore per DJGPP convention). -U marks unresolved symbols as OK (they'll be resolved at load time from previously loaded DXEs). + +.h2 Deployment (mkcd.sh) + +.list +.item Runs make all. +.item Verifies critical outputs exist (dvx.exe, libtasks.lib, libdvx.lib, dvxshell.lib). +.item Counts widget modules. +.item Creates an ISO 9660 image from bin/ using mkisofs: -iso-level 1 (strict 8.3 filenames for DOS), -J (Joliet extensions for long names), -V DVX (volume label). +.item Places the ISO at ~/.var/app/net._86box._86Box/data/86Box/dvx.iso for 86Box to mount as CD-ROM. +.endlist + +.h2 Compiler Flags + +.code + -O2 Optimization level 2 + -march=i486 486 instruction set baseline + -mtune=i586 Optimize scheduling for Pentium + -Wall -Wextra Full warnings +.endcode + +.h2 Directory Layout + +.code + dvxgui/ + +-- core/ Core library sources (dvxVideo, dvxDraw, dvxComp, dvxWm, dvxApp, widget infra) + | +-- platform/ Platform abstraction (dvxPlatform.h, dvxPlatformDos.c) + | +-- thirdparty/ stb_image, stb_ds, stb_image_write + +-- loader/ Bootstrap loader (dvx.exe) + +-- tasks/ Cooperative task switcher (libtasks.lib) + +-- shell/ DVX Shell (dvxshell.lib) + +-- widgets/ Widget DXE modules (*.wgt), each in its own subdirectory + | +-- box/ VBox/HBox layout containers + | +-- button/ Push button + | +-- textInput/ Text entry field + | +-- listView/ Multi-column list + | +-- ... (29 widget types total) + +-- texthelp/ Shared text editing helpers + +-- listhelp/ Shared dropdown/list helpers + +-- apps/ Application DXE modules (*.app) + | +-- progman/ Program Manager (desktop) + | +-- notepad/ Text editor + | +-- cpanel/ Control Panel + | +-- imgview/ Image viewer + | +-- clock/ Clock + | +-- dvxdemo/ Demo / showcase app + | +-- dvxbasic/ DVX BASIC compiler and VM + +-- tools/ Build tools (dvxres resource compiler) + +-- rs232/ ISR-driven UART driver + +-- packet/ HDLC framing, CRC-16, sliding window + +-- security/ DH key exchange, XTEA cipher, DRBG RNG + +-- seclink/ Encrypted channel wrapper + +-- serial/ Combined serial stack DXE + +-- proxy/ Linux proxy (86Box <-> secLink <-> telnet) + +-- sql/ SQLite integration + +-- bin/ Build output (dvx.exe, libs/, widgets/, apps/, config/) + +-- obj/ Intermediate object files + +-- docs/ Documentation +.endcode diff --git a/docs/src/dvx_widget_reference.dvxhelp b/docs/src/dvx_widget_reference.dvxhelp new file mode 100644 index 0000000..9bab352 --- /dev/null +++ b/docs/src/dvx_widget_reference.dvxhelp @@ -0,0 +1,1801 @@ +.topic widget.base +.title Base WidgetT (Common Properties, Events, and Operations) +.toc 0 Base WidgetT +.default +.index WidgetT +.index Widget Base +.index Common Properties +.index Common Events + +.h1 DVX Widget Reference + +Complete reference for the DVX GUI widget toolkit. All widgets are implemented as dynamically loaded DXE modules. They are created via convenience macros that wrap the per-widget API function tables. The base WidgetT structure is defined in core/dvxWidget.h; individual widget headers live in widgets/. + +.h2 Base WidgetT (Common Properties, Events, and Operations) + +Every widget inherits from the WidgetT structure defined in core/dvxWidget.h. The fields and callbacks listed here are available on all widget types. + +.h3 Common Properties + +.table + Field Type Description + ----- ---- ----------- + name char[32] Widget name for lookup via wgtFind(). + x, y, w, h int32_t Computed geometry relative to the window content area (set by layout). + minW, minH int32_t (tagged) Minimum size hints. Use wgtPixels(), wgtChars(), or wgtPercent(). 0 = auto. + maxW, maxH int32_t (tagged) Maximum size constraints. 0 = no limit. + prefW, prefH int32_t (tagged) Preferred size. 0 = auto. + weight int32_t Extra-space distribution weight. 0 = fixed, 100 = normal. A widget with weight=200 gets twice the extra space of one with weight=100. + align WidgetAlignE Main-axis alignment for children: AlignStartE, AlignCenterE, AlignEndE. + spacing int32_t (tagged) Spacing between children (containers only). 0 = default. + padding int32_t (tagged) Internal padding (containers only). 0 = default. + fgColor uint32_t Foreground color override. 0 = use color scheme default. + bgColor uint32_t Background color override. 0 = use color scheme default. + visible bool Visibility state. + enabled bool Enabled state. Disabled widgets are grayed out and ignore input. + readOnly bool Read-only mode: allows scrolling/selection but blocks editing. + swallowTab bool When true, Tab key goes to the widget instead of navigating focus. + accelKey char Lowercase accelerator character. 0 if none. + tooltip const char * Tooltip text. NULL = none. Caller owns the string. + contextMenu MenuT * Right-click context menu. NULL = none. Caller owns. + userData void * Application-defined user data pointer. +.endtable + +.h3 Size Specification Macros + +.index wgtPixels +.index wgtChars +.index wgtPercent + +.table + Macro Description + ----- ----------- + wgtPixels(v) Size in pixels. + wgtChars(v) Size in character widths (multiplied by font charWidth). + wgtPercent(v) Size as a percentage of parent dimension. +.endtable + +.h3 Common Events (Callbacks) + +These callback function pointers are available on every WidgetT. Set them directly on the widget struct. + +.index onClick +.index onChange +.index onKeyPress +.index onKeyDown +.index onMouseDown + +.table + Callback Signature Description + -------- --------- ----------- + onClick void (*)(WidgetT *w) Fires on mouse click / activation. + onDblClick void (*)(WidgetT *w) Fires on double-click. + onChange void (*)(WidgetT *w) Fires when the widget's value changes (text, selection, check state, etc.). + onFocus void (*)(WidgetT *w) Fires when the widget receives keyboard focus. + onBlur void (*)(WidgetT *w) Fires when the widget loses keyboard focus. + onKeyPress void (*)(WidgetT *w, int32_t keyAscii) Fires on a printable key press (ASCII value). + onKeyDown void (*)(WidgetT *w, int32_t keyCode, int32_t shift) Fires on key down (scan code + shift state). + onKeyUp void (*)(WidgetT *w, int32_t keyCode, int32_t shift) Fires on key up. + onMouseDown void (*)(WidgetT *w, int32_t button, int32_t x, int32_t y) Fires on mouse button press. + onMouseUp void (*)(WidgetT *w, int32_t button, int32_t x, int32_t y) Fires on mouse button release. + onMouseMove void (*)(WidgetT *w, int32_t button, int32_t x, int32_t y) Fires on mouse movement over the widget. + onScroll void (*)(WidgetT *w, int32_t delta) Fires on mouse wheel scroll. + onValidate bool (*)(WidgetT *w) Validation callback. Return false to cancel a pending write. +.endtable + +.h3 Common Operations + +.index wgtInitWindow +.index wgtGetContext +.index wgtInvalidate +.index wgtSetText +.index wgtGetText +.index wgtSetEnabled +.index wgtSetFocused +.index wgtSetVisible +.index wgtFind +.index wgtDestroy + +.table + Function Description + -------- ----------- + WidgetT *wgtInitWindow(AppContextT *ctx, WindowT *win) Initialize widgets for a window. Returns the root VBox container. + AppContextT *wgtGetContext(const WidgetT *w) Walk up from any widget to retrieve the AppContextT. + void wgtInvalidate(WidgetT *w) Mark widget for re-layout and repaint. Propagates to ancestors. + void wgtInvalidatePaint(WidgetT *w) Mark widget for repaint only (no layout recalculation). + void wgtSetText(WidgetT *w, const char *text) Set widget text (label, button, textinput, etc.). + const char *wgtGetText(const WidgetT *w) Get widget text. + void wgtSetEnabled(WidgetT *w, bool enabled) Enable or disable a widget. + void wgtSetReadOnly(WidgetT *w, bool readOnly) Set read-only mode. + void wgtSetFocused(WidgetT *w) Set keyboard focus to a widget. + WidgetT *wgtGetFocused(void) Get the currently focused widget. + void wgtSetVisible(WidgetT *w, bool visible) Show or hide a widget. + void wgtSetName(WidgetT *w, const char *name) Set widget name for lookup. + WidgetT *wgtFind(WidgetT *root, const char *name) Find a widget by name in the subtree. + void wgtDestroy(WidgetT *w) Destroy a widget and all its children. + void wgtSetTooltip(WidgetT *w, const char *text) Set tooltip text. Pass NULL to remove. +.endtable + +.hr + +.topic widget.ansiterm +.title AnsiTerm +.toc 0 AnsiTerm +.index AnsiTerm +.index wgtAnsiTerm +.index Terminal +.index VT100 + +.h2 AnsiTerm + +A VT100/ANSI-compatible terminal emulator widget designed for connecting to BBS systems over the serial link. Uses a traditional text-mode cell buffer (character + attribute byte pairs) with the CP437 character set and 16-color CGA palette. Supports cursor movement, screen/line erase, scrolling regions, SGR colors, and scrollback history. Communication is abstracted through read/write function pointers, allowing the terminal to work with raw serial ports, the secLink encrypted channel, or any other byte-oriented transport. + +Header: widgets/widgetAnsiTerm.h + +.h3 Creation + +.code +WidgetT *term = wgtAnsiTerm(parent, 80, 25); +.endcode + +.h3 Macros + +.index wgtAnsiTermWrite +.index wgtAnsiTermClear +.index wgtAnsiTermSetComm +.index wgtAnsiTermSetScrollback +.index wgtAnsiTermPoll +.index wgtAnsiTermRepaint + +.table + Macro Description + ----- ----------- + wgtAnsiTerm(parent, cols, rows) Create an ANSI terminal widget with the given column and row dimensions. + wgtAnsiTermWrite(w, data, len) Write raw bytes into the terminal's ANSI parser. data is a const uint8_t * buffer, len is the byte count. + wgtAnsiTermClear(w) Clear the terminal screen and reset the cursor to the home position. + wgtAnsiTermSetComm(w, ctx, readFn, writeFn) Attach a communication channel. readFn and writeFn are I/O callbacks; ctx is passed as their first argument. + wgtAnsiTermSetScrollback(w, maxLines) Set the maximum number of scrollback lines. Lines scrolled off the top are saved in a circular buffer. + wgtAnsiTermPoll(w) Poll the communication channel for incoming data and feed it into the ANSI parser. + wgtAnsiTermRepaint(w, outY, outH) Fast repaint path that renders dirty rows directly into the window's content buffer, bypassing the widget pipeline. Returns the dirty region via outY/outH. +.endtable + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + Cols Integer Read-only Number of columns. + Rows Integer Read-only Number of rows. + Scrollback Integer Write-only Maximum scrollback lines. +.endtable + +.h3 Methods (BASIC Interface) + +.table + Method Description + ------ ----------- + Clear Clear the terminal screen. + Write Write a string into the terminal. +.endtable + +.h3 Events + +AnsiTerm uses the common events only. No widget-specific events are defined. + +.hr + +.topic widget.box +.title Box (VBox / HBox / Frame) +.toc 0 Layout Containers +.toc 1 Box (VBox / HBox / Frame) +.index VBox +.index HBox +.index Frame +.index wgtVBox +.index wgtHBox +.index wgtFrame +.index Layout + +.h2 Box (VBox / HBox / Frame) + +Container widgets that arrange their children in a vertical column (VBox), horizontal row (HBox), or a titled group box (Frame). These are the primary layout building blocks. Children are laid out using a flexbox-like algorithm with weight-based extra-space distribution. + +Header: widgets/widgetBox.h + +.h3 Creation + +.table + Macro Description + ----- ----------- + wgtVBox(parent) Create a vertical box container. Children are stacked top to bottom. + wgtHBox(parent) Create a horizontal box container. Children are placed left to right. + wgtFrame(parent, title) Create a titled group box (a VBox with a border and label). +.endtable + +.h3 Properties + +Box containers use the common WidgetT fields for layout control: + +.table + Property Description + -------- ----------- + align Main-axis alignment of children. HBox: Start=left, Center=center, End=right. VBox: Start=top, Center=center, End=bottom. + spacing Gap between children (tagged size). + padding Internal padding around children (tagged size). + weight Controls how the box itself stretches within its parent. +.endtable + +.h3 Events + +Containers use the common events only. No widget-specific events. + +.hr + +.topic widget.button +.title Button +.toc 1 Button +.index Button +.index wgtButton + +.h2 Button + +A push button with a text label. Fires onClick when pressed and released. Supports keyboard activation via accelerator keys. + +Header: widgets/widgetButton.h + +.h3 Creation + +.code +WidgetT *btn = wgtButton(parent, "OK"); +.endcode + +.h3 Macro + +.table + Macro Description + ----- ----------- + wgtButton(parent, text) Create a push button with the given label text. +.endtable + +.h3 Properties + +Uses common WidgetT properties. Set accelKey for keyboard shortcut. Use wgtSetText() / wgtGetText() to change the label. + +.h3 Events + +.table + Callback Description + -------- ----------- + onClick Fires when the button is clicked (press + release). +.endtable + +.hr + +.topic widget.label +.title Label +.toc 1 Label +.index Label +.index wgtLabel +.index wgtLabelSetAlign + +.h2 Label + +A static text label. Does not accept keyboard focus. Typically used to describe other widgets. Supports text alignment and accelerator keys (with WCLASS_FOCUS_FORWARD, the accelerator moves focus to the next focusable sibling). + +Header: widgets/widgetLabel.h + +.h3 Creation + +.code +WidgetT *lbl = wgtLabel(parent, "Name:"); +.endcode + +.h3 Macros + +.table + Macro Description + ----- ----------- + wgtLabel(parent, text) Create a text label. + wgtLabelSetAlign(w, align) Set the text alignment (AlignStartE, AlignCenterE, AlignEndE). +.endtable + +.h3 Properties + +Use wgtSetText() / wgtGetText() to change the text. Set accelKey for accelerator support (focus forwards to next focusable widget). + +.h3 Events + +Labels use the common events only. Typically no callbacks are set on labels. + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + Alignment Enum (Left, Center, Right) Read/Write Text alignment within the label. +.endtable + +.hr + +.topic widget.textinput +.title TextInput / TextArea +.toc 0 Input Widgets +.toc 1 TextInput / TextArea +.index TextInput +.index TextArea +.index wgtTextInput +.index wgtTextArea +.index wgtPasswordInput +.index wgtMaskedInput + +.h2 TextInput / TextArea + +Single-line text input, password input, masked input, and multi-line text area with optional syntax colorization, line numbers, find/replace, and gutter decorators. + +Header: widgets/widgetTextInput.h + +.h3 Creation + +.table + Macro Description + ----- ----------- + wgtTextInput(parent, maxLen) Create a single-line text input. maxLen is the maximum number of characters. + wgtPasswordInput(parent, maxLen) Create a password input (characters displayed as bullets). + wgtMaskedInput(parent, mask) Create a masked input field. The mask string defines the input format. + wgtTextArea(parent, maxLen) Create a multi-line text area. +.endtable + +.h3 Methods (TextArea-specific) + +.index wgtTextAreaSetColorize +.index wgtTextAreaGoToLine +.index wgtTextAreaSetAutoIndent +.index wgtTextAreaSetShowLineNumbers +.index wgtTextAreaFindNext +.index wgtTextAreaReplaceAll + +.table + Macro Description + ----- ----------- + wgtTextAreaSetColorize(w, fn, ctx) Set a syntax colorization callback. The callback receives each line and fills a color index array. Color indices: 0=default, 1=keyword, 2=string, 3=comment, 4=number, 5=operator, 6=type/builtin, 7=reserved. + wgtTextAreaGoToLine(w, line) Scroll to and place the cursor on the given line number. + wgtTextAreaSetAutoIndent(w, enable) Enable or disable automatic indentation on newline. + wgtTextAreaSetShowLineNumbers(w, show) Show or hide line numbers in the gutter. + wgtTextAreaSetCaptureTabs(w, capture) When true, Tab key inserts a tab/spaces instead of moving focus. + wgtTextAreaSetTabWidth(w, width) Set the tab stop width in characters. + wgtTextAreaSetUseTabChar(w, useChar) When true, insert literal tab characters; when false, insert spaces. + wgtTextAreaFindNext(w, needle, caseSens, fwd) Search for the next occurrence. Returns true if found. + wgtTextAreaReplaceAll(w, needle, repl, caseSens) Replace all occurrences. Returns the number of replacements made. + wgtTextAreaSetLineDecorator(w, fn, ctx) Set a gutter line decorator callback. The callback returns a color and receives the line number, a color output pointer, and the user context. + wgtTextAreaGetCursorLine(w) Get the current cursor line number. + wgtTextAreaSetGutterClick(w, fn) Set a callback for gutter clicks (e.g. for breakpoint toggling). Callback receives the widget and line number. +.endtable + +.h3 Events + +.table + Callback Description + -------- ----------- + onChange Fires when the text content changes. + onKeyPress Fires on each key press (ASCII value). + onValidate Called before committing a change. Return false to cancel. +.endtable + +.hr + +.topic widget.checkbox +.title Checkbox +.toc 1 Checkbox +.index Checkbox +.index wgtCheckbox +.index wgtCheckboxIsChecked +.index wgtCheckboxSetChecked + +.h2 Checkbox + +A toggle control with a text label. Clicking toggles between checked and unchecked states. + +Header: widgets/widgetCheckbox.h + +.h3 Creation + +.code +WidgetT *cb = wgtCheckbox(parent, "Enable logging"); +.endcode + +.h3 Macros + +.table + Macro Description + ----- ----------- + wgtCheckbox(parent, text) Create a checkbox with the given label text. + wgtCheckboxIsChecked(w) Returns true if the checkbox is checked. + wgtCheckboxSetChecked(w, checked) Set the checked state programmatically. +.endtable + +.h3 Events + +.table + Callback Description + -------- ----------- + onClick Fires when clicked (after toggle). + onChange Fires when the checked state changes. +.endtable + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + Value Boolean Read/Write Whether the checkbox is checked. +.endtable + +.hr + +.topic widget.radio +.title Radio Button +.toc 1 Radio Button +.index Radio +.index RadioGroup +.index wgtRadio +.index wgtRadioGroup +.index wgtRadioGroupSetSelected +.index wgtRadioGetIndex + +.h2 Radio Button + +A mutually exclusive selection control. Radio buttons must be placed inside a radio group container. Only one radio button within a group can be selected at a time. + +Header: widgets/widgetRadio.h + +.h3 Creation + +.code +WidgetT *grp = wgtRadioGroup(parent); +WidgetT *r1 = wgtRadio(grp, "Option A"); +WidgetT *r2 = wgtRadio(grp, "Option B"); +.endcode + +.h3 Macros + +.table + Macro Description + ----- ----------- + wgtRadioGroup(parent) Create a radio group container. + wgtRadio(parent, text) Create a radio button inside a group. + wgtRadioGroupSetSelected(w, idx) Set the selected radio button by index within the group. + wgtRadioGetIndex(w) Get the index of the currently selected radio button. +.endtable + +.h3 Events + +.table + Callback Description + -------- ----------- + onClick Fires on the radio button when clicked. + onChange Fires when the selection changes. +.endtable + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + Value Integer Read-only Index of the currently selected radio button in the group. +.endtable + +.h3 Methods (BASIC Interface) + +.table + Method Description + ------ ----------- + SetSelected Set the selected radio button by index. +.endtable + +.hr + +.topic widget.dropdown +.title Dropdown +.toc 1 Dropdown +.index Dropdown +.index wgtDropdown +.index wgtDropdownSetItems +.index wgtDropdownGetSelected +.index wgtDropdownSetSelected + +.h2 Dropdown + +A drop-down list that displays a single selected item and expands to show all options when clicked. Read-only selection (the user cannot type into it). + +Header: widgets/widgetDropdown.h + +.h3 Creation + +.code +WidgetT *dd = wgtDropdown(parent); +const char *items[] = { "Red", "Green", "Blue" }; +wgtDropdownSetItems(dd, items, 3); +.endcode + +.h3 Macros + +.table + Macro Description + ----- ----------- + wgtDropdown(parent) Create a dropdown list. + wgtDropdownSetItems(w, items, count) Set the list of items. items is a const char ** array. + wgtDropdownGetSelected(w) Get the index of the selected item (-1 if none). + wgtDropdownSetSelected(w, idx) Set the selected item by index. +.endtable + +.h3 Events + +.table + Callback Description + -------- ----------- + onChange Fires when the selected item changes. +.endtable + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + ListIndex Integer Read/Write Index of the currently selected item. +.endtable + +.hr + +.topic widget.combobox +.title ComboBox +.toc 1 ComboBox +.index ComboBox +.index wgtComboBox +.index wgtComboBoxSetItems +.index wgtComboBoxGetSelected +.index wgtComboBoxSetSelected + +.h2 ComboBox + +A combination of a text input and a dropdown list. The user can either type a value or select from a list of predefined options. Unlike Dropdown, the text field is editable. + +Header: widgets/widgetComboBox.h + +.h3 Creation + +.code +WidgetT *cb = wgtComboBox(parent, 128); +const char *items[] = { "Arial", "Courier", "Times" }; +wgtComboBoxSetItems(cb, items, 3); +.endcode + +.h3 Macros + +.table + Macro Description + ----- ----------- + wgtComboBox(parent, maxLen) Create a combo box. maxLen is the maximum text input length. + wgtComboBoxSetItems(w, items, count) Set the dropdown items. + wgtComboBoxGetSelected(w) Get the index of the selected item (-1 if the text does not match any item). + wgtComboBoxSetSelected(w, idx) Set the selected item by index. +.endtable + +.h3 Events + +.table + Callback Description + -------- ----------- + onChange Fires when the text or selection changes. +.endtable + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + ListIndex Integer Read/Write Index of the currently selected item. +.endtable + +.hr + +.topic widget.datactrl +.title DataCtrl +.toc 0 Data Widgets +.toc 1 DataCtrl +.index DataCtrl +.index wgtDataCtrl +.index Database Binding +.index Master-Detail + +.h2 DataCtrl + +A VB3-style Data control for database binding. Displays a visible navigation bar that connects to a SQLite database via dvxSql* functions. Reads all rows from the RecordSource query into an in-memory cache for bidirectional navigation. Fires Reposition events when the cursor moves so bound controls can update. Supports master-detail linking between Data controls. + +Header: widgets/widgetDataCtrl.h + +.h3 Creation + +.code +WidgetT *data = wgtDataCtrl(parent); +.endcode + +.h3 Macros + +.index wgtDataCtrlRefresh +.index wgtDataCtrlMoveFirst +.index wgtDataCtrlMoveNext +.index wgtDataCtrlGetField +.index wgtDataCtrlSetField +.index wgtDataCtrlUpdate +.index wgtDataCtrlAddNew +.index wgtDataCtrlDelete + +.table + Macro Description + ----- ----------- + wgtDataCtrl(parent) Create a Data control. + wgtDataCtrlRefresh(w) Re-execute the RecordSource query and rebuild the row cache. + wgtDataCtrlMoveFirst(w) Move the cursor to the first row. + wgtDataCtrlMovePrev(w) Move the cursor to the previous row. + wgtDataCtrlMoveNext(w) Move the cursor to the next row. + wgtDataCtrlMoveLast(w) Move the cursor to the last row. + wgtDataCtrlGetField(w, colName) Get the value of a column in the current row. Returns const char *. + wgtDataCtrlSetField(w, colName, value) Set the value of a column in the current row (marks the row dirty). + wgtDataCtrlUpdateRow(w) Write the current row's pending changes back to the database. + wgtDataCtrlUpdate(w) Flush all pending changes to the database. + wgtDataCtrlAddNew(w) Begin a new row. Sets dirty state; call Update to commit. + wgtDataCtrlDelete(w) Delete the current row from the database. + wgtDataCtrlSetMasterValue(w, val) Set the master-detail filter value for this control. + wgtDataCtrlGetRowCount(w) Get the total number of cached rows. + wgtDataCtrlGetColCount(w) Get the number of columns in the result set. + wgtDataCtrlGetColName(w, col) Get the name of a column by index. Returns const char *. + wgtDataCtrlGetCellText(w, row, col) Get the text of a specific cell by row and column index. Returns const char *. + wgtDataCtrlSetCurrentRow(w, row) Set the current row by index (0-based). +.endtable + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + DatabaseName String Read/Write Path to the SQLite database file. + RecordSource String Read/Write SQL query or table name for the result set. + KeyColumn String Read/Write Primary key column name (used for UPDATE/DELETE). + MasterSource String Read/Write Name of the master Data control for master-detail linking. + MasterField String Read/Write Column in the master control to read for the filter value. + DetailField String Read/Write Column in this table to filter by the master value. + Caption String Read/Write Text displayed on the navigation bar. + BOF Boolean Read-only True when the cursor is before the first row. + EOF Boolean Read-only True when the cursor is past the last row. +.endtable + +.h3 Methods (BASIC Interface) + +.table + Method Description + ------ ----------- + AddNew Begin a new row. + Delete Delete the current row. + MoveFirst Move to the first row. + MoveLast Move to the last row. + MoveNext Move to the next row. + MovePrevious Move to the previous row. + Refresh Re-execute the query and rebuild the cache. + Update Write pending changes to the database. +.endtable + +.h3 Events + +.table + Event Description + ----- ----------- + Reposition Fires when the current row changes (navigation, refresh, etc.). Default event. + Validate Fires before writing changes. Return false to cancel. +.endtable + +.hr + +.topic widget.dbgrid +.title DbGrid +.toc 1 DbGrid +.index DbGrid +.index wgtDbGrid +.index wgtDbGridSetDataWidget +.index Database Grid + +.h2 DbGrid + +A database grid widget that displays all records from a Data control in a scrollable, sortable table. Columns auto-populate from the Data control's column names and can be hidden, resized, and renamed by the application. Clicking a column header sorts the display. Selecting a row syncs the Data control's cursor position. The grid reads directly from the Data control's cached rows, so there is no separate copy of the data. + +Header: widgets/widgetDbGrid.h + +.h3 Creation + +.code +WidgetT *grid = wgtDbGrid(parent); +wgtDbGridSetDataWidget(grid, dataCtrl); +.endcode + +.h3 Macros + +.index wgtDbGridRefresh +.index wgtDbGridSetColumnVisible +.index wgtDbGridSetColumnHeader +.index wgtDbGridSetColumnWidth +.index wgtDbGridGetSelectedRow + +.table + Macro Description + ----- ----------- + wgtDbGrid(parent) Create a database grid widget. + wgtDbGridSetDataWidget(w, dataWidget) Bind the grid to a Data control. The grid reads rows from this widget. + wgtDbGridRefresh(w) Re-read the Data control's state and repaint the grid. + wgtDbGridSetColumnVisible(w, fieldName, visible) Show or hide a column by field name. + wgtDbGridSetColumnHeader(w, fieldName, header) Set a display header for a column (overrides the field name). + wgtDbGridSetColumnWidth(w, fieldName, width) Set the width of a column by field name (tagged size, 0 = auto). + wgtDbGridGetSelectedRow(w) Get the index of the currently selected data row (-1 if none). +.endtable + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + GridLines Boolean Read/Write Whether to draw grid lines between cells. +.endtable + +.h3 Methods (BASIC Interface) + +.table + Method Description + ------ ----------- + Refresh Re-read the Data control and repaint. +.endtable + +.h3 Events + +.table + Event Description + ----- ----------- + Click Fires when a row is clicked. + DblClick Fires when a row is double-clicked. Default event. +.endtable + +.hr + +.topic widget.listbox +.title ListBox +.toc 1 ListBox +.index ListBox +.index wgtListBox +.index wgtListBoxSetItems +.index wgtListBoxGetSelected + +.h2 ListBox + +A scrollable list of text items. Supports single and multi-selection modes and drag-to-reorder. + +Header: widgets/widgetListBox.h + +.h3 Creation + +.code +WidgetT *lb = wgtListBox(parent); +const char *items[] = { "Alpha", "Beta", "Gamma" }; +wgtListBoxSetItems(lb, items, 3); +.endcode + +.h3 Macros + +.index wgtListBoxSetSelected +.index wgtListBoxSetMultiSelect +.index wgtListBoxIsItemSelected +.index wgtListBoxSetReorderable +.index wgtListBoxSelectAll +.index wgtListBoxClearSelection + +.table + Macro Description + ----- ----------- + wgtListBox(parent) Create a list box. + wgtListBoxSetItems(w, items, count) Set the list items. + wgtListBoxGetSelected(w) Get the index of the selected item (-1 if none). + wgtListBoxSetSelected(w, idx) Set the selected item by index. + wgtListBoxSetMultiSelect(w, multi) Enable or disable multi-selection mode. + wgtListBoxIsItemSelected(w, idx) Check if a specific item is selected (multi-select mode). + wgtListBoxSetItemSelected(w, idx, selected) Select or deselect a specific item. + wgtListBoxSelectAll(w) Select all items (multi-select mode). + wgtListBoxClearSelection(w) Deselect all items. + wgtListBoxSetReorderable(w, reorderable) Enable drag-to-reorder. +.endtable + +.h3 Events + +.table + Callback Description + -------- ----------- + onClick Fires when an item is clicked. + onDblClick Fires when an item is double-clicked. + onChange Fires when the selection changes. +.endtable + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + ListIndex Integer Read/Write Index of the currently selected item. +.endtable + +.h3 Methods (BASIC Interface) + +.table + Method Description + ------ ----------- + SelectAll Select all items. + ClearSelection Deselect all items. + SetMultiSelect Enable or disable multi-selection. + SetReorderable Enable or disable drag-to-reorder. + IsItemSelected Check if a specific item is selected by index. + SetItemSelected Select or deselect a specific item by index. +.endtable + +.hr + +.topic widget.listview +.title ListView +.toc 1 ListView +.index ListView +.index wgtListView +.index wgtListViewSetColumns +.index wgtListViewSetData +.index ListViewColT +.index ListViewSortE + +.h2 ListView + +A multi-column list with sortable headers. Supports single and multi-selection, column alignment, header click sorting, and drag-to-reorder. Data is provided as a flat array of strings (row-major order, one string per cell). + +Header: widgets/widgetListView.h + +.h3 Creation + +.code +WidgetT *lv = wgtListView(parent); +ListViewColT cols[] = { + { "Name", wgtChars(20), ListViewAlignLeftE }, + { "Size", wgtChars(10), ListViewAlignRightE } +}; +wgtListViewSetColumns(lv, cols, 2); +const char *cells[] = { "file.txt", "1234", "readme.md", "5678" }; +wgtListViewSetData(lv, cells, 2); +.endcode + +.h3 Column Definition + +.code +typedef struct { + const char *title; + int32_t width; // tagged size (wgtPixels/wgtChars/wgtPercent, 0 = auto) + ListViewAlignE align; // ListViewAlignLeftE, ListViewAlignCenterE, ListViewAlignRightE +} ListViewColT; +.endcode + +.h3 Sort Direction + +.code +typedef enum { + ListViewSortNoneE, + ListViewSortAscE, + ListViewSortDescE +} ListViewSortE; +.endcode + +.h3 Macros + +.index wgtListViewGetSelected +.index wgtListViewSetSelected +.index wgtListViewSetSort +.index wgtListViewSetHeaderClickCallback +.index wgtListViewSetMultiSelect +.index wgtListViewSelectAll +.index wgtListViewClearSelection +.index wgtListViewSetReorderable + +.table + Macro Description + ----- ----------- + wgtListView(parent) Create a list view. + wgtListViewSetColumns(w, cols, count) Define columns from an array of ListViewColT. + wgtListViewSetData(w, cellData, rowCount) Set row data. cellData is a flat const char ** array of size rowCount * colCount. + wgtListViewGetSelected(w) Get the index of the selected row (-1 if none). + wgtListViewSetSelected(w, idx) Set the selected row by index. + wgtListViewSetSort(w, col, dir) Set the sort column and direction. + wgtListViewSetHeaderClickCallback(w, cb) Set a callback for header clicks. Signature: void (*cb)(WidgetT *w, int32_t col, ListViewSortE dir). + wgtListViewSetMultiSelect(w, multi) Enable or disable multi-selection. + wgtListViewIsItemSelected(w, idx) Check if a specific row is selected. + wgtListViewSetItemSelected(w, idx, selected) Select or deselect a specific row. + wgtListViewSelectAll(w) Select all rows. + wgtListViewClearSelection(w) Deselect all rows. + wgtListViewSetReorderable(w, reorderable) Enable drag-to-reorder of rows. +.endtable + +.h3 Events + +.table + Callback Description + -------- ----------- + onClick Fires when a row is clicked. + onDblClick Fires when a row is double-clicked. + onChange Fires when the selection changes. +.endtable + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + ListIndex Integer Read/Write Index of the currently selected row. +.endtable + +.h3 Methods (BASIC Interface) + +.table + Method Description + ------ ----------- + SelectAll Select all rows. + ClearSelection Deselect all rows. + SetMultiSelect Enable or disable multi-selection. + SetReorderable Enable or disable drag-to-reorder. + IsItemSelected Check if a specific row is selected by index. + SetItemSelected Select or deselect a specific row by index. +.endtable + +.hr + +.topic widget.treeview +.title TreeView +.toc 1 TreeView +.index TreeView +.index TreeItem +.index wgtTreeView +.index wgtTreeItem +.index wgtTreeViewGetSelected + +.h2 TreeView + +A hierarchical tree control with expandable/collapsible nodes. Supports single and multi-selection and drag-to-reorder. Tree items are added as children of the TreeView or of other tree items to create nested hierarchies. + +Header: widgets/widgetTreeView.h + +.h3 Creation + +.code +WidgetT *tv = wgtTreeView(parent); +WidgetT *root = wgtTreeItem(tv, "Root"); +WidgetT *child = wgtTreeItem(root, "Child"); +.endcode + +.h3 Macros + +.index wgtTreeViewSetSelected +.index wgtTreeViewSetMultiSelect +.index wgtTreeViewSetReorderable +.index wgtTreeItemSetExpanded +.index wgtTreeItemIsExpanded +.index wgtTreeItemIsSelected +.index wgtTreeItemSetSelected + +.table + Macro Description + ----- ----------- + wgtTreeView(parent) Create a tree view control. + wgtTreeItem(parent, text) Add a tree item as a child of the tree view or another tree item. + wgtTreeViewGetSelected(w) Get the currently selected tree item (returns WidgetT *, NULL if none). + wgtTreeViewSetSelected(w, item) Set the selected tree item. + wgtTreeViewSetMultiSelect(w, multi) Enable or disable multi-selection. + wgtTreeViewSetReorderable(w, reorderable) Enable drag-to-reorder of items. + wgtTreeItemSetExpanded(w, expanded) Expand or collapse a tree item. + wgtTreeItemIsExpanded(w) Check if a tree item is expanded. + wgtTreeItemIsSelected(w) Check if a tree item is selected (multi-select mode). + wgtTreeItemSetSelected(w, selected) Select or deselect a tree item. +.endtable + +.h3 Events + +.table + Callback Description + -------- ----------- + onClick Fires when a tree item is clicked. + onDblClick Fires when a tree item is double-clicked. + onChange Fires when the selection changes. +.endtable + +.h3 Methods (BASIC Interface) + +.table + Method Description + ------ ----------- + SetMultiSelect Enable or disable multi-selection. + SetReorderable Enable or disable drag-to-reorder. +.endtable + +.hr + +.topic widget.image +.title Image +.toc 0 Display Widgets +.toc 1 Image +.index Image +.index wgtImage +.index wgtImageFromFile +.index wgtImageSetData +.index wgtImageLoadFile + +.h2 Image + +Displays a bitmap image. Can be created from raw pixel data or loaded from a BMP file on disk. The image is rendered at its natural size within the widget bounds. + +Header: widgets/widgetImage.h + +.h3 Creation + +.table + Macro Description + ----- ----------- + wgtImage(parent, data, w, h, pitch) Create an image widget from raw pixel data. data is a uint8_t * pixel buffer, w/h are dimensions, pitch is bytes per row. + wgtImageFromFile(parent, path) Create an image widget by loading a BMP file from disk. +.endtable + +.h3 Methods + +.table + Macro Description + ----- ----------- + wgtImageSetData(w, data, imgW, imgH, pitch) Replace the displayed image with new raw pixel data. + wgtImageLoadFile(w, path) Replace the displayed image by loading a new file. +.endtable + +.h3 Events + +.table + Callback Description + -------- ----------- + onClick Fires when the image is clicked. +.endtable + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + Picture String Write-only Load an image from a file path. + ImageWidth Integer Read-only Width of the currently loaded image in pixels. + ImageHeight Integer Read-only Height of the currently loaded image in pixels. +.endtable + +.hr + +.topic widget.imagebutton +.title ImageButton +.toc 1 ImageButton +.index ImageButton +.index wgtImageButton +.index wgtImageButtonFromFile +.index wgtImageButtonSetData +.index wgtImageButtonLoadFile + +.h2 ImageButton + +A clickable button that displays an image instead of text. Has press/release visual feedback like a regular button. Can be created from raw pixel data or a BMP file. + +Header: widgets/widgetImageButton.h + +.h3 Creation + +.table + Macro Description + ----- ----------- + wgtImageButton(parent, data, w, h, pitch) Create an image button from raw pixel data. + wgtImageButtonFromFile(parent, path) Create an image button by loading a BMP file. +.endtable + +.h3 Methods + +.table + Macro Description + ----- ----------- + wgtImageButtonSetData(w, data, imgW, imgH, pitch) Replace the image with new raw pixel data. + wgtImageButtonLoadFile(w, path) Replace the image by loading a new file. +.endtable + +.h3 Events + +.table + Callback Description + -------- ----------- + onClick Fires when the image button is clicked (press + release). +.endtable + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + Picture String Write-only Load an image from a file path. + ImageWidth Integer Read-only Width of the currently loaded image in pixels. + ImageHeight Integer Read-only Height of the currently loaded image in pixels. +.endtable + +.hr + +.topic widget.slider +.title Slider +.toc 1 Slider +.index Slider +.index wgtSlider +.index wgtSliderSetValue +.index wgtSliderGetValue + +.h2 Slider + +A horizontal slider (track bar) for selecting an integer value within a range. The user drags the thumb or clicks the track to change the value. + +Header: widgets/widgetSlider.h + +.h3 Creation + +.code +WidgetT *sl = wgtSlider(parent, 0, 100); +.endcode + +.h3 Macros + +.table + Macro Description + ----- ----------- + wgtSlider(parent, minVal, maxVal) Create a slider with the given integer range. + wgtSliderSetValue(w, value) Set the slider value programmatically. + wgtSliderGetValue(w) Get the current slider value. +.endtable + +.h3 Events + +.table + Callback Description + -------- ----------- + onChange Fires when the slider value changes. +.endtable + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + Value Integer Read/Write Current slider value. +.endtable + +.hr + +.topic widget.spinner +.title Spinner +.toc 1 Spinner +.index Spinner +.index wgtSpinner +.index wgtSpinnerSetValue +.index wgtSpinnerGetValue +.index wgtSpinnerSetRealMode + +.h2 Spinner + +A numeric input with up/down buttons for incrementing and decrementing a value within a range. Supports both integer and floating-point (real) modes. + +Header: widgets/widgetSpinner.h + +.h3 Creation + +.code +WidgetT *sp = wgtSpinner(parent, 0, 100, 1); +.endcode + +.h3 Macros + +.index wgtSpinnerSetRange +.index wgtSpinnerSetStep +.index wgtSpinnerGetRealValue +.index wgtSpinnerSetRealValue +.index wgtSpinnerSetRealRange +.index wgtSpinnerSetRealStep +.index wgtSpinnerSetDecimals + +.table + Macro Description + ----- ----------- + wgtSpinner(parent, minVal, maxVal, step) Create a spinner with the given integer range and step size. + wgtSpinnerSetValue(w, value) Set the integer value. + wgtSpinnerGetValue(w) Get the current integer value. + wgtSpinnerSetRange(w, minVal, maxVal) Set the integer range. + wgtSpinnerSetStep(w, step) Set the integer step size. + wgtSpinnerSetRealMode(w, enable) Switch to floating-point mode. + wgtSpinnerGetRealValue(w) Get the current floating-point value. + wgtSpinnerSetRealValue(w, value) Set the floating-point value. + wgtSpinnerSetRealRange(w, minVal, maxVal) Set the floating-point range. + wgtSpinnerSetRealStep(w, step) Set the floating-point step size. + wgtSpinnerSetDecimals(w, decimals) Set the number of decimal places displayed in real mode. +.endtable + +.h3 Events + +.table + Callback Description + -------- ----------- + onChange Fires when the value changes. +.endtable + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + Value Integer Read/Write Current integer value. + RealMode Boolean Read/Write Whether floating-point mode is active. + Decimals Integer Read/Write Number of decimal places displayed in real mode. +.endtable + +.h3 Methods (BASIC Interface) + +.table + Method Description + ------ ----------- + SetRange Set the integer range (min, max). + SetStep Set the integer step size. +.endtable + +.hr + +.topic widget.progressbar +.title ProgressBar +.toc 1 ProgressBar +.index ProgressBar +.index wgtProgressBar +.index wgtProgressBarV +.index wgtProgressBarSetValue +.index wgtProgressBarGetValue + +.h2 ProgressBar + +A visual indicator of progress, displayed as a filled bar. Supports both horizontal and vertical orientations. Value ranges from 0 to 100. + +Header: widgets/widgetProgressBar.h + +.h3 Creation + +.table + Macro Description + ----- ----------- + wgtProgressBar(parent) Create a horizontal progress bar. + wgtProgressBarV(parent) Create a vertical progress bar. +.endtable + +.h3 Methods + +.table + Macro Description + ----- ----------- + wgtProgressBarSetValue(w, value) Set the progress value (0-100). + wgtProgressBarGetValue(w) Get the current progress value. +.endtable + +.h3 Events + +ProgressBar is a display-only widget. Typically no callbacks are set. + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + Value Integer Read/Write Current progress value (0-100). +.endtable + +.hr + +.topic widget.canvas +.title Canvas +.toc 1 Canvas +.index Canvas +.index wgtCanvas +.index wgtCanvasClear +.index wgtCanvasDrawLine +.index wgtCanvasDrawRect +.index wgtCanvasFillRect +.index wgtCanvasFillCircle +.index wgtCanvasSetPixel +.index wgtCanvasGetPixel +.index wgtCanvasDrawText +.index wgtCanvasSave +.index wgtCanvasLoad + +.h2 Canvas + +A freeform drawing surface with a fixed-size pixel buffer. Provides drawing primitives (lines, rectangles, circles, text, individual pixels) and supports save/load to BMP files. Mouse interaction is available via a callback. + +Header: widgets/widgetCanvas.h + +.h3 Creation + +.code +WidgetT *cv = wgtCanvas(parent, 320, 200); +.endcode + +.h3 Macros + +.index wgtCanvasSetPenColor +.index wgtCanvasSetPenSize +.index wgtCanvasSetMouseCallback + +.table + Macro Description + ----- ----------- + wgtCanvas(parent, w, h) Create a canvas with the given pixel dimensions. + wgtCanvasClear(w, color) Fill the entire canvas with a solid color. + wgtCanvasSetPenColor(w, color) Set the drawing pen color. + wgtCanvasSetPenSize(w, size) Set the drawing pen size in pixels. + wgtCanvasDrawLine(w, x0, y0, x1, y1) Draw a line from (x0,y0) to (x1,y1). + wgtCanvasDrawRect(w, x, y, width, height) Draw a rectangle outline. + wgtCanvasFillRect(w, x, y, width, height) Draw a filled rectangle. + wgtCanvasFillCircle(w, cx, cy, radius) Draw a filled circle. + wgtCanvasSetPixel(w, x, y, color) Set a single pixel to the given color. + wgtCanvasGetPixel(w, x, y) Get the color of a single pixel. + wgtCanvasDrawText(w, x, y, text) Draw text at the given position using the current pen color. + wgtCanvasSetMouseCallback(w, cb) Set a mouse interaction callback. Signature: void (*cb)(WidgetT *w, int32_t cx, int32_t cy, bool drag). Receives canvas-relative coordinates and whether the mouse is being dragged. + wgtCanvasSave(w, path) Save the canvas contents to a BMP file. + wgtCanvasLoad(w, path) Load a BMP file into the canvas. +.endtable + +.h3 Events + +.table + Callback Description + -------- ----------- + onClick Fires when the canvas is clicked. + Mouse callback (via wgtCanvasSetMouseCallback) Fires on mouse down and drag with canvas-local coordinates. +.endtable + +.h3 Methods (BASIC Interface) + +.table + Method Description + ------ ----------- + Clear Clear the canvas to a given color. +.endtable + +.hr + +.topic widget.timer +.title Timer +.toc 0 Non-Visual Widgets +.toc 1 Timer +.index Timer +.index wgtTimer +.index wgtTimerStart +.index wgtTimerStop +.index wgtTimerSetInterval +.index wgtTimerIsRunning +.index wgtUpdateTimers + +.h2 Timer + +A non-visual widget that fires its onClick callback at a regular interval. Useful for animations, polling, and periodic updates. Must be explicitly started after creation. + +Header: widgets/widgetTimer.h + +.h3 Creation + +.code +WidgetT *tmr = wgtTimer(parent, 1000, true); // 1 second, repeating +tmr->onClick = onTimerTick; +wgtTimerStart(tmr); +.endcode + +.h3 Macros + +.table + Macro Description + ----- ----------- + wgtTimer(parent, intervalMs, repeat) Create a timer. intervalMs is the interval in milliseconds. repeat: true for repeating, false for one-shot. + wgtTimerStart(w) Start the timer. + wgtTimerStop(w) Stop the timer. + wgtTimerSetInterval(w, intervalMs) Change the timer interval. + wgtTimerIsRunning(w) Returns true if the timer is currently running. + wgtUpdateTimers() Global tick function. Called by the event loop to advance all active timers. +.endtable + +.h3 Events + +.table + Callback Description + -------- ----------- + onClick Fires each time the timer elapses. +.endtable + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + Enabled Boolean Read/Write Whether the timer is running. Reading returns the running state; writing starts or stops it. + Interval Integer Write-only Timer interval in milliseconds. +.endtable + +.h3 Methods (BASIC Interface) + +.table + Method Description + ------ ----------- + Start Start the timer. + Stop Stop the timer. +.endtable + +.h3 Extra Events (BASIC Interface) + +.table + Event Description + ----- ----------- + Timer Fires each time the timer elapses. Default event. +.endtable + +.hr + +.topic widget.toolbar +.title Toolbar +.toc 0 Container Widgets +.toc 1 Toolbar +.index Toolbar +.index wgtToolbar + +.h2 Toolbar + +A horizontal container for toolbar buttons and controls. Typically placed at the top of a window. Children (usually ImageButtons or Buttons) are laid out horizontally with toolbar-appropriate spacing. + +Header: widgets/widgetToolbar.h + +.h3 Creation + +.code +WidgetT *tb = wgtToolbar(parent); +wgtImageButtonFromFile(tb, "icons/save.bmp"); +wgtImageButtonFromFile(tb, "icons/open.bmp"); +.endcode + +.h3 Macro + +.table + Macro Description + ----- ----------- + wgtToolbar(parent) Create a toolbar container. +.endtable + +.h3 Properties + +Uses common container properties. Add children (buttons, separators, etc.) to populate the toolbar. + +.h3 Events + +Toolbar itself has no widget-specific events. Events fire on the child widgets. + +.hr + +.topic widget.statusbar +.title StatusBar +.toc 1 StatusBar +.index StatusBar +.index wgtStatusBar + +.h2 StatusBar + +A horizontal bar typically placed at the bottom of a window for displaying status text and informational widgets. Children are laid out horizontally. + +Header: widgets/widgetStatusBar.h + +.h3 Creation + +.code +WidgetT *sb = wgtStatusBar(parent); +wgtLabel(sb, "Ready"); +.endcode + +.h3 Macro + +.table + Macro Description + ----- ----------- + wgtStatusBar(parent) Create a status bar container. +.endtable + +.h3 Properties + +Uses common container properties. Add child widgets (labels, progress bars, etc.) to populate. + +.h3 Events + +StatusBar itself has no widget-specific events. Events fire on the child widgets. + +.hr + +.topic widget.scrollpane +.title ScrollPane +.toc 1 ScrollPane +.index ScrollPane +.index wgtScrollPane +.index wgtScrollPaneScrollToChild +.index wgtScrollPaneSetNoBorder + +.h2 ScrollPane + +A scrollable container that provides vertical and/or horizontal scrollbars when its content exceeds the visible area. Place a single child (typically a VBox or HBox) inside the scroll pane. + +Header: widgets/widgetScrollPane.h + +.h3 Creation + +.code +WidgetT *sp = wgtScrollPane(parent); +WidgetT *content = wgtVBox(sp); +// add children to content... +.endcode + +.h3 Macros + +.table + Macro Description + ----- ----------- + wgtScrollPane(parent) Create a scroll pane container. + wgtScrollPaneScrollToChild(sp, child) Scroll so that the given child widget is visible. + wgtScrollPaneSetNoBorder(w, noBorder) When true, removes the border around the scroll pane. +.endtable + +.h3 Events + +.table + Callback Description + -------- ----------- + onScroll Fires when the scroll position changes. +.endtable + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + NoBorder Boolean Read/Write Whether the border around the scroll pane is hidden. +.endtable + +.hr + +.topic widget.splitter +.title Splitter +.toc 1 Splitter +.index Splitter +.index wgtSplitter +.index wgtSplitterSetPos +.index wgtSplitterGetPos + +.h2 Splitter + +A two-pane container with a draggable divider. The user drags the splitter bar to resize the two panes. Can be oriented vertically (left/right panes) or horizontally (top/bottom panes). Add exactly two children. + +Header: widgets/widgetSplitter.h + +.h3 Creation + +.code +WidgetT *sp = wgtSplitter(parent, true); // vertical = left|right +WidgetT *left = wgtVBox(sp); +WidgetT *right = wgtVBox(sp); +.endcode + +.h3 Macros + +.table + Macro Description + ----- ----------- + wgtSplitter(parent, vertical) Create a splitter. vertical=true for left/right panes, false for top/bottom. + wgtSplitterSetPos(w, pos) Set the divider position in pixels. + wgtSplitterGetPos(w) Get the current divider position in pixels. +.endtable + +.h3 Events + +.table + Callback Description + -------- ----------- + onChange Fires when the divider position changes. +.endtable + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + Position Integer Read/Write Divider position in pixels. +.endtable + +.hr + +.topic widget.tabcontrol +.title TabControl +.toc 1 TabControl +.index TabControl +.index TabPage +.index wgtTabControl +.index wgtTabPage +.index wgtTabControlSetActive +.index wgtTabControlGetActive + +.h2 TabControl + +A tabbed container that displays one page at a time with clickable tabs along the top. Each tab page is a container that holds its own child widgets. + +Header: widgets/widgetTabControl.h + +.h3 Creation + +.code +WidgetT *tabs = wgtTabControl(parent); +WidgetT *page1 = wgtTabPage(tabs, "General"); +WidgetT *page2 = wgtTabPage(tabs, "Advanced"); +// add children to page1, page2... +.endcode + +.h3 Macros + +.table + Macro Description + ----- ----------- + wgtTabControl(parent) Create a tab control. + wgtTabPage(parent, title) Add a tab page with the given title. Returns the page container widget. + wgtTabControlSetActive(w, idx) Set the active tab by index (0-based). + wgtTabControlGetActive(w) Get the index of the active tab. +.endtable + +.h3 Events + +.table + Callback Description + -------- ----------- + onChange Fires when the active tab changes. +.endtable + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + TabIndex Integer Read/Write Index of the currently active tab (0-based). +.endtable + +.h3 Methods (BASIC Interface) + +.table + Method Description + ------ ----------- + SetActive Set the active tab by index. +.endtable + +.hr + +.topic widget.separator +.title Separator +.toc 1 Separator +.index Separator +.index wgtHSeparator +.index wgtVSeparator + +.h2 Separator + +A visual dividing line used to separate groups of widgets. Available in horizontal and vertical orientations. + +Header: widgets/widgetSeparator.h + +.h3 Creation + +.table + Macro Description + ----- ----------- + wgtHSeparator(parent) Create a horizontal separator line. + wgtVSeparator(parent) Create a vertical separator line. +.endtable + +.h3 Events + +Separator is a visual-only widget. No events. + +.hr + +.topic widget.spacer +.title Spacer +.toc 1 Spacer +.index Spacer +.index wgtSpacer + +.h2 Spacer + +An invisible widget used for layout purposes. By default it has weight=100, so it absorbs available extra space. Useful for pushing other widgets apart or aligning them to edges. + +Header: widgets/widgetSpacer.h + +.h3 Creation + +.code +WidgetT *row = wgtHBox(parent); +wgtButton(row, "OK"); +wgtSpacer(row); // pushes Cancel to the right +wgtButton(row, "Cancel"); +.endcode + +.h3 Macro + +.table + Macro Description + ----- ----------- + wgtSpacer(parent) Create an invisible spacer widget. +.endtable + +.h3 Events + +Spacer is an invisible layout widget. No events. + +.hr + +.topic widget.wrapbox +.title WrapBox +.toc 1 WrapBox +.index WrapBox +.index wgtWrapBox + +.h2 WrapBox + +A flow/wrap layout container that arranges children left-to-right, wrapping to the next row when the available width is exceeded. Each row's height is the maximum child height in that row. Supports configurable spacing between items and rows, and per-row alignment for short rows. + +Header: widgets/widgetWrapBox.h + +.h3 Creation + +.code +WidgetT *wrap = wgtWrapBox(parent); +wgtButton(wrap, "Tag 1"); +wgtButton(wrap, "Tag 2"); +wgtButton(wrap, "Tag 3"); +.endcode + +.h3 Macro + +.table + Macro Description + ----- ----------- + wgtWrapBox(parent) Create a wrap box container. +.endtable + +.h3 Properties + +WrapBox uses the common WidgetT container fields for layout control: + +.table + Property Description + -------- ----------- + spacing Gap between children in both the horizontal and vertical directions (tagged size). Default is 4 pixels. + padding Internal padding around children (tagged size). Default is 2 pixels. +.endtable + +.h3 Properties (BASIC Interface) + +.table + Property Type Access Description + -------- ---- ------ ----------- + Alignment Enum (Left, Center, Right) Read/Write Row alignment for rows that do not fill the full width. +.endtable + +.h3 Events + +WrapBox is a container widget. It uses the common events only. No widget-specific events are defined. diff --git a/docs/src/dvxbasic_control_reference.dvxhelp b/docs/src/dvxbasic_control_reference.dvxhelp new file mode 100644 index 0000000..f7ca8e4 --- /dev/null +++ b/docs/src/dvxbasic_control_reference.dvxhelp @@ -0,0 +1,1567 @@ +.topic ctrl.common.props +.title Common Properties, Events, and Methods +.toc 0 Common Properties, Events, and Methods +.default +.index Common Properties +.index Common Events +.index Common Methods +.index Properties +.index Events +.index Methods + +.h1 Common Properties, Events, and Methods + +Every control in DVX BASIC inherits a set of common properties, events, and methods. These are handled by the form runtime before dispatching to widget-specific interface descriptors. + +.h2 Common Properties + +.table + Property Type R/W Description + ---------- ------- --- ------------------------------------------- + Name String R The control's name (e.g. "Command1"). Read-only at runtime. + Left Integer R/W X position in pixels relative to the parent container. + Top Integer R/W Y position in pixels relative to the parent container. + Width Integer R/W Current width in pixels. Setting this changes the minimum width constraint. + Height Integer R/W Current height in pixels. Setting this changes the minimum height constraint. + MinWidth Integer R/W Minimum width for layout. Alias for Width in the setter. + MinHeight Integer R/W Minimum height for layout. Alias for Height in the setter. + MaxWidth Integer R/W Maximum width cap (0 = no limit, stretch to fill). + MaxHeight Integer R/W Maximum height cap (0 = no limit, stretch to fill). + Weight Integer R/W Layout weight. 0 = fixed size, >0 = share extra space proportionally. + Visible Boolean R/W Whether the control is visible. + Enabled Boolean R/W Whether the control accepts user input. + BackColor Long R/W Background color as a 32-bit ARGB value. + ForeColor Long R/W Foreground (text) color as a 32-bit ARGB value. + TabIndex Integer R Accepted for VB compatibility but ignored. DVX has no tab order. +.endtable + +.h2 Common Events + +These events are wired on every control loaded from a .frm file. Controls created dynamically at runtime via code only receive Click, DblClick, Change, GotFocus, and LostFocus; the keyboard, mouse, and scroll events below require the control to be defined in the .frm file. + +.table + Event Parameters Description + --------- ------------------------------------------- ------------------------------------------- + Click (none) Fires when the control is clicked. + DblClick (none) Fires when the control is double-clicked. + Change (none) Fires when the control's value or text changes. + GotFocus (none) Fires when the control receives keyboard focus. + LostFocus (none) Fires when the control loses keyboard focus. + KeyPress KeyAscii As Integer Fires when a printable key is pressed. KeyAscii is the ASCII code. + KeyDown KeyCode As Integer, Shift As Integer Fires when any key is pressed down. KeyCode is the scan code; Shift indicates modifier keys. + KeyUp KeyCode As Integer, Shift As Integer Fires when a key is released. + MouseDown Button As Integer, X As Integer, Y As Integer Fires when a mouse button is pressed over the control. + MouseUp Button As Integer, X As Integer, Y As Integer Fires when a mouse button is released over the control. + MouseMove Button As Integer, X As Integer, Y As Integer Fires when the mouse moves over the control. + Scroll Delta As Integer Fires when the control is scrolled (mouse wheel or scrollbar). +.endtable + +.h2 Common Methods + +.table + Method Parameters Description + -------- ---------- ------------------------------------------- + SetFocus (none) Gives keyboard focus to this control. + Refresh (none) Forces the control to repaint. +.endtable + +.link ctrl.form Form +.link ctrl.databinding Data Binding +.link ctrl.frm FRM File Format + + +.topic ctrl.form +.title Form +.toc 0 Controls +.toc 1 Form +.index Form +.index Window +.index Caption +.index AutoSize +.index Resizable +.index Load +.index Unload +.index Show +.index Hide + +.h1 Form + +VB Equivalent: Form -- DVX Widget: Window + VBox/HBox root + +The Form is the top-level container representing a DVX window. It is declared in the .frm file with Begin Form FormName. All controls are children of the form's content box, which uses either VBox (default) or HBox layout. + +.h2 Form Properties + +.table + Property Type Default Description + ---------- ------- -------------- ------------------------------------------- + Name String "Form1" The form's name, used for event dispatch and Load statement. + Caption String (same as Name) Window title bar text. + Width Integer 400 Window width in pixels. Setting this disables AutoSize. + Height Integer 300 Window height in pixels. Setting this disables AutoSize. + Left Integer 0 Initial X position. Used when Centered is False. + Top Integer 0 Initial Y position. Used when Centered is False. + Layout String "VBox" Content box layout: "VBox" (vertical) or "HBox" (horizontal). + AutoSize Boolean True When True, the window shrink-wraps to fit its content. + Resizable Boolean True Whether the user can resize the window at runtime. + Centered Boolean True When True, the window is centered on screen. When False, Left/Top are used. +.endtable + +.h2 Form Events + +.table + Event Parameters Description + ----------- --------------------- ------------------------------------------- + Load (none) Fires after the form and all controls are created. This is the default event. + Unload (none) Fires when the form is being closed or unloaded. + QueryUnload Cancel As Integer Fires before Unload. Set Cancel = 1 to abort the close. + Resize (none) Fires when the window is resized by the user. + Activate (none) Fires when the window gains focus. + Deactivate (none) Fires when the window loses focus. +.endtable + +.h2 Form Methods + +.table + Statement Description + ------------------ ------------------------------------------- + Load FormName Load the form (creates the window and controls, fires Load event). + Unload FormName Unload the form (fires Unload, destroys window). + FormName.Show Make the form visible. + FormName.Show 1 Show as modal dialog (blocks until closed). + FormName.Hide Hide the form without unloading it. +.endtable + +.h2 Example + +.code +Sub Form_Load () + Form1.Caption = "Hello World" + Print "Form loaded!" +End Sub + +Sub Form_QueryUnload (Cancel As Integer) + If MsgBox("Really quit?", 4) <> 6 Then + Cancel = 1 + End If +End Sub + +Sub Form_Resize () + Print "Window resized" +End Sub +.endcode + +.link ctrl.common.props Common Properties, Events, and Methods +.link ctrl.frm FRM File Format + + +.topic ctrl.button +.title CommandButton +.toc 1 CommandButton +.index CommandButton +.index Button +.index Click + +.h1 CommandButton + +VB Equivalent: CommandButton -- DVX Widget: button | Name Prefix: Command + +A push button that triggers an action when clicked. Created with wgtButton(parent, text). + +.h2 Type-Specific Properties + +.table + Property Type Description + -------- ------ ------------------------------------------- + Caption String The text displayed on the button. Use & for accelerator keys (e.g. "&OK"). +.endtable + +No additional type-specific properties beyond common properties and Caption. + +Default Event: Click + +.h2 Example + +.code +Begin Form Form1 + Caption = "Button Demo" + Begin CommandButton Command1 + Caption = "&Click Me!" + End +End + +Sub Command1_Click () + MsgBox "Button was clicked!" +End Sub +.endcode + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.label +.title Label +.toc 1 Label +.index Label +.index Caption +.index Alignment + +.h1 Label + +VB Equivalent: Label -- DVX Widget: label + +A static text label. Supports left, center, and right alignment. + +.h2 Type-Specific Properties + +.table + Property Type Description + --------- ---- ------------------------------------------- + Caption String The text displayed by the label. + Alignment Enum Text alignment: Left (default), Center, or Right. +.endtable + +Default Event: Click + +.h2 Example + +.code +Begin Label Label1 + Caption = "Hello, World!" + Alignment = "Center" +End +.endcode + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.textbox +.title TextBox +.toc 1 TextBox +.index TextBox +.index Text +.index DataSource +.index DataField + +.h1 TextBox + +VB Equivalent: TextBox -- DVX Widget: textbox (single-line text input, max 256 chars) + +A single-line text input field. Supports data binding via DataSource and DataField properties. + +.h2 Type-Specific Properties + +.table + Property Type Description + ---------- ------ ------------------------------------------- + Text String The text content of the input field. + DataSource String Name of a Data control for data binding. + DataField String Column name for data binding. +.endtable + +Default Event: Change + +.h2 Example + +.code +Begin TextBox Text1 + Text = "Enter text here" +End + +Sub Text1_Change () + Label1.Caption = "You typed: " & Text1.Text +End Sub +.endcode + +.link ctrl.common.props Common Properties, Events, and Methods +.link ctrl.databinding Data Binding + + +.topic ctrl.textarea +.title TextArea +.toc 1 TextArea +.index TextArea + +.h1 TextArea + +VB Equivalent: TextArea (DVX extension) -- DVX Widget: textarea (multi-line text input, max 4096 chars) + +A multi-line text editing area. This is a DVX extension with no direct VB3 equivalent (VB uses a TextBox with MultiLine=True). Supports syntax colorization, line numbers, auto-indent, and find/replace via the C API. + +.h2 Type-Specific Properties + +.table + Property Type Description + -------- ------ ------------------------------------------- + Text String The full text content. +.endtable + +Default Event: Change + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.checkbox +.title CheckBox +.toc 1 CheckBox +.index CheckBox +.index Value + +.h1 CheckBox + +VB Equivalent: CheckBox -- DVX Widget: checkbox + +A toggle control with a label. Checked state is exposed as a Boolean. + +.h2 Type-Specific Properties + +.table + Property Type Description + -------- ------- ------------------------------------------- + Caption String The text displayed next to the checkbox. + Value Boolean True if checked, False if unchecked. +.endtable + +Default Event: Click + +.h2 Example + +.code +Begin CheckBox Check1 + Caption = "Enable feature" +End + +Sub Check1_Click () + If Check1.Value Then + Label1.Caption = "Feature ON" + Else + Label1.Caption = "Feature OFF" + End If +End Sub +.endcode + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.optionbutton +.title OptionButton +.toc 1 OptionButton +.index OptionButton +.index Radio Button +.index SetSelected + +.h1 OptionButton + +VB Equivalent: OptionButton -- DVX Widget: radio (radio group + radio button) | Name Prefix: Option + +A radio button for mutually exclusive choices. DVX uses a radio group container; individual OptionButtons are children of the group. The Value property returns the button's index within its group. + +.h2 Type-Specific Properties + +.table + Property Type Description + -------- ------- ------------------------------------------- + Caption String The text displayed next to the radio button. + Value Integer The index of this radio button within its group (read-only). +.endtable + +.h2 Type-Specific Methods + +.table + Method Parameters Description + ----------- ----------------- ------------------------------------------- + SetSelected Index As Integer Select the radio button at the given index within the group. +.endtable + +Default Event: Click + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.frame +.title Frame +.toc 0 Container Controls +.toc 1 Frame +.index Frame +.index Container + +.h1 Frame + +VB Equivalent: Frame -- DVX Widget: frame (titled VBox container) + +A container with a titled border. Child controls are placed inside the frame using VBox layout. In the .frm file, nest Begin/End blocks inside the Frame block. + +.h2 Type-Specific Properties + +.table + Property Type Description + -------- ------ ------------------------------------------- + Caption String The title displayed in the frame border. +.endtable + +Container: Yes + +Default Event: Click + +.h2 Example + +.code +Begin Frame Frame1 + Caption = "Options" + Begin CheckBox Check1 + Caption = "Option A" + End + Begin CheckBox Check2 + Caption = "Option B" + End +End +.endcode + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.vbox +.title VBox +.toc 1 VBox +.index VBox +.index Vertical Layout + +.h1 VBox + +DVX Extension -- DVX Widget: vbox (vertical layout container) + +A container that arranges its children vertically, top to bottom. No title or border. Use Weight on children to distribute extra space. + +Container: Yes + +Default Event: Click + +No type-specific properties. + +.link ctrl.common.props Common Properties, Events, and Methods +.link ctrl.hbox HBox + + +.topic ctrl.hbox +.title HBox +.toc 1 HBox +.index HBox +.index Horizontal Layout + +.h1 HBox + +DVX Extension -- DVX Widget: hbox (horizontal layout container) + +A container that arranges its children horizontally, left to right. Use Weight on children to distribute extra space. + +Container: Yes + +Default Event: Click + +No type-specific properties. + +.link ctrl.common.props Common Properties, Events, and Methods +.link ctrl.vbox VBox + + +.topic ctrl.listbox +.title ListBox +.toc 0 List and Selection Controls +.toc 1 ListBox +.index ListBox +.index ListIndex +.index ListCount +.index AddItem +.index RemoveItem + +.h1 ListBox + +VB Equivalent: ListBox -- DVX Widget: listbox + +A scrollable list of selectable items. Items are managed via methods (AddItem, RemoveItem, Clear). Supports single and multi-select modes. + +.h2 Type-Specific Properties + +.table + Property Type Description + --------- ------- ------------------------------------------- + ListIndex Integer Index of the currently selected item (-1 = no selection). + ListCount Integer Number of items in the list (read-only). +.endtable + +.h2 Type-Specific Methods + +.table + Method Parameters Description + --------------- --------------------------------------- ------------------------------------------- + AddItem Text As String Add an item to the end of the list. + RemoveItem Index As Integer Remove the item at the given index. + Clear (none) Remove all items from the list. + List Index As Integer Return the text of the item at the given index. + SelectAll (none) Select all items (multi-select mode). + ClearSelection (none) Deselect all items. + SetMultiSelect Multi As Boolean Enable or disable multi-select mode. + SetReorderable Reorderable As Boolean Enable or disable drag-to-reorder. + IsItemSelected Index As Integer Returns True if the item at Index is selected. + SetItemSelected Index As Integer, Selected As Boolean Select or deselect a specific item. +.endtable + +Default Event: Click + +.h2 Example + +.code +Sub Form_Load () + List1.AddItem "Apple" + List1.AddItem "Banana" + List1.AddItem "Cherry" +End Sub + +Sub List1_Click () + Dim idx As Integer + idx = List1.ListIndex + If idx >= 0 Then + Label1.Caption = "Selected: " & List1.List(idx) + End If +End Sub +.endcode + +.link ctrl.common.props Common Properties, Events, and Methods +.link ctrl.combobox ComboBox +.link ctrl.dropdown DropDown + + +.topic ctrl.combobox +.title ComboBox +.toc 1 ComboBox +.index ComboBox + +.h1 ComboBox + +VB Equivalent: ComboBox -- DVX Widget: combobox (editable text field + drop-down list, max 256 chars) + +A combination of a text input and a drop-down list. The user can type text or select from the list. Supports the same AddItem/RemoveItem/Clear/List methods as ListBox. + +.h2 Type-Specific Properties + +.table + Property Type Description + --------- ------- ------------------------------------------- + Text String The text in the editable field. + ListIndex Integer Index of the currently selected list item (-1 = none). + ListCount Integer Number of items in the drop-down list (read-only). +.endtable + +.h2 Type-Specific Methods + +Same as .link ctrl.listbox ListBox : AddItem, RemoveItem, Clear, List. + +Default Event: Click + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.dropdown +.title DropDown +.toc 1 DropDown +.index DropDown + +.h1 DropDown + +DVX Extension -- DVX Widget: dropdown (non-editable drop-down list) + +A read-only drop-down list. Unlike ComboBox, the user cannot type free text; they can only select from the provided items. Supports AddItem/RemoveItem/Clear/List. + +.h2 Type-Specific Properties + +.table + Property Type Description + --------- ------- ------------------------------------------- + ListIndex Integer Index of the currently selected item. + ListCount Integer Number of items (read-only). +.endtable + +.h2 Type-Specific Methods + +Same as .link ctrl.listbox ListBox : AddItem, RemoveItem, Clear, List. + +Default Event: Click + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.hscrollbar +.title HScrollBar +.toc 0 Value Controls +.toc 1 HScrollBar +.index HScrollBar +.index Slider + +.h1 HScrollBar + +VB Equivalent: HScrollBar -- DVX Widget: slider | Name Prefix: HScroll + +A horizontal slider/scrollbar control. The value ranges between a minimum and maximum set at creation time (default 0 to 100). + +.h2 Type-Specific Properties + +.table + Property Type Description + -------- ------- ------------------------------------------- + Value Integer The current slider position (clamped to min/max range). +.endtable + +Default Event: Change + +.h2 Example + +.code +Begin HScrollBar HScroll1 + MinWidth = 200 +End + +Sub HScroll1_Change () + Label1.Caption = "Value: " & Str$(HScroll1.Value) +End Sub +.endcode + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.spinbutton +.title SpinButton +.toc 1 SpinButton +.index SpinButton +.index Spinner +.index SetRange +.index SetStep +.index RealMode +.index Decimals + +.h1 SpinButton + +DVX Extension -- DVX Widget: spinner | Name Prefix: Spin + +A numeric input with up/down buttons. Supports integer mode (default) and real-number mode with configurable decimal places. + +.h2 Type-Specific Properties + +.table + Property Type Description + -------- ------- ------------------------------------------- + Value Integer Current integer value (in integer mode). + RealMode Boolean True to use floating-point mode; False for integer mode. + Decimals Integer Number of decimal places shown in real mode. +.endtable + +.h2 Type-Specific Methods + +.table + Method Parameters Description + -------- ------------------------------ ------------------------------------------- + SetRange Min As Integer, Max As Integer Set the allowed value range. + SetStep Step As Integer Set the increment per button click. +.endtable + +Default Event: Change + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.timer +.title Timer +.toc 0 Non-Visual Controls +.toc 1 Timer +.index Timer +.index Interval +.index Start +.index Stop + +.h1 Timer + +VB Equivalent: Timer -- DVX Widget: timer (non-visual) + +A non-visual control that fires its event at a regular interval. The Timer widget is invisible at runtime -- it has no on-screen representation. + +.h2 Type-Specific Properties + +.table + Property Type Description + -------- ------- ------------------------------------------- + Enabled Boolean True to start the timer, False to stop it. + Interval Integer Timer interval in milliseconds (write-only from BASIC). +.endtable + +.h2 Type-Specific Methods + +.table + Method Parameters Description + ------ ---------- ------------------------------------------- + Start (none) Start the timer. + Stop (none) Stop the timer. +.endtable + +.h2 Type-Specific Events + +.table + Event Parameters Description + ----- ---------- ------------------------------------------- + Timer (none) Fires each time the interval elapses. This is the default event. +.endtable + +.note info +The Timer control fires the Timer event instead of Change. The onChange callback on the underlying widget is remapped automatically. +.endnote + +.h2 Example + +.code +Begin Timer Timer1 + Interval = 1000 + Enabled = True +End + +Dim counter As Integer + +Sub Timer1_Timer () + counter = counter + 1 + Label1.Caption = "Ticks: " & Str$(counter) +End Sub +.endcode + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.picturebox +.title PictureBox +.toc 0 Graphics Controls +.toc 1 PictureBox +.index PictureBox +.index Canvas +.index Drawing + +.h1 PictureBox + +VB Equivalent: PictureBox -- DVX Widget: canvas | Name Prefix: Picture + +A drawing surface (canvas). Supports drawing lines, rectangles, circles, text, and individual pixels. Can save and load BMP images. The default canvas size is 64x64 pixels. + +.h2 Type-Specific Methods + +.table + Method Parameters Description + ------ ---------------- ------------------------------------------- + Clear Color As Integer Fill the entire canvas with the specified color. +.endtable + +Additional drawing methods (DrawLine, DrawRect, FillRect, FillCircle, SetPixel, GetPixel, DrawText, Save, Load) are available through the C API but not currently exposed through BASIC interface descriptors. + +Default Event: Click + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.image +.title Image +.toc 1 Image +.index Image +.index Picture +.index BMP + +.h1 Image + +VB Equivalent: Image -- DVX Widget: image + +A static image display control. Loads BMP images from file. Cannot be placed via the designer toolbox (requires pixel data at creation time); typically created in code or loaded via the Picture property. + +.h2 Type-Specific Properties + +.table + Property Type Description + ----------- ------- ------------------------------------------- + Picture String Path to a BMP file to load (write-only). + ImageWidth Integer Width of the loaded image in pixels (read-only). + ImageHeight Integer Height of the loaded image in pixels (read-only). +.endtable + +Default Event: Click + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.imagebutton +.title ImageButton +.toc 1 ImageButton +.index ImageButton + +.h1 ImageButton + +DVX Extension -- DVX Widget: imagebutton + +A button that displays an image instead of text. Like Image, it requires pixel data at creation time and is typically loaded via the Picture property. + +.h2 Type-Specific Properties + +.table + Property Type Description + ----------- ------- ------------------------------------------- + Picture String Path to a BMP file to load (write-only). + ImageWidth Integer Width of the loaded image in pixels (read-only). + ImageHeight Integer Height of the loaded image in pixels (read-only). +.endtable + +Default Event: Click + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.progressbar +.title ProgressBar +.toc 1 ProgressBar +.index ProgressBar + +.h1 ProgressBar + +VB Equivalent: ProgressBar -- DVX Widget: progressbar + +A horizontal progress indicator bar. + +.h2 Type-Specific Properties + +.table + Property Type Description + -------- ------- ------------------------------------------- + Value Integer Current progress value (0-100). +.endtable + +No type-specific events or methods. No default event. + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.listview +.title ListView +.toc 0 Data Display Controls +.toc 1 ListView +.index ListView +.index Multi-Column List + +.h1 ListView + +VB Equivalent: ListView -- DVX Widget: listview + +A multi-column list with column headers. Supports sorting, multi-select, and drag-to-reorder. Columns are configured via the C API (SetColumns, SetData). + +.h2 Type-Specific Properties + +.table + Property Type Description + --------- ------- ------------------------------------------- + ListIndex Integer Index of the currently selected row (-1 = none). +.endtable + +.h2 Type-Specific Methods + +.table + Method Parameters Description + --------------- --------------------------------------- ------------------------------------------- + SelectAll (none) Select all rows. + ClearSelection (none) Deselect all rows. + SetMultiSelect Multi As Boolean Enable or disable multi-select. + SetReorderable Reorderable As Boolean Enable or disable row reordering. + IsItemSelected Index As Integer Returns True if the row at Index is selected. + SetItemSelected Index As Integer, Selected As Boolean Select or deselect a specific row. +.endtable + +Default Event: Click + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.treeview +.title TreeView +.toc 1 TreeView +.index TreeView + +.h1 TreeView + +VB Equivalent: TreeView -- DVX Widget: treeview + +A hierarchical tree of expandable/collapsible nodes. Nodes are created via the C API (wgtTreeItem). Supports multi-select and drag-to-reorder. + +.h2 Type-Specific Methods + +.table + Method Parameters Description + -------------- ---------------------- ------------------------------------------- + SetMultiSelect Multi As Boolean Enable or disable multi-select mode. + SetReorderable Reorderable As Boolean Enable or disable node reordering. +.endtable + +Default Event: Click + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.tabstrip +.title TabStrip +.toc 0 Tabbed and Split Controls +.toc 1 TabStrip +.index TabStrip +.index TabControl +.index SetActive + +.h1 TabStrip + +VB Equivalent: TabStrip -- DVX Widget: tabcontrol + +A tabbed container. Each tab page is a separate container that holds child controls. Switching tabs shows one page and hides others. + +.h2 Type-Specific Properties + +.table + Property Type Description + -------- ------- ------------------------------------------- + TabIndex Integer Index of the active tab (0-based). Note: this property name collides with the common VB-compatibility TabIndex property, which shadows it at runtime. Use the SetActive method instead to switch tabs. +.endtable + +.h2 Type-Specific Methods + +.table + Method Parameters Description + --------- ----------------- ------------------------------------------- + SetActive Index As Integer Switch to the tab at the given index. This is the recommended way to change tabs at runtime (the TabIndex property is shadowed by the common property handler). +.endtable + +Container: Yes + +Default Event: Click + +.note warning +The TabIndex property is shadowed by the common property handler at runtime. Use the SetActive method to change tabs programmatically. +.endnote + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.splitter +.title Splitter +.toc 1 Splitter +.index Splitter +.index Split Pane + +.h1 Splitter + +DVX Extension -- DVX Widget: splitter + +A resizable split pane. Holds exactly two child widgets separated by a draggable divider. Default orientation is vertical (top/bottom split). + +.h2 Type-Specific Properties + +.table + Property Type Description + -------- ------- ------------------------------------------- + Position Integer Position of the divider in pixels from the top (or left). +.endtable + +Container: Yes + +No default event. + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.scrollpane +.title ScrollPane +.toc 1 ScrollPane +.index ScrollPane +.index Scrollable Container + +.h1 ScrollPane + +DVX Extension -- DVX Widget: scrollpane | Name Prefix: Scroll + +A scrollable container. Place child controls inside and the ScrollPane automatically provides scrollbars when the content exceeds the visible area. + +.h2 Type-Specific Properties + +.table + Property Type Description + -------- ------- ------------------------------------------- + NoBorder Boolean When True, suppresses the border around the scroll pane. +.endtable + +Container: Yes + +No default event. + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.wrapbox +.title WrapBox +.toc 1 WrapBox +.index WrapBox +.index Flow Layout + +.h1 WrapBox + +DVX Extension -- DVX Widget: wrapbox + +A container that arranges children in a flowing layout, wrapping to the next row when the available width is exceeded. Similar to CSS flexbox with flex-wrap: wrap. + +.h2 Type-Specific Properties + +.table + Property Type Description + --------- ---- ------------------------------------------- + Alignment Enum Horizontal alignment of items: Left, Center, or Right. +.endtable + +Container: Yes + +Default Event: Click + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.line +.title Line +.toc 0 Decorative Controls +.toc 1 Line +.index Line +.index Separator + +.h1 Line + +VB Equivalent: Line -- DVX Widget: separator + +A visual separator line. The underlying widget supports both horizontal and vertical orientations. The default (via BASIC) is horizontal. + +No type-specific properties, events, or methods. + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.spacer +.title Spacer +.toc 1 Spacer +.index Spacer + +.h1 Spacer + +DVX Extension -- DVX Widget: spacer + +An invisible layout spacer. Takes up space in the layout without rendering anything. Useful for pushing controls apart. Give it a Weight to absorb extra space. + +No type-specific properties, events, or methods. + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.toolbar +.title Toolbar +.toc 0 Bar Controls +.toc 1 Toolbar +.index Toolbar + +.h1 Toolbar + +VB Equivalent: Toolbar -- DVX Widget: toolbar + +A horizontal container styled as a toolbar, with compact padding and spacing. Place buttons, labels, or other controls inside. + +Container: Yes + +No type-specific properties, events, or methods. + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.statusbar +.title StatusBar +.toc 1 StatusBar +.index StatusBar + +.h1 StatusBar + +VB Equivalent: StatusBar -- DVX Widget: statusbar + +A horizontal container styled as a status bar, typically placed at the bottom of a form. At the C API level it accepts child widgets, but it is not registered as a container in the form runtime, so child controls cannot be nested inside it in .frm files. Set its Caption property to display status text. + +No type-specific properties, events, or methods. + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.terminal +.title Terminal +.toc 0 Special Controls +.toc 1 Terminal +.index Terminal +.index ANSI Terminal +.index VT100 + +.h1 Terminal + +DVX Extension -- DVX Widget: ansiterm (ANSI terminal emulator) + +A VT100/ANSI terminal emulator widget. Supports ANSI escape sequences, scrollback buffer, and serial communication. Default size is 80 columns by 25 rows. + +.h2 Type-Specific Properties + +.table + Property Type Description + ---------- ------- ------------------------------------------- + Cols Integer Number of character columns (read-only). + Rows Integer Number of character rows (read-only). + Scrollback Integer Number of scrollback lines (write-only). +.endtable + +.h2 Type-Specific Methods + +.table + Method Parameters Description + ------ --------------- ------------------------------------------- + Clear (none) Clear the terminal screen. + Write Text As String Write text (with ANSI escape processing) to the terminal. +.endtable + +No default event. + +.link ctrl.common.props Common Properties, Events, and Methods + + +.topic ctrl.data +.title Data +.toc 0 Data Controls +.toc 1 Data +.index Data +.index Database +.index SQLite +.index DatabaseName +.index RecordSource +.index MoveFirst +.index MoveNext +.index AddNew +.index Reposition +.index Validate + +.h1 Data + +VB Equivalent: Data -- DVX Widget: data (database record navigator) + +A data access control that connects to a SQLite database and provides record navigation. Other controls can bind to a Data control via their DataSource and DataField properties. See .link ctrl.databinding Data Binding for details. + +.h2 Type-Specific Properties + +.table + Property Type R/W Description + ------------ ------- --- ------------------------------------------- + DatabaseName String R/W Path to the SQLite database file. + RecordSource String R/W Table name or SQL SELECT query for the recordset. + KeyColumn String R/W Primary key column name (used for UPDATE/DELETE operations). + Caption String R/W Text displayed on the navigator bar. + BOF Boolean R True if the current position is before the first record (read-only). + EOF Boolean R True if the current position is past the last record (read-only). + MasterSource String R/W Name of a master Data control (for master-detail binding). + MasterField String R/W Column in the master recordset to filter by. + DetailField String R/W Column in this recordset that matches the master field. +.endtable + +.h2 Type-Specific Methods + +.table + Method Parameters Description + ------------ ---------- ------------------------------------------- + MoveFirst (none) Navigate to the first record. + MoveLast (none) Navigate to the last record. + MoveNext (none) Navigate to the next record. + MovePrevious (none) Navigate to the previous record. + AddNew (none) Add a new blank record. + Delete (none) Delete the current record. + Refresh (none) Re-query the database and reload records. + Update (none) Write pending changes to the database. +.endtable + +.h2 Type-Specific Events + +.table + Event Parameters Description + ---------- ----------------- ------------------------------------------- + Reposition (none) Fires after the current record changes (navigation). This is the default event. + Validate Cancel As Integer Fires before writing a record. Set Cancel = 1 to abort. +.endtable + +.link ctrl.common.props Common Properties, Events, and Methods +.link ctrl.databinding Data Binding +.link ctrl.dbgrid DBGrid + + +.topic ctrl.dbgrid +.title DBGrid +.toc 1 DBGrid +.index DBGrid +.index Data-Bound Grid + +.h1 DBGrid + +VB Equivalent: DBGrid -- DVX Widget: dbgrid + +A data-bound grid that displays records from a Data control in a tabular format. Columns are auto-generated from the query results. Bind it using the DataSource property. + +.h2 Type-Specific Properties + +.table + Property Type Description + ---------- ------- ------------------------------------------- + DataSource String Name of the Data control that supplies records. + GridLines Boolean Show or hide grid lines between cells. +.endtable + +.h2 Type-Specific Methods + +.table + Method Parameters Description + ------- ---------- ------------------------------------------- + Refresh (none) Reload and redraw the grid from the Data control. +.endtable + +.h2 Type-Specific Events + +.table + Event Parameters Description + -------- ---------- ------------------------------------------- + Click (none) Fires when a cell is clicked. + DblClick (none) Fires when a cell is double-clicked. This is the default event. +.endtable + +.link ctrl.common.props Common Properties, Events, and Methods +.link ctrl.data Data +.link ctrl.databinding Data Binding + + +.topic ctrl.databinding +.title Data Binding +.toc 0 Data Binding +.index Data Binding +.index DataSource +.index DataField +.index Master-Detail + +.h1 Data Binding + +DVX BASIC provides VB3-style data binding through three properties that can be set on most controls: + +.table + Property Set On Description + ---------- ----------- ------------------------------------------- + DataSource Any control Name of the Data control to bind to (e.g. "Data1"). + DataField Any control Column name from the Data control's recordset to display. +.endtable + +.h2 How It Works + +.list +.item Place a Data control on the form and set its DatabaseName and RecordSource properties. +.item Place one or more display/edit controls (TextBox, Label, etc.) and set their DataSource to the Data control's name and DataField to a column name. +.item When the form loads, the Data control auto-refreshes: it opens the database, runs the query, and navigates to the first record. +.item Bound controls are updated automatically each time the Data control repositions (the Reposition event fires, and the runtime pushes the current record's field values into all bound controls). +.item When a bound control loses focus (LostFocus), its current text is written back to the Data control's record cache, and Update is called automatically to persist changes. +.endlist + +.h2 Master-Detail Binding + +For hierarchical data (e.g. orders and order items), use two Data controls: + +.list +.item A master Data control bound to the parent table. +.item A detail Data control with its MasterSource set to the master's name, MasterField set to the key column in the master, and DetailField set to the foreign key column in the detail table. +.endlist + +When the master record changes, the detail Data control automatically re-queries using the master's current value for filtering. All controls bound to the detail are refreshed. + +.h2 DBGrid Binding + +Set the DBGrid's DataSource to a Data control name. The grid auto-populates columns from the query results and refreshes whenever the Data control refreshes. + +.h2 Example + +.code +VERSION DVX 1.00 +Begin Form frmData + Caption = "Data Binding Example" + AutoSize = False + Width = 400 + Height = 280 + Begin Data Data1 + DatabaseName = "myapp.db" + RecordSource = "customers" + End + Begin Label lblName + Caption = "Name:" + End + Begin TextBox txtName + DataSource = "Data1" + DataField = "name" + End + Begin Label lblEmail + Caption = "Email:" + End + Begin TextBox txtEmail + DataSource = "Data1" + DataField = "email" + End +End + +Sub Data1_Reposition () + Print "Current record changed" +End Sub + +Sub Data1_Validate (Cancel As Integer) + If txtName.Text = "" Then + MsgBox "Name cannot be empty!" + Cancel = 1 + End If +End Sub +.endcode + +.link ctrl.data Data +.link ctrl.dbgrid DBGrid + + +.topic ctrl.menus +.title Menu System +.toc 0 Menu System +.index Menu +.index Menu Bar +.index Submenu +.index Separator + +.h1 Menu System + +Menus are defined in the .frm file using Begin Menu blocks. Each menu item has a name, caption, and nesting level. Menu items fire Click events dispatched as MenuName_Click. + +.h2 FRM Syntax + +.code +Begin Form Form1 + Caption = "Menu Demo" + + Begin Menu mnuFile + Caption = "&File" + Begin Menu mnuOpen + Caption = "&Open" + End + Begin Menu mnuSave + Caption = "&Save" + End + Begin Menu mnuSep1 + Caption = "-" + End + Begin Menu mnuExit + Caption = "E&xit" + End + End + + Begin Menu mnuEdit + Caption = "&Edit" + Begin Menu mnuCopy + Caption = "&Copy" + End + Begin Menu mnuPaste + Caption = "&Paste" + End + End +End +.endcode + +.h2 Menu Item Properties + +.table + Property Type Description + -------- ------- ------------------------------------------- + Caption String The text displayed. Use & for accelerator key. Set to "-" for a separator. + Checked Boolean Whether the menu item shows a checkmark. + Enabled Boolean Whether the menu item is enabled (default True). +.endtable + +.h2 Nesting + +Menu items are nested by placing Begin Menu blocks inside other Begin Menu blocks: + +.list +.item Level 0: top-level menu bar headers (e.g. "File", "Edit"). +.item Level 1: items within a top-level menu. +.item Level 2+: submenu items. +.endlist + +A level-0 menu that contains children becomes a top-level menu header. A non-level-0 menu that contains children becomes a submenu. + +.h2 Event Dispatch + +Each clickable menu item (not headers, not separators) receives a unique numeric ID at load time. When clicked, the form's onMenu handler maps the ID to the menu item's name and fires MenuName_Click. + +.code +Sub mnuOpen_Click () + MsgBox "Open was clicked" +End Sub + +Sub mnuExit_Click () + Unload Form1 +End Sub +.endcode + +.link ctrl.form Form +.link ctrl.frm FRM File Format + + +.topic ctrl.arrays +.title Control Arrays +.toc 0 Control Arrays +.index Control Arrays +.index Index Property + +.h1 Control Arrays + +DVX BASIC supports VB-style control arrays. Multiple controls can share the same name, differentiated by an Index property. When an event fires on a control array element, the element's index is passed as the first parameter. + +.h2 Defining Control Arrays in FRM + +.code +Begin CommandButton Command1 + Caption = "Button A" + Index = 0 +End +Begin CommandButton Command1 + Caption = "Button B" + Index = 1 +End +Begin CommandButton Command1 + Caption = "Button C" + Index = 2 +End +.endcode + +.h2 Event Handler Convention + +When a control has an Index property (>= 0), the event handler receives Index As Integer as the first parameter, before any event-specific parameters. + +.code +Sub Command1_Click (Index As Integer) + Select Case Index + Case 0 + MsgBox "Button A clicked" + Case 1 + MsgBox "Button B clicked" + Case 2 + MsgBox "Button C clicked" + End Select +End Sub +.endcode + +.h2 Accessing Array Elements in Code + +Use the indexed form ControlName(Index) to access a specific element: + +.code +Command1(0).Caption = "New Text" +Command1(1).Enabled = False +.endcode + +.note info +Control array elements share the same event handler Sub. The runtime prepends the Index argument automatically. If you define parameters on the Sub, Index comes first, followed by the event's own parameters (e.g. KeyPress would be Sub Ctrl1_KeyPress (Index As Integer, KeyAscii As Integer)). +.endnote + +.link ctrl.common.props Common Properties, Events, and Methods +.link ctrl.frm FRM File Format + + +.topic ctrl.frm +.title FRM File Format +.toc 0 FRM File Format +.index FRM +.index .frm +.index Form File + +.h1 FRM File Format + +The .frm file is a text file that describes a form's layout, controls, menus, and code. It follows a format compatible with VB3 .frm files, with DVX-specific extensions. + +.h2 Structure + +.code +VERSION DVX 1.00 +Begin Form FormName + form-level properties... + + Begin Menu mnuFile + Caption = "&File" + Begin Menu mnuOpen + Caption = "&Open" + End + End + + Begin TypeName ControlName + property = value + ... + End + + Begin Frame Frame1 + Caption = "Group" + Begin TypeName ChildName + ... + End + End +End + +BASIC code follows... + +Sub FormName_Load () + ... +End Sub +.endcode + +.h2 Rules + +.list +.item The VERSION line is optional. VERSION DVX 1.00 marks a native DVX form. VB forms with version <= 2.0 are accepted for import. +.item The form block begins with Begin Form Name and ends with End. +.item Controls are nested with Begin TypeName Name / End. +.item Container controls (Frame, VBox, HBox, Toolbar, TabStrip, ScrollPane, Splitter, WrapBox) can have child controls nested inside them. +.item Properties are assigned as Key = Value. String values are optionally quoted. +.item Everything after the form's closing End is BASIC source code. +.item Comments in the form section use ' (single quote). +.item Blank lines are ignored in the form section. +.endlist + +.h2 Common FRM Properties + +.table + Property Applies To Description + ----------------------- --------------- ------------------------------------------- + Caption Form, controls Display text or window title. + Text TextBox, ComboBox Initial text content. + MinWidth / Width Controls Minimum width. Both names are accepted. + MinHeight / Height Controls Minimum height. Both names are accepted. + MaxWidth Controls Maximum width (0 = no cap). + MaxHeight Controls Maximum height (0 = no cap). + Weight Controls Layout weight for flexible sizing. + Left Form, controls X position (used by Form when Centered=False; informational for controls). + Top Form, controls Y position. + Index Controls Control array index (-1 or absent = not in array). + Visible Controls Initial visibility. + Enabled Controls Initial enabled state. + Layout Form "VBox" or "HBox". + AutoSize Form Auto-fit window to content. + Resizable Form Allow runtime resizing. + Centered Form Center window on screen. + DatabaseName Data SQLite database file path. + RecordSource Data Table name or SQL query. + DataSource Bound controls Name of the Data control. + DataField Bound controls Column name in the recordset. +.endtable + +.link ctrl.form Form +.link ctrl.common.props Common Properties, Events, and Methods +.link ctrl.menus Menu System +.link ctrl.arrays Control Arrays diff --git a/docs/src/dvxbasic_ide_guide.dvxhelp b/docs/src/dvxbasic_ide_guide.dvxhelp new file mode 100644 index 0000000..1a73f69 --- /dev/null +++ b/docs/src/dvxbasic_ide_guide.dvxhelp @@ -0,0 +1,944 @@ +.topic ide.overview +.title DVX BASIC IDE Guide +.toc 0 Overview +.default +.index DVX BASIC +.index IDE +.index Visual Basic +.index Development Environment + +.h1 DVX BASIC IDE Guide + +DVX BASIC is a Visual BASIC development environment for the DVX GUI System. It provides a VB3-style integrated development environment with a code editor, form designer, project system, and a full interactive debugger -- all running natively on DOS under the DVX windowing system. + +This guide covers every feature of the IDE: menus, toolbar, editor, form designer, project management, debugger, and auxiliary windows. + +.h2 IDE Windows + +The DVX BASIC IDE is modeled after Visual Basic 3.0. It consists of several floating windows arranged on the DVX desktop: + +.list +.item Main Toolbar Window -- anchored at the top of the screen. Contains the menu bar, toolbar buttons, and status bar. +.item Code Editor -- the primary editing surface for BASIC source code, with Object/Event dropdowns, syntax highlighting, and line numbers. +.item Form Designer -- a visual design surface for .frm files, showing a WYSIWYG preview of the form with grab handles for resizing controls. +.item Project Explorer -- a tree view listing all files in the project. +.item Toolbox -- a palette of available controls for placing on forms. +.item Properties Panel -- a tree of controls and a list of editable properties for the selected control. +.item Output Window -- displays PRINT output and runtime errors. +.item Immediate Window -- an interactive REPL for evaluating expressions and modifying variables at runtime. +.item Debug Windows -- Locals, Call Stack, Watch, and Breakpoints windows that appear automatically when debugging. +.endlist + +The IDE compiles BASIC source into bytecode and runs it in an integrated virtual machine (VM). Programs execute in cooperative slices (10,000 VM steps per slice), yielding to the DVX event loop between slices so the GUI remains responsive. + +.link ide.menu.file File Menu +.link ide.menu.edit Edit Menu +.link ide.menu.run Run Menu +.link ide.menu.view View Menu +.link ide.menu.window Window Menu +.link ide.menu.tools Tools Menu +.link ide.menu.help Help Menu +.link ide.toolbar Toolbar +.link ide.editor Code Editor +.link ide.designer Form Designer +.link ide.project Project System +.link ide.properties Properties Panel +.link ide.toolbox Toolbox +.link ide.debugger Debugger +.link ide.debug.locals Locals Window +.link ide.debug.callstack Call Stack Window +.link ide.debug.watch Watch Window +.link ide.debug.breakpoints Breakpoints Window +.link ide.immediate Immediate Window +.link ide.output Output Window +.link ide.findreplace Find / Replace +.link ide.preferences Preferences +.link ide.shortcuts Keyboard Shortcuts + +.topic ide.menu.file +.title File Menu +.toc 0 Menu Reference +.toc 1 File Menu +.index File Menu +.index New Project +.index Open Project +.index Save Project +.index Close Project +.index Project Properties +.index Add File +.index Save File +.index Save All +.index Remove File +.index Exit + +.h1 File Menu + +.table + Menu Item Shortcut Description + --------- -------- ----------- + New Project... Create a new DVX BASIC project. + Open Project... Open an existing .dbp project file. + Save Project Save the current project file to disk. + Close Project Close the current project (prompts to save unsaved changes). + --- + Project Properties... Edit project metadata (name, author, version, startup form, icon, etc.). + --- + Add File... Ctrl+O Add a .bas or .frm file to the project. If no project is open, creates an implicit project from the file. + Save File Ctrl+S Save the active file to disk. + Save All Save all modified files in the project. + --- + Remove File Remove the selected file from the project (prompts to save if modified). + --- + Exit Close the IDE (prompts to save unsaved changes). +.endtable + +.link ide.menu.edit Edit Menu +.link ide.overview Back to Overview + +.topic ide.menu.edit +.title Edit Menu +.toc 1 Edit Menu +.index Edit Menu +.index Cut +.index Copy +.index Paste +.index Select All +.index Delete +.index Find +.index Find Next +.index Replace + +.h1 Edit Menu + +.table + Menu Item Shortcut Description + --------- -------- ----------- + Cut Ctrl+X Cut selected text to the clipboard. + Copy Ctrl+C Copy selected text to the clipboard. + Paste Ctrl+V Paste text from the clipboard. + --- + Select All Ctrl+A Select all text in the active editor. + --- + Delete Del Delete the selected text or control (in the form designer). + --- + Find... Ctrl+F Open the Find/Replace dialog. + Find Next F3 Find the next occurrence of the search text. + Replace... Ctrl+H Open the Find/Replace dialog with replace enabled. +.endtable + +.link ide.menu.run Run Menu +.link ide.overview Back to Overview + +.topic ide.menu.run +.title Run Menu +.toc 1 Run Menu +.index Run Menu +.index Run +.index Debug +.index Run Without Recompile +.index Stop +.index Step Into +.index Step Over +.index Step Out +.index Run to Cursor +.index Toggle Breakpoint +.index Clear Output +.index Save on Run + +.h1 Run Menu + +.table + Menu Item Shortcut Description + --------- -------- ----------- + Run F5 Compile and run the program. If paused at a breakpoint, resumes execution with debugging disabled (runs free). + Debug Shift+F5 Compile and run with the debugger active. Breakpoints are active but execution does not pause at the first statement. If paused, resumes to the next breakpoint. + Run Without Recompile Ctrl+F5 Re-run the last compiled module without recompiling. + Stop Esc Stop the running program immediately. + --- + Step Into F8 Execute one statement, stepping into SUB/FUNCTION calls. If idle, starts a debug session and breaks at the first statement. + Step Over Shift+F8 Execute one statement, stepping over SUB/FUNCTION calls. + Step Out Ctrl+Shift+F8 Run until the current SUB/FUNCTION returns. + Run to Cursor Ctrl+F8 Run until execution reaches the line where the cursor is positioned. + --- + Toggle Breakpoint F9 Toggle a breakpoint on the current editor line. + --- + Clear Output Clear the Output window. + --- + Save on Run Checkbox: when enabled, all modified files are saved automatically before compiling. Persisted in preferences. +.endtable + +.link ide.menu.view View Menu +.link ide.overview Back to Overview + +.topic ide.menu.view +.title View Menu +.toc 1 View Menu +.index View Menu +.index Code View +.index Design View +.index Toolbar Toggle +.index Status Bar Toggle +.index Menu Editor + +.h1 View Menu + +.table + Menu Item Shortcut Description + --------- -------- ----------- + Code F7 Switch to Code view for the active file (or the file selected in the Project Explorer). + Designer Shift+F7 Switch to Design view for the active form file. + --- + Toolbar Checkbox: show or hide the toolbar. Persisted in preferences. + Status Bar Checkbox: show or hide the status bar. Persisted in preferences. + --- + Menu Editor... Ctrl+E Open the Menu Editor dialog for the active form. Allows designing menu bars with captions, names, levels, checked state, and enabled state. +.endtable + +.link ide.menu.window Window Menu +.link ide.overview Back to Overview + +.topic ide.menu.window +.title Window Menu +.toc 1 Window Menu +.index Window Menu + +.h1 Window Menu + +.table + Menu Item Description + --------- ----------- + Code Editor Show or raise the Code Editor window. + Output Show or raise the Output window. + Immediate Show or raise the Immediate window. + Locals Show or raise the Locals debug window. + Call Stack Show or raise the Call Stack debug window. + Watch Show or raise the Watch debug window. + Breakpoints Show or raise the Breakpoints window. + --- + Project Explorer Show or raise the Project Explorer window. + Toolbox Show or raise the Toolbox window. + Properties Show or raise the Properties panel. +.endtable + +.link ide.menu.tools Tools Menu +.link ide.overview Back to Overview + +.topic ide.menu.tools +.title Tools Menu +.toc 1 Tools Menu +.index Tools Menu +.index Preferences +.index Debug Layout + +.h1 Tools Menu + +.table + Menu Item Description + --------- ----------- + Preferences... Open the Preferences dialog (editor settings and project defaults). + --- + Debug Layout Checkbox: toggle a debug overlay that shows widget layout boundaries. Useful for diagnosing widget layout issues. +.endtable + +.link ide.menu.help Help Menu +.link ide.overview Back to Overview + +.topic ide.menu.help +.title Help Menu +.toc 1 Help Menu +.index Help Menu +.index About + +.h1 Help Menu + +.table + Menu Item Description + --------- ----------- + About DVX BASIC... Show the About dialog with version and copyright information. +.endtable + +.link ide.overview Back to Overview + +.topic ide.toolbar +.title Toolbar +.toc 0 Toolbar +.index Toolbar + +.h1 Toolbar + +The toolbar is organized into four groups separated by vertical dividers. Each button has a tooltip showing its name and keyboard shortcut. + +.h2 File Group + +.table + Button Shortcut Action + ------ -------- ------ + Open Ctrl+O Add a file to the project (same as File > Add File). + Save Ctrl+S Save the active file. +.endtable + +.h2 Run Group + +.table + Button Shortcut Action + ------ -------- ------ + Run F5 Compile and run the program. + Stop Esc Stop the running program. +.endtable + +.h2 Debug Group + +.table + Button Shortcut Action + ------ -------- ------ + Debug Shift+F5 Start or resume a debug session. + Step Into F8 Step into the next statement. + Step Over Shift+F8 Step over the next statement. + Step Out Ctrl+Shift+F8 Step out of the current procedure. + Run to Cursor Ctrl+F8 Run to the cursor position. +.endtable + +.h2 View Group + +.table + Button Shortcut Action + ------ -------- ------ + Code F7 Switch to Code view. + Design Shift+F7 Switch to Design view. +.endtable + +.link ide.overview Back to Overview + +.topic ide.editor +.title Code Editor +.toc 0 Code Editor +.index Code Editor +.index Syntax Highlighting +.index Object Dropdown +.index Function Dropdown +.index Line Numbers +.index Auto-indent + +.h1 Code Editor + +The Code Editor is the primary editing window for BASIC source code. It occupies the center of the screen, below the toolbar and above the Output and Immediate windows. + +.h2 Object and Function Dropdowns + +At the top of the Code Editor are two dropdown lists: + +.list +.item Object -- lists (General) plus all objects (form name, control names, menu item names). Selecting an object filters the Function dropdown. +.item Function -- lists all event handlers (procedures) for the selected object. Implemented handlers are listed first (plain text); unimplemented handlers follow in brackets (e.g., [Click]). Selecting an unimplemented event creates a new event handler stub. +.endlist + +The editor shows one procedure at a time. Each procedure has its own buffer, and switching between them is instantaneous. The (General) section contains module-level declarations and code. + +.h2 Syntax Highlighting + +The editor applies real-time syntax coloring as you type. The following categories are highlighted in distinct colors: + +.table + Category Examples + -------- -------- + Keywords IF, THEN, FOR, NEXT, SUB, FUNCTION, DIM, PRINT, SELECT, CASE, DO, LOOP, WHILE, WEND, END, EXIT, CALL, GOSUB, GOTO, RETURN, DECLARE, CONST, TYPE, AND, OR, NOT, XOR, MOD, etc. + Type names INTEGER, LONG, SINGLE, DOUBLE, STRING, BOOLEAN, BYTE, TRUE, FALSE + String literals "Hello, World!" + Comments ' This is a comment, REM This is a comment + Numbers 42, 3.14 + Operators =, <, >, +, -, *, /, \, & +.endtable + +.h2 Editor Features + +.list +.item Line numbers -- displayed in the gutter on the left side. +.item Auto-indent -- new lines are automatically indented to match the previous line. +.item Tab handling -- the Tab key is captured by the editor. Tab width and whether to insert spaces or tab characters are configurable in Preferences (default: 3 spaces). +.item Gutter click -- clicking in the line number gutter toggles a breakpoint on that line. +.item Line decorations -- breakpoint lines show a red dot in the gutter. The current debug line (when paused) is highlighted with a yellow background. +.endlist + +.link ide.overview Back to Overview + +.topic ide.designer +.title Form Designer +.toc 0 Form Designer +.index Form Designer +.index Design Surface +.index Grid Snapping +.index Grab Handles +.index Control Placement +.index WYSIWYG + +.h1 Form Designer + +The Form Designer provides a visual design surface for editing .frm files. Switch to it with Shift+F7 or the Design toolbar button. It opens in a separate window showing a WYSIWYG preview of the form. + +.h2 Design Surface + +.list +.item Grid snapping -- controls snap to an 8-pixel grid (DSGN_GRID_SIZE) when placed or resized. +.item Selection -- click a control to select it. The selected control is highlighted with grab handles. +.item Grab handles -- 6x6 pixel handles appear on the right edge (E), bottom edge (S), and bottom-right corner (SE) of the selected control. Drag a handle to resize the control. +.item Reordering -- drag a control vertically to reorder it within the form's layout (VBox/HBox). +.item Placing controls -- select a control type in the Toolbox, then click on the form to place a new instance. The control is auto-named (e.g., Command1, Command2). Clicking the same tool again deselects it (toggles back to pointer mode). +.item Menu bar preview -- if the form has menu items (defined via the Menu Editor), a preview menu bar is rendered on the design window. +.item Delete key -- removes the selected control from the form. +.endlist + +.h2 Form Properties + +Forms have the following design-time properties: Name, Caption, Width, Height, Left, Top, Layout (VBox or HBox), Centered, AutoSize, and Resizable. + +.link ide.properties Properties Panel +.link ide.toolbox Toolbox +.link ide.overview Back to Overview + +.topic ide.project +.title Project System +.toc 0 Project System +.index Project System +.index Project Files +.index .dbp Files +.index Project Explorer +.index Source Map + +.h1 Project System + +.h2 Project Files (.dbp) + +A DVX BASIC project is stored as a .dbp file (DVX BASIC Project). The project file records: + +.list +.item Name -- the project display name (up to 32 characters). +.item Startup Form -- which form to show automatically when the program starts. +.item Metadata -- Author, Company, Version, Copyright, Description, and Icon Path (for compiled binaries). +.item File list -- relative paths (8.3 DOS names) of all .bas and .frm files in the project. Each entry tracks whether it is a form file. +.endlist + +.h2 Source Map + +When the project is compiled, all files are concatenated into a single source stream. A source map tracks which lines belong to which file, enabling accurate error reporting and debugger navigation across multiple files. For .frm files, an injected BEGINFORM directive is prepended to the code section. + +.h2 Project Operations + +.table + Operation Description + --------- ----------- + New Project Creates a blank project with a name and directory. A default .frm file is added automatically. + Open Project Opens a .dbp file and loads all referenced files into memory. + Save Project Writes the .dbp file to disk. + Close Project Closes the project, prompting to save unsaved changes. + Add File Adds a .bas or .frm file to the project. Opening a file without a project auto-creates an implicit project. + Remove File Removes a file from the project (prompts to save if modified). + Project Properties Opens a dialog for editing project metadata (name, author, company, version, copyright, description, icon, startup form). +.endtable + +.h2 Project Explorer + +The Project Explorer is a tree view window listing all project files. Double-click a file to open it: .bas files open in Code view, .frm files open in Design view. The selected file in the Project Explorer determines the target for View > Code and View > Designer commands. + +.link ide.overview Back to Overview + +.topic ide.properties +.title Properties Panel +.toc 0 Properties Panel +.index Properties Panel +.index Control Properties +.index Property List +.index Control Tree + +.h1 Properties Panel + +The Properties panel (Window > Properties) has two sections: + +.list +.item Control tree -- a TreeView at the top listing the form and all its controls in layout order. Click a control name to select it in both the Properties panel and the Form Designer. Drag items in the tree to reorder controls in the form's layout. +.item Property list -- a two-column ListView below the tree showing property names and values for the selected control. Double-click a property value to edit it via an InputBox dialog. Changes take effect immediately in the designer preview. +.endlist + +Each control type exposes different properties (e.g., Caption, Text, Width, Height, MaxWidth, MaxHeight, Weight, Alignment, Enabled, Visible, and type-specific properties like DataSource and DataField for data-bound controls). + +.link ide.designer Form Designer +.link ide.overview Back to Overview + +.topic ide.toolbox +.title Toolbox +.toc 0 Toolbox +.index Toolbox +.index Controls +.index Widget Palette + +.h1 Toolbox + +The Toolbox (Window > Toolbox) is a floating palette of buttons, one for each available control type. Controls are loaded dynamically from the widget plugin registry -- any widget DXE that provides a basName appears in the toolbox. + +Click a tool to select it (the active tool name is stored in the designer state), then click on the form to place a new instance. Click the same tool again to deselect it and return to pointer mode. + +.h2 Available Controls + +.table + VB Name Description + ------- ----------- + CommandButton Push button that triggers a Click event. + Label Static text label. + TextBox Single-line text input field. + TextArea Multi-line text editor. + CheckBox On/off checkbox. + OptionButton Radio button (mutually exclusive within a group). + ListBox Scrollable list of items. + ComboBox Drop-down combo box. + DropDown Simple drop-down list. + PictureBox Canvas for drawing and images. + Image Static image display. + ImageButton Clickable image button. + Frame Grouping container with a labeled border. + VBox Vertical layout container. + HBox Horizontal layout container. + WrapBox Flow layout container that wraps items to the next row. + Splitter Resizable split between two child panes. + ScrollPane Scrollable container for large content. + TabStrip Tabbed container with multiple pages. + ListView Multi-column list with headers. + TreeView Hierarchical tree control. + ProgressBar Progress indicator bar. + HScrollBar Horizontal slider/scrollbar. + SpinButton Numeric up/down spinner. + Line Horizontal or vertical separator line. + Spacer Invisible spacing element for layout. + Timer Non-visual timer that fires periodic events. + Toolbar Toolbar container for buttons. + StatusBar Status bar at the bottom of a form. + Terminal ANSI terminal emulator control. + Data Data control for binding to a database. + DBGrid Data-bound grid for displaying database query results. +.endtable + +.link ide.designer Form Designer +.link ide.overview Back to Overview + +.topic ide.debugger +.title Debugger +.toc 0 Debugger +.index Debugger +.index Breakpoints +.index Stepping +.index Debug Mode +.index DBG_IDLE +.index DBG_RUNNING +.index DBG_PAUSED + +.h1 Debugger + +The DVX BASIC IDE includes a full interactive debugger. The debugger operates as a state machine with three states: + +.table + State Description + ----- ----------- + DBG_IDLE No program loaded or running. + DBG_RUNNING Program is executing (VM running in slices). + DBG_PAUSED Execution is paused at a breakpoint or step point. The IDE GUI is fully interactive. +.endtable + +.h2 Starting a Debug Session + +.list +.item Shift+F5 (Debug) -- compiles the project and starts execution in debug mode. Breakpoints are active but execution does not pause at the first statement. +.item F8 (Step Into) -- if idle, starts a debug session and breaks at the first statement. +.item F5 (Run) -- compiles and runs without the debugger. No breakpoints are active. If already paused, resumes execution with debugging disabled. +.endlist + +.h2 Breakpoints + +.h3 Setting Breakpoints + +.list +.item Press F9 to toggle a breakpoint on the current editor line. +.item Click in the line number gutter to toggle a breakpoint on that line. +.endlist + +.h3 Breakpoint Validation + +Not every line can have a breakpoint. The IDE validates the line content and silently refuses to set breakpoints on: + +.list +.item Blank lines +.item Comment lines (' or REM) +.item SUB and FUNCTION declaration lines +.item END SUB and END FUNCTION lines +.endlist + +.h3 Breakpoint Storage + +Each breakpoint records the project file index, the code line number within the file, the procedure index, and the procedure name (as Object.Event). When the project is compiled, breakpoints are converted to concatenated source line numbers that match the VM's OP_LINE opcodes. + +.h3 Visual Indicators + +.list +.item Breakpoint lines show a red dot in the gutter. +.item The current debug line (when paused) has a yellow background. +.endlist + +.h3 Breakpoint Adjustment on Edit + +When lines are added or removed in the editor, breakpoints below the edit point are automatically shifted to stay on the correct line. + +.h2 Stepping + +.table + Action Shortcut Behavior + ------ -------- -------- + Step Into F8 Execute one statement. If the statement is a SUB/FUNCTION call, step into it. + Step Over Shift+F8 Execute one statement. If the statement is a SUB/FUNCTION call, execute the entire call and break at the next line in the current scope. + Step Out Ctrl+Shift+F8 Run until the current SUB/FUNCTION returns to its caller. + Run to Cursor Ctrl+F8 Run until execution reaches the line under the cursor. +.endtable + +.h2 The Debug Run Loop + +When a program is running in debug mode, the IDE enters a cooperative loop: + +.list +.item The VM executes up to 10,000 steps per slice. +.item If the VM hits a breakpoint (BAS_VM_BREAKPOINT), the state transitions to DBG_PAUSED. The IDE navigates the code editor to the breakpoint line, highlights it in yellow, auto-opens the Locals and Call Stack windows, and updates all debug windows. +.item While paused, the IDE pumps dvxUpdate() continuously, keeping the GUI responsive. The user can inspect variables, modify them in the Immediate window, step, continue, or stop. +.item When the user resumes (F5/Shift+F5/F8/etc.), the state transitions back to DBG_RUNNING and the loop continues. +.endlist + +.h2 Stopping + +Press Esc or click the Stop toolbar button at any time to halt execution. The VM is destroyed, debug state resets to DBG_IDLE, and the IDE restores the designer windows that were hidden at run start. + +.link ide.debug.locals Locals Window +.link ide.debug.callstack Call Stack Window +.link ide.debug.watch Watch Window +.link ide.debug.breakpoints Breakpoints Window +.link ide.overview Back to Overview + +.topic ide.debug.locals +.title Locals Window +.toc 0 Debug Windows +.toc 1 Locals Window +.index Locals Window +.index Variable Inspection + +.h1 Locals Window + +When the debugger pauses, the Locals and Call Stack windows are auto-opened (if not already visible). The Watch and Breakpoints windows can be opened manually from the Window menu. + +Shows variables for the current execution scope. Displayed as a three-column ListView: + +.table + Column Content + ------ ------- + Name Variable name (internal mangled names like static variable placeholders are filtered out). + Type Data type: Integer, Long, Single, Double, String, Boolean, Array, UDT. Array types show the element type (e.g., Integer()). + Value Current value. Strings are shown in quotes. Booleans as True/False. Arrays show bounds and element count (e.g., Integer(0 To 9) [10]). Uninitialized arrays show (uninitialized). +.endtable + +The Locals window displays: + +.list +.item Local variables for the current procedure (matched by proc index). +.item Global (module-level) variables. +.item Form-scoped variables for the current form (if the program is executing within a form context). +.endlist + +Up to 64 variables are displayed. The window is resizable. + +.link ide.debug.callstack Call Stack Window +.link ide.overview Back to Overview + +.topic ide.debug.callstack +.title Call Stack Window +.toc 1 Call Stack Window +.index Call Stack +.index Stack Trace + +.h1 Call Stack Window + +Shows the current call chain as a two-column ListView: + +.table + Column Content + ------ ------- + Procedure Procedure name (or (module) for module-level code). + Line Line number where execution is paused (shown for the topmost frame). +.endtable + +The current location is shown first, followed by each caller in the call stack (walking from the deepest frame back to the module entry point). Up to 32 frames are displayed. + +.link ide.debug.watch Watch Window +.link ide.overview Back to Overview + +.topic ide.debug.watch +.title Watch Window +.toc 1 Watch Window +.index Watch Window +.index Watch Expressions + +.h1 Watch Window + +Allows monitoring arbitrary expressions while debugging. The window has a text input at the top and a two-column ListView below: + +.table + Column Content + ------ ------- + Expression The watch expression text. + Value Evaluated result (or if evaluation fails). Blank when not paused. +.endtable + +.h2 Adding Watch Expressions + +Type an expression in the text input and press Enter. Up to 16 watch expressions can be active at once. + +.h2 Watch Expression Syntax + +Watch expressions support: + +.list +.item Simple variable names: x, count +.item Array subscripts: arr(5), matrix(2, 3) +.item UDT field access: player.name +.item Combined: items(i).price +.item Arbitrary BASIC expressions (compiled and evaluated against the paused VM's state): x + y * 2, Len(name$) +.endlist + +.h2 Editing and Deleting + +.list +.item Double-click or press Enter on a watch entry to move it back into the input box for editing. +.item Press Delete to remove the selected watch expression. +.endlist + +.link ide.debug.breakpoints Breakpoints Window +.link ide.overview Back to Overview + +.topic ide.debug.breakpoints +.title Breakpoints Window +.toc 1 Breakpoints Window +.index Breakpoints Window + +.h1 Breakpoints Window + +Lists all set breakpoints as a three-column ListView: + +.table + Column Content + ------ ------- + File Project file path. + Procedure Procedure name (Object.Event format, or (General)). + Line Code line number within the file. +.endtable + +.list +.item Double-click a breakpoint to navigate the code editor to that location. +.item Press Delete to remove selected breakpoints (multi-select is supported). +.endlist + +.link ide.debugger Debugger +.link ide.overview Back to Overview + +.topic ide.immediate +.title Immediate Window +.toc 0 Immediate Window +.index Immediate Window +.index REPL +.index Expression Evaluation +.index Variable Assignment + +.h1 Immediate Window + +The Immediate window is an interactive REPL at the bottom-right of the screen. Type a line of BASIC and press Enter to evaluate it. Results appear inline below your input. + +.h2 Expression Evaluation + +If the input is not a recognized statement keyword, it is automatically wrapped in a PRINT statement. For example, typing 2 + 2 evaluates as PRINT 2 + 2 and displays 4. + +You can also type full statements: + +.list +.item PRINT x * 2 -- evaluate and print an expression. +.item DIM tmp As Integer -- declare a temporary variable. +.item LET x = 42 -- explicit assignment (see below). +.endlist + +Parse or runtime errors are displayed inline with an Error: prefix. + +.h2 Inspecting Variables While Paused + +When the debugger is paused at a breakpoint, the Immediate window has access to the running VM's state. Global variable values are copied into the evaluation VM, so expressions like count or name$ & " test" display live values. + +.h2 Assigning Variables While Paused + +When paused, you can modify variables in the running program directly from the Immediate window using assignment syntax: + +.code +variableName = newValue +.endcode + +The optional LET keyword is also accepted: + +.code +LET variableName = newValue +.endcode + +Assignment works for: + +.list +.item Scalar variables -- x = 42, name$ = "test" +.item Array elements -- arr(5) = 100, matrix(2, 3) = 7.5 +.item UDT fields -- player.score = 1000 +.item Combined -- items(0).price = 9.99 +.endlist + +The new value is written directly into the VM's live variable slot (local, global, or form scope). A confirmation message is displayed, and the Locals and Watch windows update automatically to reflect the change. + +If the assignment target cannot be resolved (unknown variable, out-of-bounds index, wrong type), an error message is displayed. + +.link ide.overview Back to Overview + +.topic ide.output +.title Output Window +.toc 0 Output Window +.index Output Window +.index PRINT Output +.index Runtime Errors +.index Compile Errors + +.h1 Output Window + +The Output window is a read-only TextArea at the bottom-left of the screen. It displays: + +.list +.item PRINT output -- all PRINT statement output from the running program is appended here. +.item Runtime errors -- if the VM encounters a runtime error (division by zero, out-of-bounds, etc.), the error message and line number are displayed in the output with an Error on line N: prefix. +.item Compile errors -- if compilation fails, the error message and location are shown. +.endlist + +The output buffer holds up to 32,768 characters. Use Run > Clear Output to clear it. + +INPUT statements prompt the user via a modal InputBox dialog; the prompt text is also echoed to the Output window. + +.link ide.overview Back to Overview + +.topic ide.findreplace +.title Find / Replace +.toc 0 Find / Replace +.index Find +.index Replace +.index Find Next +.index Search + +.h1 Find / Replace + +Open with Ctrl+F (Find) or Ctrl+H (Replace). The Find/Replace dialog is modeless -- it stays open while you continue editing. + +.h2 Dialog Controls + +.table + Control Description + ------- ----------- + Find input The text to search for. + Replace checkbox + input Enable replacement mode and enter replacement text. + Scope Radio group: Function, Object, File, or Project. Default is Project. + Direction Radio group: Forward or Backward. + Match Case Checkbox: case-sensitive search. +.endtable + +.h2 Buttons + +.table + Button Action + ------ ------ + Find Next Find the next occurrence. Wraps across procedures, files, and the entire project depending on the scope setting. + Replace Replace the current match and find the next one. + Replace All Replace all occurrences within the selected scope. + Close Close the dialog. +.endtable + +.h2 Keyboard Shortcut + +F3 repeats the last search (Find Next) without opening the dialog. + +.link ide.overview Back to Overview + +.topic ide.preferences +.title Preferences +.toc 0 Preferences +.index Preferences +.index Settings +.index Tab Width +.index Option Explicit + +.h1 Preferences + +Open via Tools > Preferences. Settings are saved to dvxbasic.ini in the app's config directory. + +.h2 Editor Section + +.table + Setting Description Default + ------- ----------- ------- + Skip comments/strings when renaming When renaming a control or form, skip occurrences inside comments and string literals. On + Require variable declaration (OPTION EXPLICIT) When enabled, variables must be declared with DIM before use. Off + Tab width Number of spaces per tab stop (1-8). 3 + Insert spaces instead of tabs When enabled, pressing Tab inserts spaces. When disabled, inserts a real tab character. On +.endtable + +.h2 New Project Defaults Section + +These fields set the default values for new project metadata: + +.table + Field Description Default + ----- ----------- ------- + Author Default author name. (empty) + Company Default company name. (empty) + Version Default version string. 1.0 + Copyright Default copyright notice. (empty) + Description Default project description (multi-line). (empty) +.endtable + +.link ide.overview Back to Overview + +.topic ide.shortcuts +.title Keyboard Shortcuts +.toc 0 Keyboard Shortcuts +.index Keyboard Shortcuts +.index Hotkeys +.index Accelerators + +.h1 Keyboard Shortcuts + +.table + Shortcut Action + -------- ------ + Ctrl+O Add File + Ctrl+S Save File + Ctrl+A Select All + Ctrl+X Cut + Ctrl+C Copy + Ctrl+V Paste + Ctrl+F Find + Ctrl+H Replace + Ctrl+E Menu Editor + F3 Find Next + F5 Run + Shift+F5 Debug + Ctrl+F5 Run Without Recompile + Esc Stop + F7 Code View + Shift+F7 Design View + F8 Step Into + Shift+F8 Step Over + Ctrl+Shift+F8 Step Out + Ctrl+F8 Run to Cursor + F9 Toggle Breakpoint + Del Delete +.endtable + +.hr + +DVX BASIC 1.0 -- Copyright 2026 Scott Duensing diff --git a/docs/src/dvxbasic_language_reference.dvxhelp b/docs/src/dvxbasic_language_reference.dvxhelp new file mode 100644 index 0000000..9aaf3ad --- /dev/null +++ b/docs/src/dvxbasic_language_reference.dvxhelp @@ -0,0 +1,1574 @@ +.topic lang.datatypes +.title Data Types +.toc 0 Data Types +.default +.index Data Types +.index Integer +.index Long +.index Single +.index Double +.index String +.index Boolean + +.h1 Data Types + +DVX BASIC supports the following data types. Each type has a corresponding type suffix character that can be appended to variable names. + +.h2 Primary Types + +.table + Type Size Suffix Range / Description + ---- ---- ------ ------------------- + Integer 2 bytes % -32768 to 32767 + Long 4 bytes & -2147483648 to 2147483647 + Single 4 bytes ! 32-bit float, approximately 7 digits precision + Double 8 bytes # 64-bit float, approximately 15 digits precision + String variable $ Variable-length, reference-counted, dynamic string + Boolean 2 bytes (none) True (-1) or False (0) +.endtable + +.h2 Internal Types + +These types are not directly declarable but are used internally by the runtime. + +.table + Internal Type Description + ------------- ----------- + Array Reference-counted multi-dimensional array (up to 8 dimensions) + UDT User-defined type instance (created with TYPE...END TYPE) + Object Opaque host object (form reference, control reference) + Ref ByRef pointer to a variable slot (used for ByRef parameters) +.endtable + +.h2 Type Suffixes + +Type suffixes can be appended to variable names to declare their type implicitly: + +.code +count% = 42 ' Integer +total& = 100000 ' Long +rate! = 3.14 ' Single +pi# = 3.14159265 ' Double +name$ = "Hello" ' String +.endcode + +.h2 Numeric Literals + +.table + Form Example Description + ---- ------- ----------- + Decimal integer 42 Values -32768..32767 are Integer; larger are Long + Hex integer &HFF Hexadecimal literal + Long suffix 42&, &HFF& Force Long type + Floating-point 3.14, 1.5E10 Double by default + Single suffix 3.14! Force Single type + Double suffix 3.14# Force Double type +.endtable + +.h2 Type Promotion + +When mixing types in expressions, values are automatically promoted to a common type: Integer -> Long -> Single -> Double. Strings are not automatically converted to numbers (use VAL and STR$). + +.link lang.func.conversion See also: Conversion Functions + +.topic lang.operators +.title Operators +.toc 0 Operators +.index Operators +.index Precedence +.index AND +.index OR +.index NOT +.index XOR +.index EQV +.index IMP +.index MOD + +.h1 Operators + +Operators listed from highest precedence (evaluated first) to lowest precedence (evaluated last). + +.table + Precedence Operator Description + ---------- -------- ----------- + 1 (highest) ^ Exponentiation + 2 - (unary) Negation + 3 * / \ MOD Multiply, float div, integer div, modulus + 4 + - Addition, subtraction + 5 & String concatenation + 6 = <> < > <= >= Comparison (returns Boolean) + 7 NOT Logical/bitwise NOT + 8 AND Logical/bitwise AND + 9 XOR Logical/bitwise XOR + 10 OR Logical/bitwise OR + 11 EQV Logical/bitwise equivalence + 12 (lowest) IMP Logical/bitwise implication +.endtable + +.h2 String Concatenation + +Use & to concatenate strings. The + operator also concatenates when both operands are strings. + +.code +result$ = "Hello" & " " & "World" +result$ = firstName$ & " " & lastName$ +.endcode + +.topic lang.statements +.title Statements Overview +.toc 0 Statements +.index Statements +.index REM +.index Comments + +.h1 Statements + +Multiple statements can appear on one line separated by :. Lines can be continued with _ at the end. Comments start with ' or REM. + +.link lang.declarations Declaration Statements (DIM, REDIM, CONST, TYPE) +.link lang.conditionals Conditional Statements (IF, SELECT CASE) +.link lang.loops Loop Statements (FOR, DO, WHILE) +.link lang.procedures Procedures (SUB, FUNCTION, DEF FN) +.link lang.flow Flow Control (EXIT, CALL, GOTO, GOSUB, ON) +.link lang.io Input/Output (PRINT, INPUT, DATA/READ) +.link lang.misc Miscellaneous Statements + +.topic lang.declarations +.title Declaration Statements +.toc 1 Declarations +.index DIM +.index REDIM +.index CONST +.index TYPE +.index END TYPE +.index DECLARE +.index DECLARE LIBRARY +.index SHARED +.index STATIC +.index OPTION +.index OPTION BASE +.index OPTION COMPARE +.index OPTION EXPLICIT +.index DEFINT +.index DEFLNG +.index DEFSNG +.index DEFDBL +.index DEFSTR +.index LET +.index SWAP +.index ERASE + +.h1 Declaration Statements + +.h2 DIM + +Declares variables and arrays with an explicit type. + +.code +DIM variable AS type +DIM variable(upperBound) AS type +DIM variable(lower TO upper) AS type +DIM variable(dim1, dim2, ...) AS type +DIM variable AS UdtName +DIM variable AS STRING * n +DIM SHARED variable AS type +.endcode + +Examples: + +.code +Dim name As String +Dim count As Integer +Dim values(100) As Double +Dim matrix(1 To 10, 1 To 10) As Single +Dim Shared globalFlag As Boolean +Dim record As PersonType +Dim fixedStr As String * 20 +.endcode + +.note info +DIM SHARED makes a variable accessible from all procedures without passing it as a parameter. +.endnote + +.h2 REDIM + +Reallocates a dynamic array, optionally preserving existing data. + +.code +REDIM array(newBounds) AS type +REDIM PRESERVE array(newBounds) AS type +.endcode + +.code +ReDim items(newSize) As String +ReDim Preserve scores(1 To newCount) As Integer +.endcode + +.h2 CONST + +Declares a named constant. The value must be a literal (integer, float, string, or boolean). + +.code +CONST name = value +.endcode + +.code +Const MAX_SIZE = 100 +Const PI = 3.14159265 +Const APP_NAME = "DVX App" +Const DEBUG_MODE = True +.endcode + +.h2 TYPE...END TYPE + +Defines a user-defined type (record/structure). + +.code +TYPE TypeName + fieldName AS type + ... +END TYPE +.endcode + +.code +Type PersonType + firstName As String + lastName As String + age As Integer +End Type + +Dim p As PersonType +p.firstName = "Scott" +p.age = 30 +.endcode + +UDT fields can themselves be UDTs (nested types). + +.h2 DECLARE + +Forward-declares a SUB or FUNCTION. Required when a procedure is called before it is defined. + +.code +DECLARE SUB name ([BYVAL] param AS type, ...) +DECLARE FUNCTION name ([BYVAL] param AS type, ...) AS returnType +.endcode + +.h2 DECLARE LIBRARY + +Declares external native functions from a dynamically loaded library. This allows BASIC programs to call functions exported by DXE libraries. + +.code +DECLARE LIBRARY "libraryName" + DECLARE SUB name ([BYVAL] param AS type, ...) + DECLARE FUNCTION name ([BYVAL] param AS type, ...) AS returnType +END DECLARE +.endcode + +.code +Declare Library "rs232" + Declare Function ComOpen(ByVal port As Integer) As Integer + Declare Sub ComClose(ByVal port As Integer) + Declare Sub ComSend(ByVal port As Integer, ByVal data$ As String) +End Declare +.endcode + +.h2 STATIC + +Declares a local variable that retains its value between calls. + +.code +STATIC variable AS type +.endcode + +.code +Sub Counter() + Static count As Integer + count = count + 1 + Print count +End Sub +.endcode + +.h2 OPTION + +Sets compiler options. Must appear before any executable code. + +.code +OPTION BASE 0 ' Arrays start at index 0 (default) +OPTION BASE 1 ' Arrays start at index 1 +OPTION COMPARE BINARY ' Case-sensitive string comparisons (default) +OPTION COMPARE TEXT ' Case-insensitive string comparisons +OPTION EXPLICIT ' All variables must be declared with DIM +.endcode + +.h2 DEFtype Statements + +Set the default type for variables based on their first letter. + +.code +DEFINT letterRange +DEFLNG letterRange +DEFSNG letterRange +DEFDBL letterRange +DEFSTR letterRange +.endcode + +.code +DefInt I-N ' Variables starting with I through N default to Integer +DefStr S ' Variables starting with S default to String +.endcode + +.h2 Assignment + +Assigns a value to a variable, array element, or UDT field. + +.code +variable = expression +array(index) = expression +udt.field = expression +LET variable = expression +.endcode + +The LET keyword is optional and supported for compatibility. + +.h2 SWAP + +Exchanges the values of two variables. + +.code +SWAP variable1, variable2 +.endcode + +.code +Swap a, b +.endcode + +.h2 ERASE + +Frees the memory of an array and resets it. + +.code +ERASE arrayName +.endcode + +.topic lang.conditionals +.title Conditional Statements +.toc 1 Conditionals +.index IF +.index THEN +.index ELSE +.index ELSEIF +.index END IF +.index SELECT CASE +.index CASE +.index CASE ELSE +.index END SELECT + +.h1 Conditional Statements + +.h2 IF...THEN...ELSE...END IF + +Conditional execution. Supports single-line and multi-line forms. + +.h3 Single-line form + +.code +IF condition THEN statement +IF condition THEN statement ELSE statement +.endcode + +.h3 Multi-line form + +.code +IF condition THEN + statements +ELSEIF condition THEN + statements +ELSE + statements +END IF +.endcode + +.code +If x > 10 Then + Print "Large" +ElseIf x > 5 Then + Print "Medium" +Else + Print "Small" +End If + +If ready Then Print "Go!" +.endcode + +.h2 SELECT CASE + +Multi-way branch based on an expression value. + +.code +SELECT CASE expression + CASE value + statements + CASE value1, value2 + statements + CASE low TO high + statements + CASE IS operator value + statements + CASE ELSE + statements +END SELECT +.endcode + +.code +Select Case grade + Case 90 To 100 + Print "A" + Case 80 To 89 + Print "B" + Case Is >= 70 + Print "C" + Case 60, 65 + Print "D (borderline)" + Case Else + Print "F" +End Select +.endcode + +CASE items can be combined with commas. The IS keyword allows comparison operators: <, >, <=, >=, =, <>. + +.topic lang.loops +.title Loop Statements +.toc 1 Loops +.index FOR +.index NEXT +.index STEP +.index DO +.index LOOP +.index WHILE +.index WEND +.index UNTIL +.index EXIT FOR +.index EXIT DO + +.h1 Loop Statements + +.h2 FOR...NEXT + +Counted loop with an optional step value. + +.code +FOR variable = start TO limit [STEP step] + statements +NEXT [variable] +.endcode + +.code +For i = 1 To 10 + Print i +Next i + +For x = 10 To 0 Step -2 + Print x +Next +.endcode + +The variable name after NEXT is optional. Use EXIT FOR to break out early. + +.h2 DO...LOOP + +General-purpose loop with pre-test, post-test, or infinite forms. + +.code +DO [WHILE condition | UNTIL condition] + statements +LOOP [WHILE condition | UNTIL condition] +.endcode + +.code +' Pre-test +Do While count < 10 + count = count + 1 +Loop + +' Post-test +Do + line$ = ReadLine() +Loop Until line$ = "quit" + +' Infinite loop (exit with EXIT DO) +Do + DoEvents + If done Then Exit Do +Loop +.endcode + +.h2 WHILE...WEND + +Simple pre-test loop (legacy form; prefer DO...LOOP). + +.code +WHILE condition + statements +WEND +.endcode + +.code +While Not EOF(1) + Line Input #1, line$ + Print line$ +Wend +.endcode + +.topic lang.procedures +.title Procedures +.toc 1 Procedures +.index SUB +.index END SUB +.index FUNCTION +.index END FUNCTION +.index DEF FN +.index BYVAL +.index BYREF +.index EXIT SUB +.index EXIT FUNCTION + +.h1 Procedures + +.h2 SUB...END SUB + +Defines a subroutine (no return value). + +.code +SUB name ([BYVAL] param AS type, ...) + statements +END SUB +.endcode + +.code +Sub Greet(ByVal name As String) + Print "Hello, " & name +End Sub +.endcode + +Parameters are passed ByRef by default. Use ByVal for value semantics. Use EXIT SUB to return early. + +.h2 FUNCTION...END FUNCTION + +Defines a function with a return value. + +.code +FUNCTION name ([BYVAL] param AS type, ...) AS returnType + statements + name = returnValue +END FUNCTION +.endcode + +.code +Function Square(ByVal n As Double) As Double + Square = n * n +End Function +.endcode + +Assign to the function name to set the return value. Use EXIT FUNCTION to return early. + +.h2 DEF FN + +Defines a single-expression function. + +.code +DEF FNname(params) = expression +.endcode + +.code +Def FnSquare(x) = x * x +Print FnSquare(5) ' prints 25 +.endcode + +.topic lang.flow +.title Flow Control +.toc 1 Flow Control +.index EXIT +.index CALL +.index GOTO +.index GOSUB +.index RETURN +.index ON GOTO +.index ON GOSUB + +.h1 Flow Control + +.h2 EXIT + +Exits the current block early. + +.code +EXIT FOR +EXIT DO +EXIT SUB +EXIT FUNCTION +.endcode + +.h2 CALL + +Explicitly calls a subroutine or function. The return value (if any) is discarded. + +.code +CALL name +CALL name(args) +.endcode + +Normally you can omit CALL and just use the name directly. + +.h2 GOTO / GOSUB / RETURN + +.code +GOTO label +GOSUB label +RETURN +.endcode + +GOSUB pushes the return address, executes code at the label, and RETURN jumps back. At module level, RETURN returns from a GOSUB. Inside a SUB/FUNCTION, RETURN returns from the procedure. + +.code +GoSub Initialize +Print "Done" +End + +Initialize: + count = 0 + name$ = "" +Return +.endcode + +.h2 ON...GOTO / ON...GOSUB + +Computed branch based on an integer expression. + +.code +ON expression GOTO label1, label2, ... +ON expression GOSUB label1, label2, ... +.endcode + +If the expression evaluates to 1, control goes to the first label; 2, the second; and so on. If out of range, execution falls through. + +.topic lang.io +.title Input/Output Statements +.toc 1 Input/Output +.index PRINT +.index INPUT +.index DATA +.index READ +.index RESTORE +.index SPC +.index TAB +.index PRINT USING + +.h1 Input/Output Statements + +.h2 PRINT + +Outputs text to the console or to a file channel. + +.code +PRINT [expression] [{; | ,} expression] ... +PRINT #channel, expression +PRINT USING format$; expression [; expression] ... +.endcode + +.list +.item ; between items -- no separator (items are concatenated) +.item , between items -- advance to the next 14-column tab zone +.item Trailing ; or , suppresses the newline +.item ? is an alias for PRINT +.endlist + +Special functions inside PRINT: + +.list +.item SPC(n) -- print n spaces +.item TAB(n) -- advance to column n +.endlist + +.code +Print "Name:"; Tab(20); name$ +Print Using "###.##"; total +Print #1, "Written to file" +.endcode + +.h2 INPUT + +Reads a line of text from the user or from a file channel. + +.code +INPUT variable +INPUT "prompt"; variable +INPUT #channel, variable +.endcode + +.code +Input "Enter your name: "; name$ +Input #1, line$ +.endcode + +.h2 DATA / READ / RESTORE + +Inline data pool for constants. + +.code +DATA value1, value2, "string", ... +READ variable1, variable2, ... +RESTORE +.endcode + +DATA statements define a pool of values. READ reads the next value from the pool into a variable. RESTORE resets the read pointer to the beginning. + +.code +Data 10, 20, 30, "Hello" +Read a, b, c, msg$ +Print a; b; c; msg$ +Restore +.endcode + +.topic lang.misc +.title Miscellaneous Statements +.toc 1 Miscellaneous Statements +.index ON ERROR +.index RESUME +.index RESUME NEXT +.index ERROR +.index ERR +.index SHELL +.index SLEEP +.index RANDOMIZE +.index END +.index RANDOMIZE TIMER + +.h1 Miscellaneous Statements + +.h2 Error Handling + +.code +ON ERROR GOTO label ' Enable error handler +ON ERROR GOTO 0 ' Disable error handler +RESUME ' Retry the statement that caused the error +RESUME NEXT ' Continue at the next statement after the error +ERROR n ' Raise a runtime error with error number n +.endcode + +The ERR keyword returns the current error number in expressions. + +.code +On Error GoTo ErrorHandler +Open "missing.txt" For Input As #1 +Exit Sub + +ErrorHandler: + Print "Error number:"; Err + Resume Next +.endcode + +.h2 SHELL + +Executes an operating system command. + +.code +SHELL "command" +.endcode + +When used as a function, returns the exit code of the command. + +.code +Shell "DIR /B" +exitCode = Shell("COPY A.TXT B.TXT") +.endcode + +.h2 SLEEP + +Pauses execution for a specified number of seconds. + +.code +SLEEP seconds +.endcode + +.h2 RANDOMIZE + +Seeds the random number generator. + +.code +RANDOMIZE seed +RANDOMIZE TIMER ' Seed from system clock +.endcode + +.h2 END + +Terminates program execution immediately. + +.code +END +.endcode + +.topic lang.fileio +.title File I/O +.toc 0 File I/O +.index OPEN +.index CLOSE +.index PRINT # +.index INPUT # +.index LINE INPUT +.index WRITE # +.index GET +.index PUT +.index SEEK +.index FOR INPUT +.index FOR OUTPUT +.index FOR APPEND +.index FOR RANDOM +.index FOR BINARY + +.h1 File I/O + +.h2 OPEN + +Opens a file for reading, writing, or appending. + +.code +OPEN filename$ FOR INPUT AS #channel +OPEN filename$ FOR OUTPUT AS #channel +OPEN filename$ FOR APPEND AS #channel +OPEN filename$ FOR RANDOM AS #channel [LEN = recordSize] +OPEN filename$ FOR BINARY AS #channel +.endcode + +.table + Mode Description + ---- ----------- + INPUT Open for sequential reading. File must exist. + OUTPUT Open for sequential writing. Creates or truncates. + APPEND Open for sequential writing at end of file. + RANDOM Open for random-access record I/O. + BINARY Open for raw binary I/O. +.endtable + +.h2 CLOSE + +Closes an open file channel. + +.code +CLOSE #channel +.endcode + +.h2 PRINT # + +Writes text to a file. + +.code +PRINT #channel, expression +.endcode + +.h2 INPUT # + +Reads comma-delimited data from a file. + +.code +INPUT #channel, variable +.endcode + +.h2 LINE INPUT # + +Reads an entire line from a file into a string variable. + +.code +LINE INPUT #channel, variable$ +.endcode + +.h2 WRITE # + +Writes comma-delimited data to a file. Strings are enclosed in quotes, numbers are undecorated. Each statement writes a newline at the end. + +.code +WRITE #channel, expr1, expr2, ... +.endcode + +.code +Write #1, "Scott", 42, 3.14 +' Output: "Scott",42,3.14 +.endcode + +.h2 GET / PUT + +Read and write records in RANDOM or BINARY mode files. + +.code +GET #channel, [recordNum], variable +PUT #channel, [recordNum], variable +.endcode + +.h2 SEEK + +Sets the file position. As a function, returns the current position. + +.code +SEEK #channel, position ' Statement: set position +pos = SEEK(channel) ' Function: get current position +.endcode + +.topic lang.func.string +.title String Functions +.toc 0 Built-in Functions +.toc 1 String Functions +.index ASC +.index CHR$ +.index FORMAT$ +.index HEX$ +.index INSTR +.index LCASE$ +.index LEFT$ +.index LEN +.index LTRIM$ +.index MID$ +.index RIGHT$ +.index RTRIM$ +.index SPACE$ +.index STR$ +.index STRING$ +.index TRIM$ +.index UCASE$ +.index VAL + +.h1 String Functions + +.table + Function Returns Description + -------- ------- ----------- + ASC(s$) Integer ASCII code of first character of s$ + CHR$(n) String Character with ASCII code n + FORMAT$(value, fmt$) String Formats a numeric value using format string + HEX$(n) String Hexadecimal representation of n + INSTR(s$, find$) Integer Position of find$ in s$ (1-based), 0 if not found + INSTR(start, s$, find$) Integer Search starting at position start + LCASE$(s$) String Converts s$ to lowercase + LEFT$(s$, n) String Leftmost n characters of s$ + LEN(s$) Integer Length of s$ + LTRIM$(s$) String Removes leading spaces from s$ + MID$(s$, start [, length]) String Substring from position start (1-based) + RIGHT$(s$, n) String Rightmost n characters of s$ + RTRIM$(s$) String Removes trailing spaces from s$ + SPACE$(n) String String of n spaces + STR$(n) String Converts number n to string + STRING$(n, char) String String of n copies of char + TRIM$(s$) String Removes leading and trailing spaces from s$ + UCASE$(s$) String Converts s$ to uppercase + VAL(s$) Double Converts string s$ to a numeric value +.endtable + +.h2 MID$ Assignment + +MID$ can also be used on the left side of an assignment to replace a portion of a string: + +.code +Mid$(s$, 3, 2) = "XY" ' Replace 2 characters starting at position 3 +.endcode + +.topic lang.func.math +.title Math Functions +.toc 1 Math Functions +.index ABS +.index ATN +.index COS +.index EXP +.index FIX +.index INT +.index LOG +.index RND +.index SGN +.index SIN +.index SQR +.index TAN +.index TIMER + +.h1 Math Functions + +.table + Function Returns Description + -------- ------- ----------- + ABS(n) Double Absolute value of n + ATN(n) Double Arctangent of n (in radians) + COS(n) Double Cosine of n (radians) + EXP(n) Double e raised to the power n + FIX(n) Integer Truncates n toward zero (removes fractional part) + INT(n) Integer Largest integer less than or equal to n (floor) + LOG(n) Double Natural logarithm (base e) of n + RND[(n)] Double Random number between 0 (inclusive) and 1 (exclusive) + SGN(n) Integer Sign of n: -1, 0, or 1 + SIN(n) Double Sine of n (radians) + SQR(n) Double Square root of n + TAN(n) Double Tangent of n (radians) + TIMER Double Number of seconds since midnight +.endtable + +.note info +RND with a negative argument seeds and returns. RND(0) returns the previous value. Use RANDOMIZE to seed the generator. +.endnote + +.topic lang.func.conversion +.title Conversion Functions +.toc 1 Conversion Functions +.index CDBL +.index CINT +.index CLNG +.index CSNG +.index CSTR + +.h1 Conversion Functions + +.table + Function Returns Description + -------- ------- ----------- + CDBL(n) Double Converts n to Double + CINT(n) Integer Converts n to Integer (with banker's rounding) + CLNG(n) Long Converts n to Long + CSNG(n) Single Converts n to Single + CSTR(n) String Converts n to its String representation +.endtable + +.topic lang.func.fileio +.title File I/O Functions +.toc 1 File I/O Functions +.index EOF +.index FREEFILE +.index INPUT$ +.index LOC +.index LOF +.index LBOUND +.index UBOUND + +.h1 File I/O Functions + +.table + Function Returns Description + -------- ------- ----------- + EOF(channel) Boolean True if file pointer is at end of file + FREEFILE Integer Next available file channel number + INPUT$(n, #channel) String Reads n characters from the file + LOC(channel) Long Current read/write position in the file + LOF(channel) Long Length of the file in bytes + SEEK(channel) Long Current file position (function form) + LBOUND(array [, dim]) Integer Lower bound of an array dimension + UBOUND(array [, dim]) Integer Upper bound of an array dimension +.endtable + +.topic lang.func.misc +.title Miscellaneous Functions +.toc 1 Miscellaneous Functions +.index DATE$ +.index TIME$ +.index ENVIRON$ + +.h1 Miscellaneous Functions + +.table + Function Returns Description + -------- ------- ----------- + DATE$ String Current date as "MM-DD-YYYY" + TIME$ String Current time as "HH:MM:SS" + ENVIRON$(name$) String Value of environment variable name$ + ERR Integer Current runtime error number (0 if no error) +.endtable + +.topic lang.forms +.title Form and Control Statements +.toc 0 Form and Control Statements +.index LOAD +.index UNLOAD +.index Show +.index Hide +.index Me +.index DoEvents +.index DOEVENTS +.index MsgBox +.index MSGBOX +.index InputBox$ +.index INPUTBOX$ +.index vbModal +.index Control Arrays +.index Event Handlers + +.h1 Form and Control Statements + +DVX BASIC supports Visual Basic-style forms and controls for building graphical user interfaces. Forms are defined in .frm files and loaded at runtime. + +.h2 Loading and Unloading Forms + +.code +LOAD FormName +UNLOAD FormName +.endcode + +LOAD creates the form and its controls in memory. UNLOAD destroys the form and frees its resources. + +.h2 Showing and Hiding Forms + +.code +FormName.Show [modal] +FormName.Hide +Me.Show [modal] +Me.Hide +.endcode + +Pass vbModal (1) to Show for a modal dialog. + +.code +Form2.Show vbModal +Me.Hide +.endcode + +.h2 Property Access + +Read and write control properties using dot notation: + +.code +ControlName.Property = value +value = ControlName.Property +.endcode + +.code +Text1.Text = "Hello" +label1.Caption = "Name: " & name$ +x = Text1.Left +.endcode + +.h2 Method Calls + +.code +ControlName.Method [args] +.endcode + +.code +List1.AddItem "New entry" +List1.Clear +.endcode + +.h2 Me Keyword + +Me refers to the current form. Use it to access the form's own properties, controls, and methods from within event handlers. + +.code +Me.Caption = "Updated Title" +Me.Text1.Text = "" +Me.Hide +.endcode + +.h2 Control Arrays + +Multiple controls can share a name with unique indices. Access individual controls with parenthesized indices: + +.code +Option1(0).Value = True +Label1(idx).Caption = "Item " & Str$(idx) +Me.Label1(i).Visible = True +.endcode + +.h2 DoEvents + +Yields control to the DVX event loop, allowing the GUI to process pending events. Call this in long-running loops to keep the UI responsive. + +.code +DOEVENTS +.endcode + +.code +For i = 1 To 10000 + ' process data + If i Mod 100 = 0 Then DoEvents +Next +.endcode + +.h2 MsgBox + +Displays a message box dialog. Can be used as a statement (discards result) or as a function (returns the button clicked). + +.code +MSGBOX message$ [, flags] +result = MSGBOX(message$ [, flags]) +.endcode + +.code +MsgBox "Operation complete" +answer = MsgBox("Continue?", vbYesNo + vbQuestion) +If answer = vbYes Then + ' proceed +End If +.endcode + +.h2 InputBox$ + +Displays an input dialog and returns the user's text entry. + +.code +result$ = INPUTBOX$(prompt$ [, title$ [, default$]]) +.endcode + +.code +name$ = InputBox$("Enter your name:", "Name Entry", "") +.endcode + +.h2 Event Handler Convention + +Event handlers are named ControlName_EventName and defined as SUBs: + +.code +Sub Command1_Click() + MsgBox "Button clicked!" +End Sub + +Sub Form_Load() + Me.Caption = "My App" +End Sub + +Sub Text1_Change() + Label1.Caption = "You typed: " & Text1.Text +End Sub +.endcode + +.h3 Common Events + +.table + Event Description + ----- ----------- + Click Control was clicked + DblClick Control was double-clicked + Change Control value/text changed + KeyPress Key was pressed (receives key code) + KeyDown Key went down (receives key code and shift state) + KeyUp Key was released + MouseDown Mouse button pressed + MouseUp Mouse button released + MouseMove Mouse moved over control + GotFocus Control received input focus + LostFocus Control lost input focus + Form_Load Form is being loaded + Form_Unload Form is being unloaded + Form_Resize Form was resized + Timer Timer interval elapsed +.endtable + +.topic lang.sql +.title SQL Functions +.toc 0 SQL Functions +.index SQLOpen +.index SQLClose +.index SQLExec +.index SQLAffected +.index SQLQuery +.index SQLNext +.index SQLEof +.index SQLField$ +.index SQLFieldInt +.index SQLFieldDbl +.index SQLFieldCount +.index SQLFreeResult +.index SQLError$ +.index SQLite + +.h1 SQL Functions + +DVX BASIC includes built-in SQLite database support through a set of SQL functions. All functions use database handles and result set handles (integers) returned by SQLOpen and SQLQuery. + +.h2 Opening and Closing Databases + +.h3 SQLOpen + +Opens a SQLite database file and returns a database handle. + +.code +db = SQLOPEN(path$) +.endcode + +.code +db = SQLOpen(App.Data & "\mydata.db") +.endcode + +.h3 SQLClose + +Closes an open database. + +.code +SQLCLOSE db +.endcode + +.h2 Executing SQL + +.h3 SQLExec + +Executes a SQL statement that does not return data (INSERT, UPDATE, DELETE, CREATE TABLE, etc.). Can be used as a statement or as a function returning a Boolean success flag. + +.code +SQLEXEC db, sql$ +ok = SQLEXEC(db, sql$) +.endcode + +.code +SQLExec db, "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)" +SQLExec db, "INSERT INTO users (name) VALUES ('Scott')" +ok = SQLExec(db, "DELETE FROM users WHERE id = 5") +.endcode + +.h3 SQLAffected + +Returns the number of rows affected by the last INSERT, UPDATE, or DELETE. + +.code +count = SQLAFFECTED(db) +.endcode + +.h2 Querying Data + +.h3 SQLQuery + +Executes a SELECT query and returns a result set handle. + +.code +rs = SQLQUERY(db, sql$) +.endcode + +.code +rs = SQLQuery(db, "SELECT id, name FROM users ORDER BY name") +.endcode + +.h3 SQLNext + +Advances to the next row in the result set. Can be used as a statement or as a function returning True if a row is available. + +.code +SQLNEXT rs +hasRow = SQLNEXT(rs) +.endcode + +.h3 SQLEof + +Returns True if there are no more rows in the result set. + +.code +done = SQLEOF(rs) +.endcode + +.h2 Reading Fields + +.h3 SQLField$ + +Returns a field value as a string. The field can be specified by column index (0-based) or by column name. + +.code +value$ = SQLFIELD$(rs, columnIndex) +value$ = SQLFIELD$(rs, "columnName") +.endcode + +.code +name$ = SQLField$(rs, "name") +first$ = SQLField$(rs, 0) +.endcode + +.h3 SQLFieldInt + +Returns a field value as an integer. + +.code +value = SQLFIELDINT(rs, columnIndex) +.endcode + +.h3 SQLFieldDbl + +Returns a field value as a double. + +.code +value# = SQLFIELDDBL(rs, columnIndex) +.endcode + +.h3 SQLFieldCount + +Returns the number of columns in the result set. + +.code +count = SQLFIELDCOUNT(rs) +.endcode + +.h2 Result Set Cleanup + +.h3 SQLFreeResult + +Frees a result set. Always call this when done iterating a query. + +.code +SQLFREERESULT rs +.endcode + +.h2 Error Information + +.h3 SQLError$ + +Returns the last error message for the database. + +.code +msg$ = SQLERROR$(db) +.endcode + +.h2 Complete SQL Example + +.code +Dim db As Long +Dim rs As Long + +db = SQLOpen(App.Data & "\contacts.db") +SQLExec db, "CREATE TABLE IF NOT EXISTS contacts (name TEXT, phone TEXT)" +SQLExec db, "INSERT INTO contacts VALUES ('Alice', '555-1234')" + +rs = SQLQuery(db, "SELECT name, phone FROM contacts") +Do While Not SQLEof(rs) + SQLNext rs + Print SQLField$(rs, "name"); Tab(20); SQLField$(rs, "phone") +Loop +SQLFreeResult rs +SQLClose db +.endcode + +.topic lang.app +.title App Object +.toc 0 App Object +.index App +.index App.Path +.index App.Config +.index App.Data + +.h1 App Object + +The App object provides read-only properties for the application's directory paths. + +.table + Property Returns Description + -------- ------- ----------- + App.Path String Directory containing the application's executable + App.Config String Directory for application configuration files + App.Data String Directory for application data files (databases, etc.) +.endtable + +.code +configFile$ = App.Config & "\settings.ini" +dbPath$ = App.Data & "\myapp.db" +Print "Running from: " & App.Path +.endcode + +.topic lang.ini +.title INI Functions +.toc 0 INI Functions +.index IniRead +.index IniWrite +.index INI + +.h1 INI Functions + +DVX BASIC provides built-in functions for reading and writing standard INI configuration files. + +.h2 IniRead + +Reads a value from an INI file. Returns the default value if the key is not found. + +.code +value$ = INIREAD(file$, section$, key$, default$) +.endcode + +.code +name$ = IniRead(App.Config & "\app.ini", "User", "Name", "Unknown") +fontSize = Val(IniRead(App.Config & "\app.ini", "Display", "FontSize", "12")) +.endcode + +.h2 IniWrite + +Writes a value to an INI file. Creates the file, section, or key if they do not exist. + +.code +INIWRITE file$, section$, key$, value$ +.endcode + +.code +IniWrite App.Config & "\app.ini", "User", "Name", "Scott" +IniWrite App.Config & "\app.ini", "Display", "FontSize", Str$(fontSize) +.endcode + +.topic lang.constants +.title Predefined Constants +.toc 0 Predefined Constants +.index vbOKOnly +.index vbOKCancel +.index vbYesNo +.index vbYesNoCancel +.index vbRetryCancel +.index vbInformation +.index vbExclamation +.index vbCritical +.index vbQuestion +.index vbOK +.index vbCancel +.index vbYes +.index vbNo +.index vbRetry +.index True +.index False +.index Predefined Constants + +.h1 Predefined Constants + +The following constants are predefined by the compiler and available in all programs. + +.h2 MsgBox Button Style Flags + +.table + Constant Value Description + -------- ----- ----------- + vbOKOnly 0 OK button only (default) + vbOKCancel 1 OK and Cancel buttons + vbYesNo 2 Yes and No buttons + vbYesNoCancel 3 Yes, No, and Cancel buttons + vbRetryCancel 4 Retry and Cancel buttons +.endtable + +.h2 MsgBox Icon Flags + +Add an icon flag to the button style to display an icon in the message box. + +.table + Constant Value Description + -------- ----- ----------- + vbInformation &H10 Information icon + vbExclamation &H20 Warning icon + vbCritical &H30 Error/critical icon + vbQuestion &H40 Question mark icon +.endtable + +.h2 MsgBox Return Values + +.table + Constant Value Description + -------- ----- ----------- + vbOK 1 User clicked OK + vbCancel 2 User clicked Cancel + vbYes 3 User clicked Yes + vbNo 4 User clicked No + vbRetry 5 User clicked Retry +.endtable + +.h2 Show Mode Flags + +.table + Constant Value Description + -------- ----- ----------- + vbModal 1 Show form as modal dialog +.endtable + +.h2 Boolean Constants + +.table + Constant Value Description + -------- ----- ----------- + True -1 Boolean true + False 0 Boolean false +.endtable diff --git a/listhelp/Makefile b/listhelp/Makefile index ae24eea..d90fdb0 100644 --- a/listhelp/Makefile +++ b/listhelp/Makefile @@ -6,7 +6,7 @@ DJGPP_PREFIX = $(HOME)/djgpp/djgpp CC = $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-gcc DXE3GEN = PATH=$(DJGPP_PREFIX)/bin:$(PATH) DJDIR=$(DJGPP_PREFIX)/i586-pc-msdosdjgpp $(DJGPP_PREFIX)/i586-pc-msdosdjgpp/bin/dxe3gen -CFLAGS = -O2 -Wall -Wextra -Wno-type-limits -Wno-sign-compare -march=i486 -mtune=i586 -I. -I../core -I../core/platform -I../tasks -I../core/thirdparty +CFLAGS = -O2 -Wall -Wextra -Werror -Wno-type-limits -Wno-sign-compare -Wno-format-truncation -march=i486 -mtune=i586 -I. -I../core -I../core/platform -I../tasks -I../core/thirdparty OBJDIR = ../obj/listhelp LIBSDIR = ../bin/libs diff --git a/loader/Makefile b/loader/Makefile index 9cc88f9..8a80d1b 100644 --- a/loader/Makefile +++ b/loader/Makefile @@ -9,7 +9,7 @@ DJGPP_LIBPATH = $(HOME)/claude/windriver/tools/lib CC = $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-gcc EXE2COFF = $(DJGPP_PREFIX)/i586-pc-msdosdjgpp/bin/exe2coff CWSDSTUB = $(DJGPP_PREFIX)/i586-pc-msdosdjgpp/bin/CWSDSTUB.EXE -CFLAGS = -O2 -Wall -Wextra -Wno-type-limits -Wno-sign-compare -march=i486 -mtune=i586 -I../core -I../core/platform -I../tasks -I../core/thirdparty +CFLAGS = -O2 -Wall -Wextra -Werror -Wno-type-limits -Wno-sign-compare -Wno-format-truncation -march=i486 -mtune=i586 -I../core -I../core/platform -I../tasks -I../core/thirdparty LDFLAGS = -lm OBJDIR = ../obj/loader diff --git a/loader/loaderMain.c b/loader/loaderMain.c index ed5cfed..445b3c5 100644 --- a/loader/loaderMain.c +++ b/loader/loaderMain.c @@ -243,7 +243,7 @@ static void scanDir(const char *dirPath, const char *ext, ModuleT **mods) { } char path[DVX_MAX_PATH]; - snprintf(path, sizeof(path), "%s/%s", dirPath, name); + snprintf(path, sizeof(path), "%s%c%s", dirPath, DVX_PATH_SEP, name); // Check for matching extension int32_t nameLen = strlen(name); diff --git a/packet/Makefile b/packet/Makefile index 2001eff..60245f9 100644 --- a/packet/Makefile +++ b/packet/Makefile @@ -5,7 +5,7 @@ DJGPP_LIBPATH = $(HOME)/claude/windriver/tools/lib CC = $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-gcc AR = LD_LIBRARY_PATH=$(DJGPP_LIBPATH) $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-ar RANLIB = LD_LIBRARY_PATH=$(DJGPP_LIBPATH) $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-ranlib -CFLAGS = -O2 -Wall -Wextra -march=i486 -mtune=i586 +CFLAGS = -O2 -Wall -Wextra -Werror -Wno-format-truncation -march=i486 -mtune=i586 OBJDIR = ../obj/packet LIBDIR = ../lib diff --git a/proxy/Makefile b/proxy/Makefile index 3102752..b01aaa2 100644 --- a/proxy/Makefile +++ b/proxy/Makefile @@ -3,7 +3,7 @@ # shim instead of the DJGPP rs232 driver. CC = gcc -CFLAGS = -O2 -Wall -Wextra +CFLAGS = -O2 -Wall -Wextra -Werror OBJDIR = ../obj/proxy BINDIR = ../bin diff --git a/rs232/Makefile b/rs232/Makefile index d41c736..d180aec 100644 --- a/rs232/Makefile +++ b/rs232/Makefile @@ -5,7 +5,7 @@ DJGPP_LIBPATH = $(HOME)/claude/windriver/tools/lib CC = $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-gcc AR = LD_LIBRARY_PATH=$(DJGPP_LIBPATH) $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-ar RANLIB = LD_LIBRARY_PATH=$(DJGPP_LIBPATH) $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-ranlib -CFLAGS = -O2 -Wall -Wextra -march=i486 -mtune=i586 +CFLAGS = -O2 -Wall -Wextra -Werror -Wno-format-truncation -march=i486 -mtune=i586 OBJDIR = ../obj/rs232 LIBDIR = ../lib diff --git a/seclink/Makefile b/seclink/Makefile index 5430bd5..3e45194 100644 --- a/seclink/Makefile +++ b/seclink/Makefile @@ -5,7 +5,7 @@ DJGPP_LIBPATH = $(HOME)/claude/windriver/tools/lib CC = $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-gcc AR = LD_LIBRARY_PATH=$(DJGPP_LIBPATH) $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-ar RANLIB = LD_LIBRARY_PATH=$(DJGPP_LIBPATH) $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-ranlib -CFLAGS = -O2 -Wall -Wextra -march=i486 -mtune=i586 +CFLAGS = -O2 -Wall -Wextra -Werror -Wno-format-truncation -march=i486 -mtune=i586 OBJDIR = ../obj/seclink LIBDIR = ../lib diff --git a/security/Makefile b/security/Makefile index d6cb5fc..3e5987d 100644 --- a/security/Makefile +++ b/security/Makefile @@ -5,7 +5,7 @@ DJGPP_LIBPATH = $(HOME)/claude/windriver/tools/lib CC = $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-gcc AR = LD_LIBRARY_PATH=$(DJGPP_LIBPATH) $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-ar RANLIB = LD_LIBRARY_PATH=$(DJGPP_LIBPATH) $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-ranlib -CFLAGS = -O2 -Wall -Wextra -march=i486 -mtune=i586 +CFLAGS = -O2 -Wall -Wextra -Werror -Wno-format-truncation -march=i486 -mtune=i586 OBJDIR = ../obj/security LIBDIR = ../lib diff --git a/serial/Makefile b/serial/Makefile index f6faa57..161f708 100644 --- a/serial/Makefile +++ b/serial/Makefile @@ -6,7 +6,7 @@ DJGPP_PREFIX = $(HOME)/djgpp/djgpp CC = $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-gcc DXE3GEN = PATH=$(DJGPP_PREFIX)/bin:$(PATH) DJDIR=$(DJGPP_PREFIX)/i586-pc-msdosdjgpp $(DJGPP_PREFIX)/i586-pc-msdosdjgpp/bin/dxe3gen -CFLAGS = -O2 -Wall -Wextra -march=i486 -mtune=i586 -I../rs232 -I../packet -I../security -I../seclink -I../core -I../core/platform -I../tasks +CFLAGS = -O2 -Wall -Wextra -Werror -Wno-format-truncation -march=i486 -mtune=i586 -I../rs232 -I../packet -I../security -I../seclink -I../core -I../core/platform -I../tasks OBJDIR = ../obj/serial LIBSDIR = ../bin/libs diff --git a/shell/Makefile b/shell/Makefile index eb994ca..e7ce094 100644 --- a/shell/Makefile +++ b/shell/Makefile @@ -5,7 +5,7 @@ DJGPP_PREFIX = $(HOME)/djgpp/djgpp CC = $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-gcc DXE3GEN = PATH=$(DJGPP_PREFIX)/bin:$(PATH) DJDIR=$(DJGPP_PREFIX)/i586-pc-msdosdjgpp $(DJGPP_PREFIX)/i586-pc-msdosdjgpp/bin/dxe3gen -CFLAGS = -O2 -Wall -Wextra -Wno-type-limits -Wno-sign-compare -march=i486 -mtune=i586 -I../core -I../core/platform -I../widgets -I../tasks -I../core/thirdparty +CFLAGS = -O2 -Wall -Wextra -Werror -Wno-type-limits -Wno-sign-compare -Wno-format-truncation -march=i486 -mtune=i586 -I../core -I../core/platform -I../widgets -I../tasks -I../core/thirdparty OBJDIR = ../obj/shell LIBSDIR = ../bin/libs diff --git a/shell/shellApp.c b/shell/shellApp.c index abc4c2e..d7bf596 100644 --- a/shell/shellApp.c +++ b/shell/shellApp.c @@ -219,7 +219,7 @@ void shellAppInit(void) { // ============================================================ void shellConfigPath(const DxeAppContextT *ctx, const char *filename, char *outPath, int32_t outSize) { - snprintf(outPath, outSize, "%s/%s", ctx->configDir, filename); + snprintf(outPath, outSize, "%s%c%s", ctx->configDir, DVX_PATH_SEP, filename); } @@ -299,7 +299,20 @@ ShellAppT *shellGetApp(int32_t appId) { // unique temp file before dlopen, giving each instance its own code+data. // If multiInstance=false (the default), a second load of the same path is // blocked with an error message. +static int32_t shellLoadAppInternal(AppContextT *ctx, const char *path, const char *args); + + int32_t shellLoadApp(AppContextT *ctx, const char *path) { + return shellLoadAppInternal(ctx, path, NULL); +} + + +int32_t shellLoadAppWithArgs(AppContextT *ctx, const char *path, const char *args) { + return shellLoadAppInternal(ctx, path, args); +} + + +static int32_t shellLoadAppInternal(AppContextT *ctx, const char *path, const char *args) { // Allocate a slot int32_t id = allocSlot(); @@ -457,6 +470,11 @@ int32_t shellLoadApp(AppContextT *ctx, const char *path) { snprintf(app->dxeCtx->configDir, sizeof(app->dxeCtx->configDir), "CONFIG/APPS/%s", desc->name); } + // Copy launch arguments (if any) + if (args && args[0]) { + snprintf(app->dxeCtx->args, sizeof(app->dxeCtx->args), "%s", args); + } + // Launch. Set currentAppId before any app code runs so that // dvxCreateWindow stamps the correct owner on new windows. ctx->currentAppId = id; diff --git a/shell/shellApp.h b/shell/shellApp.h index 133a55e..9beb636 100644 --- a/shell/shellApp.h +++ b/shell/shellApp.h @@ -65,6 +65,9 @@ typedef struct { char appPath[DVX_MAX_PATH]; // full path to the .app file char appDir[DVX_MAX_PATH]; // directory containing the .app file char configDir[DVX_MAX_PATH]; // writable config directory (CONFIG//) + char args[1024]; // launch arguments (empty if none) + char helpFile[DVX_MAX_PATH]; // help file path (for F1 context help) + char helpTopic[128]; // current help topic ID (updated by app) } DxeAppContextT; // ============================================================ @@ -115,6 +118,10 @@ void shellAppInit(void); // app starts running on the next tsYield. int32_t shellLoadApp(AppContextT *ctx, const char *path); +// Load and run an app with arguments. The args string is copied into +// DxeAppContextT.args before appMain is called. +int32_t shellLoadAppWithArgs(AppContextT *ctx, const char *path, const char *args); + // Reap finished apps (call each frame from main loop). Returns true if // any apps were reaped, so the caller can notify the desktop to refresh. // For callback-only apps, termination is triggered by shellWrapDestroyWindow diff --git a/shell/shellMain.c b/shell/shellMain.c index 741828f..f903035 100644 --- a/shell/shellMain.c +++ b/shell/shellMain.c @@ -87,6 +87,47 @@ static void ctrlEscHandler(void *ctx) { } +// ============================================================ +// f1HelpHandler -- system-wide F1 launches context-sensitive help +// ============================================================ + +#define HELP_VIEWER_PATH "APPS/DVXHELP/DVXHELP.APP" +#define SYSTEM_HELP_FILE "APPS/DVXHELP/DVXHELP.HLP" + +static void f1HelpHandler(void *ctx) { + AppContextT *ac = (AppContextT *)ctx; + + // Find the focused window's owning app + char args[1024] = {0}; + int32_t focusedAppId = 0; + + if (ac->stack.focusedIdx >= 0) { + WindowT *win = ac->stack.windows[ac->stack.focusedIdx]; + focusedAppId = win->appId; + } + + if (focusedAppId > 0) { + ShellAppT *app = shellGetApp(focusedAppId); + + if (app && app->dxeCtx && app->dxeCtx->helpFile[0]) { + if (app->dxeCtx->helpTopic[0]) { + snprintf(args, sizeof(args), "%s %s", + app->dxeCtx->helpFile, app->dxeCtx->helpTopic); + } else { + snprintf(args, sizeof(args), "%s", app->dxeCtx->helpFile); + } + } + } + + // Fall back to system help if no app-specific help + if (!args[0]) { + snprintf(args, sizeof(args), "%s", SYSTEM_HELP_FILE); + } + + shellLoadAppWithArgs(ac, HELP_VIEWER_PATH, args); +} + + // ============================================================ // titleChangeHandler -- refresh listeners when a window title changes // ============================================================ @@ -214,6 +255,8 @@ int shellMain(int argc, char *argv[]) { sCtx.idleCtx = &sCtx; sCtx.onCtrlEsc = ctrlEscHandler; sCtx.ctrlEscCtx = &sCtx; + sCtx.onF1 = f1HelpHandler; + sCtx.f1Ctx = &sCtx; sCtx.onTitleChange = titleChangeHandler; sCtx.titleChangeCtx = &sCtx; diff --git a/sql/Makefile b/sql/Makefile index 703fab8..97824f3 100644 --- a/sql/Makefile +++ b/sql/Makefile @@ -17,7 +17,7 @@ SQLITE_DIR = thirdparty/sqlite SQLITE_SRC = $(SQLITE_DIR)/src SQLITE_TOOL = $(SQLITE_DIR)/tool -CFLAGS = -O2 -Wall -Wno-type-limits -Wno-sign-compare -march=i486 -mtune=i586 \ +CFLAGS = -O2 -Wall -Werror -Wno-type-limits -Wno-sign-compare -Wno-format-truncation -Wno-address -march=i486 -mtune=i586 \ -I../core -I../core/platform -I../tasks \ -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ -I$(SQLITE_SRC) -I$(SQLITE_DIR)/examples -I$(OBJDIR) diff --git a/sql/thirdparty/sqlite/src/btree.c b/sql/thirdparty/sqlite/src/btree.c index dd0e724..82b81fc 100644 --- a/sql/thirdparty/sqlite/src/btree.c +++ b/sql/thirdparty/sqlite/src/btree.c @@ -1192,6 +1192,7 @@ int sqlite3BtreeOpen( } sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); mutexShared = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); + (void)mutexShared; sqlite3_mutex_enter(mutexShared); for(pBt=sqlite3SharedCacheList; pBt; pBt=pBt->pNext){ assert( pBt->nRef>0 ); @@ -1295,6 +1296,7 @@ int sqlite3BtreeOpen( sqlite3_mutex *mutexShared; pBt->nRef = 1; mutexShared = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); + (void)mutexShared; if( SQLITE_THREADSAFE ){ pBt->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); if( pBt->mutex==0 ){ @@ -1370,6 +1372,7 @@ static int removeFromSharingList(BtShared *pBt){ assert( sqlite3_mutex_notheld(pBt->mutex) ); pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); + (void)pMaster; sqlite3_mutex_enter(pMaster); pBt->nRef--; if( pBt->nRef<=0 ){ diff --git a/sql/thirdparty/sqlite/src/build.c b/sql/thirdparty/sqlite/src/build.c index 9c7d82c..2a97612 100644 --- a/sql/thirdparty/sqlite/src/build.c +++ b/sql/thirdparty/sqlite/src/build.c @@ -367,6 +367,7 @@ static void sqliteDeleteIndex(Index *p){ const char *zName = p->zName; pOld = sqlite3HashInsert(&p->pSchema->idxHash, zName, strlen( zName)+1, 0); + (void)pOld; assert( pOld==0 || pOld==p ); freeIndex(p); } @@ -3128,7 +3129,7 @@ SrcList *sqlite3SrcListAppendFromTerm( ** operator with A. This routine shifts that operator over to B. */ void sqlite3SrcListShiftJoinType(SrcList *p){ - if( p && p->a ){ + if( p ){ int i; for(i=p->nSrc-1; i>0; i--){ p->a[i].jointype = p->a[i-1].jointype; diff --git a/sql/thirdparty/sqlite/src/insert.c b/sql/thirdparty/sqlite/src/insert.c index 07b069c..e4adec6 100644 --- a/sql/thirdparty/sqlite/src/insert.c +++ b/sql/thirdparty/sqlite/src/insert.c @@ -370,13 +370,13 @@ void sqlite3Insert( int appendFlag = 0; /* True if the insert is likely to be an append */ /* Register allocations */ - int regFromSelect; /* Base register for data coming from SELECT */ + int regFromSelect = 0; /* Base register for data coming from SELECT */ int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */ int regRowCount = 0; /* Memory cell used for the row counter */ int regIns; /* Block of regs holding rowid+data being inserted */ int regRowid; /* registers holding insert rowid */ - int regData; /* register holding first column to insert */ - int regRecord; /* Holds the assemblied row record */ + int regData = 0; /* register holding first column to insert */ + int regRecord = 0; /* Holds the assemblied row record */ int *aRegIdx = 0; /* One register allocated to each index */ @@ -673,6 +673,7 @@ void sqlite3Insert( ** the content of the new row, and the assemblied row record. */ regRecord = ++pParse->nMem; + (void)regRecord; regRowid = regIns = pParse->nMem+1; pParse->nMem += pTab->nCol + 1; if( IsVirtual(pTab) ){ @@ -680,6 +681,7 @@ void sqlite3Insert( pParse->nMem++; } regData = regRowid+1; + (void)regData; /* Run the BEFORE and INSTEAD OF triggers, if there are any */ @@ -1028,7 +1030,7 @@ void sqlite3GenerateConstraintChecks( Vdbe *v; int nCol; int onError; - int j1, j2, j3; /* Addresses of jump instructions */ + int j1, j2 = 0, j3; /* Addresses of jump instructions */ int regData; /* Register containing first data column */ int iCur; Index *pIdx; diff --git a/sql/thirdparty/sqlite/src/os_unix.c b/sql/thirdparty/sqlite/src/os_unix.c index 6f9b3c0..d7e9b5b 100644 --- a/sql/thirdparty/sqlite/src/os_unix.c +++ b/sql/thirdparty/sqlite/src/os_unix.c @@ -449,7 +449,7 @@ static int lockTrace(int fd, int op, struct flock *p){ if( s==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){ struct flock l2; l2 = *p; - fcntl(fd, F_GETLK, &l2); + (void)fcntl(fd, F_GETLK, &l2); if( l2.l_type==F_RDLCK ){ zType = "RDLCK"; }else if( l2.l_type==F_WRLCK ){ @@ -1083,7 +1083,7 @@ static int unixCheckReservedLock(sqlite3_file *id){ lock.l_start = RESERVED_BYTE; lock.l_len = 1; lock.l_type = F_WRLCK; - fcntl(pFile->h, F_GETLK, &lock); + (void)fcntl(pFile->h, F_GETLK, &lock); if( lock.l_type!=F_UNLCK ){ r = 1; } @@ -1163,6 +1163,7 @@ static int unixLock(sqlite3_file *id, int locktype){ struct lockInfo *pLock = pFile->pLock; struct flock lock; int s; + (void)lock; assert( pFile ); OSTRACE7("LOCK %d %s was %s(%s,%d) pid=%d\n", pFile->h, @@ -2261,7 +2262,7 @@ static int fillInUnixFile( int rc; #ifdef FD_CLOEXEC - fcntl(h, F_SETFD, fcntl(h, F_GETFD, 0) | FD_CLOEXEC); + (void)fcntl(h, F_SETFD, fcntl(h, F_GETFD, 0) | FD_CLOEXEC); #endif enterMutex(); @@ -2307,7 +2308,7 @@ static int openDirectory(const char *zFilename, int *pFd){ fd = open(zDirname, O_RDONLY|O_BINARY, 0); if( fd>=0 ){ #ifdef FD_CLOEXEC - fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC); + (void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC); #endif OSTRACE3("OPENDIR %-3d %s\n", fd, zDirname); } diff --git a/sql/thirdparty/sqlite/src/printf.c b/sql/thirdparty/sqlite/src/printf.c index eafe842..64b1320 100644 --- a/sql/thirdparty/sqlite/src/printf.c +++ b/sql/thirdparty/sqlite/src/printf.c @@ -246,6 +246,7 @@ static void vxprintf( char buf[etBUFSIZE]; /* Conversion buffer */ char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ etByte errorflag = 0; /* True if an error is encountered */ + (void)errorflag; etByte xtype; /* Conversion paradigm */ char *zExtra; /* Extra memory used for etTCLESCAPE conversions */ #ifndef SQLITE_OMIT_FLOATING_POINT diff --git a/sql/thirdparty/sqlite/src/select.c b/sql/thirdparty/sqlite/src/select.c index 981691f..b75f71d 100644 --- a/sql/thirdparty/sqlite/src/select.c +++ b/sql/thirdparty/sqlite/src/select.c @@ -62,35 +62,35 @@ Select *sqlite3SelectNew( ){ Select *pNew; Select standin; + Select *p; sqlite3 *db = pParse->db; pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); assert( !pOffset || pLimit ); /* Can't have OFFSET without LIMIT. */ + p = pNew ? pNew : &standin; if( pNew==0 ){ - pNew = &standin; - memset(pNew, 0, sizeof(*pNew)); + memset(p, 0, sizeof(*p)); } if( pEList==0 ){ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0,0,0), 0); } - pNew->pEList = pEList; - pNew->pSrc = pSrc; - pNew->pWhere = pWhere; - pNew->pGroupBy = pGroupBy; - pNew->pHaving = pHaving; - pNew->pOrderBy = pOrderBy; - pNew->isDistinct = isDistinct; - pNew->op = TK_SELECT; + p->pEList = pEList; + p->pSrc = pSrc; + p->pWhere = pWhere; + p->pGroupBy = pGroupBy; + p->pHaving = pHaving; + p->pOrderBy = pOrderBy; + p->isDistinct = isDistinct; + p->op = TK_SELECT; assert( pOffset==0 || pLimit!=0 ); - pNew->pLimit = pLimit; - pNew->pOffset = pOffset; - pNew->iLimit = -1; - pNew->iOffset = -1; - pNew->addrOpenEphm[0] = -1; - pNew->addrOpenEphm[1] = -1; - pNew->addrOpenEphm[2] = -1; - if( pNew==&standin) { - clearSelect(pNew); - pNew = 0; + p->pLimit = pLimit; + p->pOffset = pOffset; + p->iLimit = -1; + p->iOffset = -1; + p->addrOpenEphm[0] = -1; + p->addrOpenEphm[1] = -1; + p->addrOpenEphm[2] = -1; + if( pNew==0 ){ + clearSelect(p); } return pNew; } diff --git a/sql/thirdparty/sqlite/src/update.c b/sql/thirdparty/sqlite/src/update.c index fb45563..6e7201f 100644 --- a/sql/thirdparty/sqlite/src/update.c +++ b/sql/thirdparty/sqlite/src/update.c @@ -108,10 +108,10 @@ void sqlite3Update( int isView; /* Trying to update a view */ int triggers_exist = 0; /* True if any row triggers exist */ #endif - int iBeginAfterTrigger; /* Address of after trigger program */ - int iEndAfterTrigger; /* Exit of after trigger program */ - int iBeginBeforeTrigger; /* Address of before trigger program */ - int iEndBeforeTrigger; /* Exit of before trigger program */ + int iBeginAfterTrigger = 0; /* Address of after trigger program */ + int iEndAfterTrigger = 0; /* Exit of after trigger program */ + int iBeginBeforeTrigger = 0; /* Address of before trigger program */ + int iEndBeforeTrigger = 0; /* Exit of before trigger program */ u32 old_col_mask = 0; /* Mask of OLD.* columns in use */ u32 new_col_mask = 0; /* Mask of NEW.* columns in use */ diff --git a/sql/thirdparty/sqlite/src/vdbe.c b/sql/thirdparty/sqlite/src/vdbe.c index 2901752..fef4c08 100644 --- a/sql/thirdparty/sqlite/src/vdbe.c +++ b/sql/thirdparty/sqlite/src/vdbe.c @@ -501,8 +501,8 @@ int sqlite3VdbeExec( int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ u8 encoding = ENC(db); /* The database encoding */ - Mem *pIn1, *pIn2, *pIn3; /* Input operands */ - Mem *pOut; /* Output operand */ + Mem *pIn1 = 0, *pIn2 = 0, *pIn3 = 0; /* Input operands */ + Mem *pOut = 0; /* Output operand */ u8 opProperty; #ifdef VDBE_PROFILE unsigned long long start; /* CPU clock count at start of opcode */ @@ -1652,7 +1652,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ */ case OP_And: /* same as TK_AND, in1, in2, out3 */ case OP_Or: { /* same as TK_OR, in1, in2, out3 */ - int v1, v2; /* 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ + int v1 = 0, v2 = 0; /* 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ if( pIn1->flags & MEM_Null ){ v1 = 2; @@ -2738,7 +2738,7 @@ case OP_MoveGt: { /* jump, in3 */ pC = p->apCsr[i]; assert( pC!=0 ); if( pC->pCursor!=0 ){ - int res, oc; + int res = 0, oc; oc = pOp->opcode; pC->nullRow = 0; *pC->pIncrKey = oc==OP_MoveGt || oc==OP_MoveLe; @@ -3299,7 +3299,7 @@ case OP_Insert: { */ case OP_Delete: { int i = pOp->p1; - i64 iKey; + i64 iKey = 0; Cursor *pC; assert( i>=0 && inCursor ); @@ -3373,7 +3373,7 @@ case OP_RowData: { /* out2-prerelease */ int i = pOp->p1; Cursor *pC; BtCursor *pCrsr; - u32 n; + u32 n = 0; /* Note that RowKey and RowData are really exactly the same instruction */ assert( i>=0 && inCursor ); diff --git a/sql/thirdparty/sqlite/src/vdbeapi.c b/sql/thirdparty/sqlite/src/vdbeapi.c index e756c70..d1c7699 100644 --- a/sql/thirdparty/sqlite/src/vdbeapi.c +++ b/sql/thirdparty/sqlite/src/vdbeapi.c @@ -565,6 +565,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ if( pVm && pVm->pResultSet!=0 && inResColumn && i>=0 ){ sqlite3_mutex_enter(pVm->db->mutex); vals = sqlite3_data_count(pStmt); + (void)vals; pOut = &pVm->pResultSet[i]; }else{ static const Mem nullMem = {{0}, 0.0, 0, "", 0, MEM_Null, SQLITE_NULL }; diff --git a/taskmgr/Makefile b/taskmgr/Makefile index ce94bcc..ed523b2 100644 --- a/taskmgr/Makefile +++ b/taskmgr/Makefile @@ -5,7 +5,7 @@ DJGPP_PREFIX = $(HOME)/djgpp/djgpp CC = $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-gcc DXE3GEN = PATH=$(DJGPP_PREFIX)/bin:$(PATH) DJDIR=$(DJGPP_PREFIX)/i586-pc-msdosdjgpp $(DJGPP_PREFIX)/i586-pc-msdosdjgpp/bin/dxe3gen -CFLAGS = -O2 -Wall -Wextra -Wno-type-limits -Wno-sign-compare -march=i486 -mtune=i586 -I../core -I../core/platform -I../widgets -I../shell -I../tasks -I../core/thirdparty +CFLAGS = -O2 -Wall -Wextra -Werror -Wno-type-limits -Wno-sign-compare -Wno-format-truncation -march=i486 -mtune=i586 -I../core -I../core/platform -I../widgets -I../shell -I../tasks -I../core/thirdparty OBJDIR = ../obj/taskmgr LIBSDIR = ../bin/libs diff --git a/tasks/Makefile b/tasks/Makefile index a1050a1..6387359 100644 --- a/tasks/Makefile +++ b/tasks/Makefile @@ -5,7 +5,7 @@ DJGPP_PREFIX = $(HOME)/djgpp/djgpp CC = $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-gcc DXE3GEN = PATH=$(DJGPP_PREFIX)/bin:$(PATH) DJDIR=$(DJGPP_PREFIX)/i586-pc-msdosdjgpp $(DJGPP_PREFIX)/i586-pc-msdosdjgpp/bin/dxe3gen -CFLAGS = -O2 -Wall -Wextra -Wno-type-limits -Wno-sign-compare -march=i486 -mtune=i586 +CFLAGS = -O2 -Wall -Wextra -Werror -Wno-type-limits -Wno-sign-compare -Wno-format-truncation -march=i486 -mtune=i586 OBJDIR = ../obj/tasks LIBSDIR = ../bin/libs diff --git a/texthelp/Makefile b/texthelp/Makefile index 6377843..245433a 100644 --- a/texthelp/Makefile +++ b/texthelp/Makefile @@ -6,7 +6,7 @@ DJGPP_PREFIX = $(HOME)/djgpp/djgpp CC = $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-gcc DXE3GEN = PATH=$(DJGPP_PREFIX)/bin:$(PATH) DJDIR=$(DJGPP_PREFIX)/i586-pc-msdosdjgpp $(DJGPP_PREFIX)/i586-pc-msdosdjgpp/bin/dxe3gen -CFLAGS = -O2 -Wall -Wextra -Wno-type-limits -Wno-sign-compare -march=i486 -mtune=i586 -I. -I../core -I../core/platform -I../tasks -I../core/thirdparty +CFLAGS = -O2 -Wall -Wextra -Werror -Wno-type-limits -Wno-sign-compare -Wno-format-truncation -march=i486 -mtune=i586 -I. -I../core -I../core/platform -I../tasks -I../core/thirdparty OBJDIR = ../obj/texthelp LIBSDIR = ../bin/libs diff --git a/tools/Makefile b/tools/Makefile index 747dfa5..c9d0882 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -4,7 +4,7 @@ # (Linux or DOS), not on the target. No cross-compilation needed. CC = gcc -CFLAGS = -O2 -Wall -Wextra -I../core +CFLAGS = -O2 -Wall -Wextra -Werror -Wno-format-truncation -I../core -I../core/platform BINDIR = ../bin @@ -12,7 +12,7 @@ BINDIR = ../bin CONFIGDIR = ../bin/config -all: $(BINDIR)/dvxres $(BINDIR)/mkicon $(BINDIR)/mktbicon $(BINDIR)/mkwgticon $(BINDIR)/bmp2raw $(CONFIGDIR)/SPLASH.RAW +all: $(BINDIR)/dvxres $(BINDIR)/mkicon $(BINDIR)/mktbicon $(BINDIR)/mkwgticon $(BINDIR)/bmp2raw $(BINDIR)/dvxhlpc $(CONFIGDIR)/SPLASH.RAW $(BINDIR)/dvxres: dvxres.c ../core/dvxResource.c ../core/dvxResource.h | $(BINDIR) $(CC) $(CFLAGS) -o $@ dvxres.c ../core/dvxResource.c @@ -29,6 +29,9 @@ $(BINDIR)/mkwgticon: mkwgticon.c | $(BINDIR) $(BINDIR)/bmp2raw: bmp2raw.c | $(BINDIR) $(CC) $(CFLAGS) -o $@ bmp2raw.c +$(BINDIR)/dvxhlpc: dvxhlpc.c ../apps/dvxhelp/hlpformat.h | $(BINDIR) + $(CC) $(CFLAGS) -o $@ dvxhlpc.c + $(CONFIGDIR)/SPLASH.RAW: $(BINDIR)/bmp2raw ../assets/splash.bmp | $(CONFIGDIR) $(BINDIR)/bmp2raw ../assets/splash.bmp $@ diff --git a/tools/dvxhlpc.c b/tools/dvxhlpc.c new file mode 100644 index 0000000..78b2587 --- /dev/null +++ b/tools/dvxhlpc.c @@ -0,0 +1,1726 @@ +// dvxhlpc.c -- DVX Help file compiler +// +// Host-side tool (Linux) that converts .dvxhelp source files into +// the .hlp binary format consumed by the DVX help viewer. +// +// Usage: +// dvxhlpc -o output.hlp [-w 76] [-i imagedir] input1.dvxhelp [...] +// +// Five-pass algorithm: +// 1. Parse source files, build topic/TOC/index/image arrays +// 2. Word-wrap text and list-item records +// 3. Build deduplicated string table +// 4. Generate trigram search index +// 5. Serialize binary .hlp file + +#define _POSIX_C_SOURCE 200809L + +#include "../apps/dvxhelp/hlpformat.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// --------------------------------------------------------------------------- +// Limits +// --------------------------------------------------------------------------- + +#define MAX_TOPICS 1024 +#define MAX_TOC_ENTRIES 2048 +#define MAX_INDEX_ENTRIES 4096 +#define MAX_IMAGES 256 +#define MAX_RECORDS_PER_TOPIC 512 +#define MAX_LINE_LEN 1024 +#define MAX_TRIGRAMS 65536 +#define MAX_INCLUDE_DEPTH 16 +#define DEFAULT_WRAP_WIDTH 76 +#define LIST_INDENT 2 +#define INITIAL_STRTAB_SIZE 65536 +#define INITIAL_BUF_SIZE 65536 + +// --------------------------------------------------------------------------- +// Compiler data structures +// --------------------------------------------------------------------------- + +typedef struct { + uint8_t type; + uint8_t flags; + char *data; + int32_t dataLen; +} RecordT; + +typedef struct { + char id[128]; + char title[256]; + RecordT *records; + int32_t recordCount; + int32_t recordCap; + bool isDefault; +} TopicT; + +typedef struct { + char title[256]; + int32_t topicIdx; + int32_t depth; +} TocEntryT; + +typedef struct { + char keyword[128]; + int32_t topicIdx; +} IndexEntryT; + +typedef struct { + char path[520]; + int32_t poolOffset; + int32_t fileSize; +} ImageRefT; + +// String table entry for deduplication +typedef struct { + char *str; + int32_t offset; +} StrEntryT; + +// Trigram posting list +typedef struct { + uint8_t trigram[3]; + uint16_t *postings; + int32_t postingCount; + int32_t postingCap; +} TrigramT; + +// Dynamic buffer for serialization +typedef struct { + uint8_t *data; + int32_t size; + int32_t cap; +} BufT; + +// --------------------------------------------------------------------------- +// Globals +// --------------------------------------------------------------------------- + +static TopicT topics[MAX_TOPICS]; +static int32_t topicCount = 0; + +static TocEntryT tocEntries[MAX_TOC_ENTRIES]; +static int32_t tocCount = 0; + +static IndexEntryT indexEntries[MAX_INDEX_ENTRIES]; +static int32_t indexCount = 0; + +static ImageRefT imageRefs[MAX_IMAGES]; +static int32_t imageCount = 0; + +static char *strTab = NULL; +static int32_t strTabSize = 0; +static int32_t strTabCap = 0; + +static StrEntryT *strEntries = NULL; +static int32_t strEntryCount = 0; +static int32_t strEntryCap = 0; + +static TrigramT trigrams[MAX_TRIGRAMS]; +static int32_t trigramCount = 0; + +static int32_t wrapWidth = DEFAULT_WRAP_WIDTH; +static char imageDir[260] = "."; +static const char *htmlPath = NULL; +static int32_t errorCount = 0; + +// Parse state +static const char *currentFile = NULL; +static int32_t currentLine = 0; + +// --------------------------------------------------------------------------- +// Prototypes +// --------------------------------------------------------------------------- + +static void addImageRef(const char *filename); +static void addIndexEntry(const char *keyword, int32_t topicIdx); +static RecordT *addRecord(TopicT *topic, uint8_t type, uint8_t flags, const char *data, int32_t dataLen); +static void addTocEntry(const char *title, int32_t topicIdx, int32_t depth); +static TopicT *addTopic(const char *id); +static void addTrigram(uint8_t a, uint8_t b, uint8_t c, uint16_t topicIdx); +static void bufAppend(BufT *buf, const void *data, int32_t len); +static void bufInit(BufT *buf); +static void buildSearchIndex(void); +static int compareIndexEntries(const void *a, const void *b); +static int compareTrigrams(const void *a, const void *b); +static void emitError(const char *fmt, ...); +static void emitWarning(const char *fmt, ...); +static int32_t findImage(const char *filename); +static void flushParagraph(TopicT *topic, char *para, int32_t paraLen, uint8_t type, uint8_t flags); +static void freeAll(void); +static void parseDirective(const char *line, TopicT **curTopic, bool *inList, bool *inTable, bool *inCode, bool *inNote, uint8_t *noteFlags, char *para, int32_t *paraLen, int32_t includeDepth); +static void parseFile(const char *path, TopicT **curTopic, bool *inList, bool *inTable, bool *inCode, bool *inNote, uint8_t *noteFlags, char *para, int32_t *paraLen, int32_t includeDepth); +static void pass1Parse(int32_t fileCount, char **files); +static void pass2Wrap(void); +static void pass3StringTable(void); +static void pass4SearchIndex(void); +static int pass5Serialize(const char *outputPath); +static int emitHtml(const char *outputPath); +static int32_t strTableAdd(const char *str); +static int32_t strTableFind(const char *str); +static char *wordWrap(const char *text, int32_t width, int32_t indent); +static void usage(void); + +// --------------------------------------------------------------------------- +// emitError / emitWarning +// --------------------------------------------------------------------------- + +static void emitError(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + fprintf(stderr, "error: %s:%d: ", currentFile ? currentFile : "", currentLine); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + errorCount++; +} + + +static void emitWarning(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + fprintf(stderr, "warning: %s:%d: ", currentFile ? currentFile : "", currentLine); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); +} + + +// --------------------------------------------------------------------------- +// usage +// --------------------------------------------------------------------------- + +static void usage(void) { + fprintf(stderr, "Usage: dvxhlpc -o output.hlp [-w width] [-i imagedir] [--html out.html] input.dvxhelp [...]\n"); + exit(1); +} + + +// --------------------------------------------------------------------------- +// Buffer helpers +// --------------------------------------------------------------------------- + +static void bufInit(BufT *buf) { + buf->cap = INITIAL_BUF_SIZE; + buf->size = 0; + buf->data = malloc(buf->cap); + if (!buf->data) { + fprintf(stderr, "fatal: out of memory\n"); + exit(1); + } +} + + +static void bufAppend(BufT *buf, const void *data, int32_t len) { + while (buf->size + len > buf->cap) { + buf->cap *= 2; + buf->data = realloc(buf->data, buf->cap); + if (!buf->data) { + fprintf(stderr, "fatal: out of memory\n"); + exit(1); + } + } + memcpy(buf->data + buf->size, data, len); + buf->size += len; +} + + +// --------------------------------------------------------------------------- +// Topic management +// --------------------------------------------------------------------------- + +static TopicT *addTopic(const char *id) { + if (topicCount >= MAX_TOPICS) { + emitError("too many topics (max %d)", MAX_TOPICS); + return NULL; + } + TopicT *t = &topics[topicCount++]; + memset(t, 0, sizeof(*t)); + snprintf(t->id, sizeof(t->id), "%s", id); + t->recordCap = 32; + t->records = malloc(sizeof(RecordT) * t->recordCap); + if (!t->records) { + fprintf(stderr, "fatal: out of memory\n"); + exit(1); + } + return t; +} + + +static RecordT *addRecord(TopicT *topic, uint8_t type, uint8_t flags, const char *data, int32_t dataLen) { + if (topic->recordCount >= MAX_RECORDS_PER_TOPIC) { + emitError("too many records in topic '%s' (max %d)", topic->id, MAX_RECORDS_PER_TOPIC); + return NULL; + } + if (topic->recordCount >= topic->recordCap) { + topic->recordCap *= 2; + topic->records = realloc(topic->records, sizeof(RecordT) * topic->recordCap); + if (!topic->records) { + fprintf(stderr, "fatal: out of memory\n"); + exit(1); + } + } + RecordT *r = &topic->records[topic->recordCount++]; + r->type = type; + r->flags = flags; + r->dataLen = dataLen; + if (data && dataLen > 0) { + r->data = malloc(dataLen + 1); + memcpy(r->data, data, dataLen); + r->data[dataLen] = '\0'; + } else { + r->data = NULL; + r->dataLen = 0; + } + return r; +} + + +// --------------------------------------------------------------------------- +// TOC / Index / Image management +// --------------------------------------------------------------------------- + +static void addTocEntry(const char *title, int32_t topicIdx, int32_t depth) { + if (tocCount >= MAX_TOC_ENTRIES) { + emitError("too many TOC entries (max %d)", MAX_TOC_ENTRIES); + return; + } + TocEntryT *e = &tocEntries[tocCount++]; + snprintf(e->title, sizeof(e->title), "%s", title); + e->title[sizeof(e->title) - 1] = '\0'; + e->topicIdx = topicIdx; + e->depth = depth; +} + + +static void addIndexEntry(const char *keyword, int32_t topicIdx) { + if (indexCount >= MAX_INDEX_ENTRIES) { + emitError("too many index entries (max %d)", MAX_INDEX_ENTRIES); + return; + } + IndexEntryT *e = &indexEntries[indexCount++]; + snprintf(e->keyword, sizeof(e->keyword), "%s", keyword); + e->keyword[sizeof(e->keyword) - 1] = '\0'; + e->topicIdx = topicIdx; +} + + +static int32_t findImage(const char *filename) { + for (int32_t i = 0; i < imageCount; i++) { + // Compare just the filename portion + const char *base = strrchr(imageRefs[i].path, '/'); + if (!base) { + base = imageRefs[i].path; + } else { + base++; + } + if (strcmp(base, filename) == 0) { + return i; + } + } + return -1; +} + + +static void addImageRef(const char *filename) { + if (findImage(filename) >= 0) { + return; + } + if (imageCount >= MAX_IMAGES) { + emitError("too many images (max %d)", MAX_IMAGES); + return; + } + ImageRefT *img = &imageRefs[imageCount++]; + snprintf(img->path, sizeof(img->path), "%s/%s", imageDir, filename); + img->poolOffset = 0; + img->fileSize = 0; +} + + +// --------------------------------------------------------------------------- +// Word wrap +// --------------------------------------------------------------------------- + +static char *wordWrap(const char *text, int32_t width, int32_t indent) { + if (!text || !*text) { + return strdup(""); + } + + int32_t textLen = strlen(text); + // Worst case: every word on its own line + indent + char *result = malloc(textLen * 2 + 1); + if (!result) { + fprintf(stderr, "fatal: out of memory\n"); + exit(1); + } + + int32_t outPos = 0; + int32_t col = 0; + bool firstLine = true; + const char *p = text; + + while (*p) { + // Skip leading whitespace + while (*p == ' ' || *p == '\t') { + p++; + } + if (!*p) { + break; + } + + // Find end of word + const char *wordStart = p; + while (*p && *p != ' ' && *p != '\t' && *p != '\n') { + p++; + } + int32_t wordLen = (int32_t)(p - wordStart); + + // Check if word fits on current line + if (col > 0 && col + 1 + wordLen > width) { + // Wrap to next line + result[outPos++] = '\n'; + for (int32_t i = 0; i < indent; i++) { + result[outPos++] = ' '; + } + col = indent; + firstLine = false; + } else if (col > 0) { + // Add space between words + result[outPos++] = ' '; + col++; + } else if (!firstLine) { + // Start of continuation line + for (int32_t i = 0; i < indent; i++) { + result[outPos++] = ' '; + } + col = indent; + } + + memcpy(result + outPos, wordStart, wordLen); + outPos += wordLen; + col += wordLen; + + // Skip newlines in source (join continuation lines) + while (*p == '\n') { + p++; + } + } + + result[outPos] = '\0'; + return result; +} + + +// --------------------------------------------------------------------------- +// Paragraph flush +// --------------------------------------------------------------------------- + +static void flushParagraph(TopicT *topic, char *para, int32_t paraLen, uint8_t type, uint8_t flags) { + if (!topic || paraLen <= 0) { + return; + } + + // Trim trailing whitespace + while (paraLen > 0 && (para[paraLen - 1] == ' ' || para[paraLen - 1] == '\n' || para[paraLen - 1] == '\r')) { + paraLen--; + } + if (paraLen <= 0) { + return; + } + para[paraLen] = '\0'; + + addRecord(topic, type, flags, para, paraLen); +} + + +// --------------------------------------------------------------------------- +// Pass 1: Parse +// --------------------------------------------------------------------------- + +static void parseDirective(const char *line, TopicT **curTopic, bool *inList, bool *inTable, bool *inCode, bool *inNote, uint8_t *noteFlags, char *para, int32_t *paraLen, int32_t includeDepth) { + char directive[32] = {0}; + const char *rest = NULL; + + // Extract directive name + const char *p = line + 1; // skip '.' + int32_t i = 0; + while (*p && !isspace(*p) && i < (int32_t)sizeof(directive) - 1) { + directive[i++] = *p++; + } + directive[i] = '\0'; + + // Skip whitespace after directive + while (*p && isspace(*p)) { + p++; + } + rest = p; + + // Handle .topic + if (strcmp(directive, "topic") == 0) { + if (!*rest) { + emitError(".topic requires an ID"); + return; + } + // Flush pending paragraph + flushParagraph(*curTopic, para, *paraLen, HLP_REC_TEXT, 0); + *paraLen = 0; + + // Close any open blocks + *inList = false; + *inTable = false; + *inCode = false; + *inNote = false; + + // Extract topic ID (first word) + char id[128] = {0}; + int32_t j = 0; + while (*rest && !isspace(*rest) && j < (int32_t)sizeof(id) - 1) { + id[j++] = *rest++; + } + id[j] = '\0'; + + *curTopic = addTopic(id); + return; + } + + // All other directives need a current topic (except .include) + if (strcmp(directive, "include") == 0) { + if (!*rest) { + emitError(".include requires a filename"); + return; + } + // Flush pending paragraph + flushParagraph(*curTopic, para, *paraLen, *inCode ? HLP_REC_CODE : (*inTable ? HLP_REC_TABLE : HLP_REC_TEXT), *inNote ? *noteFlags : 0); + *paraLen = 0; + + // Build path relative to current file's directory + char includePath[260] = {0}; + if (rest[0] == '/') { + snprintf(includePath, sizeof(includePath), "%s", rest); + } else { + snprintf(includePath, sizeof(includePath), "%s", currentFile); + char *slash = strrchr(includePath, '/'); + if (slash) { + slash[1] = '\0'; + } else { + includePath[0] = '\0'; + } + snprintf(includePath + strlen(includePath), sizeof(includePath) - strlen(includePath), "%s", rest); + } + + // Trim trailing whitespace from path + int32_t len = strlen(includePath); + while (len > 0 && isspace(includePath[len - 1])) { + includePath[--len] = '\0'; + } + + parseFile(includePath, curTopic, inList, inTable, inCode, inNote, noteFlags, para, paraLen, includeDepth + 1); + return; + } + + if (!*curTopic) { + emitError("directive .%s outside of a topic", directive); + return; + } + + // Flush pending paragraph before most directives + if (strcmp(directive, "item") != 0) { + uint8_t flushType = HLP_REC_TEXT; + uint8_t flushFlags = 0; + if (*inCode) { + flushType = HLP_REC_CODE; + } else if (*inTable) { + flushType = HLP_REC_TABLE; + } else if (*inNote) { + flushType = HLP_REC_NOTE; + flushFlags = *noteFlags; + } + flushParagraph(*curTopic, para, *paraLen, flushType, flushFlags); + *paraLen = 0; + } + + if (strcmp(directive, "title") == 0) { + snprintf((*curTopic)->title, sizeof((*curTopic)->title), "%s", rest); + (*curTopic)->title[sizeof((*curTopic)->title) - 1] = '\0'; + + } else if (strcmp(directive, "toc") == 0) { + // .toc + int32_t depth = 0; + if (isdigit(*rest)) { + depth = *rest - '0'; + rest++; + while (isspace(*rest)) { + rest++; + } + } + addTocEntry(rest, topicCount - 1, depth); + + } else if (strcmp(directive, "h1") == 0) { + addRecord(*curTopic, HLP_REC_HEADING1, 0, rest, strlen(rest)); + + } else if (strcmp(directive, "h2") == 0) { + addRecord(*curTopic, HLP_REC_HEADING2, 0, rest, strlen(rest)); + + } else if (strcmp(directive, "h3") == 0) { + addRecord(*curTopic, HLP_REC_HEADING3, 0, rest, strlen(rest)); + + } else if (strcmp(directive, "image") == 0) { + if (!*rest) { + emitError(".image requires a filename"); + return; + } + // Trim trailing whitespace + char imgFile[260]; + snprintf(imgFile, sizeof(imgFile), "%s", rest); + imgFile[sizeof(imgFile) - 1] = '\0'; + int32_t len = strlen(imgFile); + while (len > 0 && isspace(imgFile[len - 1])) { + imgFile[--len] = '\0'; + } + addImageRef(imgFile); + addRecord(*curTopic, HLP_REC_IMAGE, 0, imgFile, strlen(imgFile)); + + } else if (strcmp(directive, "link") == 0) { + // .link + char linkTarget[128] = {0}; + int32_t j = 0; + while (*rest && !isspace(*rest) && j < (int32_t)sizeof(linkTarget) - 1) { + linkTarget[j++] = *rest++; + } + linkTarget[j] = '\0'; + while (isspace(*rest)) { + rest++; + } + // Store as "target\0display text" + int32_t targetLen = strlen(linkTarget); + int32_t displayLen = strlen(rest); + int32_t totalLen = targetLen + 1 + displayLen; + char *linkData = malloc(totalLen + 1); + memcpy(linkData, linkTarget, targetLen); + linkData[targetLen] = '\0'; + memcpy(linkData + targetLen + 1, rest, displayLen); + linkData[totalLen] = '\0'; + addRecord(*curTopic, HLP_REC_LINK, 0, linkData, totalLen); + free(linkData); + + } else if (strcmp(directive, "list") == 0) { + *inList = true; + + } else if (strcmp(directive, "item") == 0) { + if (!*inList) { + emitWarning(".item outside of .list"); + } + // Flush any pending item + flushParagraph(*curTopic, para, *paraLen, HLP_REC_LIST_ITEM, 0); + *paraLen = 0; + // Start new item with the rest text + if (*rest) { + int32_t len = strlen(rest); + memcpy(para, rest, len); + *paraLen = len; + } + + } else if (strcmp(directive, "endlist") == 0) { + // Flush final list item + flushParagraph(*curTopic, para, *paraLen, HLP_REC_LIST_ITEM, 0); + *paraLen = 0; + *inList = false; + + } else if (strcmp(directive, "table") == 0) { + *inTable = true; + + } else if (strcmp(directive, "endtable") == 0) { + *inTable = false; + + } else if (strcmp(directive, "code") == 0) { + *inCode = true; + + } else if (strcmp(directive, "endcode") == 0) { + *inCode = false; + + } else if (strcmp(directive, "note") == 0) { + *inNote = true; + if (strncmp(rest, "tip", 3) == 0) { + *noteFlags = HLP_NOTE_TIP; + } else if (strncmp(rest, "warning", 7) == 0) { + *noteFlags = HLP_NOTE_WARNING; + } else { + *noteFlags = HLP_NOTE_INFO; + } + + } else if (strcmp(directive, "endnote") == 0) { + *inNote = false; + + } else if (strcmp(directive, "index") == 0) { + if (!*rest) { + emitError(".index requires a keyword"); + return; + } + addIndexEntry(rest, topicCount - 1); + + } else if (strcmp(directive, "hr") == 0) { + addRecord(*curTopic, HLP_REC_HRULE, 0, NULL, 0); + + } else if (strcmp(directive, "default") == 0) { + (*curTopic)->isDefault = true; + + } else if (strcmp(directive, "wrap") == 0) { + int32_t w = atoi(rest); + if (w > 0) { + wrapWidth = w; + } + + } else { + emitWarning("unknown directive .%s", directive); + } +} + + +static void parseFile(const char *path, TopicT **curTopic, bool *inList, bool *inTable, bool *inCode, bool *inNote, uint8_t *noteFlags, char *para, int32_t *paraLen, int32_t includeDepth) { + if (includeDepth > MAX_INCLUDE_DEPTH) { + emitError("include depth exceeded (max %d)", MAX_INCLUDE_DEPTH); + return; + } + + FILE *f = fopen(path, "r"); + if (!f) { + emitError("cannot open '%s': %s", path, strerror(errno)); + return; + } + + // Save and set parse state + const char *savedFile = currentFile; + int32_t savedLine = currentLine; + currentFile = path; + currentLine = 0; + + fprintf(stderr, " parsing %s\n", path); + + char line[MAX_LINE_LEN]; + while (fgets(line, sizeof(line), f)) { + currentLine++; + + // Strip trailing newline/CR + int32_t len = strlen(line); + while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r')) { + line[--len] = '\0'; + } + + // Check for directive + if (line[0] == '.') { + parseDirective(line, curTopic, inList, inTable, inCode, inNote, noteFlags, para, paraLen, includeDepth); + continue; + } + + // Plain text line + if (!*curTopic) { + // Ignore text outside topics + continue; + } + + if (*inCode || *inTable) { + // In code/table blocks, preserve lines verbatim + if (*paraLen > 0) { + para[(*paraLen)++] = '\n'; + } + memcpy(para + *paraLen, line, len); + *paraLen += len; + para[*paraLen] = '\0'; + } else if (*inList) { + // In list, accumulate continuation text for current item + if (len == 0) { + // Empty line flushes current item + flushParagraph(*curTopic, para, *paraLen, HLP_REC_LIST_ITEM, 0); + *paraLen = 0; + } else { + if (*paraLen > 0) { + para[(*paraLen)++] = ' '; + } + memcpy(para + *paraLen, line, len); + *paraLen += len; + para[*paraLen] = '\0'; + } + } else if (*inNote) { + // In note block + if (len == 0) { + // Empty line separates paragraphs + flushParagraph(*curTopic, para, *paraLen, HLP_REC_NOTE, *noteFlags); + *paraLen = 0; + } else { + if (*paraLen > 0) { + para[(*paraLen)++] = ' '; + } + memcpy(para + *paraLen, line, len); + *paraLen += len; + para[*paraLen] = '\0'; + } + } else { + // Normal text + if (len == 0) { + // Empty line ends paragraph + flushParagraph(*curTopic, para, *paraLen, HLP_REC_TEXT, 0); + *paraLen = 0; + } else { + if (*paraLen > 0) { + para[(*paraLen)++] = ' '; + } + memcpy(para + *paraLen, line, len); + *paraLen += len; + para[*paraLen] = '\0'; + } + } + } + + fclose(f); + + // Restore parse state + currentFile = savedFile; + currentLine = savedLine; +} + + +static void pass1Parse(int32_t fileCount, char **files) { + fprintf(stderr, "Pass 1: Parsing %d input file(s)...\n", fileCount); + + TopicT *curTopic = NULL; + bool inList = false; + bool inTable = false; + bool inCode = false; + bool inNote = false; + uint8_t noteFlags = 0; + + // Paragraph buffer (shared across files for multi-file topics) + char para[MAX_LINE_LEN * 64]; + int32_t paraLen = 0; + + for (int32_t i = 0; i < fileCount; i++) { + parseFile(files[i], &curTopic, &inList, &inTable, &inCode, &inNote, ¬eFlags, para, ¶Len, 0); + } + + // Flush any remaining paragraph + if (curTopic && paraLen > 0) { + uint8_t type = HLP_REC_TEXT; + uint8_t flags = 0; + if (inCode) { + type = HLP_REC_CODE; + } else if (inTable) { + type = HLP_REC_TABLE; + } else if (inNote) { + type = HLP_REC_NOTE; + flags = noteFlags; + } else if (inList) { + type = HLP_REC_LIST_ITEM; + } + flushParagraph(curTopic, para, paraLen, type, flags); + } + + fprintf(stderr, " %d topic(s), %d TOC entries, %d index entries, %d image(s)\n", + topicCount, tocCount, indexCount, imageCount); +} + + +// --------------------------------------------------------------------------- +// Pass 2: Word wrap +// --------------------------------------------------------------------------- + +static void pass2Wrap(void) { + fprintf(stderr, "Pass 2: Word wrapping at %d columns...\n", wrapWidth); + + for (int32_t t = 0; t < topicCount; t++) { + TopicT *topic = &topics[t]; + for (int32_t r = 0; r < topic->recordCount; r++) { + RecordT *rec = &topic->records[r]; + + if (rec->type == HLP_REC_TEXT || rec->type == HLP_REC_NOTE) { + char *wrapped = wordWrap(rec->data, wrapWidth, 0); + free(rec->data); + rec->data = wrapped; + rec->dataLen = strlen(wrapped); + + } else if (rec->type == HLP_REC_LIST_ITEM) { + char *wrapped = wordWrap(rec->data, wrapWidth - LIST_INDENT, LIST_INDENT); + free(rec->data); + rec->data = wrapped; + rec->dataLen = strlen(wrapped); + } + // CODE, TABLE, HEADING, etc. are not wrapped + } + } +} + + +// --------------------------------------------------------------------------- +// Pass 3: String table +// --------------------------------------------------------------------------- + +static int32_t strTableFind(const char *str) { + for (int32_t i = 0; i < strEntryCount; i++) { + if (strcmp(strEntries[i].str, str) == 0) { + return strEntries[i].offset; + } + } + return -1; +} + + +static int32_t strTableAdd(const char *str) { + // Check for existing + int32_t existing = strTableFind(str); + if (existing >= 0) { + return existing; + } + + int32_t len = strlen(str); + + // Grow string table buffer + while (strTabSize + len + 1 > strTabCap) { + strTabCap *= 2; + strTab = realloc(strTab, strTabCap); + if (!strTab) { + fprintf(stderr, "fatal: out of memory\n"); + exit(1); + } + } + + // Grow entries array + if (strEntryCount >= strEntryCap) { + strEntryCap *= 2; + strEntries = realloc(strEntries, sizeof(StrEntryT) * strEntryCap); + if (!strEntries) { + fprintf(stderr, "fatal: out of memory\n"); + exit(1); + } + } + + int32_t offset = strTabSize; + memcpy(strTab + strTabSize, str, len + 1); + strTabSize += len + 1; + + strEntries[strEntryCount].str = strTab + offset; + strEntries[strEntryCount].offset = offset; + strEntryCount++; + + return offset; +} + + +static void pass3StringTable(void) { + fprintf(stderr, "Pass 3: Building string table...\n"); + + strTabCap = INITIAL_STRTAB_SIZE; + strTabSize = 0; + strTab = malloc(strTabCap); + + strEntryCap = 1024; + strEntryCount = 0; + strEntries = malloc(sizeof(StrEntryT) * strEntryCap); + + // Add empty string at offset 0 + strTableAdd(""); + + // Add all topic IDs and titles + for (int32_t i = 0; i < topicCount; i++) { + strTableAdd(topics[i].id); + strTableAdd(topics[i].title); + } + + // Add TOC titles + for (int32_t i = 0; i < tocCount; i++) { + strTableAdd(tocEntries[i].title); + } + + // Add index keywords + for (int32_t i = 0; i < indexCount; i++) { + strTableAdd(indexEntries[i].keyword); + } + + fprintf(stderr, " %d unique strings, %d bytes\n", strEntryCount, strTabSize); +} + + +// --------------------------------------------------------------------------- +// Pass 4: Search index (trigram) +// --------------------------------------------------------------------------- + +static int compareTrigrams(const void *a, const void *b) { + const TrigramT *ta = (const TrigramT *)a; + const TrigramT *tb = (const TrigramT *)b; + int32_t d = (int32_t)ta->trigram[0] - (int32_t)tb->trigram[0]; + if (d != 0) { + return d; + } + d = (int32_t)ta->trigram[1] - (int32_t)tb->trigram[1]; + if (d != 0) { + return d; + } + return (int32_t)ta->trigram[2] - (int32_t)tb->trigram[2]; +} + + +static void addTrigram(uint8_t a, uint8_t b, uint8_t c, uint16_t topicIdx) { + // Find existing trigram + TrigramT *tri = NULL; + for (int32_t i = 0; i < trigramCount; i++) { + if (trigrams[i].trigram[0] == a && trigrams[i].trigram[1] == b && trigrams[i].trigram[2] == c) { + tri = &trigrams[i]; + break; + } + } + + if (!tri) { + if (trigramCount >= MAX_TRIGRAMS) { + return; + } + tri = &trigrams[trigramCount++]; + tri->trigram[0] = a; + tri->trigram[1] = b; + tri->trigram[2] = c; + tri->postingCap = 8; + tri->postingCount = 0; + tri->postings = malloc(sizeof(uint16_t) * tri->postingCap); + } + + // Check if topic already in posting list + for (int32_t i = 0; i < tri->postingCount; i++) { + if (tri->postings[i] == topicIdx) { + return; + } + } + + // Add to posting list + if (tri->postingCount >= tri->postingCap) { + tri->postingCap *= 2; + tri->postings = realloc(tri->postings, sizeof(uint16_t) * tri->postingCap); + } + tri->postings[tri->postingCount++] = topicIdx; +} + + +static void buildSearchIndex(void) { + for (int32_t t = 0; t < topicCount; t++) { + TopicT *topic = &topics[t]; + + // Collect all searchable text for this topic + BufT textBuf; + bufInit(&textBuf); + + // Add title + int32_t titleLen = strlen(topic->title); + bufAppend(&textBuf, topic->title, titleLen); + uint8_t space = ' '; + bufAppend(&textBuf, &space, 1); + + for (int32_t r = 0; r < topic->recordCount; r++) { + RecordT *rec = &topic->records[r]; + if (!rec->data || rec->dataLen <= 0) { + continue; + } + if (rec->type == HLP_REC_TEXT || rec->type == HLP_REC_HEADING1 || rec->type == HLP_REC_HEADING2 || rec->type == HLP_REC_HEADING3 || rec->type == HLP_REC_LIST_ITEM || rec->type == HLP_REC_NOTE || rec->type == HLP_REC_CODE) { + bufAppend(&textBuf, rec->data, rec->dataLen); + bufAppend(&textBuf, &space, 1); + } + } + + // Lowercase the text + for (int32_t i = 0; i < textBuf.size; i++) { + textBuf.data[i] = tolower(textBuf.data[i]); + } + + // Generate trigrams + for (int32_t i = 0; i + 2 < textBuf.size; i++) { + uint8_t a = textBuf.data[i]; + uint8_t b = textBuf.data[i + 1]; + uint8_t c = textBuf.data[i + 2]; + if (isalnum(a) && isalnum(b) && isalnum(c)) { + addTrigram(a, b, c, (uint16_t)t); + } + } + + free(textBuf.data); + } +} + + +static void pass4SearchIndex(void) { + fprintf(stderr, "Pass 4: Building search index...\n"); + + buildSearchIndex(); + + // Sort trigrams + qsort(trigrams, trigramCount, sizeof(TrigramT), compareTrigrams); + + fprintf(stderr, " %d trigrams\n", trigramCount); +} + + +// --------------------------------------------------------------------------- +// Pass 5: Serialize +// --------------------------------------------------------------------------- + +static int compareIndexEntries(const void *a, const void *b) { + return strcasecmp(((const IndexEntryT *)a)->keyword, ((const IndexEntryT *)b)->keyword); +} + + + +// --------------------------------------------------------------------------- +// HTML output +// --------------------------------------------------------------------------- + +static const char sBase64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static void base64Encode(FILE *f, const uint8_t *data, int32_t len) { + for (int32_t i = 0; i < len; i += 3) { + uint32_t b = (uint32_t)data[i] << 16; + + if (i + 1 < len) { b |= (uint32_t)data[i + 1] << 8; } + if (i + 2 < len) { b |= (uint32_t)data[i + 2]; } + + fputc(sBase64[(b >> 18) & 0x3F], f); + fputc(sBase64[(b >> 12) & 0x3F], f); + fputc((i + 1 < len) ? sBase64[(b >> 6) & 0x3F] : '=', f); + fputc((i + 2 < len) ? sBase64[b & 0x3F] : '=', f); + } +} + + +static void htmlEscapeWrite(FILE *f, const char *text) { + for (const char *p = text; *p; p++) { + switch (*p) { + case '<': fputs("<", f); break; + case '>': fputs(">", f); break; + case '&': fputs("&", f); break; + case '"': fputs(""", f); break; + default: fputc(*p, f); break; + } + } +} + + +static void htmlWritePreformatted(FILE *f, const char *text) { + fprintf(f, "
    ");
    +    htmlEscapeWrite(f, text);
    +    fprintf(f, "
    \n"); +} + + +static void htmlWriteImage(FILE *f, const RecordT *rec) { + // rec->data is the image filename (from parse time) + // Find the image ref and embed the file as base64 + int32_t imgIdx = findImage(rec->data); + + if (imgIdx < 0) { + fprintf(f, "

    [Image: %s not found]

    \n", rec->data); + return; + } + + FILE *imgFile = fopen(imageRefs[imgIdx].path, "rb"); + + if (!imgFile) { + fprintf(f, "

    [Image: %s could not be read]

    \n", rec->data); + return; + } + + fseek(imgFile, 0, SEEK_END); + long imgSize = ftell(imgFile); + fseek(imgFile, 0, SEEK_SET); + + uint8_t *imgData = malloc(imgSize); + + if (!imgData) { + fclose(imgFile); + return; + } + + if (fread(imgData, 1, imgSize, imgFile) != (size_t)imgSize) { + free(imgData); + fclose(imgFile); + fprintf(f, "

    [Image: %s read error]

    \n", rec->data); + return; + } + + fclose(imgFile); + + fprintf(f, "

    \"%s\"

    \n", rec->data); + free(imgData); +} + + +static void htmlWriteRecords(FILE *f, const TopicT *topic) { + bool inList = false; + + for (int32_t i = 0; i < topic->recordCount; i++) { + const RecordT *rec = &topic->records[i]; + + // Close list if we're leaving list items + if (inList && rec->type != HLP_REC_LIST_ITEM) { + fprintf(f, "\n"); + inList = false; + } + + switch (rec->type) { + case HLP_REC_TEXT: + fprintf(f, "

    "); + htmlEscapeWrite(f, rec->data); + fprintf(f, "

    \n"); + break; + + case HLP_REC_HEADING1: + fprintf(f, "

    "); + htmlEscapeWrite(f, rec->data); + fprintf(f, "

    \n"); + break; + + case HLP_REC_HEADING2: + fprintf(f, "

    "); + htmlEscapeWrite(f, rec->data); + fprintf(f, "

    \n"); + break; + + case HLP_REC_HEADING3: + fprintf(f, "

    "); + htmlEscapeWrite(f, rec->data); + fprintf(f, "

    \n"); + break; + + case HLP_REC_IMAGE: + htmlWriteImage(f, rec); + break; + + case HLP_REC_LINK: { + // data format: "topicId\0displayText" + const char *targetId = rec->data; + const char *displayTxt = rec->data + strlen(rec->data) + 1; + + if (displayTxt > rec->data + rec->dataLen) { + displayTxt = targetId; + } + + fprintf(f, "

    ", targetId); + htmlEscapeWrite(f, displayTxt); + fprintf(f, "

    \n"); + break; + } + + case HLP_REC_LIST_ITEM: + if (!inList) { + fprintf(f, "
      \n"); + inList = true; + } + + fprintf(f, "
    • "); + htmlEscapeWrite(f, rec->data); + fprintf(f, "
    • \n"); + break; + + case HLP_REC_TABLE: + htmlWritePreformatted(f, rec->data); + break; + + case HLP_REC_CODE: + fprintf(f, "
      ");
      +                htmlEscapeWrite(f, rec->data);
      +                fprintf(f, "
      \n"); + break; + + case HLP_REC_HRULE: + fprintf(f, "
      \n"); + break; + + case HLP_REC_NOTE: { + const char *label = "Note"; + + if (rec->flags == HLP_NOTE_TIP) { + label = "Tip"; + } else if (rec->flags == HLP_NOTE_WARNING) { + label = "Warning"; + } + + fprintf(f, "
      %s: ", label); + htmlEscapeWrite(f, rec->data); + fprintf(f, "
      \n"); + break; + } + + case HLP_REC_END: + break; + + default: + break; + } + } + + if (inList) { + fprintf(f, "
    \n"); + } +} + + +static void htmlWriteTocEntry(FILE *f, int32_t idx) { + const TocEntryT *entry = &tocEntries[idx]; + + if (entry->topicIdx >= 0 && entry->topicIdx < topicCount) { + fprintf(f, "
  • ", topics[entry->topicIdx].id); + htmlEscapeWrite(f, entry->title); + fprintf(f, ""); + } else { + fprintf(f, "
  • "); + htmlEscapeWrite(f, entry->title); + fprintf(f, ""); + } + + // Check if next entries are children (deeper depth) + int32_t myDepth = entry->depth; + int32_t next = idx + 1; + + if (next < tocCount && tocEntries[next].depth > myDepth) { + fprintf(f, "\n
      \n"); + + while (next < tocCount && tocEntries[next].depth > myDepth) { + htmlWriteTocEntry(f, next); + + // Skip past this entry's subtree + int32_t childDepth = tocEntries[next].depth; + next++; + + while (next < tocCount && tocEntries[next].depth > childDepth) { + next++; + } + } + + fprintf(f, "
    \n"); + } + + fprintf(f, "
  • \n"); +} + + +static int emitHtml(const char *outputPath) { + FILE *f = fopen(outputPath, "w"); + + if (!f) { + fprintf(stderr, "error: cannot open %s for writing\n", outputPath); + return -1; + } + + // Find a title from the default topic or the first topic + const char *docTitle = "DVX Help"; + + for (int32_t i = 0; i < topicCount; i++) { + if (topics[i].isDefault && topics[i].title[0]) { + docTitle = topics[i].title; + break; + } + } + + fprintf(f, "\n\n\n"); + fprintf(f, "\n"); + fprintf(f, ""); + htmlEscapeWrite(f, docTitle); + fprintf(f, "\n"); + fprintf(f, "\n"); + fprintf(f, "\n\n"); + + // TOC sidebar + fprintf(f, "\n"); + + // Main content + fprintf(f, "
    \n"); + + for (int32_t i = 0; i < topicCount; i++) { + fprintf(f, "
    \n", topics[i].id); + fprintf(f, "

    "); + htmlEscapeWrite(f, topics[i].title); + fprintf(f, "

    \n"); + htmlWriteRecords(f, &topics[i]); + fprintf(f, "
    \n"); + } + + fprintf(f, "
    \n\n\n"); + fclose(f); + return 0; +} + + +static int pass5Serialize(const char *outputPath) { + fprintf(stderr, "Pass 5: Serializing to %s...\n", outputPath); + + FILE *f = fopen(outputPath, "wb"); + if (!f) { + fprintf(stderr, "error: cannot create '%s': %s\n", outputPath, strerror(errno)); + return 1; + } + + HlpHeaderT hdr; + memset(&hdr, 0, sizeof(hdr)); + hdr.magic = HLP_MAGIC; + hdr.version = HLP_VERSION; + hdr.topicCount = topicCount; + hdr.wrapWidth = wrapWidth; + + // Find default topic + hdr.defaultTopicStr = 0; + for (int32_t i = 0; i < topicCount; i++) { + if (topics[i].isDefault) { + hdr.defaultTopicStr = strTableFind(topics[i].id); + break; + } + } + + uint32_t offset = 0; + + // --- 1. Image pool --- + hdr.imagePoolOffset = offset; + for (int32_t i = 0; i < imageCount; i++) { + ImageRefT *img = &imageRefs[i]; + FILE *imgFile = fopen(img->path, "rb"); + if (!imgFile) { + fprintf(stderr, "error: cannot open image '%s': %s\n", img->path, strerror(errno)); + fclose(f); + return 1; + } + fseek(imgFile, 0, SEEK_END); + img->fileSize = ftell(imgFile); + fseek(imgFile, 0, SEEK_SET); + img->poolOffset = offset - hdr.imagePoolOffset; + + uint8_t *imgData = malloc(img->fileSize); + if (fread(imgData, 1, img->fileSize, imgFile) != (size_t)img->fileSize) { + fprintf(stderr, "error: cannot read image '%s'\n", img->path); + free(imgData); + fclose(imgFile); + fclose(f); + return 1; + } + fwrite(imgData, 1, img->fileSize, f); + offset += img->fileSize; + free(imgData); + fclose(imgFile); + fprintf(stderr, " image: %s (%d bytes)\n", img->path, img->fileSize); + } + hdr.imagePoolSize = offset - hdr.imagePoolOffset; + + // --- 2. Topic content records --- + uint32_t *topicContentOffsets = calloc(topicCount, sizeof(uint32_t)); + uint32_t *topicContentSizes = calloc(topicCount, sizeof(uint32_t)); + + for (int32_t t = 0; t < topicCount; t++) { + TopicT *topic = &topics[t]; + topicContentOffsets[t] = offset; + uint32_t startOffset = offset; + + for (int32_t r = 0; r < topic->recordCount; r++) { + RecordT *rec = &topic->records[r]; + HlpRecordHdrT recHdr; + recHdr.type = rec->type; + recHdr.flags = rec->flags; + + if (rec->type == HLP_REC_IMAGE) { + // Replace filename with HlpImageRefT + int32_t imgIdx = findImage(rec->data); + if (imgIdx < 0) { + fprintf(stderr, "error: image '%s' not found in references\n", rec->data); + recHdr.length = 0; + fwrite(&recHdr, sizeof(recHdr), 1, f); + offset += sizeof(recHdr); + } else { + HlpImageRefT imgRef; + imgRef.imageOffset = imageRefs[imgIdx].poolOffset; + imgRef.imageSize = imageRefs[imgIdx].fileSize; + recHdr.length = sizeof(HlpImageRefT); + fwrite(&recHdr, sizeof(recHdr), 1, f); + fwrite(&imgRef, sizeof(imgRef), 1, f); + offset += sizeof(recHdr) + sizeof(HlpImageRefT); + } + } else if (rec->type == HLP_REC_LINK) { + // Payload is "target\0display" -- write as-is + recHdr.length = rec->dataLen; + fwrite(&recHdr, sizeof(recHdr), 1, f); + fwrite(rec->data, 1, rec->dataLen, f); + offset += sizeof(recHdr) + rec->dataLen; + } else if (rec->type == HLP_REC_HRULE) { + recHdr.length = 0; + fwrite(&recHdr, sizeof(recHdr), 1, f); + offset += sizeof(recHdr); + } else { + // Text, headings, list items, code, table, note + recHdr.length = rec->dataLen; + fwrite(&recHdr, sizeof(recHdr), 1, f); + if (rec->dataLen > 0) { + fwrite(rec->data, 1, rec->dataLen, f); + } + offset += sizeof(recHdr) + rec->dataLen; + } + } + + // Write end-of-topic record + HlpRecordHdrT endRec; + endRec.type = HLP_REC_END; + endRec.flags = 0; + endRec.length = 0; + fwrite(&endRec, sizeof(endRec), 1, f); + offset += sizeof(endRec); + + topicContentSizes[t] = offset - startOffset; + } + + // --- 3. TOC entries --- + hdr.tocOffset = offset; + hdr.tocCount = tocCount; + for (int32_t i = 0; i < tocCount; i++) { + HlpTocEntryT entry; + entry.titleStr = strTableFind(tocEntries[i].title); + entry.topicIdx = (tocEntries[i].topicIdx >= 0) ? (uint16_t)tocEntries[i].topicIdx : 0xFFFF; + entry.depth = (uint8_t)tocEntries[i].depth; + entry.flags = 0; + fwrite(&entry, sizeof(entry), 1, f); + offset += sizeof(entry); + } + + // --- 4. Keyword index entries (sorted) --- + qsort(indexEntries, indexCount, sizeof(IndexEntryT), compareIndexEntries); + hdr.indexOffset = offset; + hdr.indexCount = indexCount; + for (int32_t i = 0; i < indexCount; i++) { + HlpIndexEntryT entry; + entry.keywordStr = strTableFind(indexEntries[i].keyword); + entry.topicIdx = (uint16_t)indexEntries[i].topicIdx; + entry.reserved = 0; + fwrite(&entry, sizeof(entry), 1, f); + offset += sizeof(entry); + } + + // --- 5. Search index --- + hdr.searchOffset = offset; + { + HlpSearchHeaderT searchHdr; + searchHdr.trigramCount = trigramCount; + fwrite(&searchHdr, sizeof(searchHdr), 1, f); + offset += sizeof(searchHdr); + + // Calculate posting list offsets + // Posting lists come after the trigram entry array + uint32_t postingBase = sizeof(searchHdr) + sizeof(HlpTrigramEntryT) * trigramCount; + uint32_t postingOff = 0; + + // Write trigram entries + for (int32_t i = 0; i < trigramCount; i++) { + HlpTrigramEntryT entry; + entry.trigram[0] = trigrams[i].trigram[0]; + entry.trigram[1] = trigrams[i].trigram[1]; + entry.trigram[2] = trigrams[i].trigram[2]; + entry.postingCount = (uint8_t)trigrams[i].postingCount; + entry.postingOffset = postingBase + postingOff; + fwrite(&entry, sizeof(entry), 1, f); + offset += sizeof(entry); + postingOff += sizeof(uint16_t) * trigrams[i].postingCount; + } + + // Write posting lists + for (int32_t i = 0; i < trigramCount; i++) { + fwrite(trigrams[i].postings, sizeof(uint16_t), trigrams[i].postingCount, f); + offset += sizeof(uint16_t) * trigrams[i].postingCount; + } + } + hdr.searchSize = offset - hdr.searchOffset; + + // --- 6. String table --- + hdr.stringTableOffset = offset; + hdr.stringTableSize = strTabSize; + fwrite(strTab, 1, strTabSize, f); + offset += strTabSize; + + // --- 7. Topic directory (sorted by topic ID) --- + hdr.topicDirOffset = offset; + HlpTopicDirT *topicDir = calloc(topicCount, sizeof(HlpTopicDirT)); + for (int32_t i = 0; i < topicCount; i++) { + topicDir[i].topicIdStr = strTableFind(topics[i].id); + topicDir[i].titleStr = strTableFind(topics[i].title); + topicDir[i].contentOffset = topicContentOffsets[i]; + topicDir[i].contentSize = topicContentSizes[i]; + topicDir[i].reserved = 0; + } + // Topic directory is NOT sorted -- indices must match what TOC and + // index entries reference (assigned sequentially during parsing). + fwrite(topicDir, sizeof(HlpTopicDirT), topicCount, f); + offset += sizeof(HlpTopicDirT) * topicCount; + + // --- 8. Header (at EOF) --- + fwrite(&hdr, sizeof(hdr), 1, f); + offset += sizeof(hdr); + + fclose(f); + + free(topicDir); + free(topicContentOffsets); + free(topicContentSizes); + + fprintf(stderr, " wrote %u bytes\n", offset); + return 0; +} + + +// --------------------------------------------------------------------------- +// Cleanup +// --------------------------------------------------------------------------- + +static void freeAll(void) { + for (int32_t i = 0; i < topicCount; i++) { + for (int32_t r = 0; r < topics[i].recordCount; r++) { + free(topics[i].records[r].data); + } + free(topics[i].records); + } + for (int32_t i = 0; i < trigramCount; i++) { + free(trigrams[i].postings); + } + free(strTab); + free(strEntries); +} + + +// --------------------------------------------------------------------------- +// main +// --------------------------------------------------------------------------- + +int main(int argc, char **argv) { + const char *outputPath = NULL; + char *inputFiles[256]; + int32_t inputCount = 0; + + // Parse command-line arguments + for (int32_t i = 1; i < argc; i++) { + if (strcmp(argv[i], "-o") == 0) { + if (++i >= argc) { + usage(); + } + outputPath = argv[i]; + } else if (strcmp(argv[i], "-w") == 0) { + if (++i >= argc) { + usage(); + } + wrapWidth = atoi(argv[i]); + if (wrapWidth < 20) { + fprintf(stderr, "error: wrap width must be >= 20\n"); + return 1; + } + } else if (strcmp(argv[i], "-i") == 0) { + if (++i >= argc) { + usage(); + } + snprintf(imageDir, sizeof(imageDir), "%s", argv[i]); + imageDir[sizeof(imageDir) - 1] = '\0'; + } else if (strcmp(argv[i], "--html") == 0) { + if (++i >= argc) { + usage(); + } + htmlPath = argv[i]; + } else if (argv[i][0] == '-') { + fprintf(stderr, "error: unknown option '%s'\n", argv[i]); + usage(); + } else { + if (inputCount >= 256) { + fprintf(stderr, "error: too many input files\n"); + return 1; + } + inputFiles[inputCount++] = argv[i]; + } + } + + if (!outputPath || inputCount == 0) { + usage(); + } + + fprintf(stderr, "dvxhlpc: DVX Help Compiler\n"); + + pass1Parse(inputCount, inputFiles); + if (errorCount > 0) { + fprintf(stderr, "Aborting due to %d error(s).\n", errorCount); + freeAll(); + return 1; + } + + pass2Wrap(); + + // Emit HTML if requested (uses wrapped text, before binary passes) + if (htmlPath) { + if (emitHtml(htmlPath) == 0) { + fprintf(stderr, "HTML: wrote %s\n", htmlPath); + } + } + + pass3StringTable(); + pass4SearchIndex(); + + int result = pass5Serialize(outputPath); + if (result == 0) { + fprintf(stderr, "Done. %d topic(s), %d TOC entries, %d index keywords, %d trigrams.\n", + topicCount, tocCount, indexCount, trigramCount); + } + + freeAll(); + return result; +} diff --git a/tools/mkicon.c b/tools/mkicon.c index 3353d82..1316f03 100644 --- a/tools/mkicon.c +++ b/tools/mkicon.c @@ -275,6 +275,37 @@ static void iconBasic(void) { } +static void iconHelp(void) { + // Blue book with white "?" on it + clear(192, 192, 192); + + // Book body (blue) + rect(6, 4, 20, 24, 0, 0, 180); + + // Book spine (darker blue) + rect(6, 4, 3, 24, 0, 0, 130); + + // Book pages (white edge) + vline(25, 5, 22, 255, 255, 255); + + // Question mark in white + // Top curve + hline(14, 9, 5, 255, 255, 255); + pixel(13, 10, 255, 255, 255); + pixel(19, 10, 255, 255, 255); + pixel(19, 11, 255, 255, 255); + pixel(18, 12, 255, 255, 255); + pixel(17, 13, 255, 255, 255); + // Stem + pixel(16, 14, 255, 255, 255); + pixel(16, 15, 255, 255, 255); + pixel(16, 16, 255, 255, 255); + // Dot + pixel(16, 19, 255, 255, 255); + pixel(16, 20, 255, 255, 255); +} + + static void writeBmp(const char *path) { int32_t rowPad = (4 - (W * 3) % 4) % 4; int32_t rowSize = W * 3 + rowPad; @@ -324,7 +355,7 @@ static void writeBmp(const char *path) { int main(int argc, char **argv) { if (argc < 3) { fprintf(stderr, "Usage: mkicon \n"); - fprintf(stderr, "Types: noicon, clock, notepad, cpanel, dvxdemo, imgview, basic\n"); + fprintf(stderr, "Types: noicon, clock, notepad, cpanel, dvxdemo, imgview, basic, help\n"); return 1; } @@ -345,6 +376,8 @@ int main(int argc, char **argv) { iconBasic(); } else if (strcmp(type, "imgview") == 0) { iconImgview(); + } else if (strcmp(type, "help") == 0) { + iconHelp(); } else { fprintf(stderr, "Unknown icon type: %s\n", type); return 1; diff --git a/widgets/Makefile b/widgets/Makefile index 09be7f0..e72ce2c 100644 --- a/widgets/Makefile +++ b/widgets/Makefile @@ -6,7 +6,7 @@ DJGPP_PREFIX = $(HOME)/djgpp/djgpp CC = $(DJGPP_PREFIX)/bin/i586-pc-msdosdjgpp-gcc DXE3GEN = PATH=$(DJGPP_PREFIX)/bin:$(PATH) DJDIR=$(DJGPP_PREFIX)/i586-pc-msdosdjgpp $(DJGPP_PREFIX)/i586-pc-msdosdjgpp/bin/dxe3gen -CFLAGS = -O2 -Wall -Wextra -Wno-type-limits -Wno-sign-compare -march=i486 -mtune=i586 -I../core -I../core/platform -I../tasks -I../core/thirdparty +CFLAGS = -O2 -Wall -Wextra -Werror -Wno-type-limits -Wno-sign-compare -Wno-format-truncation -march=i486 -mtune=i586 -I../core -I../core/platform -I../tasks -I../core/thirdparty DVXRES = ../bin/dvxres OBJDIR = ../obj/widgets diff --git a/widgets/ansiTerm/widgetAnsiTerm.c b/widgets/ansiTerm/widgetAnsiTerm.c index bd1a7ac..a3eba91 100644 --- a/widgets/ansiTerm/widgetAnsiTerm.c +++ b/widgets/ansiTerm/widgetAnsiTerm.c @@ -1070,9 +1070,9 @@ static const struct { }; static const WgtPropDescT sProps[] = { - { "Cols", WGT_IFACE_INT, (void *)wgtAnsiTermGetCols, NULL }, - { "Rows", WGT_IFACE_INT, (void *)wgtAnsiTermGetRows, NULL }, - { "Scrollback", WGT_IFACE_INT, NULL, (void *)wgtAnsiTermSetScrollback } + { "Cols", WGT_IFACE_INT, (void *)wgtAnsiTermGetCols, NULL, NULL }, + { "Rows", WGT_IFACE_INT, (void *)wgtAnsiTermGetRows, NULL, NULL }, + { "Scrollback", WGT_IFACE_INT, NULL, (void *)wgtAnsiTermSetScrollback, NULL } }; static const WgtMethodDescT sMethods[] = { diff --git a/widgets/checkbox/widgetCheckbox.c b/widgets/checkbox/widgetCheckbox.c index 34e98ce..725ab5c 100644 --- a/widgets/checkbox/widgetCheckbox.c +++ b/widgets/checkbox/widgetCheckbox.c @@ -252,7 +252,7 @@ static const struct { }; static const WgtPropDescT sProps[] = { - { "Value", WGT_IFACE_BOOL, (void *)wgtCheckboxIsChecked, (void *)wgtCheckboxSetChecked } + { "Value", WGT_IFACE_BOOL, (void *)wgtCheckboxIsChecked, (void *)wgtCheckboxSetChecked, NULL } }; static const WgtIfaceT sIface = { diff --git a/widgets/comboBox/widgetComboBox.c b/widgets/comboBox/widgetComboBox.c index 4976003..3aec805 100644 --- a/widgets/comboBox/widgetComboBox.c +++ b/widgets/comboBox/widgetComboBox.c @@ -538,7 +538,7 @@ static const struct { }; static const WgtPropDescT sProps[] = { - { "ListIndex", WGT_IFACE_INT, (void *)wgtComboBoxGetSelected, (void *)wgtComboBoxSetSelected } + { "ListIndex", WGT_IFACE_INT, (void *)wgtComboBoxGetSelected, (void *)wgtComboBoxSetSelected, NULL } }; static const WgtIfaceT sIface = { diff --git a/widgets/dropdown/widgetDropdown.c b/widgets/dropdown/widgetDropdown.c index 028c73a..94aaa52 100644 --- a/widgets/dropdown/widgetDropdown.c +++ b/widgets/dropdown/widgetDropdown.c @@ -410,7 +410,7 @@ static const struct { }; static const WgtPropDescT sProps[] = { - { "ListIndex", WGT_IFACE_INT, (void *)wgtDropdownGetSelected, (void *)wgtDropdownSetSelected } + { "ListIndex", WGT_IFACE_INT, (void *)wgtDropdownGetSelected, (void *)wgtDropdownSetSelected, NULL } }; static const WgtIfaceT sIface = { diff --git a/widgets/image/widgetImage.c b/widgets/image/widgetImage.c index c34c4c9..57cdef4 100644 --- a/widgets/image/widgetImage.c +++ b/widgets/image/widgetImage.c @@ -289,9 +289,9 @@ static const struct { }; static const WgtPropDescT sProps[] = { - { "Picture", WGT_IFACE_STRING, NULL, (void *)wgtImageLoadFile }, - { "ImageWidth", WGT_IFACE_INT, (void *)wgtImageGetWidth, NULL }, - { "ImageHeight", WGT_IFACE_INT, (void *)wgtImageGetHeight, NULL } + { "Picture", WGT_IFACE_STRING, NULL, (void *)wgtImageLoadFile, NULL }, + { "ImageWidth", WGT_IFACE_INT, (void *)wgtImageGetWidth, NULL, NULL }, + { "ImageHeight", WGT_IFACE_INT, (void *)wgtImageGetHeight, NULL, NULL } }; static const WgtIfaceT sIface = { diff --git a/widgets/imageButton/widgetImageButton.c b/widgets/imageButton/widgetImageButton.c index 5e2b5e0..fc1dee9 100644 --- a/widgets/imageButton/widgetImageButton.c +++ b/widgets/imageButton/widgetImageButton.c @@ -360,9 +360,9 @@ static const struct { }; static const WgtPropDescT sImgBtnProps[] = { - { "Picture", WGT_IFACE_STRING, NULL, (void *)wgtImageButtonLoadFile }, - { "ImageWidth", WGT_IFACE_INT, (void *)wgtImageButtonGetWidth, NULL }, - { "ImageHeight", WGT_IFACE_INT, (void *)wgtImageButtonGetHeight, NULL } + { "Picture", WGT_IFACE_STRING, NULL, (void *)wgtImageButtonLoadFile, NULL }, + { "ImageWidth", WGT_IFACE_INT, (void *)wgtImageButtonGetWidth, NULL, NULL }, + { "ImageHeight", WGT_IFACE_INT, (void *)wgtImageButtonGetHeight, NULL, NULL } }; static const WgtIfaceT sIface = { diff --git a/widgets/listBox/widgetListBox.c b/widgets/listBox/widgetListBox.c index b76c290..256f976 100644 --- a/widgets/listBox/widgetListBox.c +++ b/widgets/listBox/widgetListBox.c @@ -858,7 +858,7 @@ static const struct { }; static const WgtPropDescT sProps[] = { - { "ListIndex", WGT_IFACE_INT, (void *)wgtListBoxGetSelected, (void *)wgtListBoxSetSelected } + { "ListIndex", WGT_IFACE_INT, (void *)wgtListBoxGetSelected, (void *)wgtListBoxSetSelected, NULL } }; static const WgtMethodDescT sMethods[] = { diff --git a/widgets/listView/widgetListView.c b/widgets/listView/widgetListView.c index 5b460be..956137c 100644 --- a/widgets/listView/widgetListView.c +++ b/widgets/listView/widgetListView.c @@ -1738,7 +1738,7 @@ static const struct { }; static const WgtPropDescT sProps[] = { - { "ListIndex", WGT_IFACE_INT, (void *)wgtListViewGetSelected, (void *)wgtListViewSetSelected } + { "ListIndex", WGT_IFACE_INT, (void *)wgtListViewGetSelected, (void *)wgtListViewSetSelected, NULL } }; static const WgtMethodDescT sMethods[] = { diff --git a/widgets/progressBar/widgetProgressBar.c b/widgets/progressBar/widgetProgressBar.c index 7f9efd9..b0d3883 100644 --- a/widgets/progressBar/widgetProgressBar.c +++ b/widgets/progressBar/widgetProgressBar.c @@ -210,7 +210,7 @@ static const struct { }; static const WgtPropDescT sProps[] = { - { "Value", WGT_IFACE_INT, (void *)wgtProgressBarGetValue, (void *)wgtProgressBarSetValue } + { "Value", WGT_IFACE_INT, (void *)wgtProgressBarGetValue, (void *)wgtProgressBarSetValue, NULL } }; static const WgtIfaceT sIface = { diff --git a/widgets/radio/widgetRadio.c b/widgets/radio/widgetRadio.c index c095a98..aacb00c 100644 --- a/widgets/radio/widgetRadio.c +++ b/widgets/radio/widgetRadio.c @@ -410,7 +410,7 @@ static const struct { }; static const WgtPropDescT sProps[] = { - { "Value", WGT_IFACE_INT, (void *)wgtRadioGetIndex, NULL } + { "Value", WGT_IFACE_INT, (void *)wgtRadioGetIndex, NULL, NULL } }; static const WgtMethodDescT sMethods[] = { diff --git a/widgets/slider/widgetSlider.c b/widgets/slider/widgetSlider.c index 1e38a90..6732454 100644 --- a/widgets/slider/widgetSlider.c +++ b/widgets/slider/widgetSlider.c @@ -394,7 +394,7 @@ static const struct { }; static const WgtPropDescT sProps[] = { - { "Value", WGT_IFACE_INT, (void *)wgtSliderGetValue, (void *)wgtSliderSetValue } + { "Value", WGT_IFACE_INT, (void *)wgtSliderGetValue, (void *)wgtSliderSetValue, NULL } }; static const WgtIfaceT sIface = { diff --git a/widgets/splitter/widgetSplitter.c b/widgets/splitter/widgetSplitter.c index 08e43af..0b6e007 100644 --- a/widgets/splitter/widgetSplitter.c +++ b/widgets/splitter/widgetSplitter.c @@ -517,7 +517,7 @@ static const struct { }; static const WgtPropDescT sProps[] = { - { "Position", WGT_IFACE_INT, (void *)wgtSplitterGetPos, (void *)wgtSplitterSetPos } + { "Position", WGT_IFACE_INT, (void *)wgtSplitterGetPos, (void *)wgtSplitterSetPos, NULL } }; static const WgtIfaceT sIface = { diff --git a/widgets/tabControl/widgetTabControl.c b/widgets/tabControl/widgetTabControl.c index d71023f..095b4ec 100644 --- a/widgets/tabControl/widgetTabControl.c +++ b/widgets/tabControl/widgetTabControl.c @@ -675,7 +675,7 @@ static const struct { }; static const WgtPropDescT sProps[] = { - { "TabIndex", WGT_IFACE_INT, (void *)wgtTabControlGetActive, (void *)wgtTabControlSetActive } + { "TabIndex", WGT_IFACE_INT, (void *)wgtTabControlGetActive, (void *)wgtTabControlSetActive, NULL } }; static const WgtMethodDescT sMethods[] = { diff --git a/widgets/textInput/widgetTextInput.c b/widgets/textInput/widgetTextInput.c index 6988bf5..e2bbd3b 100644 --- a/widgets/textInput/widgetTextInput.c +++ b/widgets/textInput/widgetTextInput.c @@ -187,7 +187,6 @@ static void textAreaRebuildCache(WidgetT *w); static void textAreaOffToRowCol(const char *buf, int32_t off, int32_t *row, int32_t *col); static int32_t visualCol(const char *buf, int32_t lineStart, int32_t off, int32_t tabW); static int32_t visualColToOff(const char *buf, int32_t len, int32_t lineStart, int32_t targetVC, int32_t tabW); -static int32_t visualLineLen(const char *buf, int32_t len, int32_t lineStart, int32_t tabW); static void textEditSaveUndo(char *buf, int32_t len, int32_t cursor, char *undoBuf, int32_t *pUndoLen, int32_t *pUndoCursor, int32_t bufSize); static void widgetTextAreaDragSelect(WidgetT *w, WidgetT *root, int32_t vx, int32_t vy); static void widgetTextAreaOnDragUpdate(WidgetT *w, WidgetT *root, int32_t x, int32_t y); @@ -877,25 +876,6 @@ static int32_t visualColToOff(const char *buf, int32_t len, int32_t lineStart, i } -// Tab-aware visual line length (in visual columns). -static int32_t visualLineLen(const char *buf, int32_t len, int32_t lineStart, int32_t tabW) { - int32_t vc = 0; - int32_t i = lineStart; - - while (i < len && buf[i] != '\n') { - if (buf[i] == '\t' && tabW > 0) { - vc += tabW - (vc % tabW); - } else { - vc++; - } - - i++; - } - - return vc; -} - - static int32_t textAreaCursorToOff(const char *buf, int32_t len, int32_t row, int32_t col) { int32_t start = textAreaLineStart(buf, len, row); int32_t lineL = textAreaLineLen(buf, len, row); @@ -1651,7 +1631,7 @@ void widgetTextAreaOnMouse(WidgetT *w, WidgetT *root, int32_t vx, int32_t vy) { visCols = 1; } - int32_t totalLines = textAreaCountLines(ta->buf, ta->len); + int32_t totalLines = textAreaGetLineCount(w); int32_t maxScroll = totalLines - visRows; if (maxScroll < 0) { diff --git a/widgets/timer/widgetTimer.c b/widgets/timer/widgetTimer.c index 68abe28..99904fa 100644 --- a/widgets/timer/widgetTimer.c +++ b/widgets/timer/widgetTimer.c @@ -229,8 +229,8 @@ static const struct { }; static const WgtPropDescT sProps[] = { - { "Enabled", WGT_IFACE_BOOL, (void *)wgtTimerIsRunning, (void *)wgtTimerSetEnabled }, - { "Interval", WGT_IFACE_INT, NULL, (void *)wgtTimerSetInterval } + { "Enabled", WGT_IFACE_BOOL, (void *)wgtTimerIsRunning, (void *)wgtTimerSetEnabled, NULL }, + { "Interval", WGT_IFACE_INT, NULL, (void *)wgtTimerSetInterval, NULL } }; static const WgtMethodDescT sMethods[] = {