Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
7 changes: 7 additions & 0 deletions docs/MINTPRINT_CONFIG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.<ext>` 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
Expand Down
22 changes: 17 additions & 5 deletions docs/MintPrintSettings.guide
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
74 changes: 54 additions & 20 deletions driver/driver_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 "<prefix><base_name>" 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
Expand Down Expand Up @@ -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");

Expand All @@ -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) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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");
Expand Down
2 changes: 1 addition & 1 deletion driver/printertag.s
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion driver/printertag_classic.s
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down
Loading
Loading