revert commit 56204.
[AROS.git] / rom / usb / classes / palmpda / palmpda.class.c
bloba803726bd9200d4c356a0655b6824c9d31ac0a3f
1 /*
2 *----------------------------------------------------------------------------
3 * palmpda class for poseidon
4 *----------------------------------------------------------------------------
5 * By Chris Hodges <chrisly@platon42.de>
6 */
8 #include "debug.h"
10 #include "palmpda.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 NepSerialBase *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
37 if(UtilityBase)
39 NewList(&nh->nh_Units);
41 if((nh->nh_DevBase = (struct NepSerDevBase *) MakeLibrary((APTR) DevFuncTable, NULL, (APTR) devInit,
42 sizeof(struct NepSerDevBase), NULL)))
44 nh->nh_DevBase->np_ClsBase = nh;
45 /*NewList(&nh->nh_DummyUnit.unit_MsgPort.mp_MsgList);
46 nh->nh_DummyUnit.unit_MsgPort.mp_SigBit = 0;
47 nh->nh_DummyUnit.unit_MsgPort.mp_SigTask = NULL;
48 nh->nh_DummyUnit.unit_MsgPort.mp_Node.ln_Type = NT_MSGPORT;
49 nh->nh_DummyUnit.unit_MsgPort.mp_Flags = PA_IGNORE;*/
51 Forbid();
52 AddDevice((struct Device *) nh->nh_DevBase);
53 nh->nh_DevBase->np_Library.lib_OpenCnt++;
54 Permit();
55 ret = nh;
56 } else {
57 KPRINTF(20, ("failed to create palmpda.device\n"));
59 if(!ret)
61 CloseLibrary(UtilityBase);
63 } else {
64 KPRINTF(20, ("libInit: OpenLibrary(\"utility.library\", 39) failed!\n"));
67 KPRINTF(10, ("libInit: Ok\n"));
68 return(ret ? TRUE : FALSE);
71 static int libOpen(LIBBASETYPEPTR nh)
73 KPRINTF(10, ("libOpen nh: 0x%08lx\n", nh));
74 nLoadClassConfig(nh);
75 return(TRUE);
78 static int libExpunge(LIBBASETYPEPTR nh)
80 struct NepClassSerial *ncp;
82 KPRINTF(10, ("libExpunge nh: 0x%08lx\n", nh));
84 if(nh->nh_DevBase->np_Library.lib_OpenCnt == 1)
86 KPRINTF(1, ("libExpunge: closelibrary utilitybase 0x%08lx\n",
87 UtilityBase));
88 CloseLibrary((struct Library *) UtilityBase);
90 ncp = (struct NepClassSerial *) nh->nh_Units.lh_Head;
91 while(ncp->ncp_Unit.unit_MsgPort.mp_Node.ln_Succ)
93 Remove((struct Node *) ncp);
94 FreeVec(ncp);
95 ncp = (struct NepClassSerial *) nh->nh_Units.lh_Head;
98 nh->nh_DevBase->np_Library.lib_OpenCnt--;
99 RemDevice((struct Device *) nh->nh_DevBase);
101 KPRINTF(5, ("libExpunge: Unloading done! palmpda.class expunged!\n\n"));
102 } else {
103 KPRINTF(5, ("libExpunge: Could not expunge, LIBF_DELEXP set!\n"));
104 return(FALSE);
107 return(TRUE);
110 ADD2INITLIB(libInit, 0)
111 ADD2OPENLIB(libOpen, 0)
112 ADD2EXPUNGELIB(libExpunge, 0)
113 /* \\\ */
116 * ***********************************************************************
117 * * Library functions *
118 * ***********************************************************************
121 struct AutoBindData
123 UWORD abd_VendID;
124 UWORD abd_ProdID;
127 struct AutoBindData ClassBinds[] =
129 { HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID },
130 { HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID },
131 { HANDSPRING_VENDOR_ID, HANDSPRING_TREO600_ID },
132 { PALM_VENDOR_ID , PALM_M500_ID },
133 { PALM_VENDOR_ID , PALM_M505_ID },
134 { PALM_VENDOR_ID , PALM_M515_ID },
135 { PALM_VENDOR_ID , PALM_I705_ID },
136 { PALM_VENDOR_ID , PALM_M100_ID },
137 { PALM_VENDOR_ID , PALM_M125_ID },
138 { PALM_VENDOR_ID , PALM_M130_ID },
139 { PALM_VENDOR_ID , PALM_TUNGSTEN_T_ID },
140 { PALM_VENDOR_ID , PALM_TUNGSTEN_Z_ID },
141 { PALM_VENDOR_ID , PALM_ZIRE31_ID },
142 { PALM_VENDOR_ID , PALM_ZIRE_ID },
143 { SONY_VENDOR_ID , SONY_CLIE_3_5_ID },
144 { SONY_VENDOR_ID , SONY_CLIE_4_0_ID },
145 { SONY_VENDOR_ID , SONY_CLIE_S360_ID },
146 { SONY_VENDOR_ID , SONY_CLIE_4_1_ID },
147 { SONY_VENDOR_ID , SONY_CLIE_NX60_ID },
148 { SONY_VENDOR_ID , SONY_CLIE_NZ90V_ID },
149 { SONY_VENDOR_ID , SONY_CLIE_UX50_ID },
150 { SONY_VENDOR_ID , SONY_CLIE_TJ25_ID },
151 { SAMSUNG_VENDOR_ID , SAMSUNG_SCH_I330_ID },
152 { SAMSUNG_VENDOR_ID , SAMSUNG_SPH_I500_ID },
153 { GARMIN_VENDOR_ID , GARMIN_IQUE_3600_ID },
154 { ACEECA_VENDOR_ID , ACEECA_MEZ1000_ID },
155 { KYOCERA_VENDOR_ID , KYOCERA_7135_ID },
156 { FOSSIL_VENDOR_ID , FOSSIL_ABACUS_ID },
157 { ZODIAC_VENDOR_ID , ZODIAC_ZODIAC_ID },
158 { 0, 0 }
161 /* /// "usbAttemptDeviceBinding()" */
162 struct NepClassSerial * usbAttemptDeviceBinding(struct NepSerialBase *nh, struct PsdDevice *pd)
164 struct Library *ps;
165 struct AutoBindData *abd = ClassBinds;
166 IPTR prodid;
167 IPTR vendid;
169 KPRINTF(1, ("nepSerialAttemptDeviceBinding(%08lx)\n", pd));
170 if((ps = OpenLibrary("poseidon.library", 4)))
172 psdGetAttrs(PGA_DEVICE, pd,
173 DA_VendorID, &vendid,
174 DA_ProductID, &prodid,
175 TAG_END);
176 CloseLibrary(ps);
177 while(abd->abd_VendID)
179 if((vendid == abd->abd_VendID) && (prodid == abd->abd_ProdID))
181 return(usbForceDeviceBinding(nh, pd));
183 abd++;
186 return(NULL);
188 /* \\\ */
190 /* /// "usbForceDeviceBinding()" */
191 struct NepClassSerial * usbForceDeviceBinding(struct NepSerialBase *nh, struct PsdDevice *pd)
193 struct Library *ps;
194 struct NepClassSerial *ncp;
195 STRPTR devname;
196 IPTR prodid;
197 IPTR vendid;
198 ULONG unitno;
199 BOOL unitfound;
200 UBYTE buf[64];
201 struct Task *tmptask;
203 KPRINTF(1, ("nepSerialForceDeviceBinding(%08lx)\n", pd));
204 if((ps = OpenLibrary("poseidon.library", 4)))
206 psdGetAttrs(PGA_DEVICE, pd,
207 DA_ProductID, &prodid,
208 DA_VendorID, &vendid,
209 DA_ProductName, &devname,
210 TAG_END);
212 nLoadClassConfig(nh);
213 Forbid();
214 /* Find next free unit number */
215 unitno = 0;
216 ncp = (struct NepClassSerial *) nh->nh_Units.lh_Head;
217 while(ncp->ncp_Unit.unit_MsgPort.mp_Node.ln_Succ)
219 if(ncp->ncp_UnitNo == unitno)
221 unitno++;
222 ncp = (struct NepClassSerial *) nh->nh_Units.lh_Head;
223 } else {
224 ncp = (struct NepClassSerial *) ncp->ncp_Unit.unit_MsgPort.mp_Node.ln_Succ;
227 unitfound = FALSE;
228 ncp = (struct NepClassSerial *) nh->nh_Units.lh_Head;
229 while(ncp->ncp_Unit.unit_MsgPort.mp_Node.ln_Succ)
231 if((ncp->ncp_UnitProdID == prodid) && (ncp->ncp_UnitVendorID == vendid))
233 unitno = ncp->ncp_UnitNo;
234 unitfound = TRUE;
235 break;
237 ncp = (struct NepClassSerial *) ncp->ncp_Unit.unit_MsgPort.mp_Node.ln_Succ;
239 if(!unitfound)
241 /* as units are freed in the expunge-vector, the memory is
242 outside the scope of the poseidon library */
243 if(!(ncp = AllocVec(sizeof(struct NepClassSerial), MEMF_PUBLIC|MEMF_CLEAR)))
245 Permit();
246 CloseLibrary(ps);
247 return(NULL);
249 /* IORequests may be queued even if the task is gone. */
250 NewList(&ncp->ncp_Unit.unit_MsgPort.mp_MsgList);
251 NewList(&ncp->ncp_ReadQueue);
252 NewList(&ncp->ncp_WriteQueue);
253 AddTail(&nh->nh_Units, &ncp->ncp_Unit.unit_MsgPort.mp_Node);
254 ncp->ncp_DenyRequests = TRUE;
256 ncp->ncp_DevBase = nh->nh_DevBase;
257 ncp->ncp_UnitNo = unitno;
258 ncp->ncp_Device = pd;
259 ncp->ncp_UnitProdID = prodid;
260 ncp->ncp_UnitVendorID = vendid;
261 Permit();
263 psdSafeRawDoFmt(buf, 64, "palmpda.class<%08lx>", ncp);
264 ncp->ncp_ReadySignal = SIGB_SINGLE;
265 ncp->ncp_ReadySigTask = FindTask(NULL);
266 SetSignal(0, SIGF_SINGLE);
267 if((tmptask = psdSpawnSubTask(buf, nSerialTask, ncp)))
269 psdBorrowLocksWait(tmptask, 1UL<<ncp->ncp_ReadySignal);
270 if(ncp->ncp_Task)
272 ncp->ncp_ReadySigTask = NULL;
273 //FreeSignal(ncp->ncp_ReadySignal);
274 psdAddErrorMsg(RETURN_OK, (STRPTR) libname,
275 "This '%s' PDA is hot at %s unit %ld!",
276 devname, nh->nh_DevBase->np_Library.lib_Node.ln_Name,
277 ncp->ncp_UnitNo);
279 CloseLibrary(ps);
280 return(ncp);
283 ncp->ncp_ReadySigTask = NULL;
284 //FreeSignal(ncp->ncp_ReadySignal);
285 /* Get rid of unit structure */
286 /*Forbid();
287 Remove((struct Node *) ncp);
288 FreeVec(ncp);
289 Permit();*/
290 CloseLibrary(ps);
292 return(NULL);
294 /* \\\ */
296 /* /// "usbReleaseDeviceBinding()" */
297 void usbReleaseDeviceBinding(struct NepSerialBase *nh, struct NepClassSerial *ncp)
299 struct Library *ps;
300 STRPTR devname;
302 KPRINTF(1, ("nepSerialReleaseDeviceBinding(%08lx)\n", ncp));
303 if((ps = OpenLibrary("poseidon.library", 4)))
305 Forbid();
306 ncp->ncp_ReadySignal = SIGB_SINGLE;
307 ncp->ncp_ReadySigTask = FindTask(NULL);
308 if(ncp->ncp_Task)
310 Signal(ncp->ncp_Task, SIGBREAKF_CTRL_C);
312 Permit();
313 while(ncp->ncp_Task)
315 Wait(1L<<ncp->ncp_ReadySignal);
317 //FreeSignal(ncp->ncp_ReadySignal);
318 psdGetAttrs(PGA_DEVICE, ncp->ncp_Device, DA_ProductName, &devname, TAG_END);
319 psdAddErrorMsg(RETURN_OK, (STRPTR) libname,
320 "'%s' annealed and broke off.",
321 devname);
322 /*psdFreeVec(ncp);*/
323 CloseLibrary(ps);
326 /* \\\ */
328 /* /// "usbGetAttrsA()" */
329 AROS_LH3(LONG, usbGetAttrsA,
330 AROS_LHA(ULONG, type, D0),
331 AROS_LHA(APTR, usbstruct, A0),
332 AROS_LHA(struct TagItem *, tags, A1),
333 LIBBASETYPEPTR, nh, 5, nep)
335 AROS_LIBFUNC_INIT
337 struct TagItem *ti;
338 LONG count = 0;
340 KPRINTF(1, ("nepSerialGetAttrsA(%ld, %08lx, %08lx)\n", type, usbstruct, tags));
341 switch(type)
343 case UGA_CLASS:
344 if((ti = FindTagItem(UCCA_Priority, tags)))
346 *((SIPTR *) ti->ti_Data) = 0;
347 count++;
349 if((ti = FindTagItem(UCCA_Description, tags)))
351 *((STRPTR *) ti->ti_Data) = "Palm PDA HotSync via usbpalm.device";
352 count++;
354 if((ti = FindTagItem(UCCA_HasClassCfgGUI, tags)))
356 *((IPTR *) ti->ti_Data) = TRUE;
357 count++;
359 if((ti = FindTagItem(UCCA_HasBindingCfgGUI, tags)))
361 *((IPTR *) ti->ti_Data) = FALSE;
362 count++;
364 if((ti = FindTagItem(UCCA_AfterDOSRestart, tags)))
366 *((IPTR *) ti->ti_Data) = FALSE;
367 count++;
369 if((ti = FindTagItem(UCCA_UsingDefaultCfg, tags)))
371 *((IPTR *) ti->ti_Data) = nh->nh_UsingDefaultCfg;
372 count++;
374 break;
376 case UGA_BINDING:
377 if((ti = FindTagItem(UCBA_UsingDefaultCfg, tags)))
379 *((IPTR *) ti->ti_Data) = FALSE;
380 count++;
382 break;
385 return(count);
386 AROS_LIBFUNC_EXIT
388 /* \\\ */
390 /* /// "usbSetAttrsA()" */
391 AROS_LH3(LONG, usbSetAttrsA,
392 AROS_LHA(ULONG, type, D0),
393 AROS_LHA(APTR, usbstruct, A0),
394 AROS_LHA(struct TagItem *, tags, A1),
395 LIBBASETYPEPTR, nh, 6, nep)
397 AROS_LIBFUNC_INIT
398 return(0);
399 AROS_LIBFUNC_EXIT
401 /* \\\ */
403 /* /// "usbDoMethodA()" */
404 AROS_LH2(IPTR, usbDoMethodA,
405 AROS_LHA(ULONG, methodid, D0),
406 AROS_LHA(IPTR *, methoddata, A1),
407 LIBBASETYPEPTR, nh, 7, nep)
409 AROS_LIBFUNC_INIT
411 KPRINTF(10, ("Do Method %ld\n", methodid));
412 switch(methodid)
414 case UCM_AttemptDeviceBinding:
415 return((IPTR) usbAttemptDeviceBinding(nh, (struct PsdDevice *) methoddata[0]));
417 case UCM_ForceDeviceBinding:
418 return((IPTR) usbForceDeviceBinding(nh, (struct PsdDevice *) methoddata[0]));
420 case UCM_ReleaseDeviceBinding:
421 usbReleaseDeviceBinding(nh, (struct NepClassSerial *) methoddata[0]);
422 return(TRUE);
424 case UCM_OpenCfgWindow:
425 return(nOpenCfgWindow(nh));
427 case UCM_ConfigChangedEvent:
428 nLoadClassConfig(nh);
429 return(TRUE);
431 default:
432 break;
434 return(0);
435 AROS_LIBFUNC_EXIT
437 /* \\\ */
439 /* /// "nLoadClassConfig()" */
440 BOOL nLoadClassConfig(struct NepSerialBase *nh)
442 struct Library *ps;
443 struct ClsGlobalCfg *cgc;
444 struct PsdIFFContext *pic;
446 KPRINTF(10, ("Loading Class Config...\n"));
447 if(nh->nh_GUITask)
449 return(FALSE);
451 if(!(ps = OpenLibrary("poseidon.library", 4)))
453 return(FALSE);
455 Forbid();
456 /* Create default config */
457 nh->nh_CurrentCGC.cgc_ChunkID = AROS_LONG2BE(MAKE_ID('P','A','L','M'));
458 nh->nh_CurrentCGC.cgc_Length = AROS_LONG2BE(sizeof(struct ClsGlobalCfg)-8);
459 nh->nh_CurrentCGC.cgc_ShellStack = AROS_STACKSIZE;
460 strcpy(nh->nh_CurrentCGC.cgc_ShellCon, "CON:///130/Palm HotSync Launcher/CLOSE/AUTO/WAIT");
461 strcpy(nh->nh_CurrentCGC.cgc_InhibitTask, "SpitfireHSM");
462 nh->nh_UsingDefaultCfg = TRUE;
463 pic = psdGetClsCfg(libname);
464 if(pic)
466 if((cgc = psdGetCfgChunk(pic, AROS_LONG2BE(nh->nh_CurrentCGC.cgc_ChunkID))))
468 CopyMem(((UBYTE *) cgc) + 8, ((UBYTE *) &nh->nh_CurrentCGC) + 8, min(AROS_LONG2BE(cgc->cgc_Length), AROS_LONG2BE(nh->nh_CurrentCGC.cgc_Length)));
469 psdFreeVec(cgc);
470 nh->nh_UsingDefaultCfg = FALSE;
473 Permit();
474 CloseLibrary(ps);
475 return(FALSE);
477 /* \\\ */
479 /* /// "nOpenCfgWindow()" */
480 LONG nOpenCfgWindow(struct NepSerialBase *nh)
482 struct Library *ps;
483 KPRINTF(10, ("Opening GUI...\n"));
484 if(!(ps = OpenLibrary("poseidon.library", 4)))
486 return(FALSE);
488 Forbid();
489 if(!nh->nh_GUITask)
491 if((nh->nh_GUITask = psdSpawnSubTask(MOD_NAME_STRING " GUI", nGUITask, nh)))
493 Permit();
494 CloseLibrary(ps);
495 return(TRUE);
498 Permit();
499 CloseLibrary(ps);
500 return(FALSE);
502 /* \\\ */
504 /**************************************************************************/
506 #undef ps
507 #define ps ncp->ncp_Base
509 /* /// "nSetSerialMode()" */
510 void nSetSerialMode(struct NepClassSerial *ncp, struct IOExtSer *ioreq)
512 ncp->ncp_IsConfigured = TRUE;
514 /* \\\ */
516 /* /// "nSerialTask()" */
517 AROS_UFH0(void, nSerialTask)
519 AROS_USERFUNC_INIT
521 struct NepClassSerial *ncp;
522 struct NepSerialBase *nh;
523 ULONG sigmask;
524 ULONG sigs;
525 LONG ioerr;
526 IPTR pending;
527 struct IOExtSer *ioreq;
528 struct IOExtSer *ioreq2;
530 if((ncp = nAllocSerial()))
532 KPRINTF(1, ("nSerialTask()\n"));
533 Forbid();
534 if(ncp->ncp_ReadySigTask)
536 Signal(ncp->ncp_ReadySigTask, 1UL<<ncp->ncp_ReadySignal);
538 Permit();
539 nh = ncp->ncp_DevBase->np_ClsBase;
541 /* Main task */
542 sigmask = (1UL<<ncp->ncp_Unit.unit_MsgPort.mp_SigBit)|(1UL<<ncp->ncp_TaskMsgPort->mp_SigBit)|SIGBREAKF_CTRL_C;
544 struct MsgPort *tmpmp = NULL;
545 psdGetAttrs(PGA_PIPESTREAM, ncp->ncp_EPInStream, PSA_MessagePort, &tmpmp, TAG_END);
546 if(tmpmp)
548 sigmask |= (1UL<<tmpmp->mp_SigBit);
551 /* check, if we need to execute a command? */
552 if(*nh->nh_CurrentCGC.cgc_Command)
554 BOOL launch = TRUE;
555 if(nh->nh_CurrentCGC.cgc_InhibitTask)
557 if(FindTask(nh->nh_CurrentCGC.cgc_InhibitTask))
559 launch = FALSE;
562 if(launch)
564 struct Library *dosbase;
565 if((dosbase = OpenLibrary("dos.library", 39)))
567 BPTR fhandle;
568 LONG ioerr;
569 #define DOSBase dosbase
570 if((fhandle = Open(nh->nh_CurrentCGC.cgc_ShellCon, MODE_READWRITE)))
572 ioerr = SystemTags(nh->nh_CurrentCGC.cgc_Command,
573 SYS_Input, fhandle,
574 SYS_Output, NULL,
575 SYS_Asynch, TRUE,
576 NP_StackSize, nh->nh_CurrentCGC.cgc_ShellStack,
577 TAG_END);
578 if(ioerr)
580 psdAddErrorMsg(RETURN_ERROR, (STRPTR) libname,
581 "Execution of '%s' failed (%ld).",
582 nh->nh_CurrentCGC.cgc_Command, ioerr);
583 Close(fhandle);
584 } else {
585 psdAddErrorMsg(RETURN_OK, (STRPTR) libname,
586 "Launching '%s'...",
587 nh->nh_CurrentCGC.cgc_Command);
589 } else {
590 psdAddErrorMsg(RETURN_ERROR, (STRPTR) libname,
591 "Console '%s' could not be opened!",
592 nh->nh_CurrentCGC.cgc_ShellCon);
594 CloseLibrary(dosbase);
595 #undef DOSBase
599 //nServerRitual(ncp);
602 while((ioreq = (struct IOExtSer *) GetMsg(&ncp->ncp_Unit.unit_MsgPort)))
604 KPRINTF(5, ("command ioreq: 0x%08lx cmd: %lu len: %ld\n",
605 ioreq, ioreq->IOSer.io_Command, ioreq->IOSer.io_Length));
606 switch(ioreq->IOSer.io_Command)
608 case CMD_CLEAR:
609 psdStreamFlush(ncp->ncp_EPOutStream);
610 ReplyMsg((struct Message *) ioreq);
611 break;
613 case CMD_RESET:
614 /* Reset does a flush too */
615 case CMD_FLUSH:
616 Forbid();
617 ioreq2 = (struct IOExtSer *) ncp->ncp_WriteQueue.lh_Head;
618 while(ioreq2->IOSer.io_Message.mn_Node.ln_Succ)
620 Remove((struct Node *) ioreq2);
621 ioreq2->IOSer.io_Error = IOERR_ABORTED;
622 ReplyMsg((struct Message *) ioreq2);
623 ioreq2 = (struct IOExtSer *) ncp->ncp_WriteQueue.lh_Head;
625 ioreq2 = (struct IOExtSer *) ncp->ncp_ReadQueue.lh_Head;
626 while(ioreq2->IOSer.io_Message.mn_Node.ln_Succ)
628 Remove((struct Node *) ioreq2);
629 ioreq2->IOSer.io_Error = IOERR_ABORTED;
630 ReplyMsg((struct Message *) ioreq2);
631 ioreq2 = (struct IOExtSer *) ncp->ncp_ReadQueue.lh_Head;
633 ReplyMsg((struct Message *) ioreq);
634 Permit();
635 break;
637 case SDCMD_SETPARAMS:
638 nSetSerialMode(ncp, ioreq);
639 ReplyMsg((struct Message *) ioreq);
640 break;
642 case SDCMD_QUERY:
643 ioreq->io_Status = (1<<5);
644 pending = 0;
645 psdGetAttrs(PGA_PIPESTREAM, ncp->ncp_EPInStream,
646 PSA_BytesPending, &pending,
647 TAG_END);
648 ioreq->IOSer.io_Actual = pending;
649 if(!ioreq->IOSer.io_Actual)
651 ioreq->IOSer.io_Actual = 1;
653 ReplyMsg((struct Message *) ioreq);
654 break;
656 case CMD_INVALID:
657 psdStreamFlush(ncp->ncp_EPInStream);
658 psdPipeSetup(ncp->ncp_EP0Pipe, URTF_IN|URTF_VENDOR|URTF_ENDPOINT,
659 UPR_CLOSE_NOTIFICATION, 0, 0);
660 ioerr = psdDoPipe(ncp->ncp_EP0Pipe, NULL, 0);
661 if(ioerr)
663 psdAddErrorMsg(RETURN_WARN, (STRPTR) libname,
664 "CLOSE_NOTIFICATION failed: %s (%ld)",
665 psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
667 ReplyMsg((struct Message *) ioreq);
668 break;
670 default:
671 ioreq->IOSer.io_Error = IOERR_NOCMD;
672 ReplyMsg((struct Message *) ioreq);
673 break;
676 if(!ncp->ncp_DevSuspend)
678 Forbid();
679 ioreq = (struct IOExtSer *) ncp->ncp_ReadQueue.lh_Head;
680 while(ioreq->IOSer.io_Message.mn_Node.ln_Succ)
682 if(!ncp->ncp_IsConfigured)
684 Permit();
685 nSetSerialMode(ncp, ioreq);
686 Forbid();
688 Remove((struct Node *) ioreq);
689 Permit();
690 ioreq->IOSer.io_Actual = psdStreamRead(ncp->ncp_EPInStream, ioreq->IOSer.io_Data, ioreq->IOSer.io_Length);
691 ioerr = psdGetStreamError(ncp->ncp_EPInStream);
692 if(ioerr == UHIOERR_NAKTIMEOUT)
694 Forbid();
695 AddHead(&ncp->ncp_ReadQueue, &ioreq->IOSer.io_Message.mn_Node);
696 break;
697 } else {
698 if(ioerr > 0)
700 ioreq->IOSer.io_Error = SerErr_LineErr;
701 } else {
702 ioreq->IOSer.io_Error = ioerr;
704 ReplyMsg((struct Message *) ioreq);
706 psdGetAttrs(PGA_PIPESTREAM, ncp->ncp_EPInStream,
707 PSA_BytesPending, &pending,
708 TAG_END);
709 Forbid();
710 ioreq = (struct IOExtSer *) ncp->ncp_ReadQueue.lh_Head;
712 ioreq = (struct IOExtSer *) ncp->ncp_WriteQueue.lh_Head;
713 while(ioreq->IOSer.io_Message.mn_Node.ln_Succ)
715 if(!ncp->ncp_IsConfigured)
717 Permit();
718 nSetSerialMode(ncp, ioreq);
719 Forbid();
721 Remove((struct Node *) ioreq);
722 ncp->ncp_WritePending = ioreq;
723 Permit();
724 ioreq->IOSer.io_Actual = psdStreamWrite(ncp->ncp_EPOutStream, ioreq->IOSer.io_Data, ioreq->IOSer.io_Length);
725 ncp->ncp_WritePending = NULL;
726 ioerr = psdGetStreamError(ncp->ncp_EPInStream);
727 if(ioerr > 0)
729 ioreq->IOSer.io_Error = SerErr_LineErr;
730 } else {
731 ioreq->IOSer.io_Error = ioerr;
733 ReplyMsg((struct Message *) ioreq);
734 Forbid();
735 ioreq = (struct IOExtSer *) ncp->ncp_WriteQueue.lh_Head;
737 Permit();
739 sigs = Wait(sigmask);
740 } while(!(sigs & SIGBREAKF_CTRL_C));
741 KPRINTF(1, ("Going down...\n"));
742 /* Now remove all requests still pending *anywhere* */
743 ncp->ncp_DenyRequests = TRUE;
744 /* Read/Write queues */
745 Forbid();
746 ioreq = (struct IOExtSer *) ncp->ncp_WriteQueue.lh_Head;
747 while(ioreq->IOSer.io_Message.mn_Node.ln_Succ)
749 Remove((struct Node *) ioreq);
750 ioreq->IOSer.io_Error = IOERR_ABORTED;
751 ReplyMsg((struct Message *) ioreq);
752 ioreq = (struct IOExtSer *) ncp->ncp_WriteQueue.lh_Head;
754 ioreq = (struct IOExtSer *) ncp->ncp_ReadQueue.lh_Head;
755 while(ioreq->IOSer.io_Message.mn_Node.ln_Succ)
757 Remove((struct Node *) ioreq);
758 ioreq->IOSer.io_Error = IOERR_ABORTED;
759 ReplyMsg((struct Message *) ioreq);
760 ioreq = (struct IOExtSer *) ncp->ncp_ReadQueue.lh_Head;
762 /* Command queue */
763 while((ioreq = (struct IOExtSer *) GetMsg(&ncp->ncp_Unit.unit_MsgPort)))
765 ioreq->IOSer.io_Error = IOERR_ABORTED;
766 ReplyMsg((struct Message *) ioreq);
768 Permit();
769 KPRINTF(20, ("Going down the river!\n"));
770 nFreeSerial(ncp);
773 AROS_USERFUNC_EXIT
775 /* \\\ */
777 /* /// "nAllocSerial()" */
778 struct NepClassSerial * nAllocSerial(void)
780 struct Task *thistask;
781 struct NepClassSerial *ncp;
782 LONG ioerr;
783 ULONG cnt;
784 UWORD dummy;
786 thistask = FindTask(NULL);
787 ncp = thistask->tc_UserData;
790 if(!(ncp->ncp_Base = OpenLibrary("poseidon.library", 4)))
792 Alert(AG_OpenLib);
793 break;
795 if(!(ncp->ncp_Interface = psdFindInterface(ncp->ncp_Device, NULL, TAG_END)))
797 psdAddErrorMsg(RETURN_FAIL, (STRPTR) libname, "No interface found?!?");
798 break;
801 if((ncp->ncp_TaskMsgPort = CreateMsgPort()))
803 if((ncp->ncp_EP0Pipe = psdAllocPipe(ncp->ncp_Device, ncp->ncp_TaskMsgPort, NULL)))
805 psdPipeSetup(ncp->ncp_EP0Pipe, URTF_IN|URTF_VENDOR|URTF_ENDPOINT,
806 UPR_GET_EXT_CONNECTION_INFORMATION, 0, 0);
807 ioerr = psdDoPipe(ncp->ncp_EP0Pipe, &ncp->ncp_ExtConnectInfo, sizeof(struct ExtConnectInfo));
808 ncp->ncp_ExtConnectInfo.Streams[0].FctID = AROS_LONG2LE(ncp->ncp_ExtConnectInfo.Streams[0].FctID);
809 ncp->ncp_ExtConnectInfo.Streams[1].FctID = AROS_LONG2LE(ncp->ncp_ExtConnectInfo.Streams[1].FctID);
810 if(!ioerr)
812 for(cnt = 0; cnt < ncp->ncp_ExtConnectInfo.NumPorts; cnt++)
814 switch(ncp->ncp_ExtConnectInfo.Streams[cnt].FctID)
816 case MAKE_ID('s','y','n','c'):
817 psdAddErrorMsg(RETURN_OK, (STRPTR) libname, "There's that hotsync port (%ld) we've been looking for!", cnt+1);
818 ncp->ncp_HotsyncPort = cnt+1;
819 if(ncp->ncp_ExtConnectInfo.DiffEndPoints)
821 ncp->ncp_EPInNum = (ncp->ncp_ExtConnectInfo.Streams[cnt].EPInfo >> 4) & 15;
822 ncp->ncp_EPOutNum = ncp->ncp_ExtConnectInfo.Streams[cnt].EPInfo & 15;
823 } else {
824 ncp->ncp_EPInNum = ncp->ncp_EPOutNum = ncp->ncp_ExtConnectInfo.Streams[cnt].Port;
826 break;
828 default:
830 char fctid[5];
831 memcpy(fctid, &ncp->ncp_ExtConnectInfo.Streams[cnt].FctID, 4);
832 fctid[4] = 0;
833 psdAddErrorMsg(RETURN_WARN, (STRPTR) libname, "Unknown function %s at PDA port %ld!", fctid, cnt+1);
837 } else {
838 psdAddErrorMsg(RETURN_FAIL, (STRPTR) libname,
839 "GET_EXT_CONNECTION_INFORMATION failed: %s (%ld)",
840 psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
841 psdPipeSetup(ncp->ncp_EP0Pipe, URTF_IN|URTF_VENDOR|URTF_ENDPOINT,
842 UPR_GET_CONNECTION_INFORMATION, 0, 0);
843 ioerr = psdDoPipe(ncp->ncp_EP0Pipe, &ncp->ncp_ConnectInfo, sizeof(struct ConnectInfo));
844 ncp->ncp_ConnectInfo.NumPorts = AROS_WORD2LE(ncp->ncp_ConnectInfo.NumPorts);
845 if(!ioerr)
847 for(cnt = 0; cnt < ncp->ncp_ConnectInfo.NumPorts; cnt++)
849 switch(ncp->ncp_ConnectInfo.Streams[cnt].FctID)
851 case PALM_FUNCTION_GENERIC:
852 psdAddErrorMsg(RETURN_OK, (STRPTR) libname, "This PDA has a generic port (%ld)!", cnt+1);
853 //ncp->ncp_HotsyncPort = cnt+1;
854 break;
856 case PALM_FUNCTION_DEBUGGER:
857 psdAddErrorMsg(RETURN_OK, (STRPTR) libname, "Uuuuh, your PDA has a debugging port (%ld) aswell!", cnt+1);
858 break;
860 case PALM_FUNCTION_HOTSYNC:
861 psdAddErrorMsg(RETURN_OK, (STRPTR) libname, "There's that hotsync port (%ld) we've been looking for!", cnt+1);
862 ncp->ncp_HotsyncPort = cnt+1;
863 ncp->ncp_EPOutNum = cnt+1;
864 ncp->ncp_EPInNum = cnt+1;
865 break;
867 case PALM_FUNCTION_CONSOLE:
868 psdAddErrorMsg(RETURN_OK, (STRPTR) libname, "Your PDA supplies a console port (%ld). Nice!", cnt+1);
869 break;
871 case PALM_FUNCTION_REMOTE_FILE_SYS:
872 psdAddErrorMsg(RETURN_OK, (STRPTR) libname, "Holy Cow! There's a remote file system port (%ld)!", cnt+1);
873 break;
875 default:
876 psdAddErrorMsg(RETURN_WARN, (STRPTR) libname,
877 "Unknown function %02lx at PDA port %ld!",
878 ncp->ncp_ConnectInfo.Streams[cnt].FctID,
879 cnt+1);
880 break;
884 psdPipeSetup(ncp->ncp_EP0Pipe, URTF_IN|URTF_VENDOR|URTF_ENDPOINT,
885 UPR_REQUEST_BYTES_AVAILABLE, 0, 5);
886 ioerr = psdDoPipe(ncp->ncp_EP0Pipe, &dummy, 2);
887 if(ioerr)
889 psdAddErrorMsg(RETURN_FAIL, (STRPTR) libname,
890 "REQUEST_BYTES_AVAILABLE failed: %s (%ld)",
891 psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
893 } else {
894 psdAddErrorMsg(RETURN_FAIL, (STRPTR) libname,
895 "GET_CONNECTION_INFORMATION failed: %s (%ld)",
896 psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
899 if(ncp->ncp_HotsyncPort)
901 ncp->ncp_EPIn = psdFindEndpoint(ncp->ncp_Interface, NULL,
902 EA_EndpointNum, ncp->ncp_EPInNum,
903 EA_IsIn, TRUE,
904 EA_TransferType, USEAF_BULK,
905 TAG_END);
906 ncp->ncp_EPOut = psdFindEndpoint(ncp->ncp_Interface, NULL,
907 EA_EndpointNum, ncp->ncp_EPOutNum,
908 EA_IsIn, FALSE,
909 EA_TransferType, USEAF_BULK,
910 TAG_END);
911 if(ncp->ncp_EPIn && ncp->ncp_EPOut)
913 ncp->ncp_AbortSignal = AllocSignal(-1);
914 if((ncp->ncp_EPOutStream = psdOpenStream(ncp->ncp_EPOut,
915 PSA_BufferedWrite, FALSE,
916 PSA_NoZeroPktTerm, TRUE,
917 PSA_NakTimeout, TRUE,
918 PSA_NakTimeoutTime, 5000,
919 PSA_AbortSigMask, (1UL<<ncp->ncp_AbortSignal)|SIGBREAKF_CTRL_C,
920 TAG_END)))
922 if((ncp->ncp_EPInStream = psdOpenStream(ncp->ncp_EPIn,
923 PSA_ReadAhead, FALSE,
924 PSA_BufferedRead, TRUE,
925 PSA_NumPipes, NUMREADPIPES,
926 PSA_BufferSize, DEFREADBUFLEN,
927 PSA_AllowRuntPackets, TRUE,
928 PSA_DoNotWait, FALSE,
929 PSA_NakTimeout, TRUE,
930 PSA_NakTimeoutTime, 5000,
931 PSA_AbortSigMask, SIGBREAKF_CTRL_C,
932 TAG_END)))
934 ncp->ncp_Unit.unit_MsgPort.mp_SigBit = AllocSignal(-1);
935 ncp->ncp_Unit.unit_MsgPort.mp_SigTask = thistask;
936 ncp->ncp_Unit.unit_MsgPort.mp_Node.ln_Type = NT_MSGPORT;
937 ncp->ncp_Unit.unit_MsgPort.mp_Flags = PA_SIGNAL;
938 ncp->ncp_WritePending = NULL;
939 ncp->ncp_Task = thistask;
940 return(ncp);
942 psdCloseStream(ncp->ncp_EPOutStream);
944 FreeSignal(ncp->ncp_AbortSignal);
945 } else {
946 psdAddErrorMsg(RETURN_FAIL, (STRPTR) libname, "Unable to find endpoints for hotsync port!");
948 } else {
949 psdAddErrorMsg(RETURN_FAIL, (STRPTR) libname, "Sorry, there's no hotsync port! Giving up!");
951 psdFreePipe(ncp->ncp_EP0Pipe);
953 DeleteMsgPort(ncp->ncp_TaskMsgPort);
955 } while(FALSE);
956 CloseLibrary(ncp->ncp_Base);
957 Forbid();
958 ncp->ncp_Task = NULL;
959 if(ncp->ncp_ReadySigTask)
961 Signal(ncp->ncp_ReadySigTask, 1UL<<ncp->ncp_ReadySignal);
963 return(NULL);
965 /* \\\ */
967 /* /// "nFreeSerial()" */
968 void nFreeSerial(struct NepClassSerial *ncp)
970 struct IOStdReq *ioreq;
971 Forbid();
972 FreeSignal(ncp->ncp_AbortSignal);
973 ncp->ncp_AbortSignal = -1;
974 /* Disable the message port, messages may still be queued */
975 ncp->ncp_Unit.unit_MsgPort.mp_SigTask = NULL;
976 ncp->ncp_Unit.unit_MsgPort.mp_Flags = PA_IGNORE;
977 FreeSignal((LONG) ncp->ncp_Unit.unit_MsgPort.mp_SigBit);
978 // get rid of all messages that still have appeared here
979 while((ioreq = (struct IOStdReq *) GetMsg(&ncp->ncp_Unit.unit_MsgPort)))
981 ioreq->io_Error = IOERR_ABORTED;
982 ReplyMsg((struct Message *) ioreq);
984 Permit();
986 psdCloseStream(ncp->ncp_EPInStream);
987 psdCloseStream(ncp->ncp_EPOutStream);
988 psdFreePipe(ncp->ncp_EP0Pipe);
990 DeleteMsgPort(ncp->ncp_TaskMsgPort);
991 CloseLibrary(ncp->ncp_Base);
992 Forbid();
993 ncp->ncp_Task = NULL;
994 if(ncp->ncp_ReadySigTask)
996 Signal(ncp->ncp_ReadySigTask, 1UL<<ncp->ncp_ReadySignal);
999 /* \\\ */
1001 /**************************************************************************/
1003 /* /// "nGUITask()" */
1004 AROS_UFH0(void, nGUITask)
1006 AROS_USERFUNC_INIT
1008 struct Task *thistask;
1009 struct NepSerialBase *nh;
1010 APTR pic;
1012 thistask = FindTask(NULL);
1013 #undef ps
1014 #define ps nh->nh_PsdBase
1015 #undef IntuitionBase
1016 #define IntuitionBase nh->nh_IntBase
1017 #undef MUIMasterBase
1018 #define MUIMasterBase nh->nh_MUIBase
1020 nh = thistask->tc_UserData;
1021 ++nh->nh_Library.lib_OpenCnt;
1022 if(!(MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN)))
1024 KPRINTF(10, ("Couldn't open muimaster.library.\n"));
1025 nGUITaskCleanup(nh);
1026 return;
1029 if(!(IntuitionBase = OpenLibrary("intuition.library", 39)))
1031 KPRINTF(10, ("Couldn't open intuition.library.\n"));
1032 nGUITaskCleanup(nh);
1033 return;
1035 if(!(ps = OpenLibrary("poseidon.library", 4)))
1037 KPRINTF(10, ("Couldn't open poseidon.library.\n"));
1038 nGUITaskCleanup(nh);
1039 return;
1042 nh->nh_App = ApplicationObject,
1043 MUIA_Application_Title , (IPTR)libname,
1044 MUIA_Application_Version , (IPTR)VERSION_STRING,
1045 MUIA_Application_Copyright , (IPTR)"©2004-2009 Chris Hodges",
1046 MUIA_Application_Author , (IPTR)"Chris Hodges <chrisly@platon42.de>",
1047 MUIA_Application_Description, (IPTR)"Settings for the palmpda.class",
1048 MUIA_Application_Base , (IPTR)"PALMPDA",
1049 MUIA_Application_HelpFile , (IPTR)"HELP:Poseidon.guide",
1050 MUIA_Application_Menustrip , (IPTR)MenustripObject,
1051 Child, (IPTR)MenuObjectT((IPTR)"Project"),
1052 Child, (IPTR)(nh->nh_AboutMI = MenuitemObject,
1053 MUIA_Menuitem_Title, (IPTR)"About...",
1054 MUIA_Menuitem_Shortcut, (IPTR)"?",
1055 End),
1056 End,
1057 Child, (IPTR)MenuObjectT((IPTR)"Settings"),
1058 Child, (IPTR)(nh->nh_UseMI = MenuitemObject,
1059 MUIA_Menuitem_Title, (IPTR)"Save",
1060 MUIA_Menuitem_Shortcut, (IPTR)"S",
1061 End),
1062 Child, (IPTR)MenuitemObject,
1063 MUIA_Menuitem_Title, (IPTR)NM_BARLABEL,
1064 End,
1065 Child, (IPTR)(nh->nh_MUIPrefsMI = MenuitemObject,
1066 MUIA_Menuitem_Title, (IPTR)"MUI Settings",
1067 MUIA_Menuitem_Shortcut, (IPTR)"M",
1068 End),
1069 End,
1070 End,
1072 SubWindow, (IPTR)(nh->nh_MainWindow = WindowObject,
1073 MUIA_Window_ID , MAKE_ID('M','A','I','N'),
1074 MUIA_Window_Title, (IPTR)libname,
1075 MUIA_HelpNode, (IPTR)libname,
1077 WindowContents, (IPTR)VGroup,
1078 /* Child, actionobj = NewObject(ActionClass->mcc_Class, 0,
1079 MUIA_ShowMe, FALSE,
1080 End, */
1081 Child, (IPTR)ColGroup(2), GroupFrameT((IPTR)"Global Settings"),
1082 Child, (IPTR)Label((IPTR) "Shell console window:"),
1083 Child, (IPTR)(nh->nh_ConWindowObj = StringObject,
1084 StringFrame,
1085 MUIA_CycleChain, 1,
1086 MUIA_String_AdvanceOnCR, TRUE,
1087 MUIA_String_Contents, (IPTR)nh->nh_CurrentCGC.cgc_ShellCon,
1088 MUIA_String_MaxLen, 128,
1089 End),
1090 Child, (IPTR)Label((IPTR) "Shell default stack:"),
1091 Child, (IPTR)(nh->nh_ShellStackObj = StringObject,
1092 StringFrame,
1093 MUIA_CycleChain, 1,
1094 MUIA_String_AdvanceOnCR, TRUE,
1095 MUIA_String_Integer, nh->nh_CurrentCGC.cgc_ShellStack,
1096 MUIA_String_Accept, (IPTR)"0123456789",
1097 End),
1098 Child, (IPTR)Label((IPTR) "Command:"),
1099 Child, (IPTR)PopaslObject,
1100 MUIA_Popstring_String, (IPTR)(nh->nh_ShellComObj = StringObject,
1101 StringFrame,
1102 MUIA_CycleChain, 1,
1103 MUIA_String_AdvanceOnCR, TRUE,
1104 MUIA_String_Contents, (IPTR)nh->nh_CurrentCGC.cgc_Command,
1105 MUIA_String_MaxLen, 256,
1106 End),
1107 MUIA_Popstring_Button, (IPTR)PopButton(MUII_PopFile),
1108 ASLFR_TitleText, (IPTR)"Select an executable...",
1109 End,
1110 Child, (IPTR)Label((IPTR) "Don't launch, when this task found:"),
1111 Child, (IPTR)(nh->nh_InhibitTaskObj = StringObject,
1112 StringFrame,
1113 MUIA_CycleChain, 1,
1114 MUIA_String_AdvanceOnCR, TRUE,
1115 MUIA_String_Contents, (IPTR)nh->nh_CurrentCGC.cgc_InhibitTask,
1116 MUIA_String_MaxLen, 64,
1117 End),
1118 End,
1119 Child, (IPTR)VSpace(0),
1120 Child, (IPTR)HGroup,
1121 MUIA_Group_SameWidth, TRUE,
1122 Child, (IPTR)(nh->nh_UseObj = TextObject, ButtonFrame,
1123 MUIA_Background, MUII_ButtonBack,
1124 MUIA_CycleChain, 1,
1125 MUIA_InputMode, MUIV_InputMode_RelVerify,
1126 MUIA_Text_Contents, (IPTR)"\33c Save ",
1127 End),
1128 Child, (IPTR)(nh->nh_CloseObj = TextObject, ButtonFrame,
1129 MUIA_Background, MUII_ButtonBack,
1130 MUIA_CycleChain, 1,
1131 MUIA_InputMode, MUIV_InputMode_RelVerify,
1132 MUIA_Text_Contents, (IPTR)"\33c Use ",
1133 End),
1134 End,
1135 End,
1136 End),
1137 End;
1139 if(!nh->nh_App)
1141 KPRINTF(10, ("Couldn't create application\n"));
1142 nGUITaskCleanup(nh);
1143 return;
1145 DoMethod(nh->nh_MainWindow, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
1146 nh->nh_App, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
1147 DoMethod(nh->nh_UseObj, MUIM_Notify, MUIA_Pressed, FALSE,
1148 nh->nh_App, 2, MUIM_Application_ReturnID, ID_STORE_CONFIG);
1149 DoMethod(nh->nh_CloseObj, MUIM_Notify, MUIA_Pressed, FALSE,
1150 nh->nh_App, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
1152 DoMethod(nh->nh_AboutMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
1153 nh->nh_App, 2, MUIM_Application_ReturnID, ID_ABOUT);
1154 DoMethod(nh->nh_UseMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
1155 nh->nh_App, 2, MUIM_Application_ReturnID, ID_STORE_CONFIG);
1156 DoMethod(nh->nh_MUIPrefsMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
1157 nh->nh_App, 2, MUIM_Application_OpenConfigWindow, 0);
1160 IPTR isopen = 0;
1161 IPTR iconify = 0;
1162 ULONG sigs;
1163 ULONG sigmask;
1164 LONG retid;
1166 get(nh->nh_App, MUIA_Application_Iconified, &iconify);
1167 set(nh->nh_MainWindow, MUIA_Window_Open, TRUE);
1168 get(nh->nh_MainWindow, MUIA_Window_Open, &isopen);
1169 if(!(isopen || iconify))
1171 nGUITaskCleanup(nh);
1172 return;
1174 sigmask = 0;
1177 retid = DoMethod(nh->nh_App, MUIM_Application_NewInput, &sigs);
1178 switch(retid)
1180 case ID_STORE_CONFIG:
1181 case MUIV_Application_ReturnID_Quit:
1183 STRPTR tmpstr = NULL;
1185 get(nh->nh_ShellStackObj, MUIA_String_Integer, &nh->nh_CurrentCGC.cgc_ShellStack);
1186 get(nh->nh_ConWindowObj, MUIA_String_Contents, &tmpstr);
1187 strncpy(nh->nh_CurrentCGC.cgc_ShellCon, tmpstr, 127);
1188 get(nh->nh_ShellComObj, MUIA_String_Contents, &tmpstr);
1189 strncpy(nh->nh_CurrentCGC.cgc_Command, tmpstr, 255);
1190 get(nh->nh_InhibitTaskObj, MUIA_String_Contents, &tmpstr);
1191 strncpy(nh->nh_CurrentCGC.cgc_InhibitTask, tmpstr, 63);
1192 pic = psdGetClsCfg(libname);
1193 if(!pic)
1195 psdSetClsCfg(libname, NULL);
1196 pic = psdGetClsCfg(libname);
1198 if(pic)
1200 if(psdAddCfgEntry(pic, &nh->nh_CurrentCGC))
1202 if(retid != MUIV_Application_ReturnID_Quit)
1204 psdSaveCfgToDisk(NULL, FALSE);
1206 retid = MUIV_Application_ReturnID_Quit;
1209 break;
1211 case ID_ABOUT:
1212 MUI_RequestA(nh->nh_App, nh->nh_MainWindow, 0, NULL, "Hot stuff!", VERSION_STRING, NULL);
1213 break;
1215 if(retid == MUIV_Application_ReturnID_Quit)
1217 break;
1219 if(sigs)
1221 sigs = Wait(sigs | sigmask | SIGBREAKF_CTRL_C);
1222 if(sigs & SIGBREAKF_CTRL_C)
1224 break;
1227 } while(TRUE);
1228 set(nh->nh_MainWindow, MUIA_Window_Open, FALSE);
1230 nGUITaskCleanup(nh);
1232 AROS_USERFUNC_EXIT
1234 /* \\\ */
1236 /* /// "nGUITaskCleanup()" */
1237 void nGUITaskCleanup(struct NepSerialBase *nh)
1239 if(nh->nh_App)
1241 MUI_DisposeObject(nh->nh_App);
1242 nh->nh_App = NULL;
1244 if(MUIMasterBase)
1246 CloseLibrary(MUIMasterBase);
1247 MUIMasterBase = NULL;
1249 if(IntuitionBase)
1251 CloseLibrary(IntuitionBase);
1252 IntuitionBase = NULL;
1254 if(ps)
1256 CloseLibrary(ps);
1257 ps = NULL;
1259 Forbid();
1260 nh->nh_GUITask = NULL;
1261 --nh->nh_Library.lib_OpenCnt;
1263 /* \\\ */