AmendHub

Download:

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"