2 *----------------------------------------------------------------------------
3 * camdusbmidi class for poseidon
4 *----------------------------------------------------------------------------
5 * By Chris Hodges <chrisly@platon42.de>
8 /* TODO: Somebody needs to port the assembly 68k camd driver to something that is used under AROS! */
12 #include "camdusbmidi.class.h"
15 static const STRPTR libname
= MOD_NAME_STRING
;
17 static int libInit(LIBBASETYPEPTR nh
)
19 KPRINTF(10, ("libInit nh: 0x%08lx SysBase: 0x%08lx\n", nh
, SysBase
));
21 nh
->nh_UtilityBase
= OpenLibrary("utility.library", 39);
23 #define UtilityBase nh->nh_UtilityBase
27 /* Create default config */
28 nh
->nh_CurrentCGC
.cgc_ChunkID
= AROS_LONG2BE(MAKE_ID('C','M','I','D'));
29 nh
->nh_CurrentCGC
.cgc_Length
= AROS_LONG2BE(sizeof(struct ClsGlobalCfg
)-8);
31 NewList(&nh
->nh_Bindings
);
33 KPRINTF(20, ("libInit: OpenLibrary(\"utility.library\", 39) failed!\n"));
37 KPRINTF(10, ("libInit: Ok\n"));
38 return(nh
? TRUE
: FALSE
);
41 static int libOpen(LIBBASETYPEPTR nh
)
43 KPRINTF(10, ("libOpen nh: 0x%08lx\n", nh
));
48 static int libExpunge(LIBBASETYPEPTR nh
)
50 KPRINTF(10, ("libExpunge nh: 0x%08lx\n", nh
));
51 CloseLibrary((struct Library
*) UtilityBase
);
55 ADD2INITLIB(libInit
, 0)
56 ADD2OPENLIB(libOpen
, 0)
57 ADD2EXPUNGELIB(libExpunge
, 0)
61 * ***********************************************************************
62 * * Library functions *
63 * ***********************************************************************
66 #include "CAMDDriver.c"
68 /* /// "usbAttemptInterfaceBinding()" */
69 struct NepClassHid
* usbAttemptInterfaceBinding(struct NepHidBase
*nh
, struct PsdInterface
*pif
)
76 KPRINTF(1, ("nepHidAttemptInterfaceBinding(%08lx)\n", pif
));
77 if((ps
= OpenLibrary("poseidon.library", 4)))
79 psdGetAttrs(PGA_INTERFACE
, pif
,
81 IFA_SubClass
, &subclass
,
85 if((ifclass
== AUDIO_CLASSCODE
) && (subclass
== AUDIO_MIDI_SUBCLASS
))
87 return(usbForceInterfaceBinding(nh
, pif
));
94 /* /// "usbForceInterfaceBinding()" */
95 struct NepClassHid
* usbForceInterfaceBinding(struct NepHidBase
*nh
, struct PsdInterface
*pif
)
98 struct Library
*DOSBase
;
99 struct NepClassHid
*nch
;
100 struct PsdConfig
*pc
;
101 struct PsdDevice
*pd
;
104 struct Task
*tmptask
;
106 KPRINTF(1, ("nepHidAttemptInterfaceBinding(%08lx)\n", pif
));
107 if((ps
= OpenLibrary("poseidon.library", 4)))
109 if((nch
= psdAllocVec(sizeof(struct NepClassHid
))))
115 psdGetAttrs(PGA_INTERFACE
, pif
, IFA_Config
, &pc
, TAG_END
);
116 psdGetAttrs(PGA_CONFIG
, pc
, CA_Device
, &pd
, TAG_END
);
117 psdGetAttrs(PGA_DEVICE
, pd
, DA_ProductName
, &devname
, TAG_END
);
121 tarpos
= nch
->nch_ShortID
;
123 while(*srcpos
&& cnt
)
125 if(((*srcpos
>= 'A') && (*srcpos
<= 'Z')) ||
126 ((*srcpos
>= 'a') && (*srcpos
<= 'z')) ||
127 ((*srcpos
>= '0') && (*srcpos
<= '9')))
136 nch
->nch_ClsBase
= nh
;
137 nch
->nch_Device
= NULL
;
138 nch
->nch_Interface
= pif
;
140 nLoadClassConfig(nh
);
142 psdSafeRawDoFmt(buf
, 64, "camdusbmidi.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
);
151 nch
->nch_ReadySigTask
= NULL
;
152 //FreeSignal(nch->nch_ReadySignal);
154 AddTail(&nh
->nh_Bindings
, &nch
->nch_Node
);
157 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
,
158 "Play it again, '%s'!",
160 if((DOSBase
= OpenLibrary("dos.library", 37)))
165 psdSafeRawDoFmt(buf
, 64, "%s/%s", (STRPTR
) "DEVS:Midi", nch
->nch_ShortID
);
166 fh
= Open(buf
, MODE_OLDFILE
);
169 fh
= Open(buf
, MODE_NEWFILE
);
172 lock
= CreateDir("DEVS:Midi");
176 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
,
177 "Created directory '%s'!",
178 (STRPTR
) "DEVS:Midi");
180 fh
= Open(buf
, MODE_NEWFILE
);
184 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) libname
,
185 "Couldn't generate CAMD MIDI driver '%s'!",
188 UBYTE
*tmpmem
= psdAllocVec(sizeof(CAMDDriver
));
191 CopyMemQuick(CAMDDriver
, tmpmem
, sizeof(CAMDDriver
));
192 // fix name of driver -- position is hardcoded, but unlikely to move
193 strcpy(&tmpmem
[0x46], nch
->nch_ShortID
);
194 Write(fh
, tmpmem
, sizeof(CAMDDriver
));
196 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
,
197 "Generated CAMD MIDI driver '%s'!",
206 CloseLibrary(DOSBase
);
212 nch
->nch_ReadySigTask
= NULL
;
213 //FreeSignal(nch->nch_ReadySignal);
222 /* /// "usbReleaseInterfaceBinding()" */
223 void usbReleaseInterfaceBinding(struct NepHidBase
*nh
, struct NepClassHid
*nch
)
226 struct PsdConfig
*pc
;
227 struct PsdDevice
*pd
;
230 KPRINTF(1, ("nepHidReleaseInterfaceBinding(%08lx)\n", nch
));
231 if((ps
= OpenLibrary("poseidon.library", 4)))
234 Remove(&nch
->nch_Node
);
235 nch
->nch_ReadySignal
= SIGB_SINGLE
;
236 nch
->nch_ReadySigTask
= FindTask(NULL
);
239 Signal(nch
->nch_Task
, SIGBREAKF_CTRL_C
);
244 Wait(1L<<nch
->nch_ReadySignal
);
246 //FreeSignal(nch->nch_ReadySignal);
247 psdGetAttrs(PGA_INTERFACE
, nch
->nch_Interface
, IFA_Config
, &pc
, TAG_END
);
248 psdGetAttrs(PGA_CONFIG
, pc
, CA_Device
, &pd
, TAG_END
);
249 psdGetAttrs(PGA_DEVICE
, pd
, DA_ProductName
, &devname
, TAG_END
);
250 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
,
259 /* /// "usbGetAttrsA()" */
260 AROS_LH3(LONG
, usbGetAttrsA
,
261 AROS_LHA(ULONG
, type
, D0
),
262 AROS_LHA(APTR
, usbstruct
, A0
),
263 AROS_LHA(struct TagItem
*, tags
, A1
),
264 LIBBASETYPEPTR
, nh
, 5, nep
)
271 KPRINTF(1, ("nepHidGetAttrsA(%ld, %08lx, %08lx)\n", type
, usbstruct
, tags
));
275 if((ti
= FindTagItem(UCCA_Priority
, tags
)))
277 *((SIPTR
*) ti
->ti_Data
) = 0;
280 if((ti
= FindTagItem(UCCA_Description
, tags
)))
282 *((STRPTR
*) ti
->ti_Data
) = "USB MIDI CAMD Interface class";
285 if((ti
= FindTagItem(UCCA_HasClassCfgGUI
, tags
)))
287 *((IPTR
*) ti
->ti_Data
) = TRUE
;
290 if((ti
= FindTagItem(UCCA_HasBindingCfgGUI
, tags
)))
292 *((IPTR
*) ti
->ti_Data
) = FALSE
;
295 if((ti
= FindTagItem(UCCA_AfterDOSRestart
, tags
)))
297 *((IPTR
*) ti
->ti_Data
) = FALSE
;
300 if((ti
= FindTagItem(UCCA_UsingDefaultCfg
, tags
)))
302 *((IPTR
*) ti
->ti_Data
) = nh
->nh_UsingDefaultCfg
;
308 if((ti
= FindTagItem(UCCA_UsingDefaultCfg
, tags
)))
310 *((IPTR
*) ti
->ti_Data
) = FALSE
;
320 /* /// "usbSetAttrsA()" */
321 AROS_LH3(LONG
, usbSetAttrsA
,
322 AROS_LHA(ULONG
, type
, D0
),
323 AROS_LHA(APTR
, usbstruct
, A0
),
324 AROS_LHA(struct TagItem
*, tags
, A1
),
325 LIBBASETYPEPTR
, nh
, 6, nep
)
333 /* /// "usbDoMethodA()" */
334 AROS_LH2(IPTR
, usbDoMethodA
,
335 AROS_LHA(ULONG
, methodid
, D0
),
336 AROS_LHA(IPTR
*, methoddata
, A1
),
337 LIBBASETYPEPTR
, nh
, 7, nep
)
341 KPRINTF(10, ("Do Method %ld\n", methodid
));
344 case UCM_AttemptInterfaceBinding
:
345 return((IPTR
) usbAttemptInterfaceBinding(nh
, (struct PsdInterface
*) methoddata
[0]));
347 case UCM_ForceInterfaceBinding
:
348 return((IPTR
) usbForceInterfaceBinding(nh
, (struct PsdInterface
*) methoddata
[0]));
350 case UCM_ReleaseInterfaceBinding
:
351 usbReleaseInterfaceBinding(nh
, (struct NepClassHid
*) methoddata
[0]);
354 case UCM_OpenCfgWindow
:
355 return(nOpenCfgWindow(nh
));
357 case UCM_ConfigChangedEvent
:
358 nLoadClassConfig(nh
);
369 /* /// "usbCAMDOpenPort()" */
370 AROS_LH5(APTR
, usbCAMDOpenPort
,
371 AROS_LHA(APTR
, xmitfct
, A0
),
372 AROS_LHA(APTR
, recvfct
, A1
),
373 AROS_LHA(APTR
, userdata
, A2
),
374 AROS_LHA(STRPTR
, idstr
, A3
),
375 AROS_LHA(ULONG
, port
, D0
),
376 LIBBASETYPEPTR
, nh
, 15, nep
)
380 struct NepClassHid
*nch
;
381 struct CAMDAdapter
*ca
;
383 KPRINTF(10, ("Open Port %ld, ID=%s\n", port
, idstr
));
384 /* theoretically, we could allow multiple USB Midi devices to map
385 to different ports, but at the moment, this should suffice */
386 nch
= (struct NepClassHid
*) nh
->nh_Bindings
.lh_Head
;
387 if(!nch
->nch_Node
.ln_Succ
)
389 KPRINTF(20, ("No MIDI device available!\n"));
394 KPRINTF(20, ("Port %ld out of range!\n", port
));
397 /* fill adapter structure */
398 ca
= &nh
->nh_CAMDAdapters
[port
];
399 ca
->ca_PortNum
= port
;
400 ca
->ca_TXFunc
= xmitfct
;
401 ca
->ca_RXFunc
= recvfct
;
402 ca
->ca_UserData
= userdata
;
403 ca
->ca_MsgPort
= nch
->nch_TaskMsgPort
;
404 ca
->ca_TXBufSize
= 4096;
405 ca
->ca_TXBuffer
= AllocVec(ca
->ca_TXBufSize
, MEMF_PUBLIC
|MEMF_CLEAR
);
406 ca
->ca_TXReadPos
= 0;
407 ca
->ca_TXWritePos
= 0;
410 KPRINTF(20, ("Out of memory!\n"));
419 /* /// "usbCAMDClosePort()" */
420 AROS_LH2(void, usbCAMDClosePort
,
421 AROS_LHA(ULONG
, port
, D0
),
422 AROS_LHA(STRPTR
, idstr
, A1
),
423 LIBBASETYPEPTR
, nh
, 16, nep
)
427 struct CAMDAdapter
*ca
;
428 KPRINTF(10, ("Close Port %ld, ID=%s\n", port
, idstr
));
431 KPRINTF(10, ("Port %ld out of range!\n", port
));
433 ca
= &nh
->nh_CAMDAdapters
[port
];
434 ca
->ca_IsOpen
= FALSE
;
435 ca
->ca_MsgPort
= NULL
;
436 FreeVec(ca
->ca_TXBuffer
);
437 ca
->ca_TXBuffer
= NULL
;
443 /**************************************************************************/
446 #define ps nch->nch_Base
448 /* /// "nHidTask()" */
449 AROS_UFH0(void, nHidTask
)
453 struct NepClassHid
*nch
;
461 if((nch
= nAllocHid()))
464 if(nch
->nch_ReadySigTask
)
466 Signal(nch
->nch_ReadySigTask
, 1L<<nch
->nch_ReadySignal
);
469 sigmask
= (1L<<nch
->nch_TaskMsgPort
->mp_SigBit
)|SIGBREAKF_CTRL_C
;
470 buf
= nch
->nch_EPInBuf
;
471 psdSendPipe(nch
->nch_EPInPipe
, buf
, 1024);
474 sigs
= Wait(sigmask
);
475 while((pp
= (struct PsdPipe
*) GetMsg(nch
->nch_TaskMsgPort
)))
477 if(pp
== nch
->nch_EPInPipe
)
479 if(!(ioerr
= psdGetPipeError(pp
)))
481 len
= psdGetPipeActual(pp
);
482 nParseMidi(nch
, buf
, len
);
484 psdSendPipe(nch
->nch_EPInPipe
, buf
, 1024);
489 } while(!(sigs
& SIGBREAKF_CTRL_C
));
490 KPRINTF(20, ("Going down the river!\n"));
491 psdAbortPipe(nch
->nch_EPInPipe
);
492 psdWaitPipe(nch
->nch_EPInPipe
);
500 /* /// "nParseMidiOut()" */
501 void nParseMidiOut(struct NepClassHid
*nch
)
503 UBYTE
*out
= nch
->nch_EPOutBuf
;
506 struct CAMDAdapter
*ca
;
507 ca
= nch
->nch_ClsBase
->nh_CAMDAdapters
;
508 for(cnt
= 0; cnt
< 16; cnt
++)
510 if(ca
->ca_IsOpen
&& ca
->ca_TXReadPos
!= ca
->ca_TXWritePos
)
512 ULONG chan
= ca
->ca_PortNum
<<4;
513 ULONG mask
= ca
->ca_TXBufSize
- 1;
514 ULONG len
= (ca
->ca_TXWritePos
+ ca
->ca_TXBufSize
- ca
->ca_TXReadPos
) & mask
;
515 UBYTE
*buf
= ca
->ca_TXBuffer
;
519 KPRINTF(1, ("TXWritePos=%ld, TXReadPos=%ld, len=%ld", ca
->ca_TXWritePos
, ca
->ca_TXReadPos
, len
));
521 //KPRINTF(1, ("Data OUT %ld\n", len));
524 cmd
= buf
[ca
->ca_TXReadPos
];
527 if(ca
->ca_SysExMode
&& (cmd
!= 0xf0) && (cmd
!= 0xf7))
529 KPRINTF(10, ("SysEx Paused\n"));
531 ca
->ca_SysExMode
= 2;
548 ca
->ca_TXReadPos
= (ca
->ca_TXReadPos
+1) & mask
;
549 *out
++ = buf
[ca
->ca_TXReadPos
];
550 ca
->ca_TXReadPos
= (ca
->ca_TXReadPos
+1) & mask
;
551 *out
++ = buf
[ca
->ca_TXReadPos
];
552 ca
->ca_TXReadPos
= (ca
->ca_TXReadPos
+1) & mask
;
566 ca
->ca_TXReadPos
= (ca
->ca_TXReadPos
+1) & mask
;
567 *out
++ = buf
[ca
->ca_TXReadPos
];
568 ca
->ca_TXReadPos
= (ca
->ca_TXReadPos
+1) & mask
;
576 case 0x0: // SysEx start
577 KPRINTF(10, ("SysEx Starts\n"));
578 if(!ca
->ca_SysExMode
)
580 ca
->ca_SysExMode
= 1;
581 ca
->ca_SysExData
= cmd
;
585 ca
->ca_TXReadPos
= (ca
->ca_TXReadPos
+1) & mask
;
597 ca
->ca_TXReadPos
= (ca
->ca_TXReadPos
+1) & mask
;
598 *out
++ = buf
[ca
->ca_TXReadPos
];
599 ca
->ca_TXReadPos
= (ca
->ca_TXReadPos
+1) & mask
;
600 *out
++ = buf
[ca
->ca_TXReadPos
];
601 ca
->ca_TXReadPos
= (ca
->ca_TXReadPos
+1) & mask
;
605 case 0x3: // SongSelect
614 ca
->ca_TXReadPos
= (ca
->ca_TXReadPos
+1) & mask
;
615 *out
++ = buf
[ca
->ca_TXReadPos
];
616 ca
->ca_TXReadPos
= (ca
->ca_TXReadPos
+1) & mask
;
621 case 0x7: // SysEx Ends
623 ca
->ca_TXReadPos
= (ca
->ca_TXReadPos
+1) & mask
;
626 KPRINTF(10, ("SysEx Ends\n"));
627 if(ca
->ca_SysExMode
== 2)
629 KPRINTF(10, ("SysEx Resume\n"));
630 // was paused, continue
631 ca
->ca_SysExMode
= 1;
635 if(ca
->ca_SysExNum
== 0)
642 else if(ca
->ca_SysExNum
== 1)
645 *out
++ = ca
->ca_SysExData
;
650 *out
++ = ca
->ca_SysExData
>>8;
651 *out
++ = ca
->ca_SysExData
;
654 KPRINTF(10, ("LastPkt: %08lx\n", *((ULONG
*) &out
[-4])));
656 ca
->ca_SysExMode
= 0;
658 KPRINTF(10, ("SysEx End Ignored\n"));
662 case 0x8: // Timing Clock.
663 case 0x9: // Undefined. (Reserved)
665 case 0xb: // Continue.
667 case 0xd: // Undefined. (Reserved)
668 case 0xe: // Active Sensing.
673 ca
->ca_TXReadPos
= (ca
->ca_TXReadPos
+1) & mask
;
688 ca
->ca_SysExData
<<= 8;
689 ca
->ca_SysExData
|= cmd
;
691 if(ca
->ca_SysExNum
== 3)
693 KPRINTF(1, ("Cont 3B SysEx %06lx\n", ca
->ca_SysExData
));
694 *((ULONG
*) out
) = ((0x4|chan
)<<24)|ca
->ca_SysExData
;
696 ca
->ca_SysExData
= 0;
701 ca
->ca_TXReadPos
= (ca
->ca_TXReadPos
+1) & mask
;
703 } while(len
&& (goodpkt
< 2040));
709 //KPRINTF(1, ("Sending %ld pkts\n", goodpkt));
710 psdDoPipe(nch
->nch_EPOutPipe
, nch
->nch_EPOutBuf
, (ULONG
) goodpkt
<<2);
715 /* /// "nParseMidi()" */
716 void nParseMidi(struct NepClassHid
*nch
, UBYTE
*buf
, ULONG len
)
720 struct CAMDAdapter
*ca
;
724 KPRINTF(1, ("Msg: %02lx %02lx %02lx %02lx\n", buf
[0], buf
[1], buf
[2], buf
[3]));
726 ca
= &nch
->nch_ClsBase
->nh_CAMDAdapters
[chan
];
732 case 0x0: // Miscellaneous function codes. Reserved for future extensions.
733 case 0x1: // Cable events. Reserved for future expansion.
736 case 0x5: // Single-byte System Common Message or SysEx ends with following single byte.
737 case 0xF: // Single Byte
739 CallHookA(&ca
->ca_CAMDRXFunc
, (Object
*) buf
, NULL
);
742 case 0x2: // Two-byte System Common messages like MTC, SongSelect, etc.
743 case 0x6: // SysEx ends with following two bytes. *** FIXME? ***
745 CallHookA(&ca
->ca_CAMDRXFunc
, (Object
*) buf
, NULL
);
748 case 0x3: // Three-byte System Common messages like SPP, etc.
749 case 0x4: // SysEx starts or continues *** FIXME? ***
750 case 0x7: // SysEx ends with following three bytes. *** FIXME? ***
751 case 0x8: // Note-off
753 case 0xA: // Poly-KeyPress
754 case 0xB: // Control Change
755 case 0xE: // PitchBend Change
757 CallHookA(&ca
->ca_CAMDRXFunc
, (Object
*) buf
, NULL
);
760 case 0xC: // Program Change
761 case 0xD: // Channel Pressure
763 CallHookA(&ca
->ca_CAMDRXFunc
, (Object
*) buf
, NULL
);
767 KPRINTF(1, ("Not open\n"));
776 /* /// "nAllocHid()" */
777 struct NepClassHid
* nAllocHid(void)
779 struct Task
*thistask
;
780 struct NepClassHid
*nch
;
782 thistask
= FindTask(NULL
);
783 nch
= thistask
->tc_UserData
;
786 if(!(nch
->nch_Base
= OpenLibrary("poseidon.library", 4)))
791 psdGetAttrs(PGA_INTERFACE
, nch
->nch_Interface
,
792 IFA_Config
, &nch
->nch_Config
,
793 IFA_InterfaceNum
, &nch
->nch_IfNum
,
795 psdGetAttrs(PGA_CONFIG
, nch
->nch_Config
,
796 CA_Device
, &nch
->nch_Device
,
799 nch
->nch_EPIn
= psdFindEndpoint(nch
->nch_Interface
, NULL
,
801 EA_TransferType
, USEAF_BULK
,
804 nch
->nch_EPOut
= psdFindEndpoint(nch
->nch_Interface
, NULL
,
806 EA_TransferType
, USEAF_BULK
,
808 if(!(nch
->nch_EPIn
&& nch
->nch_EPOut
))
810 KPRINTF(1, ("Ooops!?! No Endpoints defined?\n"));
811 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) libname
,
812 "No Bulk-In or Bulk-Out Endpoint!");
815 if((nch
->nch_TaskMsgPort
= CreateMsgPort()))
817 if((nch
->nch_EP0Pipe
= psdAllocPipe(nch
->nch_Device
, nch
->nch_TaskMsgPort
, NULL
)))
819 if((nch
->nch_EPInPipe
= psdAllocPipe(nch
->nch_Device
, nch
->nch_TaskMsgPort
, nch
->nch_EPIn
)))
821 psdSetAttrs(PGA_PIPE
, nch
->nch_EPInPipe
,
822 PPA_NakTimeout
, FALSE
,
823 PPA_AllowRuntPackets
, TRUE
,
826 if((nch
->nch_EPOutPipe
= psdAllocPipe(nch
->nch_Device
, nch
->nch_TaskMsgPort
, nch
->nch_EPOut
)))
828 psdSetAttrs(PGA_PIPE
, nch
->nch_EPOutPipe
,
829 PPA_NakTimeout
, TRUE
,
830 PPA_AllowRuntPackets
, TRUE
,
831 PPA_NakTimeoutTime
, 5000,
833 if((nch
->nch_EPInBuf
= psdAllocVec(1024)))
835 if((nch
->nch_EPOutBuf
= psdAllocVec(8192)))
837 nch
->nch_Task
= thistask
;
840 psdFreeVec(nch
->nch_EPInBuf
);
842 psdFreePipe(nch
->nch_EPOutPipe
);
844 psdFreePipe(nch
->nch_EPInPipe
);
846 psdFreePipe(nch
->nch_EP0Pipe
);
848 DeleteMsgPort(nch
->nch_TaskMsgPort
);
851 CloseLibrary(nch
->nch_Base
);
853 nch
->nch_Task
= NULL
;
854 if(nch
->nch_ReadySigTask
)
856 Signal(nch
->nch_ReadySigTask
, 1L<<nch
->nch_ReadySignal
);
862 /* /// "nFreeHid()" */
863 void nFreeHid(struct NepClassHid
*nch
)
866 /* delete all msgport references to this instance, disabling all midi transmissions */
868 for(cnt
= 0; cnt
< 16; cnt
++)
870 nch
->nch_ClsBase
->nh_CAMDAdapters
[cnt
].ca_MsgPort
= NULL
;
873 psdFreeVec(nch
->nch_EPOutBuf
);
874 psdFreeVec(nch
->nch_EPInBuf
);
875 psdFreePipe(nch
->nch_EPOutPipe
);
876 psdFreePipe(nch
->nch_EPInPipe
);
877 psdFreePipe(nch
->nch_EP0Pipe
);
878 DeleteMsgPort(nch
->nch_TaskMsgPort
);
879 CloseLibrary(nch
->nch_Base
);
881 nch
->nch_Task
= NULL
;
882 if(nch
->nch_ReadySigTask
)
884 Signal(nch
->nch_ReadySigTask
, 1L<<nch
->nch_ReadySignal
);
889 /**************************************************************************/
893 /* /// "nLoadClassConfig()" */
894 BOOL
nLoadClassConfig(struct NepHidBase
*nh
)
897 struct ClsGlobalCfg
*cgc
;
898 struct PsdIFFContext
*pic
;
900 KPRINTF(10, ("Loading Class Config...\n"));
901 if(!(ps
= OpenLibrary("poseidon.library", 4)))
906 nh
->nh_UsingDefaultCfg
= TRUE
;
907 pic
= psdGetClsCfg(libname
);
910 if((cgc
= psdGetCfgChunk(pic
, AROS_LONG2BE(nh
->nh_CurrentCGC
.cgc_ChunkID
))))
912 CopyMem(((UBYTE
*) cgc
) + 8, ((UBYTE
*) &nh
->nh_CurrentCGC
) + 8, min(AROS_LONG2BE(cgc
->cgc_Length
), AROS_LONG2BE(nh
->nh_CurrentCGC
.cgc_Length
)));
914 nh
->nh_UsingDefaultCfg
= FALSE
;
923 /* /// "nOpenCfgWindow()" */
924 LONG
nOpenCfgWindow(struct NepHidBase
*nh
)
927 KPRINTF(10, ("Opening GUI...\n"));
928 if(!(ps
= OpenLibrary("poseidon.library", 4)))
935 if((nh
->nh_GUITask
= psdSpawnSubTask(MOD_NAME_STRING
" GUI", nGUITask
, nh
)))
948 /* /// "nGUITask()" */
949 AROS_UFH0(void, nGUITask
)
953 struct Task
*thistask
;
954 struct NepHidBase
*nh
;
957 thistask
= FindTask(NULL
);
959 #define ps nh->nh_PsdBase
961 #define IntuitionBase nh->nh_IntBase
963 #define MUIMasterBase nh->nh_MUIBase
965 nh
= thistask
->tc_UserData
;
966 ++nh
->nh_Library
.lib_OpenCnt
;
967 if(!(MUIMasterBase
= OpenLibrary(MUIMASTER_NAME
, MUIMASTER_VMIN
)))
969 KPRINTF(10, ("Couldn't open muimaster.library.\n"));
974 if(!(IntuitionBase
= OpenLibrary("intuition.library", 39)))
976 KPRINTF(10, ("Couldn't open intuition.library.\n"));
980 if(!(ps
= OpenLibrary("poseidon.library", 4)))
982 KPRINTF(10, ("Couldn't open poseidon.library.\n"));
987 nh
->nh_App
= ApplicationObject
,
988 MUIA_Application_Title
, (IPTR
)libname
,
989 MUIA_Application_Version
, (IPTR
)VERSION_STRING
,
990 MUIA_Application_Copyright
, (IPTR
)"©2006-2009 Chris Hodges",
991 MUIA_Application_Author
, (IPTR
)"Chris Hodges <chrisly@platon42.de>",
992 MUIA_Application_Description
, (IPTR
)"Settings for the camdusbmidi.class",
993 MUIA_Application_Base
, (IPTR
)"CAMDUSBMIDI",
994 MUIA_Application_HelpFile
, (IPTR
)"HELP:Poseidon.guide",
995 MUIA_Application_Menustrip
, (IPTR
)MenustripObject
,
996 Child
, (IPTR
)MenuObjectT((IPTR
)"Project"),
997 Child
, (IPTR
)(nh
->nh_AboutMI
= MenuitemObject
,
998 MUIA_Menuitem_Title
, (IPTR
)"About...",
999 MUIA_Menuitem_Shortcut
, (IPTR
)"?",
1002 Child
, (IPTR
)MenuObjectT((IPTR
)"Settings"),
1003 Child
, (IPTR
)(nh
->nh_UseMI
= MenuitemObject
,
1004 MUIA_Menuitem_Title
, (IPTR
)"Save",
1005 MUIA_Menuitem_Shortcut
, (IPTR
)"S",
1007 Child
, (IPTR
)MenuitemObject
,
1008 MUIA_Menuitem_Title
, (IPTR
)NM_BARLABEL
,
1010 Child
, (IPTR
)(nh
->nh_MUIPrefsMI
= MenuitemObject
,
1011 MUIA_Menuitem_Title
, (IPTR
)"MUI Settings",
1012 MUIA_Menuitem_Shortcut
, (IPTR
)"M",
1017 SubWindow
, (IPTR
)(nh
->nh_MainWindow
= WindowObject
,
1018 MUIA_Window_ID
, MAKE_ID('M','A','I','N'),
1019 MUIA_Window_Title
, (IPTR
)libname
,
1020 MUIA_HelpNode
, (IPTR
)libname
,
1022 WindowContents
, (IPTR
)VGroup
,
1023 Child
, (IPTR
)ColGroup(2), GroupFrameT("Global Settings"),
1024 Child
, (IPTR
)Label((IPTR
) "None"),
1025 Child
, (IPTR
)HSpace(0),
1027 Child
, (IPTR
)VSpace(0),
1028 Child
, (IPTR
)HGroup
,
1029 MUIA_Group_SameWidth
, TRUE
,
1030 Child
, (IPTR
)(nh
->nh_UseObj
= TextObject
, ButtonFrame
,
1031 MUIA_Background
, MUII_ButtonBack
,
1033 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
1034 MUIA_Text_Contents
, (IPTR
)"\33c Save ",
1036 Child
, (IPTR
)(nh
->nh_CloseObj
= TextObject
, ButtonFrame
,
1037 MUIA_Background
, MUII_ButtonBack
,
1039 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
1040 MUIA_Text_Contents
, (IPTR
)"\33c Use ",
1049 KPRINTF(10, ("Couldn't create application\n"));
1050 nGUITaskCleanup(nh
);
1053 DoMethod(nh
->nh_MainWindow
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
,
1054 nh
->nh_App
, 2, MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
1055 DoMethod(nh
->nh_UseObj
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
1056 nh
->nh_App
, 2, MUIM_Application_ReturnID
, ID_STORE_CONFIG
);
1057 DoMethod(nh
->nh_CloseObj
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
1058 nh
->nh_App
, 2, MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
1060 DoMethod(nh
->nh_AboutMI
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
1061 nh
->nh_App
, 2, MUIM_Application_ReturnID
, ID_ABOUT
);
1062 DoMethod(nh
->nh_UseMI
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
1063 nh
->nh_App
, 2, MUIM_Application_ReturnID
, ID_STORE_CONFIG
);
1064 DoMethod(nh
->nh_MUIPrefsMI
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
1065 nh
->nh_App
, 2, MUIM_Application_OpenConfigWindow
, 0);
1074 get(nh
->nh_App
, MUIA_Application_Iconified
, &iconify
);
1075 set(nh
->nh_MainWindow
, MUIA_Window_Open
, TRUE
);
1076 get(nh
->nh_MainWindow
, MUIA_Window_Open
, &isopen
);
1077 if(!(isopen
|| iconify
))
1079 nGUITaskCleanup(nh
);
1085 retid
= DoMethod(nh
->nh_App
, MUIM_Application_NewInput
, &sigs
);
1088 case ID_STORE_CONFIG
:
1089 case MUIV_Application_ReturnID_Quit
:
1090 pic
= psdGetClsCfg(libname
);
1093 psdSetClsCfg(libname
, NULL
);
1094 pic
= psdGetClsCfg(libname
);
1098 if(psdAddCfgEntry(pic
, &nh
->nh_CurrentCGC
))
1100 if(retid
!= MUIV_Application_ReturnID_Quit
)
1102 psdSaveCfgToDisk(NULL
, FALSE
);
1104 retid
= MUIV_Application_ReturnID_Quit
;
1110 MUI_RequestA(nh
->nh_App
, nh
->nh_MainWindow
, 0, NULL
, "Marvellous!", VERSION_STRING
, NULL
);
1113 if(retid
== MUIV_Application_ReturnID_Quit
)
1119 sigs
= Wait(sigs
| sigmask
| SIGBREAKF_CTRL_C
);
1120 if(sigs
& SIGBREAKF_CTRL_C
)
1126 set(nh
->nh_MainWindow
, MUIA_Window_Open
, FALSE
);
1128 nGUITaskCleanup(nh
);
1134 /* /// "nGUITaskCleanup()" */
1135 void nGUITaskCleanup(struct NepHidBase
*nh
)
1139 MUI_DisposeObject(nh
->nh_App
);
1144 CloseLibrary(MUIMasterBase
);
1145 MUIMasterBase
= NULL
;
1149 CloseLibrary(IntuitionBase
);
1150 IntuitionBase
= NULL
;
1158 nh
->nh_GUITask
= NULL
;
1159 --nh
->nh_Library
.lib_OpenCnt
;