thecloud
/SimpleSpooler
/amendments
/3
refactor StartSpooler code to allow auto-running server
- make separate ConfigureSpooler and StartSpooler functions
- server startup only needs to invoke UI if not configured to auto-run
- move more control drawing to the dialog filter's update handler
- add Settings and Print Status menu items
- add the auto-run option
- add "skip reverse feeds" option (not functional yet)
- rename IW1 mode to "compatibility" since it's not really a mode
thecloud made amendment 3 2 days ago
--- PAP.c Mon Feb 23 10:27:55 2026
+++ PAP.c Mon Mar 30 01:01:17 2026
@@ -96,6 +96,7 @@ int gPrinterType; /* {0..3}, see kPrinterType definiti
Boolean gColorRibbon;
Boolean gSheetFeeder;
Boolean gIW1Mode;
+Boolean gNoReverse;
Boolean gFinishedQuery = false;
Handle gQueryHdl = nil; /* query sent to us by the LW driver */
int gQueryLength; /* length of query */
@@ -139,18 +140,22 @@ char *PAPFunctionNames[] = {
"Status", /* 9 */
};
-void SetPrinterOptions(Boolean colorRibbon, Boolean sheetFeeder, Boolean iw1Mode)
+void SetPrinterOptions(Boolean colorRibbon, Boolean sheetFeeder,
+ Boolean iw1Mode, Boolean noReverse)
{
gColorRibbon = colorRibbon;
gSheetFeeder = sheetFeeder;
gIW1Mode = iw1Mode;
+ gNoReverse = noReverse;
}
-void GetPrinterOptions(Boolean *colorRibbon, Boolean *sheetFeeder, Boolean *iw1Mode)
+void GetPrinterOptions(Boolean *colorRibbon, Boolean *sheetFeeder,
+ Boolean *iw1Mode, Boolean *noReverse)
{
if (colorRibbon) { *colorRibbon = gColorRibbon; }
if (sheetFeeder) { *sheetFeeder = gSheetFeeder; }
if (iw1Mode) { *iw1Mode = gIW1Mode; }
+ if (noReverse) { *noReverse = gNoReverse; }
}
int GetActiveClientConnections(void)
--- PAP.h Mon Feb 23 00:10:10 2026
+++ PAP.h Fri Mar 27 22:48:00 2026
@@ -3,7 +3,7 @@
* C Interface to PAP (Printer Access Protocol) routines
*
* Written by: Ken McLeod, 2026-01-07
- * Last update: 2026-02-22
+ * Last update: 2026-03-27
*
* This software is provided as-is, with no warranties expressed or implied,
* under the terms of the BSD 2-Clause License. See separate "LICENSE" file.
@@ -43,10 +43,12 @@ extern "C" {
void CheckATP(void);
/* call this prior to SLInit to specify emulated printer options */
-void SetPrinterOptions(Boolean colorRibbon, Boolean sheetFeeder, Boolean iw1Mode);
+void SetPrinterOptions(Boolean colorRibbon, Boolean sheetFeeder,
+ Boolean iw1Mode, Boolean noReverse);
/* accessor for options */
-void GetPrinterOptions(Boolean *colorRibbon, Boolean *sheetFeeder, Boolean *iw1Mode);
+void GetPrinterOptions(Boolean *colorRibbon, Boolean *sheetFeeder,
+ Boolean *iw1Mode, Boolean *noReverse);
/* number of active connections (i.e. not idle) */
int GetActiveClientConnections(void);
--- Spooler.c Mon Feb 23 10:10:14 2026
+++ Spooler.c Wed Jul 29 20:43:03 2026
@@ -10,7 +10,7 @@
* file is present in the spool directory.
*
* Written by: Ken McLeod, 2026-01-07
- * Last update: 2026-02-23
+ * Last update: 2026-07-27
*
* Some code was adapted from the Neighborhood Watch sample application
* by Ricardo Batista, found on Apple Developer CD Volume IX, and from the
@@ -65,6 +65,8 @@
#define startSpoolerItem 1
#define stopSpoolerItem 2
+#define settingsItem 4
+#define statusItem 5
#define okItem 1
#define cancelItem 2
@@ -77,18 +79,26 @@
#define colorRibbonCBoxItem 13
#define sheetFeederCBoxItem 14
#define iw1ModeCBoxItem 15
-#define printingEnabledItem 16
-#define scheduleUserItem 17
-#define printerTypeUserItem 18
-#define localPortUserItem 19
+#define noReverseCBoxItem 16
+#define printingEnabledItem 17
+#define scheduleUserItem 18
+#define printerTypeUserItem 19
+#define localPortUserItem 20
+#define autoRunCBoxItem 21
#define logWindowID 128
#define spoolerDialogID 128
-#define upDownArrowsPictID 128
+#define upDownArrowsPictID 128
#define typeStringsID 128
#define nameStringsID 129
-#define portStringsID 130
+#define portStringsID 130
+#define buttonStringsID 131
+#define okStrIndex 1
+#define cancelStrIndex 2
+#define startStrIndex 3
+#define saveStrIndex 4
+
#define kIconFrameInset -5
#define kIconFrameSize 2
#define kButtonFrameInset -4
@@ -103,6 +113,7 @@
void DoAbout(void);
void DoStatus(void);
+OSErr ConfigureSpooler(Boolean startingServer);
OSErr StartSpooler(void);
OSErr StopSpooler(void);
void SetMenus(void);
@@ -125,12 +136,15 @@ WindowPtr textWindow = 0L;
TEHandle textTE = 0L;
Rect windowRect = { 40, 10, 320, 490 }; /* default, global coordinates */
ControlHandle textScrollBar = 0L;
+PicHandle arrowsPictHdl = 0L;
short defaultPrinterItem = iconIWItem;
short defaultPortItem = modemPortItem;
Boolean defaultColorRibbon = false;
Boolean defaultSheetFeeder = false;
Boolean defaultPrintEnabled = true;
Boolean defaultIW1Mode = false;
+Boolean defaultNoReverse = false;
+Boolean defaultAutoRun = false;
short curSelectedIndex = 0; /* selected segment in date scheduler */
short schedStartHour = 0; /* default start to 12 AM */
short schedEndHour = 24; /* default end to next 12 AM */
@@ -146,7 +160,8 @@ void main()
if (!Setup()) {
return;
}
- Message(LOG_ERR,"\pSelect Control > Start Spooler… to start the server");
+ /* either auto-run the server, or present the settings panel */
+ DoCommand((controlMenu << 16) + startSpoolerItem);
while (RunEventLoop()) ;
@@ -376,6 +391,7 @@ Boolean DoCommand(long mResult)
EnableItem(myMenu[controlMenu-appleMenu],stopSpoolerItem);
DisableItem(myMenu[controlMenu-appleMenu],startSpoolerItem);
} else {
+ Message(LOG_ERR,"\pSelect Control > Start Spooler to start the server");
EnableItem(myMenu[controlMenu-appleMenu],startSpoolerItem);
DisableItem(myMenu[controlMenu-appleMenu],stopSpoolerItem);
}
@@ -391,6 +407,20 @@ Boolean DoCommand(long mResult)
EnableItem(myMenu[controlMenu-appleMenu],startSpoolerItem);
DisableItem(myMenu[controlMenu-appleMenu],stopSpoolerItem);
break;
+ case settingsItem:
+ err = ConfigureSpooler(false);
+ if (err == noErr && serverRef) {
+ /* spooler already running, recursively stop and restart it */
+ Boolean savedAutoRun = defaultAutoRun;
+ DoCommand((controlMenu << 16) + stopSpoolerItem);
+ defaultAutoRun = true; /* don't put up the dialog twice */
+ DoCommand((controlMenu << 16) + startSpoolerItem);
+ defaultAutoRun = savedAutoRun;
+ }
+ break;
+ case statusItem:
+ DoStatus();
+ break;
default:
break;
}
@@ -680,8 +710,8 @@ pascal Boolean MyDialogFilter(DialogPtr theDialog, Eve
char tmpChar;
short tmpInt;
Handle tmpHandle;
- Rect tmpRect;
- Point tmpPt;
+ Rect tmpRect, schedRect, picRect;
+ Point tmpPt = { 0,0 };
switch(theEvent->what) {
case keyDown:
@@ -710,27 +740,58 @@ pascal Boolean MyDialogFilter(DialogPtr theDialog, Eve
HandleClickInScheduler(tmpPt, &tmpRect, false);
}
return false;
+ case updateEvt:
+ /* is the update event for this window? */
+ if (theEvent->message == (long)theDialog) {
+ /* draw default button indicator */
+ GetDItem(theDialog, okItem, &tmpInt, &tmpHandle, &tmpRect);
+ PenSize(kButtonFrameSize,kButtonFrameSize);
+ InsetRect(&tmpRect,kButtonFrameInset,kButtonFrameInset);
+ FrameRoundRect(&tmpRect,kButtonFrameRadius,kButtonFrameRadius);
+ PenNormal();
+
+ /* draw group boxes around user items */
+ GetDItem(theDialog, printerTypeUserItem, &tmpInt, &tmpHandle, &tmpRect);
+ PenSize(1,1);
+ PenPat(&qd.gray);
+ FrameRect(&tmpRect);
+ PenNormal();
+ GetDItem(theDialog, localPortUserItem, &tmpInt, &tmpHandle, &tmpRect);
+ PenSize(1,1);
+ PenPat(&qd.gray);
+ FrameRect(&tmpRect);
+ PenNormal();
+
+ /* draw arrow control */
+ GetDItem(theDialog, scheduleUserItem, &tmpInt, &tmpHandle, &tmpRect);
+ HLock((Handle)arrowsPictHdl);
+ picRect = (**arrowsPictHdl).picFrame;
+ HUnlock((Handle)arrowsPictHdl);
+ schedRect = tmpRect;
+ tmpRect.left = schedRect.right - (picRect.right-picRect.left);
+ tmpRect.bottom = schedRect.top + (picRect.bottom-picRect.top);
+ DrawPicture(arrowsPictHdl,&tmpRect);
+ HandleClickInScheduler(tmpPt,&schedRect,true); /* draw current values */
+ }
+ return false;
default:
return false;
}
return false;
}
-OSErr StartSpooler(void)
+OSErr ConfigureSpooler(Boolean willStartServer)
{
- OSErr err = noErr;
char portStr[256];
char typeStr[256];
char nameStr[256];
GrafPtr savePort;
DialogTHndl dtHdl;
DialogPtr aDialog;
- short item, index;
+ short item;
Handle H;
- PicHandle arrowsPictHdl;
- Rect box, picBox, tmpBox;
- DialogRecord d;
- Point pt = { 0,0 };
+ Rect box, printerBox, portBox;
+ DialogRecord dlgRec;
/* preload stuff */
LoadPreferences();
@@ -740,73 +801,65 @@ OSErr StartSpooler(void)
GetPort(&savePort);
/* get handle to dialog template and center it before displaying */
dtHdl = CenterDialog(spoolerDialogID);
- aDialog = GetNewDialog(spoolerDialogID, (Ptr) &d, (WindowPtr) -1L);
+ aDialog = GetNewDialog(spoolerDialogID, (Ptr)&dlgRec, (WindowPtr) -1L);
if (aDialog) {
- SetPort(aDialog);
- /* draw default button indicator */
+ /* set up default and alternate button titles */
+ GetIndString(nameStr,buttonStringsID,(willStartServer) ? startStrIndex:saveStrIndex);
GetDItem(aDialog, okItem, &item, &H, &box);
- PenSize(kButtonFrameSize,kButtonFrameSize);
- InsetRect(&box,kButtonFrameInset,kButtonFrameInset);
- FrameRoundRect(&box,kButtonFrameRadius,kButtonFrameRadius);
- PenNormal();
-
- /* draw group boxes */
- GetDItem(aDialog, printerTypeUserItem, &item, &H, &box);
- PenSize(1,1);
- PenPat(&qd.gray);
- FrameRect(&box);
- PenNormal();
- GetDItem(aDialog, localPortUserItem, &item, &H, &box);
- PenSize(1,1);
- PenPat(&qd.gray);
- FrameRect(&box);
- PenNormal();
+ SetCTitle((ControlHandle)H, nameStr);
+ /* should we disable button if server is already running? */
+ /* (no, just stop and restart the server to pick up new settings) */
+ /*HiliteControl((ControlHandle)H,(serverRef!=0)?255:0);*/
+ GetIndString(nameStr,buttonStringsID,cancelStrIndex);
+ GetDItem(aDialog, cancelItem, &item, &H, &box);
+ SetCTitle((ControlHandle)H, nameStr);
- /* arrow control */
- GetDItem(aDialog, scheduleUserItem, &item, &H, &box);
- HLock((Handle)arrowsPictHdl);
- picBox = (**arrowsPictHdl).picFrame;
- HUnlock((Handle)arrowsPictHdl);
- tmpBox = box;
- tmpBox.left = tmpBox.right - (picBox.right-picBox.left);
- tmpBox.bottom = tmpBox.top + (picBox.bottom-picBox.top);
- DrawPicture(arrowsPictHdl,&tmpBox);
- HandleClickInScheduler(pt,&box,true); /* draw initial values */
-
/* set up default name, printer type, and printer options */
GetIndString(typeStr,typeStringsID,defaultPrinterItem-(iconLWItem-1));
GetIndString(nameStr,nameStringsID,defaultPrinterItem-(iconLWItem-1));
GetDItem(aDialog, spoolerNameItem, &item, &H, &box);
SetIText(H, (ourName[0] > 0) ? ourName : nameStr);
GetDItem(aDialog, defaultPrinterItem, &item, &H, &box);
- PenSize(kIconFrameSize,kIconFrameSize);
- InsetRect(&box,kIconFrameInset,kIconFrameInset);
- FrameRect(&box);
- PenNormal();
- GetDItem(aDialog, colorRibbonCBoxItem, &index, &H, &box);
+ printerBox = box;
+
+ GetDItem(aDialog, colorRibbonCBoxItem, &item, &H, &box);
SetCtlValue((ControlHandle)H,defaultColorRibbon);
HiliteControl((ControlHandle)H,(defaultPrinterItem==iconLWItem)?255:0);
- GetDItem(aDialog, sheetFeederCBoxItem, &index, &H, &box);
+ GetDItem(aDialog, sheetFeederCBoxItem, &item, &H, &box);
SetCtlValue((ControlHandle)H,defaultSheetFeeder);
HiliteControl((ControlHandle)H,(defaultPrinterItem==iconLWItem)?255:0);
- GetDItem(aDialog, iw1ModeCBoxItem, &index, &H, &box);
+ GetDItem(aDialog, iw1ModeCBoxItem, &item, &H, &box);
SetCtlValue((ControlHandle)H,defaultIW1Mode);
HiliteControl((ControlHandle)H,(defaultPrinterItem==iconLWItem)?255:0);
- GetDItem(aDialog, printingEnabledItem, &index, &H, &box);
+ GetDItem(aDialog, noReverseCBoxItem, &item, &H, &box);
+ SetCtlValue((ControlHandle)H,defaultNoReverse);
+ HiliteControl((ControlHandle)H,(defaultPrinterItem==iconLWItem)?255:0);
+ GetDItem(aDialog, printingEnabledItem, &item, &H, &box);
SetCtlValue((ControlHandle)H,defaultPrintEnabled);
+ GetDItem(aDialog, autoRunCBoxItem, &item, &H, &box);
+ SetCtlValue((ControlHandle)H,defaultAutoRun);
/* set up default port */
GetIndString(portStr,portStringsID,defaultPortItem-(modemPortItem-1));
GetDItem(aDialog, defaultPortItem, &item, &H, &box);
+ portBox = box;
+
+ SetPort(aDialog);
+ ShowWindow(aDialog);
+ InitCursor();
+
+ /* draw frames for initial selections */
PenSize(kIconFrameSize,kIconFrameSize);
- InsetRect(&box,kIconFrameInset,kIconFrameInset);
- FrameRect(&box);
+ InsetRect(&printerBox,kIconFrameInset,kIconFrameInset);
+ FrameRect(&printerBox);
+ InsetRect(&portBox,kIconFrameInset,kIconFrameInset);
+ FrameRect(&portBox);
PenNormal();
item = 0;
while ((item != okItem) && (item != cancelItem)) {
if (item >= iconLWItem && item <= iconIWItem) {
- short tmpItem;
+ short tmpItem, index;
for (index = iconLWItem; index <= iconIWItem; index++) {
GetDItem(aDialog, index, &tmpItem, &H, &box);
InsetRect(&box,kIconFrameInset,kIconFrameInset);
@@ -832,9 +885,12 @@ OSErr StartSpooler(void)
GetDItem(aDialog, iw1ModeCBoxItem, &tmpItem, &H, &box);
HiliteControl((ControlHandle)H,(item!=iconIWItem)?255:0);
if (item!=iconIWItem) { SetCtlValue((ControlHandle)H,0); }
+ GetDItem(aDialog, noReverseCBoxItem, &tmpItem, &H, &box);
+ HiliteControl((ControlHandle)H,(item==iconLWItem)?255:0);
+ if (item==iconLWItem) { SetCtlValue((ControlHandle)H,0); }
}
else if (item >= modemPortItem && item <= printerPortItem) {
- short tmpItem;
+ short tmpItem, index;
for (index = modemPortItem; index <= printerPortItem; index++) {
GetDItem(aDialog, index, &tmpItem, &H, &box);
InsetRect(&box,kIconFrameInset,kIconFrameInset);
@@ -851,7 +907,8 @@ OSErr StartSpooler(void)
PenNormal();
GetIndString(portStr, 130, item-(modemPortItem-1));
}
- else if (item >= colorRibbonCBoxItem && item <= printingEnabledItem) {
+ else if ((item >= colorRibbonCBoxItem && item <= printingEnabledItem) ||
+ (item == autoRunCBoxItem)) {
short tmpItem, curValue;
GetDItem(aDialog, item, &tmpItem, &H, &box);
curValue = GetCtlValue((ControlHandle)H);
@@ -861,7 +918,8 @@ OSErr StartSpooler(void)
}
if (item == okItem) {
short tmpItem;
- Boolean hasColorRibbon, hasSheetFeeder, iw1Mode, printEnabled;
+ Boolean hasColorRibbon, hasSheetFeeder;
+ Boolean iw1Mode, noReverse, printEnabled, autoRun;
GetDItem(aDialog, spoolerNameItem, &tmpItem, &H, &box);
GetIText(H, nameStr);
GetDItem(aDialog, colorRibbonCBoxItem, &tmpItem, &H, &box);
@@ -870,16 +928,23 @@ OSErr StartSpooler(void)
hasSheetFeeder = (GetCtlValue((ControlHandle)H) != 0);
GetDItem(aDialog, iw1ModeCBoxItem, &tmpItem, &H, &box);
iw1Mode = (GetCtlValue((ControlHandle)H) != 0);
+ GetDItem(aDialog, noReverseCBoxItem, &tmpItem, &H, &box);
+ noReverse = (GetCtlValue((ControlHandle)H) != 0);
GetDItem(aDialog, printingEnabledItem, &tmpItem, &H, &box);
printEnabled = (GetCtlValue((ControlHandle)H) != 0);
- SetPrinterOptions(hasColorRibbon, hasSheetFeeder,iw1Mode);
+ GetDItem(aDialog, autoRunCBoxItem, &tmpItem, &H, &box);
+ autoRun = (GetCtlValue((ControlHandle)H) != 0);
+ SetPrinterOptions(hasColorRibbon, hasSheetFeeder,iw1Mode,noReverse);
defaultColorRibbon = hasColorRibbon;
defaultSheetFeeder = hasSheetFeeder;
defaultPrintEnabled = printEnabled;
defaultIW1Mode = iw1Mode;
+ defaultNoReverse = noReverse;
+ defaultAutoRun = autoRun;
}
curSelectedIndex = 0;
ReleaseResource((Handle)arrowsPictHdl);
+ arrowsPictHdl = 0L;
CloseDialog(aDialog);
}
SetPort(savePort);
@@ -900,36 +965,49 @@ OSErr StartSpooler(void)
ourPrefix[3] = '-';
/* save for next time (after spool folder is set up) */
SavePreferences();
- {
- EntityName name;
- PAPStatusRec stRec;
- name.zoneStr[0] = 1;
- name.zoneStr[1] = '*';
- BlockMove(ourType, name.typeStr, 33L);
- BlockMove(ourName, name.objStr, 33L);
- BlockMove("\pRegistering", stRec.statusStr, 12L);
-
- err = SLInit(&name, kPAPMaxQuantum, &stRec, &serverRef);
- if (err != noErr) {
- MessageWithIntValue(LOG_ERR_X,"\pRegistering name:",err);
- (void) SLClose(serverRef);
- } else {
- BlockMove("Registered “", &nameStr[1],12L);
- nameStr[0] = 12;
- BlockMove(&ourName[1],&nameStr[nameStr[0]+1],(long)((short)ourName[0]));
- nameStr[0] += ourName[0];
- BlockMove("” in local zone", &nameStr[nameStr[0]+1],15L);
- nameStr[0] += 15;
- Message(LOG_ERR,nameStr);
- }
+ }
+ return (item == okItem) ? noErr : userCanceledErr;
+}
+
+OSErr StartSpooler(void)
+{
+ OSErr err = noErr;
+ if (!defaultAutoRun) {
+ err = ConfigureSpooler(true);
+ }
+ if (err == noErr) {
+ char nameStr[256];
+ EntityName name;
+ PAPStatusRec stRec;
+ name.zoneStr[0] = 1;
+ name.zoneStr[1] = '*';
+ BlockMove(ourType, name.typeStr, 33L);
+ BlockMove(ourName, name.objStr, 33L);
+ BlockMove("\pRegistering", stRec.statusStr, 12L);
+
+ err = SLInit(&name, kPAPMaxQuantum, &stRec, &serverRef);
+ if (err != noErr) {
+ MessageWithIntValue(LOG_ERR_X,"\pRegistering name:",err);
+ (void) SLClose(serverRef);
+ serverRef = 0;
+ } else {
+ BlockMove("Registered “", &nameStr[1],12L);
+ nameStr[0] = 12;
+ BlockMove(&ourName[1],&nameStr[nameStr[0]+1],(long)((short)ourName[0]));
+ nameStr[0] += ourName[0];
+ BlockMove("” in local zone", &nameStr[nameStr[0]+1],15L);
+ nameStr[0] += 15;
+ Message(LOG_ERR,nameStr);
}
}
- return (item == okItem && !err) ? noErr : userCanceledErr;
+ return err;
}
OSErr StopSpooler(void)
{
- return SLClose(serverRef);
+ OSErr err = SLClose(serverRef);
+ serverRef = 0;
+ return err;
}
void DoAbout()
@@ -938,7 +1016,7 @@ void DoAbout()
Message(0,"\pSimple Spooler is a basic print spooler application.");
Message(0,"\pIt presents itself as an AppleTalk printer and will");
Message(0,"\prespond to Printer Access Protocol (PAP) messages.");
- Message(0,"\pVersion 0.2, Copyright © 2026 Ken McLeod.");
+ Message(0,"\pVersion 0.3, Copyright © 2026 Ken McLeod.");
Message(0,sepStr);
}
@@ -951,6 +1029,7 @@ void DoStatus()
MessageWithIntValue(0,"\pColor ribbon:",(defaultColorRibbon)?1:0);
MessageWithIntValue(0,"\pSheet feeder:",(defaultSheetFeeder)?1:0);
MessageWithIntValue(0,"\pImageWriter 1 mode:",(defaultIW1Mode)?1:0);
+ MessageWithIntValue(0,"\pSkip reverse feed:",(defaultNoReverse)?1:0);
MessageWithQuotedString(0,"\pPrint to port:",ourPort);
MessageWithIntValue(0,"\pPrinting enabled:",(defaultPrintEnabled)?1:0);
MessageWithIntValue(0,"\pScheduled start hour:",schedStartHour);
@@ -981,7 +1060,9 @@ void LoadPreferences()
schedEndHour = *((char*)&prefData[13]);
/* window rect in global coordinates */
windowRect = *((Rect*)&prefData[14]);
- /* reserved chars at prefsData[22..31] */
+ defaultNoReverse = *((char*)&prefData[22]);
+ defaultAutoRun = *((char*)&prefData[23]);
+ /* reserved chars at prefsData[24..31] */
p = (char*)&prefData[32];
BlockMove(p,ourName,p[0]+1);
p += p[0]+1;
@@ -989,12 +1070,16 @@ void LoadPreferences()
p += p[0]+1;
BlockMove(p,ourPort,p[0]+1);
DisposPtr(prefData);
+
+ /* let PAP module know about the new options */
+ SetPrinterOptions(defaultColorRibbon,defaultSheetFeeder,defaultIW1Mode,defaultNoReverse);
}
void SavePreferences()
{
char *p, val;
- Boolean hasColorRibbon, hasSheetFeeder, iw1Mode, printEnabled;
+ Boolean hasColorRibbon, hasSheetFeeder;
+ Boolean iw1Mode, noReverse, printEnabled, autoRun;
long length = 4L+2L+8+18+ourName[0]+1+ourType[0]+1+ourPort[0]+1;
Ptr prefData = NewPtrClear(length);
if (!prefData) { return; }
@@ -1011,7 +1096,7 @@ void SavePreferences()
val = (ourPort[1] == 'M') ? modemPortItem : printerPortItem;
*((char*)&prefData[7]) = val;
/* offset 8, 9: boolean values of Color Ribbon and Sheet Feeder */
- GetPrinterOptions(&hasColorRibbon,&hasSheetFeeder,&iw1Mode);
+ GetPrinterOptions(&hasColorRibbon,&hasSheetFeeder,&iw1Mode,&noReverse);
*((char*)&prefData[8]) = (hasColorRibbon) ? -1 : 0;
*((char*)&prefData[9]) = (hasSheetFeeder) ? -1 : 0;
/* offset 10, 11: boolean values of Print Enabled and IW1 Mode */
@@ -1027,8 +1112,11 @@ void SavePreferences()
*((Rect*)&prefData[14]) = ((GrafPtr)textWindow)->portRect;
LocalToGlobal((Point*)&prefData[14]);
LocalToGlobal((Point*)&prefData[18]);
- /* reserved chars from [22..31] */
-
+ /* offset 22, 23: boolean values of No Reverse and Auto Run */
+ *((char*)&prefData[22]) = (noReverse) ? -1 : 0;
+ autoRun = defaultAutoRun;
+ *((char*)&prefData[23]) = (autoRun) ? -1 : 0;
+ /* reserved chars from [24..31] */
p = (char*)&prefData[32];
BlockMove(ourName,p,ourName[0]+1);
p += ourName[0]+1;
--- Spooler.r Sun Feb 22 23:55:14 2026
+++ Spooler.r Mon Jul 27 14:50:52 2026
@@ -7,7 +7,7 @@
#include "Types.r"
#include "SysTypes.r"
-#define VERSION_STR "0.2"
+#define VERSION_STR "0.3"
/* resource type declarations */
type 'spoo' as 'STR ';
@@ -53,14 +53,14 @@ resource 'FREF' (129, purgeable) {
resource 'vers' (1) {
0x00, 0x10, development, 0x00, verUS,
VERSION_STR,
- $$Format("Simple Spooler %s \nCopyright © 2026 Ken McLeod",
+ $$Format("Simple Spooler %s\nCopyright © 2026 Ken McLeod",
VERSION_STR)
};
resource 'DLOG' (128, "Printer Setup") {
- {40, 40, 264, 464},
+ {40, 40, 268, 464},
dBoxProc,
- visible,
+ invisible,
noGoAway,
0x0,
128,
@@ -68,18 +68,18 @@ resource 'DLOG' (128, "Printer Setup") {
};
resource 'DITL' (128) {
- { /* array DITLarray: 19 elements */
+ { /* array DITLarray: 21 elements */
/* [1] */
- {191, 344, 211, 410},
+ {195, 344, 215, 410},
Button {
enabled,
- "Start"
+ ""
},
/* [2] */
- {191, 266, 211, 332},
+ {195, 266, 215, 332},
Button {
enabled,
- "Cancel"
+ ""
},
/* [3] */
{34, 81, 51, 409},
@@ -88,10 +88,10 @@ resource 'DITL' (128) {
""
},
/* [4] */
- {13, 78, 29, 412},
+ {13, 78, 29, 183},
StaticText {
disabled,
- "Spooler name:"
+ "Printer name:"
},
/* [5] */
{11, 23, 43, 55},
@@ -124,13 +124,13 @@ resource 'DITL' (128) {
" Virtual printer type:"
},
/* [10] */
- {88, 290, 120, 322},
+ {88, 298, 120, 330},
Icon {
enabled,
200
},
/* [11] */
- {88, 339, 120, 371},
+ {88, 347, 120, 379},
Icon {
enabled,
201
@@ -145,45 +145,57 @@ resource 'DITL' (128) {
{133, 88, 151, 206},
CheckBox {
enabled,
- "Color Ribbon"
+ "Color ribbon"
},
/* [14] */
{152, 88, 170, 194},
CheckBox {
enabled,
- "Sheet Feeder"
+ "Sheet feeder"
},
/* [15] */
{171, 88, 189, 245},
CheckBox {
enabled,
- "ImageWriter 1 mode"
+ "IW1 compatibility"
},
/* [16] */
+ {190, 88, 208, 245},
+ CheckBox {
+ enabled,
+ "Skip reverse feeds"
+ },
+ /* [17] */
{133, 276, 151, 358},
CheckBox {
enabled,
"Enabled"
},
- /* [17] */
+ /* [18] */
{153, 292, 171, 402},
UserItem {
enabled
},
- /* [18] */
- {68, 78, 211, 253},
+ /* [19] */
+ {68, 78, 215, 253},
UserItem {
disabled
},
- /* [19] */
- {68, 266, 178, 410},
+ /* [20] */
+ {68, 266, 182, 410},
UserItem {
disabled
+ },
+ /* [21] */
+ {11, 264, 30, 412},
+ CheckBox {
+ enabled,
+ "Auto-run at launch"
}
}
};
-resource 'MENU' (128) {
+resource 'MENU' (128, preload) {
128,
textMenuProc,
0x7FFFFFFD,
@@ -197,7 +209,7 @@ resource 'MENU' (128) {
}
};
-resource 'MENU' (129) {
+resource 'MENU' (129, preload) {
129,
textMenuProc,
allEnabled,
@@ -238,14 +250,20 @@ resource 'MENU' (130, preload) {
resource 'MENU' (131, preload) {
131,
textMenuProc,
- 0x0,
+ 0x7FFFFFF8,
enabled,
"Control",
- { /* array: 2 elements */
+ { /* array: 5 elements */
/* [1] */
- "Start Spooler…", noIcon, noKey, noMark, plain,
+ "Start Spooler", noIcon, "R", noMark, plain,
/* [2] */
- "Stop Spooler", noIcon, noKey, noMark, plain,
+ "Stop Spooler", noIcon, ".", noMark, plain,
+ /* [3] */
+ "-", noIcon, noKey, noMark, plain,
+ /* [4] */
+ "Settings…", noIcon, noKey, noMark, plain,
+ /* [5] */
+ "Print Status", noIcon, noKey, noMark, plain
}
};
@@ -331,6 +349,18 @@ resource 'STR#' (130, "Ports") {
}
};
+resource 'STR#' (131, "Buttons") {
+ { /* array StringArray: 4 elements */
+ /* [1] */
+ "OK",
+ /* [2] */
+ "Cancel",
+ /* [3] */
+ "Start",
+ /* [4] */
+ "Save"
+ }
+};
resource 'ics8' (128) {
$"0000 0000 0000 0000 0000 0000 0000 0000"
$"0000 0000 FFFF FF00 0000 00FF FF00 0000"