diff --git a/apps/progman/progman.c b/apps/progman/progman.c index 80415c5..f139a53 100644 --- a/apps/progman/progman.c +++ b/apps/progman/progman.c @@ -669,8 +669,8 @@ static void showSystemInfo(void) { ta->weight = 100; wgtSetText(ta, info); - // Mark read-only by disabling the text area - wgtSetEnabled(ta, false); + // Don't disable — wgtSetEnabled(false) blocks all input including scrollbar + wgtSetReadOnly(ta, true); } diff --git a/dvx/dvxWidget.h b/dvx/dvxWidget.h index a61b954..84f3e6d 100644 --- a/dvx/dvxWidget.h +++ b/dvx/dvxWidget.h @@ -338,6 +338,7 @@ typedef struct WidgetT { // State bool visible; bool enabled; + bool readOnly; bool focused; char accelKey; // lowercase accelerator character, 0 if none @@ -895,6 +896,9 @@ const char *wgtGetText(const WidgetT *w); // Enable/disable a widget void wgtSetEnabled(WidgetT *w, bool enabled); +// Set read-only mode (allows scrolling/selection but blocks editing) +void wgtSetReadOnly(WidgetT *w, bool readOnly); + // Show/hide a widget void wgtSetVisible(WidgetT *w, bool visible); diff --git a/dvx/platform/dvxPlatformDos.c b/dvx/platform/dvxPlatformDos.c index 4f9ef58..69aa371 100644 --- a/dvx/platform/dvxPlatformDos.c +++ b/dvx/platform/dvxPlatformDos.c @@ -831,7 +831,8 @@ const char *platformGetSystemInfo(const DisplayT *display) { if (__dpmi_get_free_memory_information(&memInfo) == 0) { if (memInfo.largest_available_free_block_in_bytes != 0xFFFFFFFFUL) { - sysInfoAppend("Largest free block: %lu KB", (unsigned long)(memInfo.largest_available_free_block_in_bytes / 1024)); + uint32_t largestKb = memInfo.largest_available_free_block_in_bytes / 1024; + sysInfoAppend("Largest free block: %lu KB (%lu MB)", (unsigned long)largestKb, (unsigned long)(largestKb / 1024)); } if (memInfo.total_number_of_physical_pages != 0xFFFFFFFFUL) { uint32_t totalKb = memInfo.total_number_of_physical_pages * 4; diff --git a/dvx/widgets/widgetOps.c b/dvx/widgets/widgetOps.c index 15332b6..c3c53c1 100644 --- a/dvx/widgets/widgetOps.c +++ b/dvx/widgets/widgetOps.c @@ -466,6 +466,17 @@ void wgtSetEnabled(WidgetT *w, bool enabled) { } +// ============================================================ +// wgtSetReadOnly +// ============================================================ + +void wgtSetReadOnly(WidgetT *w, bool readOnly) { + if (w) { + w->readOnly = readOnly; + } +} + + // ============================================================ // wgtSetText // ============================================================ diff --git a/dvx/widgets/widgetTextInput.c b/dvx/widgets/widgetTextInput.c index 1ca278f..8c8c7c8 100644 --- a/dvx/widgets/widgetTextInput.c +++ b/dvx/widgets/widgetTextInput.c @@ -1319,6 +1319,11 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { return; } + // Read-only: allow select-all, copy, and navigation but block editing + if (w->readOnly) { + goto navigation; + } + // Ctrl+V — paste if (key == 22) { if (sClipboardLen > 0) { @@ -1543,6 +1548,7 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { return; } +navigation: // Left arrow if (key == (0x4B | 0x100)) { SEL_BEGIN(); @@ -1712,8 +1718,8 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { return; } - // Printable character - if (key >= 32 && key < 127) { + // Printable character (blocked in read-only mode) + if (key >= 32 && key < 127 && !w->readOnly) { if (*pLen < bufSize - 1) { textEditSaveUndo(buf, *pLen, CUR_OFF(), w->as.textArea.undoBuf, &w->as.textArea.undoLen, &w->as.textArea.undoCursor, bufSize); diff --git a/dvxshell/shellExport.c b/dvxshell/shellExport.c index 3aff038..8eb3729 100644 --- a/dvxshell/shellExport.c +++ b/dvxshell/shellExport.c @@ -353,6 +353,7 @@ DXE_EXPORT_TABLE(shellExportTable) DXE_EXPORT(wgtSetTooltip) DXE_EXPORT(wgtGetText) DXE_EXPORT(wgtSetEnabled) + DXE_EXPORT(wgtSetReadOnly) DXE_EXPORT(wgtSetVisible) DXE_EXPORT(wgtGetContext) DXE_EXPORT(wgtSetName)