From 16fac733e8dbfb3d06152ee8a60ddffc374f8a04 Mon Sep 17 00:00:00 2001 From: Darren Banfi <33876110+boingball@users.noreply.github.com> Date: Thu, 3 Sep 2026 08:45:04 +0100 Subject: [PATCH 1/8] Fix queried defaults and show RAM spool jobs --- src/MintPrintSettings.c | 137 ++++++++++++++++++++++++++++++---------- 1 file changed, 103 insertions(+), 34 deletions(-) diff --git a/src/MintPrintSettings.c b/src/MintPrintSettings.c index 0ca3835..3691496 100644 --- a/src/MintPrintSettings.c +++ b/src/MintPrintSettings.c @@ -2908,6 +2908,7 @@ static void apply_driver_config_to_gadgets(struct Window *win) { void update_media_dropdown(struct Window *win) { int i; int count = num_media_tray_mappings; + int active = 0; printf("Updating media dropdown, num_mappings=%d\n", num_media_tray_mappings); @@ -2935,6 +2936,29 @@ void update_media_dropdown(struct Window *win) { printf("Dropdown item %d: %s\n", i, mp_media_label_storage[i]); } + + /* GT_SetGadgetAttrs() changes what a V37 Cycle displays but does not + * emit IDCMP_GADGETUP. Keep the persisted value in step with the + * programmatic selection, otherwise Query -> Save writes blank or + * stale MEDIA=/SOURCE= fields unless the user manually cycles it. */ + if (driver_media_buffer[0]) { + for (i = 0; i < count; ++i) { + if (strcmp(media_tray_map[i].media, + driver_media_buffer) == 0 && + (!driver_source_buffer[0] || + strcmp(media_tray_map[i].source, + driver_source_buffer) == 0)) { + active = i; + break; + } + } + } + strncpy(driver_media_buffer, media_tray_map[active].media, + sizeof(driver_media_buffer) - 1); + driver_media_buffer[sizeof(driver_media_buffer) - 1] = '\0'; + strncpy(driver_source_buffer, media_tray_map[active].source, + sizeof(driver_source_buffer) - 1); + driver_source_buffer[sizeof(driver_source_buffer) - 1] = '\0'; } mp_media_label_ptrs[count] = NULL; @@ -2943,7 +2967,7 @@ void update_media_dropdown(struct Window *win) { if (media_dropdown && win) { GT_SetGadgetAttrs(media_dropdown, win, NULL, GTCY_Labels, (ULONG)media_dropdown_items, - GTCY_Active, 0, + GTCY_Active, (ULONG)active, GA_Disabled, num_media_tray_mappings > 0 ? FALSE : TRUE, TAG_DONE); RefreshGList(media_dropdown, win, NULL, 1); @@ -2955,6 +2979,8 @@ void update_scaling_dropdown(struct Window *win) { struct Gadget *g; int i; int count = num_supported_scaling; + int active = 0; + BOOL saved_found = FALSE; if (count <= 0) { count = 1; @@ -2969,37 +2995,44 @@ void update_scaling_dropdown(struct Window *win) { strncpy(mp_scaling_label_storage[i], supported_scaling[i], sizeof(mp_scaling_label_storage[i]) - 1); mp_scaling_label_storage[i][sizeof(mp_scaling_label_storage[i]) - 1] = '\0'; + if (driver_scaling_buffer[0] && + strcmp(driver_scaling_buffer, supported_scaling[i]) == 0) { + active = i; + saved_found = TRUE; + } } - } - mp_scaling_label_ptrs[count] = NULL; - scaling_mode_labels = mp_scaling_label_ptrs; - /* Prefer "auto" when the printer offers it, rather than whichever - * value the printer happened to list first. Confirmed on real - * hardware: "auto-fit" got a job rejected outright as malformed on - * one printer and mis-paginated a single page across multiple - * physical sheets on another, while "auto" printed correctly both - * times - "auto" is the safer default across printers generally, - * not just a preference for this one. */ - { - int preferred = 0; - for (i = 0; i < count; i++) { - if (strcmp(mp_scaling_label_storage[i], "auto") == 0) { - preferred = i; - break; + /* Prefer "auto" for a new/unsupported saved choice, but persist the + * same value we put on screen. Programmatic Cycle updates do not + * generate GADGETUP on the V37 path used for OS2 compatibility. */ + if (!saved_found) { + active = 0; + for (i = 0; i < count; i++) { + if (strcmp(supported_scaling[i], "auto") == 0) { + active = i; + break; + } } } + strncpy(driver_scaling_buffer, supported_scaling[active], + sizeof(driver_scaling_buffer) - 1); + driver_scaling_buffer[sizeof(driver_scaling_buffer) - 1] = '\0'; + strncpy(selected_scaling, supported_scaling[active], + sizeof(selected_scaling) - 1); + selected_scaling[sizeof(selected_scaling) - 1] = '\0'; + } + mp_scaling_label_ptrs[count] = NULL; + scaling_mode_labels = mp_scaling_label_ptrs; - g = find_gadget_by_id(GAD_SCALING_MODE); - if (g && win) { - GT_SetGadgetAttrs(g, win, NULL, - GTCY_Labels, (ULONG)scaling_mode_labels, - GTCY_Active, (ULONG)preferred, - GA_Disabled, num_supported_scaling > 0 ? FALSE : TRUE, - TAG_DONE); - RefreshGList(g, win, NULL, 1); - GT_RefreshWindow(win, NULL); - } + g = find_gadget_by_id(GAD_SCALING_MODE); + if (g && win) { + GT_SetGadgetAttrs(g, win, NULL, + GTCY_Labels, (ULONG)scaling_mode_labels, + GTCY_Active, (ULONG)active, + GA_Disabled, num_supported_scaling > 0 ? FALSE : TRUE, + TAG_DONE); + RefreshGList(g, win, NULL, 1); + GT_RefreshWindow(win, NULL); } } @@ -3007,6 +3040,7 @@ void update_print_mode_dropdown(struct Window *win) { struct Gadget *g; int i; int count = num_supported_print_modes; + int active = 0; if (count <= 0) { count = 1; @@ -3021,7 +3055,18 @@ void update_print_mode_dropdown(struct Window *win) { strncpy(mp_print_mode_label_storage[i], supported_print_modes[i], sizeof(mp_print_mode_label_storage[i]) - 1); mp_print_mode_label_storage[i][sizeof(mp_print_mode_label_storage[i]) - 1] = '\0'; + if (driver_color_buffer[0] && + strcmp(driver_color_buffer, supported_print_modes[i]) == 0) + active = i; } + + strncpy(driver_color_buffer, supported_print_modes[active], + sizeof(driver_color_buffer) - 1); + driver_color_buffer[sizeof(driver_color_buffer) - 1] = '\0'; + strncpy(selected_print_mode, supported_print_modes[active], + sizeof(selected_print_mode) - 1); + selected_print_mode[sizeof(selected_print_mode) - 1] = '\0'; + print_mode = active; } mp_print_mode_label_ptrs[count] = NULL; print_mode_labels = mp_print_mode_label_ptrs; @@ -3030,7 +3075,7 @@ void update_print_mode_dropdown(struct Window *win) { if (g && win) { GT_SetGadgetAttrs(g, win, NULL, GTCY_Labels, (ULONG)print_mode_labels, - GTCY_Active, 0, + GTCY_Active, (ULONG)active, GA_Disabled, num_supported_print_modes > 0 ? FALSE : TRUE, TAG_DONE); RefreshGList(g, win, NULL, 1); @@ -3088,6 +3133,7 @@ void update_quality_dropdown(struct Window *win) { struct Gadget *g; int i; int count = num_supported_quality; + int active = 0; if (count <= 0) { count = 1; @@ -3102,7 +3148,17 @@ void update_quality_dropdown(struct Window *win) { strncpy(mp_quality_label_storage[i], supported_quality[i], sizeof(mp_quality_label_storage[i]) - 1); mp_quality_label_storage[i][sizeof(mp_quality_label_storage[i]) - 1] = '\0'; + if (driver_quality_buffer[0] && + strcmp(driver_quality_buffer, supported_quality[i]) == 0) + active = i; } + + strncpy(driver_quality_buffer, supported_quality[active], + sizeof(driver_quality_buffer) - 1); + driver_quality_buffer[sizeof(driver_quality_buffer) - 1] = '\0'; + strncpy(selected_quality, supported_quality[active], + sizeof(selected_quality) - 1); + selected_quality[sizeof(selected_quality) - 1] = '\0'; } mp_quality_label_ptrs[count] = NULL; quality_mode_labels = mp_quality_label_ptrs; @@ -3111,7 +3167,7 @@ void update_quality_dropdown(struct Window *win) { if (g && win) { GT_SetGadgetAttrs(g, win, NULL, GTCY_Labels, (ULONG)quality_mode_labels, - GTCY_Active, 0, + GTCY_Active, (ULONG)active, GA_Disabled, num_supported_quality > 0 ? FALSE : TRUE, TAG_DONE); RefreshGList(g, win, NULL, 1); @@ -6239,11 +6295,21 @@ static int mp_scan_spool_jobs(struct MPSpoolJobEntry *jobs, int max_jobs, struct FileInfoBlock fib; int count = 0; int i; + const char *path_sep; NewList(list); - if (!mp_spool_keep_available()) return 0; - snprintf(dir_path, sizeof(dir_path), "%sMPSPOOL", driver_spool_buffer); + /* HDD jobs live in their MPSPOOL drawer. RAM jobs use the historical + * fixed T:MintPRINT-job. name; driver 41.17 adds a matching status + * sidecar so the current job and the last failed job are visible here. */ + if (!driver_spool_buffer[0] || + strcmp(driver_spool_buffer, "RAM") == 0) { + strcpy(dir_path, "T:"); + } else { + snprintf(dir_path, sizeof(dir_path), "%sMPSPOOL", + driver_spool_buffer); + } + path_sep = dir_path[strlen(dir_path) - 1] == ':' ? "" : "/"; lock = Lock((CONST_STRPTR)dir_path, ACCESS_READ); if (!lock) return 0; @@ -6254,7 +6320,9 @@ static int mp_scan_spool_jobs(struct MPSpoolJobEntry *jobs, int max_jobs, /* fib_DirEntryType < 0 -> plain file, not a drawer. */ if (fib.fib_DirEntryType < 0 && len > 7 && - strcmp(name + len - 7, ".status") == 0) { + strcmp(name + len - 7, ".status") == 0 && + (strcmp(driver_spool_buffer, "RAM") != 0 || + strncmp(name, "MintPRINT-job.", 14) == 0)) { BPTR sfh; size_t blen = (len - 7 < sizeof(jobs[count].basename) - 1) ? len - 7 : sizeof(jobs[count].basename) - 1; @@ -6265,9 +6333,10 @@ static int mp_scan_spool_jobs(struct MPSpoolJobEntry *jobs, int max_jobs, snprintf(jobs[count].status_path, sizeof(jobs[count].status_path), - "%s/%s", dir_path, name); + "%s%s%s", dir_path, path_sep, name); snprintf(jobs[count].job_path, sizeof(jobs[count].job_path), - "%s/%s", dir_path, jobs[count].basename); + "%s%s%s", dir_path, path_sep, + jobs[count].basename); strcpy(jobs[count].state, "UNKNOWN"); jobs[count].reason[0] = '\0'; From 5828966de3e00bab76a0f427e6fd20f5bf139d59 Mon Sep 17 00:00:00 2001 From: Darren Banfi <33876110+boingball@users.noreply.github.com> Date: Thu, 3 Sep 2026 08:45:12 +0100 Subject: [PATCH 2/8] Retain failed RAM spool jobs for recovery --- driver/driver_core.c | 74 ++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 20 deletions(-) diff --git a/driver/driver_core.c b/driver/driver_core.c index 1bddc32..6afe3a9 100644 --- a/driver/driver_core.c +++ b/driver/driver_core.c @@ -55,7 +55,7 @@ * MP_DRIVER_REV (the version half) only bumps for something that * warrants a new version number outright, not on every rebuild. */ #define MP_DRIVER_REV 41 -#define MP_DRIVER_SUBREV 16 +#define MP_DRIVER_SUBREV 17 struct ExecBase *SysBase = NULL; struct DosLibrary *DOSBase = NULL; @@ -123,13 +123,12 @@ static char g_job_file_urf[MP_SPOOL_PATH_MAX]; static char g_job_file_back[MP_SPOOL_PATH_MAX]; static char g_job_file_accum[MP_SPOOL_PATH_MAX]; -/* Non-empty only while the current job is a tracked (Spooler HDD + - * "Keep spooled jobs") one - the status sidecar mp_write_job_status() - * writes to as the job progresses. Empty means "not tracked": no sidecar, - * and the job file's original Debug-only retention behaviour applies - * unchanged. Reset at the top of every mp_job_begin() (see there) so a - * job that turns out untracked never inherits a stale path from the - * previous one. */ +/* Non-empty while the current job has a status sidecar. HDD jobs get one + * when "Keep spooled jobs" is enabled; RAM jobs always get one so View + * Spooler can show a live job and retain a failed job for Retry/Delete. + * Successful RAM jobs still remove both document and sidecar unless Debug + * is enabled. Empty means an untracked HDD job whose original Debug-only + * retention behaviour applies. Reset before every real job-file open. */ static char g_job_status_path[MP_SPOOL_PATH_MAX + 8]; /* + ".status" */ /* Multiple Render(status=0 begin -> rows -> status=4 end) cycles inside one @@ -396,6 +395,11 @@ static BOOL mp_streq(const char *a, const char *b) return a[i] == 0 && b[i] == 0; } +static BOOL mp_ram_spool_selected(void) +{ + return !g_config.spool[0] || mp_streq(g_config.spool, "RAM"); +} + /* Builds "" into dst (bounded by cap). prefix is "T:" * when g_config.spool is empty or "RAM" - MintPRINT's original, * unconfigurable behaviour, spooling flat exactly as before - or @@ -747,10 +751,10 @@ static void mp_job_cleanup(void) static BOOL mp_open_real_job_file(void) { /* Only a hard drive Spooler location with "Keep spooled jobs" on - * gets a unique per-job name and a tracked status sidecar - RAM - * (or Keep off) reuses the fixed per-engine name exactly as - * before, unconditionally overwritten by mp_job_open()'s - * MODE_NEWFILE every time, same as MintPRINT has always done. */ + * gets a unique per-job name. RAM reuses the fixed per-engine name, + * overwritten by mp_job_open()'s MODE_NEWFILE each time, but now gets + * a status sidecar so View Spooler can expose the live/failed job. + * An HDD job with Keep off remains completely untracked. */ BOOL track = g_config.spool_keep && g_config.spool[0] && !mp_streq(g_config.spool, "RAM"); @@ -773,6 +777,16 @@ static BOOL mp_open_real_job_file(void) } } else { g_job_open = mp_spool_job_open(mp_job_filename()); + if (g_job_open && mp_ram_spool_selected()) { + /* RAM keeps one fixed file per engine rather than unbounded + * timestamped history. Its status sidecar makes the current + * transfer and a failed result visible to View Spooler. */ + mp_copy_bounded(g_job_status_path, + sizeof(g_job_status_path), + mp_job_filename()); + mp_append_bounded(g_job_status_path, + sizeof(g_job_status_path), ".status"); + } } if (!g_job_open) { @@ -1383,6 +1397,9 @@ static BOOL mp_job_finish(ULONG expected_rows) (LONG)g_postscript.write_calls, (LONG)MP_POSTSCRIPT_OUTPUT_BUFFER); } + if (!ok) + mp_write_job_status("FAILED", NULL); + if (ok && mp_duplex_requested()) mp_job_release_buffers(); else @@ -1613,13 +1630,21 @@ static LONG mp_page_submit_and_track(ULONG rows_for_streak) g_tiny_page_streak = 0; } } - /* A tracked (spool_keep) job's file is never auto-deleted, success or - * failure alike - that retention is the entire point of the Spooler - * management window. Untracked jobs keep the original Debug-only - * retention behaviour. */ + /* Retained HDD jobs remain history. RAM keeps a failed job so it can be + * inspected/retried, but removes a successful document and sidecar just + * as the historical RAM path removed its fixed output file. */ if (!g_config.capture_only && !g_config.debug && - !mp_duplex_requested() && !g_job_status_path[0]) - mp_spool_job_delete(fname); + !mp_duplex_requested()) { + if (mp_ram_spool_selected()) { + if (ipp_rc == 0) { + mp_spool_job_delete(fname); + if (g_job_status_path[0]) + mp_spool_job_delete((CONST_STRPTR)g_job_status_path); + } + } else if (!g_job_status_path[0]) { + mp_spool_job_delete(fname); + } + } return ipp_rc; } @@ -2196,8 +2221,17 @@ VOID PRT_STDARGS DriverClose(struct IORequest *ior) mp_log_text("Duplex job discarded after page failure"); mp_write_job_status("FAILED", NULL); } - if (!g_config.capture_only && !g_config.debug && !g_job_status_path[0]) - mp_spool_job_delete(mp_job_filename()); + if (!g_config.capture_only && !g_config.debug) { + if (mp_ram_spool_selected()) { + if (!g_duplex_job_failed) { + mp_spool_job_delete(mp_job_filename()); + if (g_job_status_path[0]) + mp_spool_job_delete((CONST_STRPTR)g_job_status_path); + } + } else if (!g_job_status_path[0]) { + mp_spool_job_delete(mp_job_filename()); + } + } } mp_job_cleanup(); mp_log_text("Close"); From 2aac14ed7074afac0a78751624494dea054e32be Mon Sep 17 00:00:00 2001 From: Darren Banfi <33876110+boingball@users.noreply.github.com> Date: Thu, 3 Sep 2026 08:45:18 +0100 Subject: [PATCH 3/8] Bump driver revision to 41.17 --- driver/printertag.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver/printertag.s b/driver/printertag.s index 98c92f9..3f15a9d 100644 --- a/driver/printertag.s +++ b/driver/printertag.s @@ -104,5 +104,5 @@ printerName: * something that warrants a new version number outright. */ mp_driver_version_marker: - .asciz "$VER: MintPRINT 41.16 (01.09.2026)" + .asciz "$VER: MintPRINT 41.17 (03.09.2026)" .even From 1fba3629ff869bca1c18c5b86d5682f711cf1b80 Mon Sep 17 00:00:00 2001 From: Darren Banfi <33876110+boingball@users.noreply.github.com> Date: Thu, 3 Sep 2026 08:45:19 +0100 Subject: [PATCH 4/8] Bump driver revision to 41.17 --- driver/printertag_classic.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver/printertag_classic.s b/driver/printertag_classic.s index 84c3175..15709a5 100644 --- a/driver/printertag_classic.s +++ b/driver/printertag_classic.s @@ -80,7 +80,7 @@ printerName: * binary for that release. */ mp_driver_version_marker: - .asciz "$VER: MintPRINT 41.16 (01.09.2026)" + .asciz "$VER: MintPRINT 41.17 (03.09.2026)" .even /* Human-readable marker useful when inspecting a built driver. */ From 8b4d3d901893f629536385d165ea67e1175c12cb Mon Sep 17 00:00:00 2001 From: Darren Banfi <33876110+boingball@users.noreply.github.com> Date: Thu, 3 Sep 2026 08:45:26 +0100 Subject: [PATCH 5/8] Document issue 91 fixes --- CHANGELOG.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e4d22b..fc60b8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,16 @@ to this page; replace that summary when preparing the next release. ## Unreleased -_No unreleased changes._ +- **Query defaults now save correctly.** The AmigaOS 2.x-compatible V37 + event path now synchronises programmatically selected media/tray, colour, + quality and scaling values with the Unit config. Query Printer followed by + Save no longer writes blank `MEDIA=`, `SOURCE=`, `COLOR=` or + `SCALING=` fields unless the printer genuinely supplied no choice. +- **Failed RAM jobs are recoverable (driver 41.17).** RAM/T: spooling now + writes a live status sidecar. View Spooler can show a rendering/submitting + job and retains a failed rendered document for Retry, Copies or Delete. + Successful RAM jobs are still removed automatically, avoiding unbounded + RAM use. ## 1.3.0 From 14d3cdf6b8fc13cf0026c0162fbb10508f343d5d Mon Sep 17 00:00:00 2001 From: Darren Banfi <33876110+boingball@users.noreply.github.com> Date: Thu, 3 Sep 2026 08:45:27 +0100 Subject: [PATCH 6/8] Document issue 91 fixes --- docs/MintPrintSettings.guide | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/docs/MintPrintSettings.guide b/docs/MintPrintSettings.guide index fd9d23d..93904b9 100644 --- a/docs/MintPrintSettings.guide +++ b/docs/MintPrintSettings.guide @@ -466,12 +466,23 @@ Choosing a hard drive Spooler unlocks a second option, "Keep Jobs (HDD)" - off by default. With it on, each job is kept under MPSPOOL after it prints (or fails to), instead of being deleted once sent, and given a unique name so later jobs never overwrite earlier ones. + +RAM does not keep successful history, because retained raster files can +consume a large amount of memory. It does create a status entry for the +job currently rendering or submitting. If that job fails, its fixed +T:MintPRINT-job file and status are left in place so they can be recovered; +a successful job is removed automatically as before. A later job using the +same engine replaces that fixed RAM file, so Retry it or move to HDD +spooling before printing another document if it matters. + The "View Spool..." button opens a Spooler Management window listing -every kept job with its current status (RENDERING, SUBMITTING, DONE, -or FAILED with a plain-English reason - connection refused, out of -paper, low ink, and so on) and the host:port it was sent to. +the current/failed RAM job, or every kept job on the selected HDD, with +its current status (RENDERING, SUBMITTING, DONE, or FAILED with a +plain-English reason - connection refused, out of paper, low ink, and +so on) and the host:port it was sent to. - - Delete removes the selected job from the list and from disk. + - Delete removes the selected job from the list and from its spool + location, releasing RAM immediately for a RAM-spooled failure. - Retry resubmits it - to the printer named by the "Retry to:" cycle gadget at the bottom of the window, which defaults to whichever Unit is active in the main window but can be switched @@ -482,7 +493,8 @@ paper, low ink, and so on) and the host:port it was sent to. that - once per copy, each one individually recorded - since not every printer this driver targets honours the IPP copies attribute. - - Refresh rescans MPSPOOL for the latest status of every job. + - Refresh rescans the selected RAM or HDD spool location for the + latest status of every job. As a practical guide, allow roughly 2 MB of free RAM when using the default RAM/T: spooler for a full-page print. An HDD Spooler can make a 1 MB system From 9c0861fbe1c604045c9cd7a771be10a4fb1a89a7 Mon Sep 17 00:00:00 2001 From: Darren Banfi <33876110+boingball@users.noreply.github.com> Date: Thu, 3 Sep 2026 08:45:28 +0100 Subject: [PATCH 7/8] Document issue 91 fixes --- docs/MINTPRINT_CONFIG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/MINTPRINT_CONFIG.md b/docs/MINTPRINT_CONFIG.md index 26a0c77..ba17f96 100644 --- a/docs/MINTPRINT_CONFIG.md +++ b/docs/MINTPRINT_CONFIG.md @@ -67,6 +67,13 @@ time if it doesn't already exist - the driver itself never creates it, only writes into it, so a Unit0 pointing at a since-deleted `MPSPOOL` will fail to open its job file rather than silently recreating it. +RAM jobs retain their historical fixed `T:MintPRINT-job.` names. Driver +41.17 also writes a matching `.status` sidecar so View Spooler can show the +current RAM job. On success the document and sidecar are deleted normally; on +failure they remain available for Retry, Copies or Delete until another job +using the same engine replaces them. This is deliberately not an unlimited RAM +history. HDD jobs only receive status sidecars when Keep Jobs is enabled. + `PWG_SHEET_BACK=` records the printer's `pwg-raster-document-sheet-back` capability (`normal`, `rotated`, `flipped`, or `manual-tumble`). Query Printer writes it automatically. It controls the From fbc34e4372a358a3d62ac65d14fd3885c3aff089 Mon Sep 17 00:00:00 2001 From: Darren Banfi <33876110+boingball@users.noreply.github.com> Date: Thu, 3 Sep 2026 08:46:43 +0100 Subject: [PATCH 8/8] Tighten RAM spool status filtering --- src/MintPrintSettings.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/MintPrintSettings.c b/src/MintPrintSettings.c index 3691496..c8d971a 100644 --- a/src/MintPrintSettings.c +++ b/src/MintPrintSettings.c @@ -6321,7 +6321,8 @@ static int mp_scan_spool_jobs(struct MPSpoolJobEntry *jobs, int max_jobs, /* fib_DirEntryType < 0 -> plain file, not a drawer. */ if (fib.fib_DirEntryType < 0 && len > 7 && strcmp(name + len - 7, ".status") == 0 && - (strcmp(driver_spool_buffer, "RAM") != 0 || + ((driver_spool_buffer[0] && + strcmp(driver_spool_buffer, "RAM") != 0) || strncmp(name, "MintPRINT-job.", 14) == 0)) { BPTR sfh; size_t blen = (len - 7 < sizeof(jobs[count].basename) - 1)