Documented GVF_SAVE_VAR alongside other flags, and removed a query/doubt
[AROS.git] / rom / usb / classes / rawwrap / rawwrap.class.c
blob2b584f16ac5d349686f166f11f2051965bb29677
1 /*
2 *----------------------------------------------------------------------------
3 * rawwrap class for poseidon
4 *----------------------------------------------------------------------------
5 * By Chris Hodges <chrisly@platon42.de>
6 */
8 #include "debug.h"
10 #include "rawwrap.class.h"
12 /* /// "Lib Stuff" */
13 static const STRPTR libname = MOD_NAME_STRING;
15 static
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),
24 (APTR) -1,
27 static int libInit(LIBBASETYPEPTR nh)
29 struct NepClassRawWrap *ncp;
30 struct NepRawWrapBase *ret = NULL;
32 KPRINTF(10, ("libInit nh: 0x%08lx SysBase: 0x%08lx\n", nh, SysBase));
34 nh->nh_UtilityBase = OpenLibrary("utility.library", 39);
36 #define UtilityBase nh->nh_UtilityBase
38 if(UtilityBase)
40 NewList(&nh->nh_Units);
42 if((nh->nh_DevBase = (struct NepRawDevBase *) MakeLibrary((APTR) DevFuncTable, NULL, (APTR) devInit,
43 sizeof(struct NepRawDevBase), NULL)))
45 ncp = &nh->nh_DummyNCP;
46 ncp->ncp_ClsBase = nh;
47 ncp->ncp_Interface = NULL;
48 ncp->ncp_CDC = AllocVec(sizeof(struct ClsDevCfg), MEMF_PUBLIC|MEMF_CLEAR);
49 if(ncp->ncp_CDC)
51 nh->nh_DevBase->np_ClsBase = nh;
52 Forbid();
53 AddDevice((struct Device *) nh->nh_DevBase);
54 nh->nh_DevBase->np_Library.lib_OpenCnt++;
55 Permit();
56 ret = nh;
58 } else {
59 KPRINTF(20, ("failed to create usbparallel.device\n"));
61 if(!ret)
63 CloseLibrary(UtilityBase);
65 } else {
66 KPRINTF(20, ("libInit: OpenLibrary(\"utility.library\", 39) failed!\n"));
69 KPRINTF(10, ("libInit: Ok\n"));
70 return(ret ? TRUE : FALSE);
73 static int libOpen(LIBBASETYPEPTR nh)
75 KPRINTF(10, ("libOpen nh: 0x%08lx\n", nh));
76 nLoadClassConfig(nh);
78 return(TRUE);
81 static int libExpunge(LIBBASETYPEPTR nh)
83 struct NepClassRawWrap *ncp;
85 KPRINTF(10, ("libExpunge nh: 0x%08lx\n", nh));
87 if(nh->nh_DevBase->np_Library.lib_OpenCnt == 1)
89 KPRINTF(1, ("libExpunge: closelibrary utilitybase 0x%08lx\n",
90 UtilityBase));
91 CloseLibrary((struct Library *) UtilityBase);
93 ncp = (struct NepClassRawWrap *) nh->nh_Units.lh_Head;
94 while(ncp->ncp_Unit.unit_MsgPort.mp_Node.ln_Succ)
96 Remove((struct Node *) ncp);
97 FreeVec(ncp->ncp_CDC);
98 FreeVec(ncp);
99 ncp = (struct NepClassRawWrap *) nh->nh_Units.lh_Head;
102 nh->nh_DevBase->np_Library.lib_OpenCnt--;
103 RemDevice((struct Device *) nh->nh_DevBase);
105 KPRINTF(5, ("libExpunge: Unloading done! rawwrap.class expunged!\n\n"));
106 } else {
107 KPRINTF(5, ("libExpunge: Could not expunge, LIBF_DELEXP set!\n"));
108 return(FALSE);
111 return(TRUE);
114 ADD2INITLIB(libInit, 0)
115 ADD2OPENLIB(libOpen, 0)
116 ADD2EXPUNGELIB(libExpunge, 0)
117 /* \\\ */
120 * ***********************************************************************
121 * * Library functions *
122 * ***********************************************************************
125 /* /// "usbAttemptInterfaceBinding()" */
126 struct NepClassRawWrap * usbAttemptInterfaceBinding(struct NepRawWrapBase *nh, struct PsdInterface *pif)
128 struct Library *ps;
129 struct ClsGlobalCfg *cgc;
130 IPTR ifclass;
131 IPTR subclass;
132 IPTR proto;
134 KPRINTF(1, ("nepRawWrapAttemptInterfaceBinding(%08lx)\n", pif));
135 if((ps = OpenLibrary("poseidon.library", 4)))
137 cgc = &nh->nh_CurrentCGC;
139 psdGetAttrs(PGA_INTERFACE, pif,
140 IFA_Class, &ifclass,
141 IFA_SubClass, &subclass,
142 IFA_Protocol, &proto,
143 TAG_DONE);
144 CloseLibrary(ps);
145 if(cgc->cgc_BindAll)
147 return(usbForceInterfaceBinding(nh, pif));
149 if(cgc->cgc_BindVendor && ((ifclass == 0xff) || (ifclass == 0)))
151 return(usbForceInterfaceBinding(nh, pif));
154 return(NULL);
156 /* \\\ */
158 /* /// "usbForceInterfaceBinding()" */
159 struct NepClassRawWrap * usbForceInterfaceBinding(struct NepRawWrapBase *nh, struct PsdInterface *pif)
161 struct Library *ps;
162 struct NepClassRawWrap *ncp;
163 struct NepClassRawWrap *tmpncp;
164 struct PsdConfig *pc;
165 struct PsdDevice *pd;
166 struct ClsDevCfg *cdc;
167 STRPTR devname;
168 STRPTR ifidstr;
169 STRPTR devidstr;
170 IPTR altifnum;
171 IPTR ifnum;
172 IPTR cfgnum;
173 IPTR prodid;
174 IPTR vendid;
175 ULONG unitno;
176 BOOL unitfound;
177 UBYTE buf[64];
178 struct Task *tmptask;
180 KPRINTF(1, ("nepRawWrapAttemptInterfaceBinding(%08lx)\n", pif));
181 if((ps = OpenLibrary("poseidon.library", 4)))
183 psdGetAttrs(PGA_INTERFACE, pif,
184 IFA_InterfaceNum, &ifnum,
185 IFA_AlternateNum, &altifnum,
186 IFA_IDString, &ifidstr,
187 IFA_Config, &pc,
188 TAG_DONE);
189 psdGetAttrs(PGA_CONFIG, pc,
190 CA_Device, &pd,
191 CA_ConfigNum, &cfgnum,
192 TAG_END);
193 psdGetAttrs(PGA_DEVICE, pd,
194 DA_ProductID, &prodid,
195 DA_VendorID, &vendid,
196 DA_ProductName, &devname,
197 DA_IDString, &devidstr,
198 TAG_END);
199 Forbid();
200 unitfound = FALSE;
201 unitno = (ULONG) -1;
202 ncp = (struct NepClassRawWrap *) nh->nh_Units.lh_Head;
203 while(ncp->ncp_Unit.unit_MsgPort.mp_Node.ln_Succ)
205 if((ncp->ncp_UnitAltIfNum == altifnum) && (ncp->ncp_UnitIfNum == ifnum) &&
206 (ncp->ncp_UnitProdID == prodid) && (ncp->ncp_UnitVendorID == vendid))
208 unitno = ncp->ncp_UnitNo;
209 unitfound = TRUE;
210 break;
212 ncp = (struct NepClassRawWrap *) ncp->ncp_Unit.unit_MsgPort.mp_Node.ln_Succ;
214 if(!unitfound)
216 /* as units are freed in the expunge-vector, the memory is
217 outside the scope of the poseidon library */
218 if(!(ncp = AllocVec(sizeof(struct NepClassRawWrap), MEMF_PUBLIC|MEMF_CLEAR)))
220 Permit();
221 CloseLibrary(ps);
222 return(NULL);
224 ncp->ncp_CDC = cdc = AllocVec(sizeof(struct ClsDevCfg), MEMF_PUBLIC|MEMF_CLEAR);
225 if(!cdc)
227 Permit();
228 FreeVec(ncp);
229 CloseLibrary(ps);
230 return(NULL);
232 /* IORequests may be queued even if the task is gone. */
233 ncp->ncp_UnitNo = (ULONG) -1;
234 NewList(&ncp->ncp_Unit.unit_MsgPort.mp_MsgList);
235 NewList(&ncp->ncp_ReadQueue);
236 NewList(&ncp->ncp_WriteQueue);
237 AddTail(&nh->nh_Units, &ncp->ncp_Unit.unit_MsgPort.mp_Node);
239 ncp->ncp_ClsBase = nh;
240 ncp->ncp_Interface = pif;
241 ncp->ncp_Device = pd;
242 ncp->ncp_Config = pc;
243 ncp->ncp_UnitAltIfNum = altifnum;
244 ncp->ncp_UnitIfNum = ifnum;
245 ncp->ncp_UnitCfgNum = cfgnum;
246 ncp->ncp_UnitProdID = prodid;
247 ncp->ncp_UnitVendorID = vendid;
248 ncp->ncp_DevIDString = devidstr;
249 ncp->ncp_IfIDString = ifidstr;
251 if(!nLoadBindingConfig(ncp))
253 /* felix' defaults for epson scanners */
254 if(vendid == 0x04b8)
256 switch(prodid)
258 case 0x0101: // EPSON Perfection 636U and 636 Photo
259 case 0x0103: // EPSON Perfection 610
260 case 0x0104: // EPSON Perfection 1200U and 1200 Photo
261 case 0x0106: // EPSON Stylus Scan 2500
262 case 0x0107: // EPSON Expression 1600
263 case 0x010a: // EPSON Perfection 1640 SU and 1640 SU Photo
264 case 0x010b: // EPSON Perfection 1240 U
265 case 0x010c: // EPSON Perfection 640 U
266 case 0x010e: // EPSON Perfection 1680
267 case 0x0110: // EPSON Perfection 1650
268 case 0x011e: // EPSON Perfection 1660 (NEW IN V1.2!!)
269 case 0x011b: // EPSON Perfection 2400 (NEW IN V1.2!!)
270 case 0x0112: // EPSON Perfection 2450 - GT-9700 for the Japanese market
271 cdc = ncp->ncp_CDC;
272 cdc->cdc_InNakTimeout = 200;
273 cdc->cdc_OutNakTimeout = 200;
274 cdc->cdc_InBufferMode = BUFMODE_NO;
275 cdc->cdc_InBufferSize = 1;
276 cdc->cdc_ShortReadTerm = TRUE;
277 cdc->cdc_UnitExclusive = FALSE;
278 break;
283 /* Find next free unit number */
284 if(unitno == (ULONG) -1)
286 unitno = ncp->ncp_CDC->cdc_DefaultUnit;
287 tmpncp = (struct NepClassRawWrap *) nh->nh_Units.lh_Head;
288 while(tmpncp->ncp_Unit.unit_MsgPort.mp_Node.ln_Succ)
290 if(tmpncp->ncp_UnitNo == unitno)
292 unitno++;
293 tmpncp = (struct NepClassRawWrap *) nh->nh_Units.lh_Head;
294 } else {
295 tmpncp = (struct NepClassRawWrap *) tmpncp->ncp_Unit.unit_MsgPort.mp_Node.ln_Succ;
299 ncp->ncp_UnitNo = unitno;
300 Permit();
302 psdSafeRawDoFmt(buf, 64, "rawwrap.class<%08lx>", ncp);
303 ncp->ncp_ReadySignal = SIGB_SINGLE;
304 ncp->ncp_ReadySigTask = FindTask(NULL);
305 SetSignal(0, SIGF_SINGLE);
306 if((tmptask = psdSpawnSubTask(buf, nRawWrapTask, ncp)))
308 psdBorrowLocksWait(tmptask, 1UL<<ncp->ncp_ReadySignal);
309 if(ncp->ncp_Task)
311 ncp->ncp_ReadySigTask = NULL;
312 //FreeSignal(ncp->ncp_ReadySignal);
313 psdAddErrorMsg(RETURN_OK, (STRPTR) libname,
314 "Bold and raw dude '%s' fixed to %s unit %ld!",
315 devname, nh->nh_DevBase->np_Library.lib_Node.ln_Name,
316 ncp->ncp_UnitNo);
318 CloseLibrary(ps);
319 return(ncp);
322 ncp->ncp_ReadySigTask = NULL;
323 //FreeSignal(ncp->ncp_ReadySignal);
324 /* Get rid of unit structure */
325 /*Forbid();
326 Remove((struct Node *) ncp);
327 FreeVec(ncp->ncp_CDC);
328 FreeVec(ncp);
329 Permit();*/
330 CloseLibrary(ps);
332 return(NULL);
334 /* \\\ */
336 /* /// "usbReleaseInterfaceBinding()" */
337 void usbReleaseInterfaceBinding(struct NepRawWrapBase *nh, struct NepClassRawWrap *ncp)
339 struct Library *ps;
340 STRPTR devname;
342 KPRINTF(1, ("nepRawWrapReleaseInterfaceBinding(%08lx)\n", ncp));
343 if((ps = OpenLibrary("poseidon.library", 4)))
345 Forbid();
346 ncp->ncp_ReadySignal = SIGB_SINGLE;
347 ncp->ncp_ReadySigTask = FindTask(NULL);
348 if(ncp->ncp_Task)
350 Signal(ncp->ncp_Task, SIGBREAKF_CTRL_C);
352 Permit();
353 while(ncp->ncp_Task)
355 Wait(1L<<ncp->ncp_ReadySignal);
357 //FreeSignal(ncp->ncp_ReadySignal);
358 psdGetAttrs(PGA_DEVICE, ncp->ncp_Device, DA_ProductName, &devname, TAG_END);
359 psdAddErrorMsg(RETURN_OK, (STRPTR) libname,
360 "'%s' was wrapped into a bodybag.",
361 devname);
362 /*psdFreeVec(ncp);*/
363 CloseLibrary(ps);
366 /* \\\ */
368 /* /// "usbGetAttrsA()" */
369 AROS_LH3(LONG, usbGetAttrsA,
370 AROS_LHA(ULONG, type, D0),
371 AROS_LHA(APTR, usbstruct, A0),
372 AROS_LHA(struct TagItem *, tags, A1),
373 LIBBASETYPEPTR, nh, 5, nep)
375 AROS_LIBFUNC_INIT
377 struct TagItem *ti;
378 LONG count = 0;
380 KPRINTF(1, ("nepRawWrapGetAttrsA(%ld, %08lx, %08lx)\n", type, usbstruct, tags));
381 switch(type)
383 case UGA_CLASS:
384 if((ti = FindTagItem(UCCA_Priority, tags)))
386 *((SIPTR *) ti->ti_Data) = -110;
387 count++;
389 if((ti = FindTagItem(UCCA_Description, tags)))
391 *((STRPTR *) ti->ti_Data) = "Simple USB bulk IO wrapper via usbraw.device";
392 count++;
394 if((ti = FindTagItem(UCCA_HasClassCfgGUI, tags)))
396 *((IPTR *) ti->ti_Data) = TRUE;
397 count++;
399 if((ti = FindTagItem(UCCA_HasBindingCfgGUI, tags)))
401 *((IPTR *) ti->ti_Data) = TRUE;
402 count++;
404 if((ti = FindTagItem(UCCA_AfterDOSRestart, tags)))
406 *((IPTR *) ti->ti_Data) = FALSE;
407 count++;
409 if((ti = FindTagItem(UCCA_UsingDefaultCfg, tags)))
411 *((IPTR *) ti->ti_Data) = nh->nh_DummyNCP.ncp_UsingDefaultCfg;
412 count++;
414 break;
416 case UGA_BINDING:
417 if((ti = FindTagItem(UCBA_UsingDefaultCfg, tags)))
419 *((IPTR *) ti->ti_Data) = ((struct NepClassRawWrap *) usbstruct)->ncp_UsingDefaultCfg;
420 count++;
422 break;
424 return(count);
425 AROS_LIBFUNC_EXIT
427 /* \\\ */
429 /* /// "usbSetAttrsA()" */
430 AROS_LH3(LONG, usbSetAttrsA,
431 AROS_LHA(ULONG, type, D0),
432 AROS_LHA(APTR, usbstruct, A0),
433 AROS_LHA(struct TagItem *, tags, A1),
434 LIBBASETYPEPTR, nh, 6, nep)
436 AROS_LIBFUNC_INIT
437 return(0);
438 AROS_LIBFUNC_EXIT
440 /* \\\ */
442 /* /// "usbDoMethodA()" */
443 AROS_LH2(IPTR, usbDoMethodA,
444 AROS_LHA(ULONG, methodid, D0),
445 AROS_LHA(IPTR *, methoddata, A1),
446 LIBBASETYPEPTR, nh, 7, nep)
448 AROS_LIBFUNC_INIT
450 struct NepClassRawWrap *ncp;
452 KPRINTF(10, ("Do Method %ld\n", methodid));
453 switch(methodid)
455 case UCM_AttemptInterfaceBinding:
456 return((IPTR) usbAttemptInterfaceBinding(nh, (struct PsdInterface *) methoddata[0]));
458 case UCM_ForceInterfaceBinding:
459 return((IPTR) usbForceInterfaceBinding(nh, (struct PsdInterface *) methoddata[0]));
461 case UCM_ReleaseInterfaceBinding:
462 usbReleaseInterfaceBinding(nh, (struct NepClassRawWrap *) methoddata[0]);
463 return(TRUE);
465 case UCM_OpenCfgWindow:
466 return(nOpenBindingCfgWindow(nh, &nh->nh_DummyNCP));
468 case UCM_OpenBindingCfgWindow:
469 return(nOpenBindingCfgWindow(nh, (struct NepClassRawWrap *) methoddata[0]));
471 case UCM_ConfigChangedEvent:
472 nLoadClassConfig(nh);
473 Forbid();
474 ncp = (struct NepClassRawWrap *) nh->nh_Units.lh_Head;
475 while(ncp->ncp_Unit.unit_MsgPort.mp_Node.ln_Succ)
477 nLoadBindingConfig(ncp);
478 ncp = (struct NepClassRawWrap *) ncp->ncp_Unit.unit_MsgPort.mp_Node.ln_Succ;
480 Permit();
481 return(TRUE);
483 default:
484 break;
486 return(0);
487 AROS_LIBFUNC_EXIT
489 /* \\\ */
491 /* /// "nLoadClassConfig()" */
492 BOOL nLoadClassConfig(struct NepRawWrapBase *nh)
494 struct NepClassRawWrap *ncp = &nh->nh_DummyNCP;
495 struct Library *ps;
496 struct ClsDevCfg *cdc;
497 struct ClsGlobalCfg *cgc;
498 struct PsdIFFContext *pic;
500 KPRINTF(10, ("Loading Class Config...\n"));
501 if(ncp->ncp_GUITask)
503 return(FALSE);
505 if(!(ps = OpenLibrary("poseidon.library", 4)))
507 return(FALSE);
510 Forbid();
511 /* Create global config */
512 nh->nh_CurrentCGC.cgc_ChunkID = AROS_LONG2BE(MAKE_ID('R','W','R','G'));
513 nh->nh_CurrentCGC.cgc_Length = AROS_LONG2BE(sizeof(struct ClsGlobalCfg)-8);
514 nh->nh_CurrentCGC.cgc_BindVendor = FALSE;
515 nh->nh_CurrentCGC.cgc_BindAll = FALSE;
516 /* Create default config */
517 cdc = ncp->ncp_CDC;
518 cdc->cdc_ChunkID = AROS_LONG2BE(MAKE_ID('R','W','R','P'));
519 cdc->cdc_Length = AROS_LONG2BE(sizeof(struct ClsDevCfg)-8);
520 cdc->cdc_InNakTimeout = 300;
521 cdc->cdc_OutNakTimeout = 300;
522 cdc->cdc_InBufferMode = BUFMODE_READONREQ;
523 cdc->cdc_InBufferSize = 2;
524 cdc->cdc_ShortReadTerm = TRUE;
525 cdc->cdc_DefaultUnit = 0;
526 cdc->cdc_UnitExclusive = FALSE;
527 ncp->ncp_UsingDefaultCfg = TRUE;
528 /* try to load default config */
529 pic = psdGetClsCfg(libname);
530 if(pic)
532 cdc = psdGetCfgChunk(pic, AROS_LONG2BE(ncp->ncp_CDC->cdc_ChunkID));
533 if(cdc)
535 CopyMem(((UBYTE *) cdc) + 8, ((UBYTE *) ncp->ncp_CDC) + 8, min(AROS_LONG2BE(cdc->cdc_Length), AROS_LONG2BE(ncp->ncp_CDC->cdc_Length)));
536 psdFreeVec(cdc);
537 ncp->ncp_UsingDefaultCfg = FALSE;
539 cgc = psdGetCfgChunk(pic, AROS_LONG2BE(nh->nh_CurrentCGC.cgc_ChunkID));
540 if(cgc)
542 CopyMem(((UBYTE *) cgc) + 8, ((UBYTE *) &nh->nh_CurrentCGC) + 8, min(AROS_LONG2BE(cgc->cgc_Length), AROS_LONG2BE(nh->nh_CurrentCGC.cgc_Length)));
543 psdFreeVec(cgc);
544 ncp->ncp_UsingDefaultCfg = FALSE;
547 Permit();
548 CloseLibrary(ps);
549 return(FALSE);
551 /* \\\ */
553 /* /// "nLoadBindingConfig()" */
554 BOOL nLoadBindingConfig(struct NepClassRawWrap *ncp)
556 struct NepRawWrapBase *nh = ncp->ncp_ClsBase;
557 struct Library *ps;
558 struct ClsDevCfg *cdc;
559 struct PsdIFFContext *pic;
561 KPRINTF(10, ("Loading Binding Config...\n"));
562 if(ncp->ncp_GUITask)
564 return(FALSE);
566 //nLoadClassConfig(nh);
567 *ncp->ncp_CDC = *nh->nh_DummyNCP.ncp_CDC;
568 ncp->ncp_UsingDefaultCfg = TRUE;
570 if(!(ps = OpenLibrary("poseidon.library", 4)))
572 return(FALSE);
575 Forbid();
576 /* Load config */
577 pic = psdGetUsbDevCfg(libname, ncp->ncp_DevIDString, ncp->ncp_IfIDString);
578 if(pic)
580 cdc = psdGetCfgChunk(pic, AROS_LONG2BE(ncp->ncp_CDC->cdc_ChunkID));
581 if(cdc)
583 CopyMem(((UBYTE *) cdc) + 8, ((UBYTE *) ncp->ncp_CDC) + 8, min(AROS_LONG2BE(cdc->cdc_Length), AROS_LONG2BE(ncp->ncp_CDC->cdc_Length)));
584 psdFreeVec(cdc);
585 ncp->ncp_UsingDefaultCfg = FALSE;
588 Permit();
589 CloseLibrary(ps);
590 return(FALSE);
592 /* \\\ */
594 /* /// "nOpenBindingCfgWindow()" */
595 LONG nOpenBindingCfgWindow(struct NepRawWrapBase *nh, struct NepClassRawWrap *ncp)
597 struct Library *ps;
598 KPRINTF(10, ("Opening GUI...\n"));
599 if(!(ps = OpenLibrary("poseidon.library", 4)))
601 return(FALSE);
603 Forbid();
604 if(!ncp->ncp_GUITask)
606 if((ncp->ncp_GUITask = psdSpawnSubTask(MOD_NAME_STRING " GUI", nGUITask, ncp)))
608 Permit();
609 CloseLibrary(ps);
610 return(TRUE);
613 Permit();
614 CloseLibrary(ps);
615 return(FALSE);
617 /* \\\ */
619 /**************************************************************************/
621 #undef ps
622 #define ps ncp->ncp_Base
624 /* /// "nRawWrapTask()" */
625 AROS_UFH0(void, nRawWrapTask)
627 AROS_USERFUNC_INIT
629 struct NepClassRawWrap *ncp;
630 struct PsdPipe *pp;
631 ULONG sigmask;
632 ULONG sigs;
633 LONG ioerr;
634 ULONG len;
635 struct IOStdReq *ioreq;
636 struct IOStdReq *ioreq2;
638 if((ncp = nAllocRawWrap()))
640 Forbid();
641 if(ncp->ncp_ReadySigTask)
643 Signal(ncp->ncp_ReadySigTask, 1L<<ncp->ncp_ReadySignal);
645 Permit();
647 /* Main task */
648 sigmask = (1L<<ncp->ncp_Unit.unit_MsgPort.mp_SigBit)|(1L<<ncp->ncp_TaskMsgPort->mp_SigBit)|SIGBREAKF_CTRL_C;
651 if(ncp->ncp_AbortRead)
653 ncp->ncp_AbortRead = FALSE;
654 if(ncp->ncp_ReadPending)
656 psdAbortPipe(ncp->ncp_EPInPipe);
659 if(ncp->ncp_AbortWrite)
661 ncp->ncp_AbortWrite = FALSE;
662 if(ncp->ncp_WritePending)
664 psdAbortPipe(ncp->ncp_EPOutPipe);
668 while((pp = (struct PsdPipe *) GetMsg(ncp->ncp_TaskMsgPort)))
670 KPRINTF(1, ("Pipe back %08lx\n", pp));
671 if(pp == ncp->ncp_EPOutPipe)
673 if((ioreq = ncp->ncp_WritePending))
675 ioerr = psdGetPipeError(pp);
676 ioreq->io_Actual = psdGetPipeActual(pp);
677 if(ioerr)
679 psdAddErrorMsg(RETURN_WARN, (STRPTR) libname,
680 "RawWrap transmit failed: %s (%ld)",
681 psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
682 ioreq->io_Error = (ioerr > 0) ? IOERR_BADLENGTH : ioerr;
684 ReplyMsg((struct Message *) ioreq);
685 ncp->ncp_WritePending = NULL;
688 else if(pp == ncp->ncp_EPInPipe)
690 ncp->ncp_ShortPktRead = FALSE;
691 switch(ncp->ncp_CDC->cdc_InBufferMode)
693 case BUFMODE_NO:
694 if((ioreq = ncp->ncp_ReadPending))
696 ioerr = psdGetPipeError(pp);
697 ioreq->io_Actual = psdGetPipeActual(pp);
698 if(ioerr)
700 psdAddErrorMsg(RETURN_WARN, (STRPTR) libname,
701 "RawWrap receive failed: %s (%ld)",
702 psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
703 ioreq->io_Error = (ioerr > 0) ? IOERR_BADLENGTH : ioerr;
705 ReplyMsg((struct Message *) ioreq);
707 break;
709 case BUFMODE_READAHEAD:
710 case BUFMODE_READONREQ:
711 ioerr = psdGetPipeError(pp);
712 len = psdGetPipeActual(pp);
713 ioreq = ncp->ncp_ReadPending;
714 KPRINTF(1, ("IO=%08lx, err=%ld, len=%ld\n", ioreq, ioerr, len));
715 if(ioerr)
717 psdAddErrorMsg(RETURN_WARN, (STRPTR) libname,
718 "RawWrap receive failed: %s (%ld)",
719 psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
720 if(ioreq)
722 if (ioreq == (APTR)-1)
724 ncp->ncp_ShortPktRead = TRUE;
725 } else {
726 ioreq->io_Actual += len;
727 ioreq->io_Error = (ioerr > 0) ? IOERR_BADLENGTH : ioerr;
728 Remove((struct Node *) ioreq);
729 ReplyMsg((struct Message *) ioreq);
732 break;
734 ncp->ncp_ShortPktRead = len & (ncp->ncp_EPInMaxPktSize-1);
735 if(!len)
737 ncp->ncp_ShortPktRead = TRUE;
738 psdAddErrorMsg(RETURN_WARN, (STRPTR) libname, "RawWrap received null bytes packet.");
741 if(ioreq)
743 if (ioreq == (APTR)-1)
745 if(len)
747 ncp->ncp_ReadBuffer[ncp->ncp_RBufWOffset+len] = 0;
748 KPRINTF(1, ("Received %ld bytes...('%s')\n", len, &ncp->ncp_ReadBuffer[ncp->ncp_RBufWOffset]));
749 ncp->ncp_RBufFull += len;
750 ncp->ncp_RBufWOffset += len;
752 if(ncp->ncp_RBufWOffset + READBUFCHUNK >= ncp->ncp_RBufSize)
754 KPRINTF(5, ("Wrapping read buffer\n"));
755 ncp->ncp_RBufWrap = ncp->ncp_RBufWOffset;
756 ncp->ncp_RBufWOffset = 0;
758 if(ncp->ncp_RBufFull > ncp->ncp_RBufWrap)
760 KPRINTF(5, ("Read buffer overflow by %ld bytes\n",
761 ncp->ncp_RBufFull - ncp->ncp_RBufWrap));
762 ncp->ncp_RBufFull = ncp->ncp_RBufWrap;
765 } else {
766 ioreq->io_Actual += len;
769 break;
771 ncp->ncp_ReadPending = NULL;
774 if((ncp->ncp_CDC->cdc_InBufferMode == BUFMODE_READAHEAD) &&
775 (!(ncp->ncp_DenyRequests || ncp->ncp_ReadPending)))
777 psdSendPipe(ncp->ncp_EPInPipe, &ncp->ncp_ReadBuffer[ncp->ncp_RBufWOffset], READBUFCHUNK);
778 ncp->ncp_ReadPending = (struct IOStdReq *) -1;
781 while((ioreq = (struct IOStdReq *) GetMsg(&ncp->ncp_Unit.unit_MsgPort)))
783 KPRINTF(5, ("command ioreq: 0x%08lx cmd: %lu len: %ld\n",
784 ioreq, ioreq->io_Command, ioreq->io_Length));
785 switch(ioreq->io_Command)
787 case CMD_READ:
788 ioreq->io_Actual = 0;
789 Forbid();
790 AddTail(&ncp->ncp_ReadQueue, &ioreq->io_Message.mn_Node);
791 Permit();
792 break;
794 case CMD_WRITE:
795 ioreq->io_Actual = 0;
796 if(ioreq->io_Length == -1)
798 ioreq->io_Length = strlen(ioreq->io_Data);
800 Forbid();
801 AddTail(&ncp->ncp_WriteQueue, &ioreq->io_Message.mn_Node);
802 Permit();
803 break;
805 case CMD_CLEAR:
806 ncp->ncp_RBufWrap = ncp->ncp_RBufSize;
807 ncp->ncp_RBufWOffset = 0;
808 ncp->ncp_RBufROffset = 0;
809 ncp->ncp_RBufFull = 0;
810 if(ncp->ncp_ReadPending)
812 psdAbortPipe(ncp->ncp_EPInPipe);
814 ReplyMsg((struct Message *) ioreq);
815 break;
817 case CMD_RESET:
818 if((ioreq2 = ncp->ncp_WritePending))
820 psdAbortPipe(ncp->ncp_EPOutPipe);
821 psdWaitPipe(ncp->ncp_EPOutPipe);
822 ncp->ncp_WritePending = NULL;
823 ioreq2->io_Error = IOERR_ABORTED;
824 ReplyMsg((struct Message *) ioreq2);
826 /* Reset does a flush too */
827 case CMD_FLUSH:
828 ioreq2 = (struct IOStdReq *) ncp->ncp_WriteQueue.lh_Head;
829 while(ioreq2->io_Message.mn_Node.ln_Succ)
831 Remove((struct Node *) ioreq2);
832 ioreq2->io_Error = IOERR_ABORTED;
833 ReplyMsg((struct Message *) ioreq2);
834 ioreq2 = (struct IOStdReq *) ncp->ncp_WriteQueue.lh_Head;
836 ioreq2 = (struct IOStdReq *) ncp->ncp_ReadQueue.lh_Head;
837 while(ioreq2->io_Message.mn_Node.ln_Succ)
839 Remove((struct Node *) ioreq2);
840 ioreq2->io_Error = IOERR_ABORTED;
841 ReplyMsg((struct Message *) ioreq2);
842 ioreq2 = (struct IOStdReq *) ncp->ncp_ReadQueue.lh_Head;
844 if((ioreq2 = ncp->ncp_ReadPending))
846 psdAbortPipe(ncp->ncp_EPInPipe);
847 psdWaitPipe(ncp->ncp_EPInPipe);
848 ioreq2->io_Error = IOERR_ABORTED;
849 ReplyMsg((struct Message *) ioreq2);
850 ncp->ncp_ReadPending = NULL;
852 //ncp->ncp_WritePending = NULL;
853 ReplyMsg((struct Message *) ioreq);
854 break;
856 default:
857 ioreq->io_Error = IOERR_NOCMD;
858 ReplyMsg((struct Message *) ioreq);
859 break;
862 switch(ncp->ncp_CDC->cdc_InBufferMode)
864 case BUFMODE_NO:
865 ioreq = (struct IOStdReq *) ncp->ncp_ReadQueue.lh_Head;
866 if((!ncp->ncp_ReadPending) && ioreq->io_Message.mn_Node.ln_Succ)
868 Remove((struct Node *) ioreq);
869 ncp->ncp_ReadPending = ioreq;
870 psdSendPipe(ncp->ncp_EPInPipe, ioreq->io_Data, ioreq->io_Length);
872 break;
874 case BUFMODE_READAHEAD:
875 case BUFMODE_READONREQ:
876 ioreq = (struct IOStdReq *) ncp->ncp_ReadQueue.lh_Head;
877 while(ioreq->io_Message.mn_Node.ln_Succ)
879 if(ncp->ncp_RBufFull)
881 len = ioreq->io_Length - ioreq->io_Actual;
882 if(len > ncp->ncp_RBufFull)
884 len = ncp->ncp_RBufFull;
886 if(ncp->ncp_RBufROffset+len < ncp->ncp_RBufWrap)
888 /* No wraparound */
889 KPRINTF(1, ("NoWrapCopy %ld (%ld/%ld)\n", len, ncp->ncp_RBufROffset, ncp->ncp_RBufWrap));
890 CopyMem(&ncp->ncp_ReadBuffer[ncp->ncp_RBufROffset],
891 &((UBYTE *)ioreq->io_Data)[ioreq->io_Actual],
892 len);
893 ncp->ncp_RBufROffset += len;
894 ncp->ncp_RBufFull -= len;
895 ioreq->io_Actual += len;
896 } else {
897 /* Wrap around */
898 ULONG chunk1 = ncp->ncp_RBufWrap - ncp->ncp_RBufROffset;
899 KPRINTF(1, ("WrapCopy1 %ld (%ld/%ld)\n", chunk1, ncp->ncp_RBufROffset, ncp->ncp_RBufWrap));
900 ncp->ncp_RBufFull -= len;
901 CopyMem(&ncp->ncp_ReadBuffer[ncp->ncp_RBufROffset],
902 &((UBYTE *)ioreq->io_Data)[ioreq->io_Actual],
903 chunk1);
904 ioreq->io_Actual += chunk1;
906 len -= chunk1;
907 if(len)
909 KPRINTF(1, ("WrapCopy2 %ld\n", len));
910 CopyMem(ncp->ncp_ReadBuffer,
911 &((UBYTE *)ioreq->io_Data)[ioreq->io_Actual],
912 len);
913 ioreq->io_Actual += len;
915 ncp->ncp_RBufROffset = len;
918 len = ioreq->io_Length - ioreq->io_Actual;
919 if((!len) || (ncp->ncp_ShortPktRead && ncp->ncp_CDC->cdc_ShortReadTerm))
921 if(len)
923 KPRINTF(1, ("Short Packet reply, %ld less bytes\n", len));
924 } else {
925 KPRINTF(1, ("IO ready reply\n"));
927 Remove((struct Node *) ioreq);
928 ReplyMsg((struct Message *) ioreq);
929 ioreq = (struct IOStdReq *) ncp->ncp_ReadQueue.lh_Head;
930 ncp->ncp_ShortPktRead = FALSE;
931 } else {
932 if(ncp->ncp_CDC->cdc_InBufferMode == BUFMODE_READONREQ)
934 if(len >= ncp->ncp_EPInMaxPktSize)
936 if(!ncp->ncp_ReadPending)
938 //Remove((struct Node *) ioreq);
939 ncp->ncp_ReadPending = ioreq;
940 psdSendPipe(ncp->ncp_EPInPipe, &((UBYTE *)ioreq->io_Data)[ioreq->io_Actual], len & (~(ncp->ncp_EPInMaxPktSize-1)));
942 } else {
943 psdSendPipe(ncp->ncp_EPInPipe, &ncp->ncp_ReadBuffer[ncp->ncp_RBufWOffset], ncp->ncp_EPInMaxPktSize);
944 ncp->ncp_ReadPending = (struct IOStdReq *) -1;
947 break;
950 break;
952 ioreq = (struct IOStdReq *) ncp->ncp_WriteQueue.lh_Head;
953 if((!ncp->ncp_WritePending) && ioreq->io_Message.mn_Node.ln_Succ)
955 Remove((struct Node *) ioreq);
956 ncp->ncp_WritePending = ioreq;
957 psdSendPipe(ncp->ncp_EPOutPipe, ioreq->io_Data, ioreq->io_Length);
959 sigs = Wait(sigmask);
960 } while(!(sigs & SIGBREAKF_CTRL_C));
961 Forbid();
962 /* Now remove all requests still pending *anywhere* */
963 ncp->ncp_DenyRequests = TRUE;
964 /* Current transfers */
965 if((ioreq = ncp->ncp_WritePending))
967 KPRINTF(1, ("Aborting pending write...\n"));
968 psdAbortPipe(ncp->ncp_EPOutPipe);
969 psdWaitPipe(ncp->ncp_EPOutPipe);
970 ioreq->io_Error = IOERR_ABORTED;
971 ReplyMsg((struct Message *) ioreq);
972 ncp->ncp_WritePending = NULL;
974 if((ioreq = ncp->ncp_ReadPending))
976 KPRINTF(1, ("Aborting pending read...\n"));
977 psdAbortPipe(ncp->ncp_EPInPipe);
978 psdWaitPipe(ncp->ncp_EPInPipe);
979 if (ioreq != (APTR)-1)
981 ioreq->io_Error = IOERR_ABORTED;
982 ReplyMsg((struct Message *) ioreq);
984 ncp->ncp_ReadPending = NULL;
986 /* Read/Write queues */
987 ioreq = (struct IOStdReq *) ncp->ncp_WriteQueue.lh_Head;
988 while(ioreq->io_Message.mn_Node.ln_Succ)
990 KPRINTF(1, ("Removing write request...\n"));
991 Remove((struct Node *) ioreq);
992 ioreq->io_Error = IOERR_ABORTED;
993 ReplyMsg((struct Message *) ioreq);
994 ioreq = (struct IOStdReq *) ncp->ncp_WriteQueue.lh_Head;
996 ioreq = (struct IOStdReq *) ncp->ncp_ReadQueue.lh_Head;
997 while(ioreq->io_Message.mn_Node.ln_Succ)
999 KPRINTF(1, ("Removing read request...\n"));
1000 Remove((struct Node *) ioreq);
1001 ioreq->io_Error = IOERR_ABORTED;
1002 ReplyMsg((struct Message *) ioreq);
1003 ioreq = (struct IOStdReq *) ncp->ncp_ReadQueue.lh_Head;
1005 /* Command queue */
1006 while((ioreq = (struct IOStdReq *) GetMsg(&ncp->ncp_Unit.unit_MsgPort)))
1008 KPRINTF(1, ("Aborting pending requests...\n"));
1009 ioreq->io_Error = IOERR_ABORTED;
1010 ReplyMsg((struct Message *) ioreq);
1012 Permit();
1013 KPRINTF(20, ("Going down the river!\n"));
1014 nFreeRawWrap(ncp);
1017 AROS_USERFUNC_EXIT
1019 /* \\\ */
1021 /* /// "nAllocRawWrap()" */
1022 struct NepClassRawWrap * nAllocRawWrap(void)
1024 struct Task *thistask;
1025 struct NepClassRawWrap *ncp;
1027 thistask = FindTask(NULL);
1030 ncp = thistask->tc_UserData;
1031 if(!(ncp->ncp_Base = OpenLibrary("poseidon.library", 4)))
1033 Alert(AG_OpenLib);
1034 break;
1036 ncp->ncp_EPIn = psdFindEndpoint(ncp->ncp_Interface, NULL,
1037 EA_IsIn, TRUE,
1038 EA_TransferType, USEAF_BULK,
1039 TAG_END);
1040 ncp->ncp_EPOut = psdFindEndpoint(ncp->ncp_Interface, NULL,
1041 EA_IsIn, FALSE,
1042 EA_TransferType, USEAF_BULK,
1043 TAG_END);
1044 if(!(ncp->ncp_EPIn && ncp->ncp_EPOut))
1046 psdAddErrorMsg(RETURN_FAIL, (STRPTR) libname, "IN or OUT endpoint missing!");
1047 break;
1050 psdGetAttrs(PGA_ENDPOINT, ncp->ncp_EPIn,
1051 EA_MaxPktSize, &ncp->ncp_EPInMaxPktSize,
1052 TAG_END);
1054 ncp->ncp_ReadPending = NULL;
1055 ncp->ncp_WritePending = NULL;
1056 ncp->ncp_RBufWrap = ncp->ncp_RBufSize = ncp->ncp_CDC->cdc_InBufferSize*1024;
1057 if(!(ncp->ncp_ReadBuffer = AllocVec(ncp->ncp_RBufSize, MEMF_PUBLIC|MEMF_CLEAR)))
1059 KPRINTF(1, ("Out of memory for read buffer\n"));
1060 break;
1062 ncp->ncp_Unit.unit_MsgPort.mp_SigBit = AllocSignal(-1);
1063 ncp->ncp_Unit.unit_MsgPort.mp_SigTask = thistask;
1064 ncp->ncp_Unit.unit_MsgPort.mp_Node.ln_Type = NT_MSGPORT;
1065 ncp->ncp_Unit.unit_MsgPort.mp_Flags = PA_SIGNAL;
1066 ncp->ncp_RBufWOffset = 0;
1067 ncp->ncp_RBufROffset = 0;
1068 ncp->ncp_RBufFull = 0;
1070 if((ncp->ncp_TaskMsgPort = CreateMsgPort()))
1072 if((ncp->ncp_EP0Pipe = psdAllocPipe(ncp->ncp_Device, ncp->ncp_TaskMsgPort, NULL)))
1074 if((ncp->ncp_EPOutPipe = psdAllocPipe(ncp->ncp_Device, ncp->ncp_TaskMsgPort, ncp->ncp_EPOut)))
1076 /* Turn off short packets */
1077 psdSetAttrs(PGA_PIPE, ncp->ncp_EPOutPipe,
1078 PPA_NoShortPackets, TRUE,
1079 PPA_NakTimeout, ncp->ncp_CDC->cdc_OutNakTimeout ? TRUE : FALSE,
1080 PPA_NakTimeoutTime, ncp->ncp_CDC->cdc_OutNakTimeout*100,
1081 TAG_END);
1082 if((ncp->ncp_EPInPipe = psdAllocPipe(ncp->ncp_Device, ncp->ncp_TaskMsgPort, ncp->ncp_EPIn)))
1084 /* Turn off short packets */
1085 psdSetAttrs(PGA_PIPE, ncp->ncp_EPInPipe,
1086 PPA_NakTimeout, ncp->ncp_CDC->cdc_InNakTimeout ? TRUE : FALSE,
1087 PPA_NakTimeoutTime, ncp->ncp_CDC->cdc_InNakTimeout*100,
1088 PPA_AllowRuntPackets, TRUE,
1089 TAG_END);
1090 ncp->ncp_Task = thistask;
1091 return(ncp);
1093 psdFreePipe(ncp->ncp_EPOutPipe);
1095 psdFreePipe(ncp->ncp_EP0Pipe);
1097 DeleteMsgPort(ncp->ncp_TaskMsgPort);
1099 FreeSignal((LONG) ncp->ncp_Unit.unit_MsgPort.mp_SigBit);
1100 } while(FALSE);
1101 CloseLibrary(ncp->ncp_Base);
1102 Forbid();
1103 ncp->ncp_Task = NULL;
1104 if(ncp->ncp_ReadySigTask)
1106 Signal(ncp->ncp_ReadySigTask, 1L<<ncp->ncp_ReadySignal);
1108 return(NULL);
1110 /* \\\ */
1112 /* /// "nFreeRawWrap()" */
1113 void nFreeRawWrap(struct NepClassRawWrap *ncp)
1115 struct IOStdReq *ioreq;
1116 Forbid();
1117 /* Disable the message port, messages may still be queued */
1118 ncp->ncp_Unit.unit_MsgPort.mp_SigTask = NULL;
1119 ncp->ncp_Unit.unit_MsgPort.mp_Flags = PA_IGNORE;
1120 FreeSignal((LONG) ncp->ncp_Unit.unit_MsgPort.mp_SigBit);
1121 // get rid of all messages that still have appeared here
1122 while((ioreq = (struct IOStdReq *) GetMsg(&ncp->ncp_Unit.unit_MsgPort)))
1124 ioreq->io_Error = IOERR_ABORTED;
1125 ReplyMsg((struct Message *) ioreq);
1127 Permit();
1129 psdFreePipe(ncp->ncp_EPInPipe);
1130 psdFreePipe(ncp->ncp_EPOutPipe);
1131 psdFreePipe(ncp->ncp_EP0Pipe);
1133 if(ncp->ncp_ReadBuffer)
1135 FreeVec(ncp->ncp_ReadBuffer);
1136 ncp->ncp_ReadBuffer = NULL;
1139 DeleteMsgPort(ncp->ncp_TaskMsgPort);
1140 CloseLibrary(ncp->ncp_Base);
1141 Forbid();
1142 ncp->ncp_Task = NULL;
1143 if(ncp->ncp_ReadySigTask)
1145 Signal(ncp->ncp_ReadySigTask, 1L<<ncp->ncp_ReadySignal);
1148 /* \\\ */
1150 /**************************************************************************/
1152 static char *BufferModeStrings[] = { "No Buffering", "Readahead", "Read on request", NULL };
1153 static char *MainGUIPages[] = { "Global", "Interface", NULL };
1154 static char *MainGUIPagesDefault[] = { "Global", "Default Interface", NULL };
1156 /* /// "nGUITask()" */
1157 AROS_UFH0(void, nGUITask)
1159 AROS_USERFUNC_INIT
1161 struct Task *thistask;
1162 struct NepRawWrapBase *nh;
1163 struct NepClassRawWrap *ncp;
1164 struct PsdIFFContext *pic;
1166 thistask = FindTask(NULL);
1167 #undef ps
1168 #define ps ncp->ncp_PsdBase
1169 #undef IntuitionBase
1170 #define IntuitionBase ncp->ncp_IntBase
1171 #undef MUIMasterBase
1172 #define MUIMasterBase ncp->ncp_MUIBase
1174 ncp = thistask->tc_UserData;
1175 nh = ncp->ncp_ClsBase;
1177 ++nh->nh_Library.lib_OpenCnt;
1178 if(!(MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN)))
1180 KPRINTF(10, ("Couldn't open muimaster.library.\n"));
1181 nGUITaskCleanup(ncp);
1182 return;
1185 if(!(IntuitionBase = OpenLibrary("intuition.library", 39)))
1187 KPRINTF(10, ("Couldn't open intuition.library.\n"));
1188 nGUITaskCleanup(ncp);
1189 return;
1191 if(!(ps = OpenLibrary("poseidon.library", 4)))
1193 KPRINTF(10, ("Couldn't open poseidon.library.\n"));
1194 nGUITaskCleanup(ncp);
1195 return;
1198 ncp->ncp_App = ApplicationObject,
1199 MUIA_Application_Title , (IPTR)libname,
1200 MUIA_Application_Version , (IPTR)VERSION_STRING,
1201 MUIA_Application_Copyright , (IPTR)"©2002-2009 Chris Hodges",
1202 MUIA_Application_Author , (IPTR)"Chris Hodges <chrisly@platon42.de>",
1203 MUIA_Application_Description, (IPTR)"Settings for the rawwrap.class",
1204 MUIA_Application_Base , (IPTR)"RAWWRAP",
1205 MUIA_Application_HelpFile , (IPTR)"HELP:Poseidon.guide",
1206 MUIA_Application_Menustrip , (IPTR)MenustripObject,
1207 Child, (IPTR)MenuObjectT((IPTR)"Project"),
1208 Child, (IPTR)(ncp->ncp_AboutMI = MenuitemObject,
1209 MUIA_Menuitem_Title, (IPTR)"About...",
1210 MUIA_Menuitem_Shortcut, (IPTR)"?",
1211 End),
1212 End,
1213 Child, (IPTR)MenuObjectT((IPTR)"Settings"),
1214 Child, (IPTR)(ncp->ncp_UseMI = MenuitemObject,
1215 MUIA_Menuitem_Title, (IPTR)"Save",
1216 MUIA_Menuitem_Shortcut, (IPTR)"S",
1217 End),
1218 Child, (IPTR)(ncp->ncp_SetDefaultMI = MenuitemObject,
1219 MUIA_Menuitem_Title, (IPTR)"Set as Default",
1220 MUIA_Menuitem_Shortcut, (IPTR)"D",
1221 End),
1222 Child, (IPTR)MenuitemObject,
1223 MUIA_Menuitem_Title, (IPTR)NM_BARLABEL,
1224 End,
1225 Child, (IPTR)(ncp->ncp_MUIPrefsMI = MenuitemObject,
1226 MUIA_Menuitem_Title, (IPTR)"MUI Settings",
1227 MUIA_Menuitem_Shortcut, (IPTR)"M",
1228 End),
1229 End,
1230 End,
1232 SubWindow, (IPTR)(ncp->ncp_MainWindow = WindowObject,
1233 MUIA_Window_ID , MAKE_ID('M','A','I','N'),
1234 MUIA_Window_Title, (IPTR)libname,
1235 MUIA_HelpNode, (IPTR)libname,
1237 WindowContents, (IPTR)VGroup,
1238 Child, (IPTR)RegisterGroup(ncp->ncp_Interface ? MainGUIPages : MainGUIPagesDefault),
1239 MUIA_CycleChain, 1,
1240 MUIA_Register_Frame, ncp->ncp_Interface ? FALSE : TRUE,
1241 MUIA_Group_ActivePage, ncp->ncp_Interface ? 1 : 0,
1242 Child, (IPTR)HGroup, GroupFrameT((IPTR)"Global Settings"),
1243 MUIA_Disabled, ncp->ncp_Interface ? TRUE : FALSE,
1244 Child, (IPTR)HSpace(0),
1245 Child, (IPTR)ColGroup(2),
1246 Child, (IPTR)Label((IPTR) "Bind to Vendor/Unknown Interfaces:"),
1247 Child, (IPTR)HGroup,
1248 Child, (IPTR)(ncp->ncp_BindVendorObj = ImageObject, ImageButtonFrame,
1249 MUIA_Background, MUII_ButtonBack,
1250 MUIA_CycleChain, 1,
1251 MUIA_InputMode, MUIV_InputMode_Toggle,
1252 MUIA_Image_Spec, MUII_CheckMark,
1253 MUIA_Image_FreeVert, TRUE,
1254 MUIA_Selected, nh->nh_CurrentCGC.cgc_BindVendor,
1255 MUIA_ShowSelState, FALSE,
1256 End),
1257 Child, (IPTR)HSpace(0),
1258 End,
1259 Child, (IPTR)Label((IPTR) "Bind to all interfaces:"),
1260 Child, (IPTR)HGroup,
1261 Child, (IPTR)(ncp->ncp_BindAllObj = ImageObject, ImageButtonFrame,
1262 MUIA_Background, MUII_ButtonBack,
1263 MUIA_CycleChain, 1,
1264 MUIA_InputMode, MUIV_InputMode_Toggle,
1265 MUIA_Image_Spec, MUII_CheckMark,
1266 MUIA_Image_FreeVert, TRUE,
1267 MUIA_Selected, nh->nh_CurrentCGC.cgc_BindAll,
1268 MUIA_ShowSelState, FALSE,
1269 End),
1270 Child, (IPTR)HSpace(0),
1271 End,
1272 End,
1273 Child, (IPTR)HSpace(0),
1274 End,
1275 Child, (IPTR)ColGroup(2), GroupFrameT((IPTR)(ncp->ncp_Interface ? "Device Settings" : "Default Device Settings")),
1276 //Child, HSpace(0),
1277 Child, (IPTR)Label((IPTR) "Default " DEVNAME " Unit:"),
1278 Child, (IPTR)HGroup,
1279 Child, (IPTR)(ncp->ncp_UnitObj = StringObject,
1280 StringFrame,
1281 MUIA_CycleChain, 1,
1282 MUIA_String_AdvanceOnCR, TRUE,
1283 MUIA_String_Integer, ncp->ncp_CDC->cdc_DefaultUnit,
1284 MUIA_String_Accept, (IPTR)"0123456789",
1285 End),
1286 Child, (IPTR)HSpace(0),
1287 Child, (IPTR)Label((IPTR) "Exclusive access:"),
1288 Child, (IPTR)(ncp->ncp_UnitExclObj = ImageObject, ImageButtonFrame,
1289 MUIA_Background, MUII_ButtonBack,
1290 MUIA_CycleChain, 1,
1291 MUIA_InputMode, MUIV_InputMode_Toggle,
1292 MUIA_Image_Spec, MUII_CheckMark,
1293 MUIA_Image_FreeVert, TRUE,
1294 MUIA_Selected, ncp->ncp_CDC->cdc_UnitExclusive,
1295 MUIA_ShowSelState, FALSE,
1296 End),
1297 End,
1298 Child, (IPTR)Label((IPTR) "Out NAK Timeout:"),
1299 Child, (IPTR)(ncp->ncp_OutNakTimeoutObj = SliderObject, SliderFrame,
1300 MUIA_CycleChain, 1,
1301 MUIA_Numeric_Min, 0,
1302 MUIA_Numeric_Max, 600,
1303 MUIA_Numeric_Value, ncp->ncp_CDC->cdc_OutNakTimeout,
1304 MUIA_Numeric_Format, (IPTR)"%ld00ms",
1305 End),
1306 Child, (IPTR)Label((IPTR) "In NAK Timeout:"),
1307 Child, (IPTR)(ncp->ncp_InNakTimeoutObj = SliderObject, SliderFrame,
1308 MUIA_CycleChain, 1,
1309 MUIA_Numeric_Min, 0,
1310 MUIA_Numeric_Max, 600,
1311 MUIA_Numeric_Value, ncp->ncp_CDC->cdc_InNakTimeout,
1312 MUIA_Numeric_Format, (IPTR)"%ld00ms",
1313 End),
1314 Child, (IPTR)Label((IPTR) "In Buffer Mode:"),
1315 Child, (IPTR)HGroup,
1316 Child, (IPTR)(ncp->ncp_InBufferModeObj = CycleObject,
1317 MUIA_CycleChain, 1,
1318 MUIA_Cycle_Entries, (IPTR)BufferModeStrings,
1319 MUIA_Cycle_Active, ncp->ncp_CDC->cdc_InBufferMode,
1320 End),
1321 Child, (IPTR)Label((IPTR) "Buffer Size:"),
1322 Child, (IPTR)(ncp->ncp_InBufferSizeObj = SliderObject, SliderFrame,
1323 MUIA_CycleChain, 1,
1324 MUIA_Numeric_Min, 1,
1325 MUIA_Numeric_Max, 512,
1326 MUIA_Numeric_Value, ncp->ncp_CDC->cdc_InBufferSize,
1327 MUIA_Numeric_Format, (IPTR)"%ldKB",
1328 End),
1329 End,
1330 Child, (IPTR)Label((IPTR) "Short Reads Terminate:"),
1331 Child, (IPTR)HGroup,
1332 Child, (IPTR)(ncp->ncp_ShortReadTermObj = ImageObject, ImageButtonFrame,
1333 MUIA_Background, MUII_ButtonBack,
1334 MUIA_CycleChain, 1,
1335 MUIA_InputMode, MUIV_InputMode_Toggle,
1336 MUIA_Image_Spec, MUII_CheckMark,
1337 MUIA_Image_FreeVert, TRUE,
1338 MUIA_Selected, ncp->ncp_CDC->cdc_ShortReadTerm,
1339 MUIA_ShowSelState, FALSE,
1340 End),
1341 Child, (IPTR)HSpace(0),
1342 End,
1343 End,
1344 End,
1345 Child, (IPTR)VSpace(0),
1346 Child, (IPTR)HGroup,
1347 MUIA_Group_SameWidth, TRUE,
1348 Child, (IPTR)(ncp->ncp_UseObj = TextObject, ButtonFrame,
1349 MUIA_ShowMe, (IPTR)ncp->ncp_Interface,
1350 MUIA_Background, MUII_ButtonBack,
1351 MUIA_CycleChain, 1,
1352 MUIA_InputMode, MUIV_InputMode_RelVerify,
1353 MUIA_Text_Contents, (IPTR)"\33c Save ",
1354 End),
1355 Child, (IPTR)(ncp->ncp_SetDefaultObj = TextObject, ButtonFrame,
1356 MUIA_Background, MUII_ButtonBack,
1357 MUIA_CycleChain, 1,
1358 MUIA_InputMode, MUIV_InputMode_RelVerify,
1359 MUIA_Text_Contents, (IPTR)(ncp->ncp_Interface ? "\33c Save as Default " : "\33c Save Defaults "),
1360 End),
1361 Child, (IPTR)(ncp->ncp_CloseObj = TextObject, ButtonFrame,
1362 MUIA_Background, MUII_ButtonBack,
1363 MUIA_CycleChain, 1,
1364 MUIA_InputMode, MUIV_InputMode_RelVerify,
1365 MUIA_Text_Contents, (IPTR)"\33c Use ",
1366 End),
1367 End,
1368 End,
1369 End),
1370 End;
1372 if(!ncp->ncp_App)
1374 KPRINTF(10, ("Couldn't create application\n"));
1375 nGUITaskCleanup(ncp);
1376 return;
1379 DoMethod(ncp->ncp_MainWindow, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
1380 ncp->ncp_App, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
1381 DoMethod(ncp->ncp_UseObj, MUIM_Notify, MUIA_Pressed, FALSE,
1382 ncp->ncp_App, 2, MUIM_Application_ReturnID, ID_STORE_CONFIG);
1383 DoMethod(ncp->ncp_SetDefaultObj, MUIM_Notify, MUIA_Pressed, FALSE,
1384 ncp->ncp_App, 2, MUIM_Application_ReturnID, ID_DEF_CONFIG);
1385 DoMethod(ncp->ncp_CloseObj, MUIM_Notify, MUIA_Pressed, FALSE,
1386 ncp->ncp_App, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
1388 DoMethod(ncp->ncp_AboutMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
1389 ncp->ncp_App, 2, MUIM_Application_ReturnID, ID_ABOUT);
1390 DoMethod(ncp->ncp_UseMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
1391 ncp->ncp_App, 2, MUIM_Application_ReturnID, ID_STORE_CONFIG);
1392 DoMethod(ncp->ncp_SetDefaultMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
1393 ncp->ncp_App, 2, MUIM_Application_ReturnID, ID_DEF_CONFIG);
1394 DoMethod(ncp->ncp_MUIPrefsMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
1395 ncp->ncp_App, 2, MUIM_Application_OpenConfigWindow, 0);
1397 IPTR isopen = 0;
1398 IPTR iconify = 0;
1399 ULONG sigs;
1400 ULONG sigmask;
1401 LONG retid;
1403 get(ncp->ncp_App, MUIA_Application_Iconified, &iconify);
1404 set(ncp->ncp_MainWindow, MUIA_Window_Open, TRUE);
1405 get(ncp->ncp_MainWindow, MUIA_Window_Open, &isopen);
1406 if(!(isopen || iconify))
1408 nGUITaskCleanup(ncp);
1409 return;
1411 sigmask = 0;
1414 retid = DoMethod(ncp->ncp_App, MUIM_Application_NewInput, &sigs);
1415 switch(retid)
1417 case ID_DEF_CONFIG:
1418 case ID_STORE_CONFIG:
1419 case MUIV_Application_ReturnID_Quit:
1421 if(!ncp->ncp_Interface)
1423 get(ncp->ncp_BindVendorObj, MUIA_Selected, &nh->nh_CurrentCGC.cgc_BindVendor);
1424 get(ncp->ncp_BindAllObj, MUIA_Selected, &nh->nh_CurrentCGC.cgc_BindAll);
1426 get(ncp->ncp_UnitObj, MUIA_String_Integer, &ncp->ncp_CDC->cdc_DefaultUnit);
1427 get(ncp->ncp_UnitExclObj, MUIA_Selected, &ncp->ncp_CDC->cdc_UnitExclusive);
1428 get(ncp->ncp_OutNakTimeoutObj, MUIA_Numeric_Value, &ncp->ncp_CDC->cdc_OutNakTimeout);
1429 get(ncp->ncp_InNakTimeoutObj, MUIA_Numeric_Value, &ncp->ncp_CDC->cdc_InNakTimeout);
1430 get(ncp->ncp_InBufferSizeObj, MUIA_Numeric_Value, &ncp->ncp_CDC->cdc_InBufferSize);
1431 get(ncp->ncp_InBufferModeObj, MUIA_Cycle_Active, &ncp->ncp_CDC->cdc_InBufferMode);
1432 get(ncp->ncp_ShortReadTermObj, MUIA_Selected, &ncp->ncp_CDC->cdc_ShortReadTerm);
1434 if(retid == ID_DEF_CONFIG)
1436 pic = psdGetClsCfg(libname);
1437 if(!pic)
1439 psdSetClsCfg(libname, NULL);
1440 pic = psdGetClsCfg(libname);
1442 if(pic)
1444 psdAddCfgEntry(pic, &nh->nh_CurrentCGC);
1445 psdAddCfgEntry(pic, ncp->ncp_CDC);
1446 psdSaveCfgToDisk(NULL, FALSE);
1449 if(ncp->ncp_Interface)
1451 pic = psdGetUsbDevCfg(libname, ncp->ncp_DevIDString, ncp->ncp_IfIDString);
1452 if(!pic)
1454 psdSetUsbDevCfg(libname, ncp->ncp_DevIDString, ncp->ncp_IfIDString, NULL);
1455 pic = psdGetUsbDevCfg(libname, ncp->ncp_DevIDString, ncp->ncp_IfIDString);
1457 if(pic)
1459 if(psdAddCfgEntry(pic, ncp->ncp_CDC))
1461 if(retid != MUIV_Application_ReturnID_Quit)
1463 psdSaveCfgToDisk(NULL, FALSE);
1465 retid = MUIV_Application_ReturnID_Quit;
1468 } else {
1469 retid = MUIV_Application_ReturnID_Quit;
1471 break;
1474 case ID_ABOUT:
1475 MUI_RequestA(ncp->ncp_App, ncp->ncp_MainWindow, 0, NULL, "Blimey!", VERSION_STRING, NULL);
1476 break;
1478 if(retid == MUIV_Application_ReturnID_Quit)
1480 break;
1482 if(sigs)
1484 sigs = Wait(sigs | sigmask | SIGBREAKF_CTRL_C);
1485 if(sigs & SIGBREAKF_CTRL_C)
1487 break;
1490 } while(TRUE);
1491 set(ncp->ncp_MainWindow, MUIA_Window_Open, FALSE);
1493 nGUITaskCleanup(ncp);
1495 AROS_USERFUNC_EXIT
1497 /* \\\ */
1499 /* /// "nGUITaskCleanup()" */
1500 void nGUITaskCleanup(struct NepClassRawWrap *ncp)
1502 if(ncp->ncp_App)
1504 MUI_DisposeObject(ncp->ncp_App);
1505 ncp->ncp_App = NULL;
1507 if(MUIMasterBase)
1509 CloseLibrary(MUIMasterBase);
1510 MUIMasterBase = NULL;
1512 if(IntuitionBase)
1514 CloseLibrary(IntuitionBase);
1515 IntuitionBase = NULL;
1517 if(ps)
1519 CloseLibrary(ps);
1520 ps = NULL;
1522 Forbid();
1523 ncp->ncp_GUIBinding = NULL;
1524 ncp->ncp_GUITask = NULL;
1525 if(ncp->ncp_ReadySigTask)
1527 Signal(ncp->ncp_ReadySigTask, 1L<<ncp->ncp_ReadySignal);
1529 --ncp->ncp_ClsBase->nh_Library.lib_OpenCnt;
1531 /* \\\ */