Now using -Wall -Werror (for real). All warnings fixed. Help system added.
This commit is contained in:
parent
0f5da09d1f
commit
2a641f42c3
80 changed files with 20540 additions and 9414 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "opcodes.h"
|
||||
#include "thirdparty/stb_ds_wrap.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
|
|
|||
|
|
@ -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, "<error>");
|
||||
}
|
||||
} else {
|
||||
snprintf(sWatchValBuf[i], 256, "");
|
||||
sWatchValBuf[i][0] = '\0';
|
||||
}
|
||||
|
||||
sWatchCells[i * 2 + 0] = sWatchExprBuf[i];
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "values.h"
|
||||
#include "dvxTypes.h"
|
||||
#include "dvxPlatform.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
|
|
|||
1406
apps/dvxhelp/dvxhelp.c
Normal file
1406
apps/dvxhelp/dvxhelp.c
Normal file
File diff suppressed because it is too large
Load diff
5
apps/dvxhelp/dvxhelp.res
Normal file
5
apps/dvxhelp/dvxhelp.res
Normal file
|
|
@ -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"
|
||||
157
apps/dvxhelp/hlpformat.h
Normal file
157
apps/dvxhelp/hlpformat.h
Normal file
|
|
@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 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
|
||||
BIN
apps/dvxhelp/icon32.bmp
(Stored with Git LFS)
Normal file
BIN
apps/dvxhelp/icon32.bmp
(Stored with Git LFS)
Normal file
Binary file not shown.
155
apps/dvxhelp/sample.dvxhelp
Normal file
155
apps/dvxhelp/sample.dvxhelp
Normal file
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
||||
|
|
|
|||
|
|
@ -18,11 +18,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
// 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.)
|
||||
|
|
|
|||
|
|
@ -12,14 +12,6 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
// ============================================================
|
||||
// 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
|
||||
// ============================================================
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@
|
|||
|
||||
#include <setjmp.h>
|
||||
|
||||
// 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);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
155
docs/dvx_help_sample.html
Normal file
155
docs/dvx_help_sample.html
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Welcome to DVX</title>
|
||||
<style>
|
||||
body { font-family: sans-serif; margin: 0; padding: 0; display: flex; }
|
||||
nav { width: 250px; min-width: 250px; background: #f0f0f0; padding: 16px;
|
||||
border-right: 1px solid #ccc; height: 100vh; overflow-y: auto;
|
||||
position: sticky; top: 0; box-sizing: border-box; }
|
||||
nav ul { list-style: none; padding-left: 16px; margin: 4px 0; }
|
||||
nav > ul { padding-left: 0; }
|
||||
nav a { text-decoration: none; color: #0066cc; }
|
||||
nav a:hover { text-decoration: underline; }
|
||||
main { flex: 1; padding: 24px 32px; max-width: 800px; }
|
||||
h1 { border-bottom: 2px solid #333; padding-bottom: 4px; }
|
||||
h2 { border-bottom: 1px solid #999; padding-bottom: 2px; margin-top: 32px; }
|
||||
h3 { margin-top: 24px; }
|
||||
pre { background: #f8f8f8; border: 1px solid #ddd; padding: 8px;
|
||||
overflow-x: auto; font-size: 14px; }
|
||||
blockquote { background: #fffde7; border-left: 4px solid #ffc107;
|
||||
padding: 8px 12px; margin: 12px 0; }
|
||||
hr { border: none; border-top: 1px solid #ccc; margin: 24px 0; }
|
||||
img { max-width: 100%; }
|
||||
.topic { margin-bottom: 48px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<h3>Contents</h3>
|
||||
<ul>
|
||||
<li><a href="#intro">Welcome to DVX</a></li>
|
||||
<li><a href="#overview">System Overview</a></li>
|
||||
<li><a href="#widgets">Widget System</a></li>
|
||||
<li><a href="#keyboard">Keyboard Shortcuts</a></li>
|
||||
</ul>
|
||||
<h3>Index</h3>
|
||||
<ul>
|
||||
<li><a href="#intro">DVX</a></li>
|
||||
<li><a href="#intro">Introduction</a></li>
|
||||
<li><a href="#intro">Getting Started</a></li>
|
||||
<li><a href="#overview">Architecture</a></li>
|
||||
<li><a href="#overview">Layers</a></li>
|
||||
<li><a href="#widgets">Widgets</a></li>
|
||||
<li><a href="#widgets">Controls</a></li>
|
||||
<li><a href="#keyboard">Keyboard</a></li>
|
||||
<li><a href="#keyboard">Shortcuts</a></li>
|
||||
<li><a href="#keyboard">Hotkeys</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<main>
|
||||
<div class="topic" id="intro">
|
||||
<h1>Welcome to DVX</h1>
|
||||
<h2>Welcome to DVX</h2>
|
||||
<p>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.</p>
|
||||
<p>DVX features include:</p>
|
||||
<ul>
|
||||
<li>A window manager with drag, resize, and minimize support</li>
|
||||
<li>Over 25 built-in widget types including buttons, lists, and trees</li>
|
||||
<li>Dynamic application loading via DXE3 modules</li>
|
||||
<li>Theme support with customizable color schemes</li>
|
||||
</ul>
|
||||
<p>VESA VBE 2.0+ linear framebuffer rendering</p>
|
||||
<p><a href="#overview">See also: System Overview</a></p>
|
||||
<hr>
|
||||
<blockquote><strong>Tip:</strong> Press F1 from any DVX application to open context-sensitive help.</blockquote>
|
||||
</div>
|
||||
<div class="topic" id="overview">
|
||||
<h1>System Overview</h1>
|
||||
<h2>System Overview</h2>
|
||||
<p>DVX is built as a five-layer architecture, with each layer providing
|
||||
services to the layer above it.</p>
|
||||
<h3>Video Layer</h3>
|
||||
<p>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.</p>
|
||||
<h3>Drawing Layer</h3>
|
||||
<p>The drawing layer (dvxDraw) provides primitive rendering operations: filled
|
||||
rectangles, beveled borders, text rendering, bitmap blitting, and clipped
|
||||
drawing.</p>
|
||||
<h3>Compositor</h3>
|
||||
<p>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.</p>
|
||||
<h3>Window Manager</h3>
|
||||
<p>The window manager (dvxWm) handles the window stack, chrome rendering (title
|
||||
bars, borders, close buttons), drag and resize interaction, focus
|
||||
management, and menu bars.</p>
|
||||
<h3>Application Layer</h3>
|
||||
<p>The application layer (dvxApp) ties everything together with the event loop,
|
||||
mouse and keyboard input, accelerator tables, and the public API used by
|
||||
applications.</p>
|
||||
<p><a href="#widgets">See also: Widget System</a></p>
|
||||
</div>
|
||||
<div class="topic" id="widgets">
|
||||
<h1>Widget System</h1>
|
||||
<h2>Widget System</h2>
|
||||
<p>DVX provides a rich set of widgets (controls) for building application user
|
||||
interfaces. Widgets are loaded as DXE3 plugin modules at startup.</p>
|
||||
<h3>Layout Widgets</h3>
|
||||
<ul>
|
||||
<li>VBox -- Vertical box layout (stacks children vertically)</li>
|
||||
<li>HBox -- Horizontal box layout (stacks children horizontally)</li>
|
||||
<li>Frame -- Labeled group box with border</li>
|
||||
<li>ScrollPane -- Scrollable container for oversized content</li>
|
||||
<li>Splitter -- Resizable split between two panes</li>
|
||||
</ul>
|
||||
<p>TabControl -- Tabbed container</p>
|
||||
<h3>Input Widgets</h3>
|
||||
<ul>
|
||||
<li>Button -- Push button with text label</li>
|
||||
<li>TextInput -- Single-line text entry field</li>
|
||||
<li>TextArea -- Multi-line text editor with syntax highlighting</li>
|
||||
<li>Checkbox -- Boolean toggle with label</li>
|
||||
<li>Radio -- Mutually exclusive option selector</li>
|
||||
<li>Dropdown -- Drop-down selection list</li>
|
||||
<li>ComboBox -- Editable dropdown with text entry</li>
|
||||
<li>Slider -- Horizontal or vertical value slider</li>
|
||||
</ul>
|
||||
<p>Spinner -- Numeric up/down control</p>
|
||||
<h3>Display Widgets</h3>
|
||||
<ul>
|
||||
<li>Label -- Single-line text display</li>
|
||||
<li>Image -- Bitmap image display</li>
|
||||
<li>ProgressBar -- Visual progress indicator</li>
|
||||
<li>Canvas -- Custom drawing surface</li>
|
||||
</ul>
|
||||
<p>Separator -- Horizontal or vertical divider line</p>
|
||||
<h3>Data Widgets</h3>
|
||||
<ul>
|
||||
<li>ListBox -- Scrollable list of text items</li>
|
||||
<li>ListView -- Multi-column sortable list with headers</li>
|
||||
</ul>
|
||||
<p>TreeView -- Hierarchical tree with expand/collapse</p>
|
||||
</div>
|
||||
<div class="topic" id="keyboard">
|
||||
<h1>Keyboard Shortcuts</h1>
|
||||
<h2>Keyboard Shortcuts</h2>
|
||||
<p>The following keyboard shortcuts are available system-wide in DVX:</p>
|
||||
<pre> 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</pre>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
3499
docs/src/dvx_api_reference.dvxhelp
Normal file
3499
docs/src/dvx_api_reference.dvxhelp
Normal file
File diff suppressed because it is too large
Load diff
776
docs/src/dvx_architecture.dvxhelp
Normal file
776
docs/src/dvx_architecture.dvxhelp
Normal file
|
|
@ -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
|
||||
1801
docs/src/dvx_widget_reference.dvxhelp
Normal file
1801
docs/src/dvx_widget_reference.dvxhelp
Normal file
File diff suppressed because it is too large
Load diff
1567
docs/src/dvxbasic_control_reference.dvxhelp
Normal file
1567
docs/src/dvxbasic_control_reference.dvxhelp
Normal file
File diff suppressed because it is too large
Load diff
944
docs/src/dvxbasic_ide_guide.dvxhelp
Normal file
944
docs/src/dvxbasic_ide_guide.dvxhelp
Normal file
|
|
@ -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 <error> 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
|
||||
1574
docs/src/dvxbasic_language_reference.dvxhelp
Normal file
1574
docs/src/dvxbasic_language_reference.dvxhelp
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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/<apppath>/)
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
3
sql/thirdparty/sqlite/src/btree.c
vendored
3
sql/thirdparty/sqlite/src/btree.c
vendored
|
|
@ -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 ){
|
||||
|
|
|
|||
3
sql/thirdparty/sqlite/src/build.c
vendored
3
sql/thirdparty/sqlite/src/build.c
vendored
|
|
@ -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;
|
||||
|
|
|
|||
10
sql/thirdparty/sqlite/src/insert.c
vendored
10
sql/thirdparty/sqlite/src/insert.c
vendored
|
|
@ -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;
|
||||
|
|
|
|||
9
sql/thirdparty/sqlite/src/os_unix.c
vendored
9
sql/thirdparty/sqlite/src/os_unix.c
vendored
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
1
sql/thirdparty/sqlite/src/printf.c
vendored
1
sql/thirdparty/sqlite/src/printf.c
vendored
|
|
@ -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
|
||||
|
|
|
|||
40
sql/thirdparty/sqlite/src/select.c
vendored
40
sql/thirdparty/sqlite/src/select.c
vendored
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
8
sql/thirdparty/sqlite/src/update.c
vendored
8
sql/thirdparty/sqlite/src/update.c
vendored
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
12
sql/thirdparty/sqlite/src/vdbe.c
vendored
12
sql/thirdparty/sqlite/src/vdbe.c
vendored
|
|
@ -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 && i<p->nCursor );
|
||||
|
|
@ -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 && i<p->nCursor );
|
||||
|
|
|
|||
1
sql/thirdparty/sqlite/src/vdbeapi.c
vendored
1
sql/thirdparty/sqlite/src/vdbeapi.c
vendored
|
|
@ -565,6 +565,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
|
|||
if( pVm && pVm->pResultSet!=0 && i<pVm->nResColumn && 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 };
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 $@
|
||||
|
||||
|
|
|
|||
1726
tools/dvxhlpc.c
Normal file
1726
tools/dvxhlpc.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -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 <output.bmp> <type>\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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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[] = {
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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[] = {
|
||||
|
|
|
|||
|
|
@ -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[] = {
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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[] = {
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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[] = {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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[] = {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue