revert between 56095 -> 55830 in arch
[AROS.git] / rom / usb / classes / bootmouse / bootmouse.class.c
blob7ab9e55c3028ceb8222b387ae68bb3a499e83c10
1 /*
2 *----------------------------------------------------------------------------
3 * bootmouse class for poseidon
4 *----------------------------------------------------------------------------
5 * By Chris Hodges <chrisly@platon42.de>
6 */
8 #include "debug.h"
10 #include "bootmouse.class.h"
12 /* /// "Lib Stuff" */
13 static const STRPTR libname = MOD_NAME_STRING;
15 static int libInit(LIBBASETYPEPTR nh)
17 KPRINTF(10, ("libInit nh: 0x%08lx SysBase: 0x%08lx\n", nh, SysBase));
19 nh->nh_UtilityBase = OpenLibrary("utility.library", 39);
21 #define UtilityBase nh->nh_UtilityBase
23 if(UtilityBase)
25 struct NepClassHid *nch;
26 NewList(&nh->nh_Bindings);
27 nch = &nh->nh_DummyNCH;
28 nch->nch_ClsBase = nh;
29 nch->nch_Interface = NULL;
30 nch->nch_CDC = AllocVec(sizeof(struct ClsDevCfg), MEMF_PUBLIC|MEMF_CLEAR);
31 if(!nch->nch_CDC)
33 return FALSE;
35 } else {
36 KPRINTF(20, ("libInit: OpenLibrary(\"utility.library\", 39) failed!\n"));
37 return FALSE;
40 KPRINTF(10, ("libInit: Ok\n"));
41 return TRUE;
44 static int libOpen(LIBBASETYPEPTR nh)
46 KPRINTF(10, ("libOpen nh: 0x%08lx\n", nh));
47 nLoadClassConfig(nh);
48 return TRUE;
51 static int libExpunge(LIBBASETYPEPTR nh)
53 KPRINTF(10, ("libExpunge nh: 0x%08lx SysBase: 0x%08lx\n", nh, SysBase));
54 CloseLibrary(UtilityBase);
55 FreeVec(nh->nh_DummyNCH.nch_CDC);
56 return TRUE;
59 ADD2INITLIB(libInit, 0)
60 ADD2OPENLIB(libOpen, 0)
61 ADD2EXPUNGELIB(libExpunge, 0)
62 /* \\\ */
65 * ***********************************************************************
66 * * Library functions *
67 * ***********************************************************************
70 /* /// "usbAttemptInterfaceBinding()" */
71 struct NepClassHid * usbAttemptInterfaceBinding(struct NepHidBase *nh, struct PsdInterface *pif)
73 struct Library *ps;
74 IPTR ifclass;
75 IPTR subclass;
76 IPTR proto;
78 KPRINTF(1, ("nepHidAttemptInterfaceBinding(%08lx)\n", pif));
79 if((ps = OpenLibrary("poseidon.library", 4)))
81 psdGetAttrs(PGA_INTERFACE, pif,
82 IFA_Class, &ifclass,
83 IFA_SubClass, &subclass,
84 IFA_Protocol, &proto,
85 TAG_DONE);
86 CloseLibrary(ps);
88 if((ifclass == HID_CLASSCODE) && (subclass == HID_BOOT_SUBCLASS) && (proto == HID_PROTO_MOUSE))
90 return(usbForceInterfaceBinding(nh, pif));
93 return(NULL);
95 /* \\\ */
97 /* /// "usbForceInterfaceBinding()" */
98 struct NepClassHid * usbForceInterfaceBinding(struct NepHidBase *nh, struct PsdInterface *pif)
100 struct Library *ps;
101 struct NepClassHid *nch;
102 struct PsdConfig *pc;
103 struct PsdDevice *pd;
104 STRPTR devname;
105 STRPTR ifidstr;
106 STRPTR devidstr;
107 UBYTE buf[64];
108 struct Task *tmptask;
110 KPRINTF(1, ("nepHidForceInterfaceBinding(%08lx)\n", pif));
111 if((ps = OpenLibrary("poseidon.library", 4)))
113 psdGetAttrs(PGA_INTERFACE, pif,
114 IFA_Config, &pc,
115 IFA_IDString, &ifidstr,
116 TAG_DONE);
117 psdGetAttrs(PGA_CONFIG, pc,
118 CA_Device, &pd,
119 TAG_END);
120 psdGetAttrs(PGA_DEVICE, pd,
121 DA_ProductName, &devname,
122 DA_IDString, &devidstr,
123 TAG_END);
124 if((nch = psdAllocVec(sizeof(struct NepClassHid))))
126 nch->nch_ClsBase = nh;
127 nch->nch_CDC = psdAllocVec(sizeof(struct ClsDevCfg));
128 if(!nch->nch_CDC)
130 psdFreeVec(nch);
131 CloseLibrary(ps);
132 return(NULL);
135 nch->nch_Device = pd;
136 nch->nch_Interface = pif;
137 nch->nch_DevIDString = devidstr;
138 nch->nch_IfIDString = ifidstr;
140 nLoadBindingConfig(nch);
142 psdSafeRawDoFmt(buf, 64, "bootmouse.class<%08lx>", nch);
143 nch->nch_ReadySignal = SIGB_SINGLE;
144 nch->nch_ReadySigTask = FindTask(NULL);
145 SetSignal(0, SIGF_SINGLE);
146 if((tmptask = psdSpawnSubTask(buf, nHidTask, nch)))
148 psdBorrowLocksWait(tmptask, 1UL<<nch->nch_ReadySignal);
149 if(nch->nch_Task)
151 nch->nch_ReadySigTask = NULL;
152 //FreeSignal(nch->nch_ReadySignal);
153 psdAddErrorMsg(RETURN_OK, (STRPTR) libname,
154 "I'm pleased to introduce a mouse alliance to '%s'!",
155 devname);
157 Forbid();
158 AddTail(&nh->nh_Bindings, &nch->nch_Node);
159 Permit();
160 CloseLibrary(ps);
161 return(nch);
164 nch->nch_ReadySigTask = NULL;
165 //FreeSignal(nch->nch_ReadySignal);
166 psdFreeVec(nch->nch_CDC);
167 psdFreeVec(nch);
169 CloseLibrary(ps);
171 return(NULL);
174 /* \\\ */
176 /* /// "usbReleaseInterfaceBinding()" */
177 void usbReleaseInterfaceBinding(struct NepHidBase *nh, struct NepClassHid *nch)
179 struct Library *ps;
180 struct PsdConfig *pc;
181 struct PsdDevice *pd;
182 STRPTR devname;
184 KPRINTF(1, ("nepHidReleaseInterfaceBinding(%08lx)\n", nch));
185 if((ps = OpenLibrary("poseidon.library", 4)))
187 Forbid();
188 nch->nch_ReadySignal = SIGB_SINGLE;
189 nch->nch_ReadySigTask = FindTask(NULL);
190 if(nch->nch_GUITask)
192 Signal(nch->nch_GUITask, SIGBREAKF_CTRL_C);
194 Permit();
195 while(nch->nch_GUITask)
197 Wait(1L<<nch->nch_ReadySignal);
200 Forbid();
201 if(nch->nch_Task)
203 Signal(nch->nch_Task, SIGBREAKF_CTRL_C);
205 Permit();
206 while(nch->nch_Task)
208 Wait(1L<<nch->nch_ReadySignal);
210 //FreeSignal(nch->nch_ReadySignal);
211 psdGetAttrs(PGA_INTERFACE, nch->nch_Interface, IFA_Config, &pc, TAG_END);
212 psdGetAttrs(PGA_CONFIG, pc, CA_Device, &pd, TAG_END);
213 psdGetAttrs(PGA_DEVICE, pd, DA_ProductName, &devname, TAG_END);
214 psdAddErrorMsg(RETURN_OK, (STRPTR) libname,
215 "A cat ate my mouse '%s'!",
216 devname);
217 Forbid();
218 Remove(&nch->nch_Node);
219 Permit();
220 psdFreeVec(nch->nch_CDC);
221 psdFreeVec(nch);
222 CloseLibrary(ps);
225 /* \\\ */
227 /* /// "usbGetAttrsA()" */
228 AROS_LH3(LONG, usbGetAttrsA,
229 AROS_LHA(ULONG, type, D0),
230 AROS_LHA(APTR, usbstruct, A0),
231 AROS_LHA(struct TagItem *, tags, A1),
232 LIBBASETYPEPTR, nh, 5, nep)
234 AROS_LIBFUNC_INIT
236 struct TagItem *ti;
237 LONG count = 0;
239 KPRINTF(1, ("nepHidGetAttrsA(%ld, %08lx, %08lx)\n", type, usbstruct, tags));
240 switch(type)
242 case UGA_CLASS:
243 if((ti = FindTagItem(UCCA_Priority, tags)))
245 *((SIPTR *) ti->ti_Data) = -100;
246 count++;
248 if((ti = FindTagItem(UCCA_Description, tags)))
250 *((STRPTR *) ti->ti_Data) = "Support for mice/tablets in boot protocol mode";
251 count++;
253 if((ti = FindTagItem(UCCA_HasClassCfgGUI, tags)))
255 *((IPTR *) ti->ti_Data) = TRUE;
256 count++;
258 if((ti = FindTagItem(UCCA_HasBindingCfgGUI, tags)))
260 *((IPTR *) ti->ti_Data) = TRUE;
261 count++;
263 if((ti = FindTagItem(UCCA_AfterDOSRestart, tags)))
265 *((IPTR *) ti->ti_Data) = TRUE;
266 count++;
268 if((ti = FindTagItem(UCCA_UsingDefaultCfg, tags)))
270 *((IPTR *) ti->ti_Data) = nh->nh_DummyNCH.nch_UsingDefaultCfg;
271 count++;
273 break;
275 case UGA_BINDING:
276 if((ti = FindTagItem(UCBA_UsingDefaultCfg, tags)))
278 *((IPTR *) ti->ti_Data) = ((struct NepClassHid *) usbstruct)->nch_UsingDefaultCfg;
279 count++;
281 break;
283 return(count);
284 AROS_LIBFUNC_EXIT
286 /* \\\ */
288 /* /// "usbSetAttrsA()" */
289 AROS_LH3(LONG, usbSetAttrsA,
290 AROS_LHA(ULONG, type, D0),
291 AROS_LHA(APTR, usbstruct, A0),
292 AROS_LHA(struct TagItem *, tags, A1),
293 LIBBASETYPEPTR, nh, 6, nep)
295 AROS_LIBFUNC_INIT
296 return(0);
297 AROS_LIBFUNC_EXIT
299 /* \\\ */
301 /* /// "usbDoMethodA()" */
302 AROS_LH2(IPTR, usbDoMethodA,
303 AROS_LHA(ULONG, methodid, D0),
304 AROS_LHA(IPTR *, methoddata, A1),
305 LIBBASETYPEPTR, nh, 7, nep)
307 AROS_LIBFUNC_INIT
309 struct NepClassHid *nch;
311 KPRINTF(10, ("Do Method %ld\n", methodid));
312 switch(methodid)
314 case UCM_AttemptInterfaceBinding:
315 return((IPTR) usbAttemptInterfaceBinding(nh, (struct PsdInterface *) methoddata[0]));
317 case UCM_ForceInterfaceBinding:
318 return((IPTR) usbForceInterfaceBinding(nh, (struct PsdInterface *) methoddata[0]));
320 case UCM_ReleaseInterfaceBinding:
321 usbReleaseInterfaceBinding(nh, (struct NepClassHid *) methoddata[0]);
322 return(TRUE);
324 case UCM_OpenCfgWindow:
325 return(nOpenBindingCfgWindow(nh, &nh->nh_DummyNCH));
327 case UCM_OpenBindingCfgWindow:
328 return(nOpenBindingCfgWindow(nh, (struct NepClassHid *) methoddata[0]));
330 case UCM_ConfigChangedEvent:
331 nLoadClassConfig(nh);
332 Forbid();
333 nch = (struct NepClassHid *) nh->nh_Bindings.lh_Head;
334 while(nch->nch_Node.ln_Succ)
336 nLoadBindingConfig(nch);
337 nch = (struct NepClassHid *) nch->nch_Node.ln_Succ;
339 Permit();
340 return(TRUE);
342 default:
343 break;
345 return(0);
346 AROS_LIBFUNC_EXIT
348 /* \\\ */
350 /* /// "nLoadClassConfig()" */
351 BOOL nLoadClassConfig(struct NepHidBase *nh)
353 struct NepClassHid *nch = &nh->nh_DummyNCH;
354 struct Library *ps;
355 struct ClsDevCfg *cdc;
356 struct PsdIFFContext *pic;
358 KPRINTF(10, ("Loading Class Config...\n"));
359 if(nch->nch_GUITask)
361 return(FALSE);
363 if(!(ps = OpenLibrary("poseidon.library", 4)))
365 return(FALSE);
368 Forbid();
369 /* Create default config */
370 nch->nch_CDC->cdc_ChunkID = AROS_LONG2BE(MAKE_ID('B','M','S','E'));
371 nch->nch_CDC->cdc_Length = AROS_LONG2BE(sizeof(struct ClsDevCfg)-8);
372 nch->nch_CDC->cdc_Wheelmouse = FALSE;
373 nch->nch_UsingDefaultCfg = TRUE;
374 /* try to load default config */
375 pic = psdGetClsCfg(libname);
376 if(pic)
378 cdc = psdGetCfgChunk(pic, AROS_LONG2BE(nch->nch_CDC->cdc_ChunkID));
379 if(cdc)
381 CopyMem(((UBYTE *) cdc) + 8, ((UBYTE *) nch->nch_CDC) + 8, min(AROS_LONG2BE(cdc->cdc_Length), AROS_LONG2BE(nch->nch_CDC->cdc_Length)));
382 psdFreeVec(cdc);
383 nch->nch_UsingDefaultCfg = FALSE;
386 Permit();
387 CloseLibrary(ps);
388 return(FALSE);
390 /* \\\ */
392 /* /// "nLoadBindingConfig()" */
393 BOOL nLoadBindingConfig(struct NepClassHid *nch)
395 struct NepHidBase *nh = nch->nch_ClsBase;
396 struct Library *ps;
397 struct ClsDevCfg *cdc;
398 struct PsdIFFContext *pic;
400 KPRINTF(10, ("Loading Binding Config...\n"));
401 if(nch->nch_GUITask)
403 return(FALSE);
405 //nLoadClassConfig(nh);
406 *nch->nch_CDC = *nh->nh_DummyNCH.nch_CDC;
407 nch->nch_UsingDefaultCfg = TRUE;
409 if(!(ps = OpenLibrary("poseidon.library", 4)))
411 return(FALSE);
414 Forbid();
415 /* Load config */
416 pic = psdGetUsbDevCfg(libname, nch->nch_DevIDString, nch->nch_IfIDString);
417 if(pic)
419 cdc = psdGetCfgChunk(pic, AROS_LONG2BE(nch->nch_CDC->cdc_ChunkID));
420 if(cdc)
422 CopyMem(((UBYTE *) cdc) + 8, ((UBYTE *) nch->nch_CDC) + 8, min(AROS_LONG2BE(cdc->cdc_Length), AROS_LONG2BE(nch->nch_CDC->cdc_Length)));
423 psdFreeVec(cdc);
424 nch->nch_UsingDefaultCfg = FALSE;
427 Permit();
428 CloseLibrary(ps);
429 return(FALSE);
431 /* \\\ */
433 /* /// "nOpenBindingCfgWindow()" */
434 LONG nOpenBindingCfgWindow(struct NepHidBase *nh, struct NepClassHid *nch)
436 struct Library *ps;
437 KPRINTF(10, ("Opening GUI...\n"));
438 if(!(ps = OpenLibrary("poseidon.library", 4)))
440 return(FALSE);
442 Forbid();
443 if(!nch->nch_GUITask)
445 if((nch->nch_GUITask = psdSpawnSubTask(MOD_NAME_STRING " GUI", nGUITask, nch)))
447 Permit();
448 CloseLibrary(ps);
449 return(TRUE);
452 Permit();
453 CloseLibrary(ps);
454 return(FALSE);
456 /* \\\ */
458 /**************************************************************************/
460 #undef ps
461 #define ps nch->nch_Base
463 /* /// "nHidTask()" */
464 AROS_UFH0(void, nHidTask)
466 AROS_USERFUNC_INIT
468 struct NepClassHid *nch;
469 struct PsdPipe *pp;
470 ULONG sigmask;
471 ULONG sigs;
472 UWORD iecode;
473 UWORD qualifier;
474 UWORD buts;
475 UWORD oldbuts = 0;
476 WORD wheel = 0;
477 WORD oldwheel = 0;
478 UWORD wheeliecode;
479 UWORD wheeldist;
480 BOOL newmouse;
481 UBYTE *buf;
482 UBYTE *bufreal;
483 LONG ioerr;
484 BOOL firstpkt = TRUE;
486 if((nch = nAllocHid()))
488 Forbid();
489 if(nch->nch_ReadySigTask)
491 Signal(nch->nch_ReadySigTask, 1L<<nch->nch_ReadySignal);
493 Permit();
494 sigmask = (1L<<nch->nch_TaskMsgPort->mp_SigBit)|SIGBREAKF_CTRL_C;
495 bufreal = buf = nch->nch_EP1Buf;
496 psdSendPipe(nch->nch_EP1Pipe, buf, nch->nch_EP1PktSize);
499 sigs = Wait(sigmask);
500 while((pp = (struct PsdPipe *) GetMsg(nch->nch_TaskMsgPort)))
502 if(pp == nch->nch_EP1Pipe)
504 if(!(ioerr = psdGetPipeError(pp)))
506 if(firstpkt)
508 if(*buf == 0x01)
510 bufreal++;
512 firstpkt = 0;
514 KPRINTF(1, ("Data: %08lx %08lx\n", (*(ULONG *) bufreal), ((ULONG *) bufreal)[1]));
515 newmouse = FALSE;
516 qualifier = IEQUALIFIER_RELATIVEMOUSE;
517 buts = bufreal[0];
518 iecode = wheeliecode = IECODE_NOBUTTON;
519 wheeldist = 0;
520 if(buts & 1)
522 qualifier |= IEQUALIFIER_LEFTBUTTON;
524 if(buts & 2)
526 qualifier |= IEQUALIFIER_RBUTTON;
528 if(buts & 4)
530 qualifier |= IEQUALIFIER_MIDBUTTON;
532 if(nch->nch_CDC->cdc_Wheelmouse)
534 wheel = ((BYTE *) bufreal)[3];
535 if(wheel != oldwheel)
537 if(oldwheel > 0)
539 wheeliecode = RAWKEY_NM_WHEEL_UP|IECODE_UP_PREFIX;
540 newmouse = TRUE;
542 else if(oldwheel < 0)
544 wheeliecode = RAWKEY_NM_WHEEL_DOWN|IECODE_UP_PREFIX;
545 newmouse = TRUE;
547 oldwheel = wheel;
549 if(wheel > 0)
551 wheeliecode = RAWKEY_NM_WHEEL_UP;
552 wheeldist = wheel;
553 newmouse = TRUE;
555 else if(wheel < 0)
557 wheeliecode = RAWKEY_NM_WHEEL_DOWN;
558 wheeldist = -wheel;
559 newmouse = TRUE;
563 if((buts^oldbuts) & 1)
565 iecode = (buts & 1) ? IECODE_LBUTTON : IECODE_LBUTTON|IECODE_UP_PREFIX;
566 oldbuts ^= 1;
568 else if((buts^oldbuts) & 2)
570 iecode = (buts & 2) ? IECODE_RBUTTON : IECODE_RBUTTON|IECODE_UP_PREFIX;
571 oldbuts ^= 2;
573 else if((buts^oldbuts) & 4)
575 iecode = (buts & 4) ? IECODE_MBUTTON : IECODE_MBUTTON|IECODE_UP_PREFIX;
576 oldbuts ^= 4;
578 nch->nch_FakeEvent.ie_X = ((BYTE *) bufreal)[1];
579 nch->nch_FakeEvent.ie_Y = ((BYTE *) bufreal)[2];
580 nch->nch_FakeEvent.ie_Class = IECLASS_RAWMOUSE;
581 nch->nch_FakeEvent.ie_SubClass = 0;
582 nch->nch_FakeEvent.ie_Code = iecode;
583 nch->nch_FakeEvent.ie_NextEvent = NULL;
584 nch->nch_FakeEvent.ie_Qualifier = qualifier;
585 nch->nch_InpIOReq->io_Data = &nch->nch_FakeEvent;
586 nch->nch_InpIOReq->io_Length = sizeof(struct InputEvent);
587 nch->nch_InpIOReq->io_Command = IND_WRITEEVENT;
588 DoIO((struct IORequest *) nch->nch_InpIOReq);
589 if(newmouse)
591 while(wheeldist--)
593 KPRINTF(1, ("Doing wheel %ld\n", wheel));
594 nch->nch_FakeEvent.ie_Class = IECLASS_RAWKEY;
595 nch->nch_FakeEvent.ie_SubClass = 0;
596 nch->nch_FakeEvent.ie_Code = wheeliecode;
597 nch->nch_FakeEvent.ie_NextEvent = NULL;
598 nch->nch_FakeEvent.ie_Qualifier = qualifier;
599 nch->nch_InpIOReq->io_Data = &nch->nch_FakeEvent;
600 nch->nch_InpIOReq->io_Length = sizeof(struct InputEvent);
601 nch->nch_InpIOReq->io_Command = IND_WRITEEVENT;
602 DoIO((struct IORequest *) nch->nch_InpIOReq);
604 nch->nch_FakeEvent.ie_Class = IECLASS_NEWMOUSE;
605 nch->nch_FakeEvent.ie_SubClass = 0;
606 nch->nch_FakeEvent.ie_Code = wheeliecode;
607 nch->nch_FakeEvent.ie_NextEvent = NULL;
608 nch->nch_FakeEvent.ie_Qualifier = qualifier;
609 nch->nch_InpIOReq->io_Data = &nch->nch_FakeEvent;
610 nch->nch_InpIOReq->io_Length = sizeof(struct InputEvent);
611 nch->nch_InpIOReq->io_Command = IND_WRITEEVENT;
612 DoIO((struct IORequest *) nch->nch_InpIOReq);
615 } else {
616 KPRINTF(1, ("Int Pipe failed %ld\n", ioerr));
617 psdDelayMS(20);
619 psdSendPipe(nch->nch_EP1Pipe, buf, nch->nch_EP1PktSize);
620 break;
623 } while(!(sigs & SIGBREAKF_CTRL_C));
624 KPRINTF(20, ("Going down the river!\n"));
625 psdAbortPipe(nch->nch_EP1Pipe);
626 psdWaitPipe(nch->nch_EP1Pipe);
627 nFreeHid(nch);
629 AROS_USERFUNC_EXIT
631 /* \\\ */
633 /* /// "nAllocHid()" */
634 struct NepClassHid * nAllocHid(void)
636 struct Task *thistask;
637 struct NepClassHid *nch;
638 LONG ioerr;
640 thistask = FindTask(NULL);
641 nch = thistask->tc_UserData;
644 if(!(nch->nch_Base = OpenLibrary("poseidon.library", 4)))
646 Alert(AG_OpenLib);
647 break;
649 psdGetAttrs(PGA_INTERFACE, nch->nch_Interface,
650 IFA_Config, &nch->nch_Config,
651 IFA_InterfaceNum, &nch->nch_IfNum,
652 TAG_END);
653 psdGetAttrs(PGA_CONFIG, nch->nch_Config,
654 CA_Device, &nch->nch_Device,
655 TAG_END);
657 nch->nch_EP1 = psdFindEndpoint(nch->nch_Interface, NULL,
658 EA_IsIn, TRUE,
659 EA_TransferType, USEAF_INTERRUPT,
660 TAG_END);
661 if(!nch->nch_EP1)
663 KPRINTF(1, ("Ooops!?! No Endpoints defined?\n"));
664 break;
666 psdGetAttrs(PGA_ENDPOINT, nch->nch_EP1,
667 EA_MaxPktSize, &nch->nch_EP1PktSize,
668 TAG_END);
669 if((nch->nch_InpMsgPort = CreateMsgPort()))
671 if((nch->nch_InpIOReq = (struct IOStdReq *) CreateIORequest(nch->nch_InpMsgPort, sizeof(struct IOStdReq))))
673 if(!OpenDevice("input.device", 0, (struct IORequest *) nch->nch_InpIOReq, 0))
675 if((nch->nch_TaskMsgPort = CreateMsgPort()))
677 if((nch->nch_EP0Pipe = psdAllocPipe(nch->nch_Device, nch->nch_TaskMsgPort, NULL)))
679 if((nch->nch_EP1Pipe = psdAllocPipe(nch->nch_Device, nch->nch_TaskMsgPort, nch->nch_EP1)))
681 psdPipeSetup(nch->nch_EP0Pipe, URTF_CLASS|URTF_INTERFACE,
682 UHR_SET_PROTOCOL, HID_PROTO_BOOT, nch->nch_IfNum);
683 ioerr = psdDoPipe(nch->nch_EP0Pipe, NULL, 0);
684 if(!ioerr)
686 psdPipeSetup(nch->nch_EP0Pipe, URTF_CLASS|URTF_INTERFACE,
687 UHR_SET_IDLE, 0, nch->nch_IfNum);
688 ioerr = psdDoPipe(nch->nch_EP0Pipe, NULL, 0);
689 if(ioerr)
691 psdAddErrorMsg(RETURN_WARN, (STRPTR) libname,
692 "SET_IDLE=0 failed: %s (%ld)!",
693 psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
695 if((nch->nch_EP1Buf = psdAllocVec(nch->nch_EP1PktSize)))
697 psdSetAttrs(PGA_PIPE, nch->nch_EP1Pipe,
698 PPA_AllowRuntPackets, TRUE,
699 TAG_END);
700 nch->nch_Task = thistask;
701 return(nch);
703 } else {
704 psdAddErrorMsg(RETURN_FAIL, (STRPTR) libname,
705 "SET_PROTOCOL=BOOT failed: %s (%ld)!",
706 psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
708 psdFreePipe(nch->nch_EP1Pipe);
710 psdFreePipe(nch->nch_EP0Pipe);
712 DeleteMsgPort(nch->nch_TaskMsgPort);
714 CloseDevice((struct IORequest *) nch->nch_InpIOReq);
716 DeleteIORequest((struct IORequest *) nch->nch_InpIOReq);
718 DeleteMsgPort(nch->nch_InpMsgPort);
720 } while(FALSE);
721 CloseLibrary(nch->nch_Base);
722 Forbid();
723 nch->nch_Task = NULL;
724 if(nch->nch_ReadySigTask)
726 Signal(nch->nch_ReadySigTask, 1L<<nch->nch_ReadySignal);
728 return(NULL);
730 /* \\\ */
732 /* /// "nFreeHid()" */
733 void nFreeHid(struct NepClassHid *nch)
735 psdFreeVec(nch->nch_EP1Buf);
736 psdFreePipe(nch->nch_EP1Pipe);
737 psdFreePipe(nch->nch_EP0Pipe);
738 DeleteMsgPort(nch->nch_TaskMsgPort);
739 CloseDevice((struct IORequest *) nch->nch_InpIOReq);
740 DeleteIORequest((struct IORequest *) nch->nch_InpIOReq);
741 DeleteMsgPort(nch->nch_InpMsgPort);
742 CloseLibrary(nch->nch_Base);
743 Forbid();
744 nch->nch_Task = NULL;
745 if(nch->nch_ReadySigTask)
747 Signal(nch->nch_ReadySigTask, 1L<<nch->nch_ReadySignal);
750 /* \\\ */
752 /**************************************************************************/
754 #undef ps
755 #define ps nch->nch_PsdBase
756 #undef IntuitionBase
757 #define IntuitionBase nch->nch_IntBase
758 #undef MUIMasterBase
759 #define MUIMasterBase nch->nch_MUIBase
761 /* /// "nGUITask()" */
762 AROS_UFH0(void, nGUITask)
764 AROS_USERFUNC_INIT
766 struct Task *thistask;
767 struct NepHidBase *nh;
768 struct NepClassHid *nch;
769 APTR pic;
771 thistask = FindTask(NULL);
772 nch = thistask->tc_UserData;
773 nh = nch->nch_ClsBase;
775 ++nh->nh_Library.lib_OpenCnt;
776 if(!(MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN)))
778 KPRINTF(10, ("Couldn't open muimaster.library.\n"));
779 nGUITaskCleanup(nch);
780 return;
783 if(!(IntuitionBase = OpenLibrary("intuition.library", 39)))
785 KPRINTF(10, ("Couldn't open intuition.library.\n"));
786 nGUITaskCleanup(nch);
787 return;
789 if(!(ps = OpenLibrary("poseidon.library", 4)))
791 KPRINTF(10, ("Couldn't open poseidon.library.\n"));
792 nGUITaskCleanup(nch);
793 return;
796 nch->nch_App = ApplicationObject,
797 MUIA_Application_Title , (IPTR)libname,
798 MUIA_Application_Version , (IPTR)VERSION_STRING,
799 MUIA_Application_Copyright , (IPTR)"©2002-2009 Chris Hodges",
800 MUIA_Application_Author , (IPTR)"Chris Hodges <chrisly@platon42.de>",
801 MUIA_Application_Description, (IPTR)"Settings for the bootmouse.class",
802 MUIA_Application_Base , (IPTR)"BOOTMOUSE",
803 MUIA_Application_HelpFile , (IPTR)"HELP:Poseidon.guide",
804 MUIA_Application_Menustrip , (IPTR)MenustripObject,
805 Child, (IPTR)MenuObjectT((IPTR)"Project"),
806 Child, (IPTR)(nch->nch_AboutMI = MenuitemObject,
807 MUIA_Menuitem_Title, (IPTR)"About...",
808 MUIA_Menuitem_Shortcut, (IPTR)"?",
809 End),
810 End,
811 Child, (IPTR)MenuObjectT((IPTR)"Settings"),
812 Child, (IPTR)(nch->nch_UseMI = MenuitemObject,
813 MUIA_Menuitem_Title, (IPTR)"Save",
814 MUIA_Menuitem_Shortcut, (IPTR)"S",
815 End),
816 Child, (IPTR)(nch->nch_SetDefaultMI = MenuitemObject,
817 MUIA_Menuitem_Title, (IPTR)"Save as Default",
818 MUIA_Menuitem_Shortcut, (IPTR)"D",
819 End),
820 Child, (IPTR)MenuitemObject,
821 MUIA_Menuitem_Title, (IPTR)NM_BARLABEL,
822 End,
823 Child, (IPTR)(nch->nch_MUIPrefsMI = MenuitemObject,
824 MUIA_Menuitem_Title, (IPTR)"MUI Settings",
825 MUIA_Menuitem_Shortcut, (IPTR)"M",
826 End),
827 End,
828 End,
830 SubWindow, (IPTR)(nch->nch_MainWindow = WindowObject,
831 MUIA_Window_ID , MAKE_ID('M','A','I','N'),
832 MUIA_Window_Title, (IPTR)libname,
833 MUIA_HelpNode, (IPTR)libname,
835 WindowContents, (IPTR)VGroup,
836 Child, (IPTR)HGroup, GroupFrameT((IPTR)(nch->nch_Interface ? "Device Settings" : "Default Device Settings")),
837 Child, (IPTR)HSpace(0),
838 Child, (IPTR)ColGroup(2),
839 Child, (IPTR)Label((IPTR) "Experimental Wheelmouse support:"),
840 Child, (IPTR)HGroup,
841 Child, (IPTR)(nch->nch_WheelmouseObj = ImageObject, ImageButtonFrame,
842 MUIA_Background, MUII_ButtonBack,
843 MUIA_CycleChain, 1,
844 MUIA_InputMode, MUIV_InputMode_Toggle,
845 MUIA_Image_Spec, MUII_CheckMark,
846 MUIA_Image_FreeVert, TRUE,
847 MUIA_Selected, nch->nch_CDC->cdc_Wheelmouse,
848 MUIA_ShowSelState, FALSE,
849 End),
850 Child, (IPTR)HSpace(0),
851 End,
852 End,
853 Child, (IPTR)HSpace(0),
854 End,
855 Child, (IPTR)VSpace(0),
856 Child, (IPTR)HGroup,
857 MUIA_Group_SameWidth, TRUE,
858 Child, (IPTR)(nch->nch_UseObj = TextObject, ButtonFrame,
859 MUIA_ShowMe, (IPTR)nch->nch_Interface,
860 MUIA_Background, MUII_ButtonBack,
861 MUIA_CycleChain, 1,
862 MUIA_InputMode, MUIV_InputMode_RelVerify,
863 MUIA_Text_Contents, (IPTR)"\33c Save ",
864 End),
865 Child, (IPTR)(nch->nch_SetDefaultObj = TextObject, ButtonFrame,
866 MUIA_Background, MUII_ButtonBack,
867 MUIA_CycleChain, 1,
868 MUIA_InputMode, MUIV_InputMode_RelVerify,
869 MUIA_Text_Contents, (IPTR)(nch->nch_Interface ? "\33c Save as Default " : "\33c Save Defaults "),
870 End),
871 Child, (IPTR)(nch->nch_CloseObj = TextObject, ButtonFrame,
872 MUIA_Background, MUII_ButtonBack,
873 MUIA_CycleChain, 1,
874 MUIA_InputMode, MUIV_InputMode_RelVerify,
875 MUIA_Text_Contents, (IPTR)"\33c Use ",
876 End),
877 End,
878 End,
879 End),
880 End;
882 if(!nch->nch_App)
884 KPRINTF(10, ("Couldn't create application\n"));
885 nGUITaskCleanup(nch);
886 return;
889 DoMethod(nch->nch_MainWindow, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
890 nch->nch_App, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
891 DoMethod(nch->nch_UseObj, MUIM_Notify, MUIA_Pressed, FALSE,
892 nch->nch_App, 2, MUIM_Application_ReturnID, ID_STORE_CONFIG);
893 DoMethod(nch->nch_SetDefaultObj, MUIM_Notify, MUIA_Pressed, FALSE,
894 nch->nch_App, 2, MUIM_Application_ReturnID, ID_DEF_CONFIG);
895 DoMethod(nch->nch_CloseObj, MUIM_Notify, MUIA_Pressed, FALSE,
896 nch->nch_App, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
898 DoMethod(nch->nch_AboutMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
899 nch->nch_App, 2, MUIM_Application_ReturnID, ID_ABOUT);
900 DoMethod(nch->nch_UseMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
901 nch->nch_App, 2, MUIM_Application_ReturnID, ID_STORE_CONFIG);
902 DoMethod(nch->nch_SetDefaultMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
903 nch->nch_App, 2, MUIM_Application_ReturnID, ID_DEF_CONFIG);
904 DoMethod(nch->nch_MUIPrefsMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
905 nch->nch_App, 2, MUIM_Application_OpenConfigWindow, 0);
907 IPTR isopen = 0;
908 IPTR iconify = 0;
909 ULONG sigs;
910 ULONG sigmask;
911 LONG retid;
913 get(nch->nch_App, MUIA_Application_Iconified, &iconify);
914 set(nch->nch_MainWindow, MUIA_Window_Open, TRUE);
915 get(nch->nch_MainWindow, MUIA_Window_Open, &isopen);
916 if(!(isopen || iconify))
918 nGUITaskCleanup(nch);
919 return;
921 sigmask = 0;
924 retid = DoMethod(nch->nch_App, MUIM_Application_NewInput, &sigs);
925 switch(retid)
927 case ID_DEF_CONFIG:
928 case ID_STORE_CONFIG:
929 case MUIV_Application_ReturnID_Quit:
930 get(nch->nch_WheelmouseObj, MUIA_Selected, &nch->nch_CDC->cdc_Wheelmouse);
932 if(retid == ID_DEF_CONFIG)
934 pic = psdGetClsCfg(libname);
935 if(!pic)
937 psdSetClsCfg(libname, NULL);
938 pic = psdGetClsCfg(libname);
940 if(pic)
942 if(psdAddCfgEntry(pic, nch->nch_CDC))
944 psdSaveCfgToDisk(NULL, FALSE);
948 if(nch->nch_Interface)
950 pic = psdGetUsbDevCfg(libname, nch->nch_DevIDString, nch->nch_IfIDString);
951 if(!pic)
953 psdSetUsbDevCfg(libname, nch->nch_DevIDString, nch->nch_IfIDString, NULL);
954 pic = psdGetUsbDevCfg(libname, nch->nch_DevIDString, nch->nch_IfIDString);
956 if(pic)
958 if(psdAddCfgEntry(pic, nch->nch_CDC))
960 if(retid != MUIV_Application_ReturnID_Quit)
962 psdSaveCfgToDisk(NULL, FALSE);
964 retid = MUIV_Application_ReturnID_Quit;
967 } else {
968 retid = MUIV_Application_ReturnID_Quit;
970 break;
972 case ID_ABOUT:
973 MUI_RequestA(nch->nch_App, nch->nch_MainWindow, 0, NULL, "Blimey!", VERSION_STRING, NULL);
974 break;
976 if(retid == MUIV_Application_ReturnID_Quit)
978 break;
980 if(sigs)
982 sigs = Wait(sigs | sigmask | SIGBREAKF_CTRL_C);
983 if(sigs & SIGBREAKF_CTRL_C)
985 break;
988 } while(TRUE);
989 set(nch->nch_MainWindow, MUIA_Window_Open, FALSE);
991 nGUITaskCleanup(nch);
993 AROS_USERFUNC_EXIT
995 /* \\\ */
997 /* /// "nGUITaskCleanup()" */
998 void nGUITaskCleanup(struct NepClassHid *nch)
1000 if(nch->nch_App)
1002 MUI_DisposeObject(nch->nch_App);
1003 nch->nch_App = NULL;
1005 if(MUIMasterBase)
1007 CloseLibrary(MUIMasterBase);
1008 MUIMasterBase = NULL;
1010 if(IntuitionBase)
1012 CloseLibrary(IntuitionBase);
1013 IntuitionBase = NULL;
1015 if(ps)
1017 CloseLibrary(ps);
1018 ps = NULL;
1020 Forbid();
1021 nch->nch_GUIBinding = NULL;
1022 nch->nch_GUITask = NULL;
1023 if(nch->nch_ReadySigTask)
1025 Signal(nch->nch_ReadySigTask, 1L<<nch->nch_ReadySignal);
1027 --nch->nch_ClsBase->nh_Library.lib_OpenCnt;
1029 /* \\\ */