2 *----------------------------------------------------------------------------
3 * printer class for poseidon
4 *----------------------------------------------------------------------------
5 * By Chris Hodges <chrisly@platon42.de>
10 #include "printer.class.h"
13 static const STRPTR libname
= MOD_NAME_STRING
;
16 const APTR DevFuncTable
[] =
18 &AROS_SLIB_ENTRY(devOpen
, dev
, 1),
19 &AROS_SLIB_ENTRY(devClose
, dev
, 2),
20 &AROS_SLIB_ENTRY(devExpunge
, dev
, 3),
21 &AROS_SLIB_ENTRY(devReserved
, dev
, 4),
22 &AROS_SLIB_ENTRY(devBeginIO
, dev
, 5),
23 &AROS_SLIB_ENTRY(devAbortIO
, dev
, 6),
27 static int libInit(LIBBASETYPEPTR nh
)
29 struct NepPrinterBase
*ret
= NULL
;
31 KPRINTF(10, ("libInit nh: 0x%08lx SysBase: 0x%08lx\n", nh
, SysBase
));
33 nh
->nh_UtilityBase
= OpenLibrary("utility.library", 39);
35 #define UtilityBase nh->nh_UtilityBase
39 NewList(&nh
->nh_Units
);
41 if((nh
->nh_DevBase
= (struct NepPrtDevBase
*) MakeLibrary((APTR
) DevFuncTable
, NULL
, (APTR
) devInit
,
42 sizeof(struct NepPrtDevBase
), NULL
)))
44 nh
->nh_DevBase
->np_ClsBase
= nh
;
46 AddDevice((struct Device
*) nh
->nh_DevBase
);
47 nh
->nh_DevBase
->np_Library
.lib_OpenCnt
++;
51 KPRINTF(20, ("failed to create usbparallel.device\n"));
55 CloseLibrary(UtilityBase
);
58 KPRINTF(20, ("libInit: OpenLibrary(\"utility.library\", 39) failed!\n"));
61 KPRINTF(10, ("libInit: Ok\n"));
62 return(ret
? TRUE
: FALSE
);
65 static int libOpen(LIBBASETYPEPTR nh
)
67 KPRINTF(10, ("libOpen nh: 0x%08lx\n", nh
));
72 static int libExpunge(LIBBASETYPEPTR nh
)
74 struct NepClassPrinter
*ncp
;
76 KPRINTF(10, ("libExpunge nh: 0x%08lx\n", nh
));
78 if(nh
->nh_DevBase
->np_Library
.lib_OpenCnt
== 1)
80 KPRINTF(1, ("libExpunge: closelibrary utilitybase 0x%08lx\n",
82 CloseLibrary((struct Library
*) UtilityBase
);
84 ncp
= (struct NepClassPrinter
*) nh
->nh_Units
.lh_Head
;
85 while(ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Succ
)
87 Remove((struct Node
*) ncp
);
89 ncp
= (struct NepClassPrinter
*) nh
->nh_Units
.lh_Head
;
92 nh
->nh_DevBase
->np_Library
.lib_OpenCnt
--;
93 RemDevice((struct Device
*) nh
->nh_DevBase
);
95 KPRINTF(5, ("libExpunge: Unloading done! printer.class expunged!\n\n"));
97 KPRINTF(5, ("libExpunge: Could not expunge, LIBF_DELEXP set!\n"));
104 ADD2INITLIB(libInit
, 0)
105 ADD2OPENLIB(libOpen
, 0)
106 ADD2EXPUNGELIB(libExpunge
, 0)
110 * ***********************************************************************
111 * * Library functions *
112 * ***********************************************************************
115 /* /// "usbAttemptInterfaceBinding()" */
116 struct NepClassPrinter
* usbAttemptInterfaceBinding(struct NepPrinterBase
*nh
, struct PsdInterface
*pif
)
123 KPRINTF(1, ("nepPrinterAttemptInterfaceBinding(%08lx)\n", pif
));
124 if((ps
= OpenLibrary("poseidon.library", 4)))
126 psdGetAttrs(PGA_INTERFACE
, pif
,
128 IFA_SubClass
, &subclass
,
129 IFA_Protocol
, &proto
,
132 if((ifclass
== PRINTER_CLASSCODE
) && (subclass
== 0x01) &&
133 ((proto
== PRT_PROTO_BIDIR
) || (proto
== PRT_PROTO_UNIDIR
)))// || (proto == PRT_PROTO_IEEE1284)))
135 return(usbForceInterfaceBinding(nh
, pif
));
142 /* /// "usbForceInterfaceBinding()" */
143 struct NepClassPrinter
* usbForceInterfaceBinding(struct NepPrinterBase
*nh
, struct PsdInterface
*pif
)
146 struct NepClassPrinter
*ncp
;
147 struct PsdConfig
*pc
;
148 struct PsdDevice
*pd
;
158 struct Task
*tmptask
;
160 KPRINTF(1, ("nepPrinterAttemptInterfaceBinding(%08lx)\n", pif
));
161 if((ps
= OpenLibrary("poseidon.library", 4)))
163 psdGetAttrs(PGA_INTERFACE
, pif
,
164 IFA_InterfaceNum
, &ifnum
,
165 IFA_AlternateNum
, &altifnum
,
168 psdGetAttrs(PGA_CONFIG
, pc
,
170 CA_ConfigNum
, &cfgnum
,
172 psdGetAttrs(PGA_DEVICE
, pd
,
173 DA_ProductID
, &prodid
,
174 DA_VendorID
, &vendid
,
175 DA_ProductName
, &devname
,
178 /* Find next free unit number */
180 ncp
= (struct NepClassPrinter
*) nh
->nh_Units
.lh_Head
;
181 while(ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Succ
)
183 if(ncp
->ncp_UnitNo
== unitno
)
186 ncp
= (struct NepClassPrinter
*) nh
->nh_Units
.lh_Head
;
188 ncp
= (struct NepClassPrinter
*) ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Succ
;
192 ncp
= (struct NepClassPrinter
*) nh
->nh_Units
.lh_Head
;
193 while(ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Succ
)
195 if((ncp
->ncp_UnitAltIfNum
== altifnum
) && (ncp
->ncp_UnitIfNum
== ifnum
) &&
196 (ncp
->ncp_UnitProdID
== prodid
) && (ncp
->ncp_UnitVendorID
== vendid
))
198 unitno
= ncp
->ncp_UnitNo
;
202 ncp
= (struct NepClassPrinter
*) ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Succ
;
206 /* as units are freed in the expunge-vector, the memory is
207 outside the scope of the poseidon library */
208 if(!(ncp
= AllocVec(sizeof(struct NepClassPrinter
), MEMF_PUBLIC
|MEMF_CLEAR
)))
214 /* IORequests may be queued even if the task is gone. */
215 NewList(&ncp
->ncp_Unit
.unit_MsgPort
.mp_MsgList
);
216 NewList(&ncp
->ncp_ReadQueue
);
217 NewList(&ncp
->ncp_WriteQueue
);
218 AddTail(&nh
->nh_Units
, &ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
);
220 ncp
->ncp_ClsBase
= nh
;
221 ncp
->ncp_UnitNo
= unitno
;
222 ncp
->ncp_Interface
= pif
;
223 ncp
->ncp_Device
= pd
;
224 ncp
->ncp_Config
= pc
;
225 ncp
->ncp_UnitAltIfNum
= altifnum
;
226 ncp
->ncp_UnitIfNum
= ifnum
;
227 ncp
->ncp_UnitCfgNum
= cfgnum
;
228 ncp
->ncp_UnitProdID
= prodid
;
229 ncp
->ncp_UnitVendorID
= vendid
;
233 nLoadClassConfig(nh
);
235 psdSafeRawDoFmt(buf
, 64, "printer.class<%08lx>", ncp
);
236 ncp
->ncp_ReadySignal
= SIGB_SINGLE
;
237 ncp
->ncp_ReadySigTask
= FindTask(NULL
);
238 SetSignal(0, SIGF_SINGLE
);
239 if((tmptask
= psdSpawnSubTask(buf
, nPrinterTask
, ncp
)))
241 psdBorrowLocksWait(tmptask
, 1UL<<ncp
->ncp_ReadySignal
);
244 ncp
->ncp_ReadySigTask
= NULL
;
245 //FreeSignal(ncp->ncp_ReadySignal);
246 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
,
247 "Please welcome '%s' to the family at %s unit %ld!",
248 devname
, nh
->nh_DevBase
->np_Library
.lib_Node
.ln_Name
,
255 ncp
->ncp_ReadySigTask
= NULL
;
256 //FreeSignal(ncp->ncp_ReadySignal);
257 /* Get rid of unit structure */
259 Remove((struct Node *) ncp);
268 /* /// "usbReleaseInterfaceBinding()" */
269 void usbReleaseInterfaceBinding(struct NepPrinterBase
*nh
, struct NepClassPrinter
*ncp
)
274 KPRINTF(1, ("nepPrinterReleaseInterfaceBinding(%08lx)\n", ncp
));
275 if((ps
= OpenLibrary("poseidon.library", 4)))
278 ncp
->ncp_ReadySignal
= SIGB_SINGLE
;
279 ncp
->ncp_ReadySigTask
= FindTask(NULL
);
282 Signal(ncp
->ncp_Task
, SIGBREAKF_CTRL_C
);
287 Wait(1UL<<ncp
->ncp_ReadySignal
);
289 //FreeSignal(ncp->ncp_ReadySignal);
290 psdGetAttrs(PGA_DEVICE
, ncp
->ncp_Device
, DA_ProductName
, &devname
, TAG_END
);
291 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
,
292 "'%s' died of boredom.",
300 /* /// "usbGetAttrsA()" */
301 AROS_LH3(LONG
, usbGetAttrsA
,
302 AROS_LHA(ULONG
, type
, D0
),
303 AROS_LHA(APTR
, usbstruct
, A0
),
304 AROS_LHA(struct TagItem
*, tags
, A1
),
305 LIBBASETYPEPTR
, nh
, 5, nep
)
312 KPRINTF(1, ("nepHidGetAttrsA(%ld, %08lx, %08lx)\n", type
, usbstruct
, tags
));
316 if((ti
= FindTagItem(UCCA_Priority
, tags
)))
318 *((SIPTR
*) ti
->ti_Data
) = 0;
321 if((ti
= FindTagItem(UCCA_Description
, tags
)))
323 *((STRPTR
*) ti
->ti_Data
) = "Bidirectional printer driver via usbparallel.device";
326 if((ti
= FindTagItem(UCCA_HasClassCfgGUI
, tags
)))
328 *((IPTR
*) ti
->ti_Data
) = TRUE
;
331 if((ti
= FindTagItem(UCCA_HasBindingCfgGUI
, tags
)))
333 *((IPTR
*) ti
->ti_Data
) = FALSE
;
336 if((ti
= FindTagItem(UCCA_AfterDOSRestart
, tags
)))
338 *((IPTR
*) ti
->ti_Data
) = FALSE
;
341 if((ti
= FindTagItem(UCCA_UsingDefaultCfg
, tags
)))
343 *((IPTR
*) ti
->ti_Data
) = nh
->nh_UsingDefaultCfg
;
349 if((ti
= FindTagItem(UCBA_UsingDefaultCfg
, tags
)))
351 *((IPTR
*) ti
->ti_Data
) = FALSE
;
361 /* /// "usbSetAttrsA()" */
362 AROS_LH3(LONG
, usbSetAttrsA
,
363 AROS_LHA(ULONG
, type
, D0
),
364 AROS_LHA(APTR
, usbstruct
, A0
),
365 AROS_LHA(struct TagItem
*, tags
, A1
),
366 LIBBASETYPEPTR
, nh
, 6, nep
)
374 /* /// "usbDoMethodA()" */
375 AROS_LH2(IPTR
, usbDoMethodA
,
376 AROS_LHA(ULONG
, methodid
, D0
),
377 AROS_LHA(IPTR
*, methoddata
, A1
),
378 LIBBASETYPEPTR
, nh
, 7, nep
)
382 KPRINTF(10, ("Do Method %ld\n", methodid
));
385 case UCM_AttemptInterfaceBinding
:
386 return((IPTR
) usbAttemptInterfaceBinding(nh
, (struct PsdInterface
*) methoddata
[0]));
388 case UCM_ForceInterfaceBinding
:
389 return((IPTR
) usbForceInterfaceBinding(nh
, (struct PsdInterface
*) methoddata
[0]));
391 case UCM_ReleaseInterfaceBinding
:
392 usbReleaseInterfaceBinding(nh
, (struct NepClassPrinter
*) methoddata
[0]);
395 case UCM_OpenCfgWindow
:
396 return(nOpenCfgWindow(nh
));
398 case UCM_ConfigChangedEvent
:
399 nLoadClassConfig(nh
);
410 /* /// "nLoadClassConfig()" */
411 BOOL
nLoadClassConfig(struct NepPrinterBase
*nh
)
414 struct ClsGlobalCfg
*cgc
;
415 struct PsdIFFContext
*pic
;
417 KPRINTF(10, ("Loading Class Config...\n"));
422 if(!(ps
= OpenLibrary("poseidon.library", 4)))
427 /* Create default config */
428 nh
->nh_CurrentCGC
.cgc_ChunkID
= AROS_LONG2BE(MAKE_ID('U','P','R','T'));
429 nh
->nh_CurrentCGC
.cgc_Length
= AROS_LONG2BE(sizeof(struct ClsGlobalCfg
)-8);
430 nh
->nh_CurrentCGC
.cgc_EpsonInit
= TRUE
;
431 nh
->nh_CurrentCGC
.cgc_SoftReset
= TRUE
;
432 nh
->nh_UsingDefaultCfg
= TRUE
;
433 pic
= psdGetClsCfg(libname
);
436 if((cgc
= psdGetCfgChunk(pic
, AROS_LONG2BE(nh
->nh_CurrentCGC
.cgc_ChunkID
))))
438 CopyMem(((UBYTE
*) cgc
) + 8, ((UBYTE
*) &nh
->nh_CurrentCGC
) + 8, min(AROS_LONG2BE(cgc
->cgc_Length
), AROS_LONG2BE(nh
->nh_CurrentCGC
.cgc_Length
)));
440 nh
->nh_UsingDefaultCfg
= FALSE
;
449 /* /// "nOpenCfgWindow()" */
450 LONG
nOpenCfgWindow(struct NepPrinterBase
*nh
)
453 KPRINTF(10, ("Opening GUI...\n"));
454 if(!(ps
= OpenLibrary("poseidon.library", 4)))
461 if((nh
->nh_GUITask
= psdSpawnSubTask(MOD_NAME_STRING
" GUI", nGUITask
, nh
)))
474 /**************************************************************************/
477 #define ps ncp->ncp_Base
479 /* /// "nPrinterTask()" */
480 AROS_UFH0(void, nPrinterTask
)
484 struct NepClassPrinter
*ncp
;
488 struct PsdConfig
*pc
;
491 BOOL epsonmode
= FALSE
;
494 char *epsonid
= "MFG:EPSON";//;CMD:ESCPL2,BDC,D4;MDL:Stylus Photo 870;CLS:PRINTER;DES:EPSON Stylus Photo 870;";
495 struct IOExtPar
*ioreq
;
496 struct IOExtPar
*ioreq2
;
497 char epsonusbinit
[] = { 0x00, 0x00, 0x00, 0x1b, 0x01, 0x40, 0x45, 0x4a,
498 0x4c, 0x20, 0x31, 0x32, 0x38, 0x34, 0x2e, 0x34,
499 0x0a, 0x40, 0x45, 0x4a, 0x4c, 0x20, 0x20, 0x20,
502 if((ncp
= nAllocPrinter()))
505 if(ncp
->ncp_ReadySigTask
)
507 Signal(ncp
->ncp_ReadySigTask
, 1UL<<ncp
->ncp_ReadySignal
);
511 psdGetAttrs(PGA_INTERFACE
, ncp
->ncp_Interface
, IFA_Config
, &pc
, TAG_END
);
512 psdGetAttrs(PGA_CONFIG
, pc
, CA_ConfigNum
, &confignum
, TAG_END
);
514 psdPipeSetup(ncp
->ncp_EP0Pipe
, URTF_IN
|URTF_CLASS
|URTF_INTERFACE
,
515 UPR_GET_DEVICE_ID
, confignum
-1, (ULONG
) ((ncp
->ncp_UnitIfNum
<<8)|ncp
->ncp_UnitAltIfNum
));
517 ioerr
= psdDoPipe(ncp
->ncp_EP0Pipe
, &len
, 2);
520 psdPipeSetup(ncp
->ncp_EP0Pipe
, URTF_IN
|URTF_CLASS
|URTF_INTERFACE
,
521 UPR_GET_DEVICE_ID
, 0, (ULONG
) (ncp
->ncp_UnitIfNum
<<8));
523 ioerr
= psdDoPipe(ncp
->ncp_EP0Pipe
, &len
, 2);
527 len
= AROS_BE2WORD(len
);
528 if((tmpbuf
= psdAllocVec((ULONG
) len
+1)))
530 ioerr
= psdDoPipe(ncp
->ncp_EP0Pipe
, tmpbuf
, (ULONG
) len
);
534 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
,
535 "Look at this: '%s'", &tmpbuf
[2]);
536 if(!strncmp(&tmpbuf
[2], epsonid
, 9))
541 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) libname
,
542 "GET_DEVICE_ID (len %ld) failed: %s (%ld)",
543 len
, psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
548 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) libname
,
549 "GET_DEVICE_ID (len %ld) failed: %s (%ld)",
550 2, psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
553 if(ncp
->ncp_ClsBase
->nh_CurrentCGC
.cgc_SoftReset
)
555 psdPipeSetup(ncp
->ncp_EP0Pipe
, URTF_CLASS
|URTF_INTERFACE
,
556 UPR_SOFT_RESET
, 0, ((ULONG
) ncp
->ncp_UnitIfNum
)<<8);
557 ioerr
= psdDoPipe(ncp
->ncp_EP0Pipe
, NULL
, 0);
560 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) libname
,
561 "SOFT_RESET(USB1.1) failed: %s (%ld)",
562 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
563 psdPipeSetup(ncp
->ncp_EP0Pipe
, URTF_CLASS
|URTF_OTHER
,
564 UPR_SOFT_RESET
, 0, ((ULONG
) ncp
->ncp_UnitIfNum
)<<8);
565 ioerr
= psdDoPipe(ncp
->ncp_EP0Pipe
, NULL
, 0);
568 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) libname
,
569 "SOFT_RESET(USB1.0) failed: %s (%ld)",
570 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
574 if(epsonmode
&& ncp
->ncp_ClsBase
->nh_CurrentCGC
.cgc_EpsonInit
)
576 psdStreamWrite(ncp
->ncp_EPOutStream
, epsonusbinit
, 27);
577 psdStreamFlush(ncp
->ncp_EPOutStream
);
578 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
, "Inserted special Epson init sequence...");
582 sigmask
= (1UL<<ncp
->ncp_Unit
.unit_MsgPort
.mp_SigBit
)|(1UL<<ncp
->ncp_TaskMsgPort
->mp_SigBit
)|SIGBREAKF_CTRL_C
;
583 if(ncp
->ncp_EPInStream
)
585 struct MsgPort
*tmpmp
= NULL
;
586 psdGetAttrs(PGA_PIPESTREAM
, ncp
->ncp_EPInStream
, PSA_MessagePort
, &tmpmp
, TAG_END
);
589 sigmask
|= (1UL<<tmpmp
->mp_SigBit
);
594 while((ioreq
= (struct IOExtPar
*) GetMsg(&ncp
->ncp_Unit
.unit_MsgPort
)))
596 KPRINTF(5, ("command ioreq: 0x%08lx cmd: %lu len: %ld\n",
597 ioreq
, ioreq
->IOPar
.io_Command
, ioreq
->IOPar
.io_Length
));
598 switch(ioreq
->IOPar
.io_Command
)
601 psdStreamFlush(ncp
->ncp_EPOutStream
);
602 ReplyMsg((struct Message
*) ioreq
);
606 psdStreamFlush(ncp
->ncp_EPOutStream
);
607 if(ncp
->ncp_ClsBase
->nh_CurrentCGC
.cgc_SoftReset
)
609 psdPipeSetup(ncp
->ncp_EP0Pipe
, URTF_CLASS
|URTF_INTERFACE
,
610 UPR_SOFT_RESET
, 0, ((ULONG
) ncp
->ncp_UnitIfNum
)<<8);
611 ioerr
= psdDoPipe(ncp
->ncp_EP0Pipe
, NULL
, 0);
614 psdPipeSetup(ncp
->ncp_EP0Pipe
, URTF_CLASS
|URTF_OTHER
,
615 UPR_SOFT_RESET
, 0, ((ULONG
) ncp
->ncp_UnitIfNum
)<<8);
616 ioerr
= psdDoPipe(ncp
->ncp_EP0Pipe
, NULL
, 0);
620 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) libname
,
621 "SOFT_RESET failed: %s (%ld)",
622 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
623 ioreq
->IOPar
.io_Error
= ParErr_LineErr
;
626 /* Reset does a flush too */
630 ioreq2
= (struct IOExtPar
*) ncp
->ncp_WriteQueue
.lh_Head
;
631 while(ioreq2
->IOPar
.io_Message
.mn_Node
.ln_Succ
)
633 Remove((struct Node
*) ioreq2
);
634 ioreq2
->IOPar
.io_Error
= IOERR_ABORTED
;
635 ReplyMsg((struct Message
*) ioreq2
);
636 ioreq2
= (struct IOExtPar
*) ncp
->ncp_WriteQueue
.lh_Head
;
638 ioreq2
= (struct IOExtPar
*) ncp
->ncp_ReadQueue
.lh_Head
;
639 while(ioreq2
->IOPar
.io_Message
.mn_Node
.ln_Succ
)
641 Remove((struct Node
*) ioreq2
);
642 ioreq2
->IOPar
.io_Error
= IOERR_ABORTED
;
643 ReplyMsg((struct Message
*) ioreq2
);
644 ioreq2
= (struct IOExtPar
*) ncp
->ncp_ReadQueue
.lh_Head
;
646 ReplyMsg((struct Message
*) ioreq
);
651 ioreq
->io_Status
= 0;
652 psdPipeSetup(ncp
->ncp_EP0Pipe
, URTF_CLASS
|URTF_INTERFACE
,
653 UPR_GET_PORT_STATUS
, 0, ((ULONG
) ncp
->ncp_UnitIfNum
)<<8);
654 ioerr
= psdDoPipe(ncp
->ncp_EP0Pipe
, &portstatus
, 1);
657 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) libname
,
658 "GET_PORT_STATUS failed: %s (%ld)",
659 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
660 ioreq
->IOPar
.io_Error
= ParErr_LineErr
;
662 if(portstatus
& 0x10) ioreq
->io_Status
|= IOPTF_PARSEL
;
663 if(portstatus
& 0x20) ioreq
->io_Status
|= IOPTF_PAPEROUT
;
664 ReplyMsg((struct Message
*) ioreq
);
667 /*case PDCMD_SETPARAMS:
668 ReplyMsg((struct Message *) ioreq);
672 ioreq
->IOPar
.io_Error
= IOERR_NOCMD
;
673 ReplyMsg((struct Message
*) ioreq
);
677 if(!ncp
->ncp_DevSuspend
)
680 ioreq
= (struct IOExtPar
*) ncp
->ncp_ReadQueue
.lh_Head
;
681 while(ioreq
->IOPar
.io_Message
.mn_Node
.ln_Succ
)
683 Remove((struct Node
*) ioreq
);
685 ioreq
->IOPar
.io_Actual
= psdStreamRead(ncp
->ncp_EPInStream
, ioreq
->IOPar
.io_Data
, ioreq
->IOPar
.io_Length
);
686 ioerr
= psdGetStreamError(ncp
->ncp_EPInStream
);
687 if(ioerr
== UHIOERR_NAKTIMEOUT
)
690 AddHead(&ncp
->ncp_ReadQueue
, &ioreq
->IOPar
.io_Message
.mn_Node
);
695 ioreq
->IOPar
.io_Error
= ParErr_LineErr
;
697 ioreq
->IOPar
.io_Error
= ioerr
;
699 ReplyMsg((struct Message
*) ioreq
);
702 ioreq
= (struct IOExtPar
*) ncp
->ncp_ReadQueue
.lh_Head
;
704 ioreq
= (struct IOExtPar
*) ncp
->ncp_WriteQueue
.lh_Head
;
705 while(ioreq
->IOPar
.io_Message
.mn_Node
.ln_Succ
)
707 Remove((struct Node
*) ioreq
);
708 ncp
->ncp_WritePending
= ioreq
;
710 ioreq
->IOPar
.io_Actual
= psdStreamWrite(ncp
->ncp_EPOutStream
, ioreq
->IOPar
.io_Data
, ioreq
->IOPar
.io_Length
);
711 ncp
->ncp_WritePending
= NULL
;
712 ioerr
= psdGetStreamError(ncp
->ncp_EPInStream
);
715 ioreq
->IOPar
.io_Error
= ParErr_LineErr
;
717 ioreq
->IOPar
.io_Error
= ioerr
;
719 ReplyMsg((struct Message
*) ioreq
);
721 ioreq
= (struct IOExtPar
*) ncp
->ncp_WriteQueue
.lh_Head
;
725 if(ncp
->ncp_FlushBuffer
)
727 psdStreamFlush(ncp
->ncp_EPOutStream
);
728 ncp
->ncp_FlushBuffer
= FALSE
;
730 sigs
= Wait(sigmask
);
731 } while(!(sigs
& SIGBREAKF_CTRL_C
));
732 /* Now remove all requests still pending *anywhere* */
733 ncp
->ncp_DenyRequests
= TRUE
;
734 /* Current transfers */
735 psdStreamFlush(ncp
->ncp_EPOutStream
);
736 /* Read/Write queues */
738 ioreq
= (struct IOExtPar
*) ncp
->ncp_WriteQueue
.lh_Head
;
739 while(ioreq
->IOPar
.io_Message
.mn_Node
.ln_Succ
)
741 Remove((struct Node
*) ioreq
);
742 ioreq
->IOPar
.io_Error
= IOERR_ABORTED
;
743 ReplyMsg((struct Message
*) ioreq
);
744 ioreq
= (struct IOExtPar
*) ncp
->ncp_WriteQueue
.lh_Head
;
746 ioreq
= (struct IOExtPar
*) ncp
->ncp_ReadQueue
.lh_Head
;
747 while(ioreq
->IOPar
.io_Message
.mn_Node
.ln_Succ
)
749 Remove((struct Node
*) ioreq
);
750 ioreq
->IOPar
.io_Error
= IOERR_ABORTED
;
751 ReplyMsg((struct Message
*) ioreq
);
752 ioreq
= (struct IOExtPar
*) ncp
->ncp_ReadQueue
.lh_Head
;
755 while((ioreq
= (struct IOExtPar
*) GetMsg(&ncp
->ncp_Unit
.unit_MsgPort
)))
757 ioreq
->IOPar
.io_Error
= IOERR_ABORTED
;
758 ReplyMsg((struct Message
*) ioreq
);
761 KPRINTF(20, ("Going down the river!\n"));
769 /* /// "nAllocPrinter()" */
770 struct NepClassPrinter
* nAllocPrinter(void)
772 struct Task
*thistask
;
773 struct NepClassPrinter
*ncp
;
775 thistask
= FindTask(NULL
);
776 ncp
= thistask
->tc_UserData
;
779 if(!(ncp
->ncp_Base
= OpenLibrary("poseidon.library", 4)))
784 ncp
->ncp_EPIn
= psdFindEndpoint(ncp
->ncp_Interface
, NULL
,
786 EA_TransferType
, USEAF_BULK
,
788 ncp
->ncp_EPOut
= psdFindEndpoint(ncp
->ncp_Interface
, NULL
,
790 EA_TransferType
, USEAF_BULK
,
794 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) libname
, "OUT endpoint missing!");
798 ncp
->ncp_Unit
.unit_MsgPort
.mp_SigBit
= AllocSignal(-1);
799 ncp
->ncp_Unit
.unit_MsgPort
.mp_SigTask
= thistask
;
800 ncp
->ncp_Unit
.unit_MsgPort
.mp_Node
.ln_Type
= NT_MSGPORT
;
801 ncp
->ncp_Unit
.unit_MsgPort
.mp_Flags
= PA_SIGNAL
;
802 if((ncp
->ncp_TaskMsgPort
= CreateMsgPort()))
804 if((ncp
->ncp_EP0Pipe
= psdAllocPipe(ncp
->ncp_Device
, ncp
->ncp_TaskMsgPort
, NULL
)))
806 psdSetAttrs(PGA_PIPE
, ncp
->ncp_EP0Pipe
,
807 PPA_NakTimeout
, TRUE
,
808 PPA_NakTimeoutTime
, 5000,
810 ncp
->ncp_AbortSignal
= AllocSignal(-1);
811 if((ncp
->ncp_EPOutStream
= psdOpenStream(ncp
->ncp_EPOut
,
812 PSA_BufferSize
, 1024,
813 PSA_BufferedWrite
, TRUE
,
814 PSA_AbortSigMask
, 1UL<<ncp
->ncp_AbortSignal
,
817 /* EPIn is only optional! */
820 ncp
->ncp_Task
= thistask
;
823 if((ncp
->ncp_EPInStream
= psdOpenStream(ncp
->ncp_EPIn
,
824 PSA_BufferSize
, 1024,
825 PSA_ReadAhead
, FALSE
,
826 PSA_BufferedRead
, TRUE
,
827 PSA_ShortPktTerm
, TRUE
,
828 PSA_NakTimeout
, TRUE
,
829 PSA_NakTimeoutTime
, 1000,
832 ncp
->ncp_Task
= thistask
;
835 psdCloseStream(ncp
->ncp_EPOutStream
);
837 FreeSignal(ncp
->ncp_AbortSignal
);
838 psdFreePipe(ncp
->ncp_EP0Pipe
);
840 DeleteMsgPort(ncp
->ncp_TaskMsgPort
);
842 FreeSignal((LONG
) ncp
->ncp_Unit
.unit_MsgPort
.mp_SigBit
);
844 CloseLibrary(ncp
->ncp_Base
);
846 ncp
->ncp_Task
= NULL
;
847 if(ncp
->ncp_ReadySigTask
)
849 Signal(ncp
->ncp_ReadySigTask
, 1UL<<ncp
->ncp_ReadySignal
);
855 /* /// "nFreePrinter()" */
856 void nFreePrinter(struct NepClassPrinter
*ncp
)
858 struct IOStdReq
*ioreq
;
860 FreeSignal(ncp
->ncp_AbortSignal
);
861 ncp
->ncp_AbortSignal
= -1;
862 /* Disable the message port, messages may still be queued */
863 ncp
->ncp_Unit
.unit_MsgPort
.mp_SigTask
= NULL
;
864 ncp
->ncp_Unit
.unit_MsgPort
.mp_Flags
= PA_IGNORE
;
865 FreeSignal((LONG
) ncp
->ncp_Unit
.unit_MsgPort
.mp_SigBit
);
866 // get rid of all messages that still have appeared here
867 while((ioreq
= (struct IOStdReq
*) GetMsg(&ncp
->ncp_Unit
.unit_MsgPort
)))
869 ioreq
->io_Error
= IOERR_ABORTED
;
870 ReplyMsg((struct Message
*) ioreq
);
874 if(ncp
->ncp_EPInStream
)
876 psdCloseStream(ncp
->ncp_EPInStream
);
877 ncp
->ncp_EPInStream
= NULL
;
879 psdCloseStream(ncp
->ncp_EPOutStream
);
880 psdFreePipe(ncp
->ncp_EP0Pipe
);
881 DeleteMsgPort(ncp
->ncp_TaskMsgPort
);
882 CloseLibrary(ncp
->ncp_Base
);
884 ncp
->ncp_Task
= NULL
;
885 if(ncp
->ncp_ReadySigTask
)
887 Signal(ncp
->ncp_ReadySigTask
, 1UL<<ncp
->ncp_ReadySignal
);
892 /**************************************************************************/
894 /* /// "nGUITask()" */
895 AROS_UFH0(void, nGUITask
)
899 struct Task
*thistask
;
900 struct NepPrinterBase
*nh
;
903 thistask
= FindTask(NULL
);
905 #define ps nh->nh_PsdBase
907 #define IntuitionBase nh->nh_IntBase
909 #define MUIMasterBase nh->nh_MUIBase
911 nh
= thistask
->tc_UserData
;
912 ++nh
->nh_Library
.lib_OpenCnt
;
913 if(!(MUIMasterBase
= OpenLibrary(MUIMASTER_NAME
, MUIMASTER_VMIN
)))
915 KPRINTF(10, ("Couldn't open muimaster.library.\n"));
920 if(!(IntuitionBase
= OpenLibrary("intuition.library", 39)))
922 KPRINTF(10, ("Couldn't open intuition.library.\n"));
926 if(!(ps
= OpenLibrary("poseidon.library", 4)))
928 KPRINTF(10, ("Couldn't open poseidon.library.\n"));
933 nh
->nh_App
= ApplicationObject
,
934 MUIA_Application_Title
, (IPTR
)libname
,
935 MUIA_Application_Version
, (IPTR
)VERSION_STRING
,
936 MUIA_Application_Copyright
, (IPTR
)"©2002-2009 Chris Hodges",
937 MUIA_Application_Author
, (IPTR
)"Chris Hodges <chrisly@platon42.de>",
938 MUIA_Application_Description
, (IPTR
)"Settings for the printer.class",
939 MUIA_Application_Base
, (IPTR
)"PRINTER",
940 MUIA_Application_HelpFile
, (IPTR
)"HELP:Poseidon.guide",
941 MUIA_Application_Menustrip
, (IPTR
)MenustripObject
,
942 Child
, (IPTR
)MenuObjectT((IPTR
)"Project"),
943 Child
, (IPTR
)(nh
->nh_AboutMI
= MenuitemObject
,
944 MUIA_Menuitem_Title
, (IPTR
)"About...",
945 MUIA_Menuitem_Shortcut
, (IPTR
)"?",
948 Child
, (IPTR
)MenuObjectT((IPTR
)"Settings"),
949 Child
, (IPTR
)(nh
->nh_UseMI
= MenuitemObject
,
950 MUIA_Menuitem_Title
, (IPTR
)"Save",
951 MUIA_Menuitem_Shortcut
, (IPTR
)"S",
953 Child
, (IPTR
)MenuitemObject
,
954 MUIA_Menuitem_Title
, (IPTR
)NM_BARLABEL
,
956 Child
, (IPTR
)(nh
->nh_MUIPrefsMI
= MenuitemObject
,
957 MUIA_Menuitem_Title
, (IPTR
)"MUI Settings",
958 MUIA_Menuitem_Shortcut
, (IPTR
)"M",
963 SubWindow
, (IPTR
)(nh
->nh_MainWindow
= WindowObject
,
964 MUIA_Window_ID
, MAKE_ID('M','A','I','N'),
965 MUIA_Window_Title
, (IPTR
)libname
,
966 MUIA_HelpNode
, (IPTR
)libname
,
968 WindowContents
, (IPTR
)VGroup
,
969 /* Child, actionobj = NewObject(ActionClass->mcc_Class, 0,
972 Child
, (IPTR
)ColGroup(2), GroupFrameT((IPTR
) "Global Settings"),
973 Child
, (IPTR
)Label((IPTR
) "Epson Init Sequence:"),
975 Child
, (IPTR
)(nh
->nh_EpsonInitObj
= ImageObject
, ImageButtonFrame
,
976 MUIA_Background
, MUII_ButtonBack
,
978 MUIA_InputMode
, MUIV_InputMode_Toggle
,
979 MUIA_Image_Spec
, MUII_CheckMark
,
980 MUIA_Image_FreeVert
, TRUE
,
981 MUIA_Selected
, nh
->nh_CurrentCGC
.cgc_EpsonInit
,
982 MUIA_ShowSelState
, FALSE
,
984 Child
, (IPTR
)HSpace(0),
986 Child
, (IPTR
)Label((IPTR
) "Enable SoftReset:"),
988 Child
, (IPTR
)(nh
->nh_SoftResetObj
= ImageObject
, ImageButtonFrame
,
989 MUIA_Background
, MUII_ButtonBack
,
991 MUIA_InputMode
, MUIV_InputMode_Toggle
,
992 MUIA_Image_Spec
, MUII_CheckMark
,
993 MUIA_Image_FreeVert
, TRUE
,
994 MUIA_Selected
, nh
->nh_CurrentCGC
.cgc_SoftReset
,
995 MUIA_ShowSelState
, FALSE
,
997 Child
, (IPTR
)HSpace(0),
1000 Child
, (IPTR
)VSpace(0),
1001 Child
, (IPTR
)HGroup
,
1002 MUIA_Group_SameWidth
, TRUE
,
1003 Child
, (IPTR
)(nh
->nh_UseObj
= TextObject
, ButtonFrame
,
1004 MUIA_Background
, MUII_ButtonBack
,
1006 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
1007 MUIA_Text_Contents
, (IPTR
)"\33c Save ",
1009 Child
, (IPTR
)(nh
->nh_CloseObj
= TextObject
, ButtonFrame
,
1010 MUIA_Background
, MUII_ButtonBack
,
1012 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
1013 MUIA_Text_Contents
, (IPTR
)"\33c Use ",
1022 KPRINTF(10, ("Couldn't create application\n"));
1023 nGUITaskCleanup(nh
);
1026 DoMethod(nh
->nh_MainWindow
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
,
1027 nh
->nh_App
, 2, MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
1028 DoMethod(nh
->nh_UseObj
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
1029 nh
->nh_App
, 2, MUIM_Application_ReturnID
, ID_STORE_CONFIG
);
1030 DoMethod(nh
->nh_CloseObj
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
1031 nh
->nh_App
, 2, MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
1033 DoMethod(nh
->nh_AboutMI
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
1034 nh
->nh_App
, 2, MUIM_Application_ReturnID
, ID_ABOUT
);
1035 DoMethod(nh
->nh_UseMI
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
1036 nh
->nh_App
, 2, MUIM_Application_ReturnID
, ID_STORE_CONFIG
);
1037 DoMethod(nh
->nh_MUIPrefsMI
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
1038 nh
->nh_App
, 2, MUIM_Application_OpenConfigWindow
, 0);
1047 get(nh
->nh_App
, MUIA_Application_Iconified
, &iconify
);
1048 set(nh
->nh_MainWindow
, MUIA_Window_Open
, TRUE
);
1049 get(nh
->nh_MainWindow
, MUIA_Window_Open
, &isopen
);
1050 if(!(isopen
|| iconify
))
1052 nGUITaskCleanup(nh
);
1058 retid
= DoMethod(nh
->nh_App
, MUIM_Application_NewInput
, &sigs
);
1061 case ID_STORE_CONFIG
:
1062 case MUIV_Application_ReturnID_Quit
:
1063 get(nh
->nh_EpsonInitObj
, MUIA_Selected
, &nh
->nh_CurrentCGC
.cgc_EpsonInit
);
1064 get(nh
->nh_SoftResetObj
, MUIA_Selected
, &nh
->nh_CurrentCGC
.cgc_SoftReset
);
1065 pic
= psdGetClsCfg(libname
);
1068 psdSetClsCfg(libname
, NULL
);
1069 pic
= psdGetClsCfg(libname
);
1073 if(psdAddCfgEntry(pic
, &nh
->nh_CurrentCGC
))
1075 if(retid
!= MUIV_Application_ReturnID_Quit
)
1077 psdSaveCfgToDisk(NULL
, FALSE
);
1079 retid
= MUIV_Application_ReturnID_Quit
;
1085 MUI_RequestA(nh
->nh_App
, nh
->nh_MainWindow
, 0, NULL
, "I'm utterly squished!", VERSION_STRING
, NULL
);
1088 if(retid
== MUIV_Application_ReturnID_Quit
)
1094 sigs
= Wait(sigs
| sigmask
| SIGBREAKF_CTRL_C
);
1095 if(sigs
& SIGBREAKF_CTRL_C
)
1101 set(nh
->nh_MainWindow
, MUIA_Window_Open
, FALSE
);
1103 nGUITaskCleanup(nh
);
1109 /* /// "nGUITaskCleanup()" */
1110 void nGUITaskCleanup(struct NepPrinterBase
*nh
)
1114 MUI_DisposeObject(nh
->nh_App
);
1119 CloseLibrary(MUIMasterBase
);
1120 MUIMasterBase
= NULL
;
1124 CloseLibrary(IntuitionBase
);
1125 IntuitionBase
= NULL
;
1133 nh
->nh_GUITask
= NULL
;
1134 --nh
->nh_Library
.lib_OpenCnt
;