2 *----------------------------------------------------------------------------
3 * simplemidi class for poseidon
4 *----------------------------------------------------------------------------
5 * By Chris Hodges <chrisly@platon42.de>
10 #include "simplemidi.class.h"
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
25 /* Create default config */
26 nh
->nh_CurrentCGC
.cgc_ChunkID
= AROS_LONG2BE(MAKE_ID('M','I','D','I'));
27 nh
->nh_CurrentCGC
.cgc_Length
= AROS_LONG2BE(sizeof(struct ClsGlobalCfg
)-8);
28 nh
->nh_CurrentCGC
.cgc_MidiMinOctave
= 2;
29 nh
->nh_CurrentCGC
.cgc_KeyMaxOctave
= 5;
30 nh
->nh_CurrentCGC
.cgc_AutoKeyUp
= TRUE
;
32 KPRINTF(20, ("libInit: OpenLibrary(\"utility.library\", 39) failed!\n"));
36 KPRINTF(10, ("libInit: Ok\n"));
37 return(nh
? TRUE
: FALSE
);
40 static int libOpen(LIBBASETYPEPTR nh
)
42 KPRINTF(10, ("libOpen nh: 0x%08lx\n", nh
));
47 static int libExpunge(LIBBASETYPEPTR nh
)
49 KPRINTF(10, ("libExpunge nh: 0x%08lx\n", nh
));
50 CloseLibrary((struct Library
*) UtilityBase
);
54 ADD2INITLIB(libInit
, 0)
55 ADD2OPENLIB(libOpen
, 0)
56 ADD2EXPUNGELIB(libExpunge
, 0)
60 * ***********************************************************************
61 * * Library functions *
62 * ***********************************************************************
67 /* /// "usbAttemptInterfaceBinding()" */
68 struct NepClassHid
* usbAttemptInterfaceBinding(struct NepHidBase
*nh
, struct PsdInterface
*pif
)
75 KPRINTF(1, ("nepHidAttemptInterfaceBinding(%08lx)\n", pif
));
76 if((ps
= OpenLibrary("poseidon.library", 4)))
78 psdGetAttrs(PGA_INTERFACE
, pif
,
80 IFA_SubClass
, &subclass
,
84 if((ifclass
== AUDIO_CLASSCODE
) && (subclass
== AUDIO_MIDI_SUBCLASS
))
86 return(usbForceInterfaceBinding(nh
, pif
));
93 /* /// "usbForceInterfaceBinding()" */
94 struct NepClassHid
* usbForceInterfaceBinding(struct NepHidBase
*nh
, struct PsdInterface
*pif
)
97 struct NepClassHid
*nch
;
102 struct Task
*tmptask
;
104 KPRINTF(1, ("nepHidAttemptInterfaceBinding(%08lx)\n", pif
));
105 if((ps
= OpenLibrary("poseidon.library", 4)))
107 if((nch
= psdAllocVec(sizeof(struct NepClassHid
))))
109 nch
->nch_ClsBase
= nh
;
110 nch
->nch_Device
= NULL
;
111 nch
->nch_Interface
= pif
;
113 nLoadClassConfig(nh
);
115 psdSafeRawDoFmt(buf
, 64, "simplemidi.class<%08lx>", nch
);
116 nch
->nch_ReadySignal
= SIGB_SINGLE
;
117 nch
->nch_ReadySigTask
= FindTask(NULL
);
118 SetSignal(0, SIGF_SINGLE
);
119 if((tmptask
= psdSpawnSubTask(buf
, nHidTask
, nch
)))
121 psdBorrowLocksWait(tmptask
, 1UL<<nch
->nch_ReadySignal
);
124 nch
->nch_ReadySigTask
= NULL
;
125 //FreeSignal(nch->nch_ReadySignal);
126 psdGetAttrs(PGA_INTERFACE
, pif
, IFA_Config
, &pc
, TAG_END
);
127 psdGetAttrs(PGA_CONFIG
, pc
, CA_Device
, &pd
, TAG_END
);
128 psdGetAttrs(PGA_DEVICE
, pd
, DA_ProductName
, &devname
, TAG_END
);
129 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
,
130 "Play it again, '%s'!",
137 nch
->nch_ReadySigTask
= NULL
;
138 //FreeSignal(nch->nch_ReadySignal);
147 /* /// "usbReleaseInterfaceBinding()" */
148 void usbReleaseInterfaceBinding(struct NepHidBase
*nh
, struct NepClassHid
*nch
)
151 struct PsdConfig
*pc
;
152 struct PsdDevice
*pd
;
155 KPRINTF(1, ("nepHidReleaseInterfaceBinding(%08lx)\n", nch
));
156 if((ps
= OpenLibrary("poseidon.library", 4)))
159 nch
->nch_ReadySignal
= SIGB_SINGLE
;
160 nch
->nch_ReadySigTask
= FindTask(NULL
);
163 Signal(nch
->nch_Task
, SIGBREAKF_CTRL_C
);
168 Wait(1L<<nch
->nch_ReadySignal
);
170 //FreeSignal(nch->nch_ReadySignal);
171 psdGetAttrs(PGA_INTERFACE
, nch
->nch_Interface
, IFA_Config
, &pc
, TAG_END
);
172 psdGetAttrs(PGA_CONFIG
, pc
, CA_Device
, &pd
, TAG_END
);
173 psdGetAttrs(PGA_DEVICE
, pd
, DA_ProductName
, &devname
, TAG_END
);
174 psdAddErrorMsg(RETURN_OK
, (STRPTR
) libname
,
183 /* /// "usbGetAttrsA()" */
184 AROS_LH3(LONG
, usbGetAttrsA
,
185 AROS_LHA(ULONG
, type
, D0
),
186 AROS_LHA(APTR
, usbstruct
, A0
),
187 AROS_LHA(struct TagItem
*, tags
, A1
),
188 LIBBASETYPEPTR
, nh
, 5, nep
)
195 KPRINTF(1, ("nepHidGetAttrsA(%ld, %08lx, %08lx)\n", type
, usbstruct
, tags
));
199 if((ti
= FindTagItem(UCCA_Priority
, tags
)))
201 *((SIPTR
*) ti
->ti_Data
) = -100;
204 if((ti
= FindTagItem(UCCA_Description
, tags
)))
206 *((STRPTR
*) ti
->ti_Data
) = "Simple MIDI-IN Stream class mapping to keyboard";
209 if((ti
= FindTagItem(UCCA_HasClassCfgGUI
, tags
)))
211 *((IPTR
*) ti
->ti_Data
) = TRUE
;
214 if((ti
= FindTagItem(UCCA_HasBindingCfgGUI
, tags
)))
216 *((IPTR
*) ti
->ti_Data
) = FALSE
;
219 if((ti
= FindTagItem(UCCA_AfterDOSRestart
, tags
)))
221 *((IPTR
*) ti
->ti_Data
) = TRUE
;
224 if((ti
= FindTagItem(UCCA_UsingDefaultCfg
, tags
)))
226 *((IPTR
*) ti
->ti_Data
) = nh
->nh_UsingDefaultCfg
;
232 if((ti
= FindTagItem(UCCA_UsingDefaultCfg
, tags
)))
234 *((IPTR
*) ti
->ti_Data
) = FALSE
;
244 /* /// "usbSetAttrsA()" */
245 AROS_LH3(LONG
, usbSetAttrsA
,
246 AROS_LHA(ULONG
, type
, D0
),
247 AROS_LHA(APTR
, usbstruct
, A0
),
248 AROS_LHA(struct TagItem
*, tags
, A1
),
249 LIBBASETYPEPTR
, nh
, 6, nep
)
257 /* /// "usbDoMethodA()" */
258 AROS_LH2(IPTR
, usbDoMethodA
,
259 AROS_LHA(ULONG
, methodid
, D0
),
260 AROS_LHA(IPTR
*, methoddata
, A1
),
261 LIBBASETYPEPTR
, nh
, 7, nep
)
265 KPRINTF(10, ("Do Method %ld\n", methodid
));
268 case UCM_AttemptInterfaceBinding
:
269 return((IPTR
) usbAttemptInterfaceBinding(nh
, (struct PsdInterface
*) methoddata
[0]));
271 case UCM_ForceInterfaceBinding
:
272 return((IPTR
) usbForceInterfaceBinding(nh
, (struct PsdInterface
*) methoddata
[0]));
274 case UCM_ReleaseInterfaceBinding
:
275 usbReleaseInterfaceBinding(nh
, (struct NepClassHid
*) methoddata
[0]);
278 case UCM_OpenCfgWindow
:
279 return(nOpenCfgWindow(nh
));
281 case UCM_ConfigChangedEvent
:
282 nLoadClassConfig(nh
);
293 /**************************************************************************/
295 static const UBYTE lowoctave
[] =
297 0x31, 0x21, 0x32, 0x22, 0x33, 0x34, 0x24, 0x35, 0x25, 0x36, 0x26, 0x37, /* C-1 - B-1 */
298 0x38, 0x28, 0x39, 0x29, 0x3a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* C-2 - E-2 */
301 static const UBYTE highoctave
[] =
303 0x10, 0x02, 0x11, 0x03, 0x12, 0x13, 0x05, 0x14, 0x06, 0x15, 0x07, 0x16, /* C-2 - B-2 */
304 0x17, 0x09, 0x18, 0x0a, 0x19, 0x1a, 0x0b, 0x1b, 0xff, 0xff, 0xff, 0xff /* C-3 - F-3 */
308 #define ps nch->nch_Base
310 /* /// "nHidTask()" */
311 AROS_UFH0(void, nHidTask
)
315 struct NepClassHid
*nch
;
323 if((nch
= nAllocHid()))
326 if(nch
->nch_ReadySigTask
)
328 Signal(nch
->nch_ReadySigTask
, 1L<<nch
->nch_ReadySignal
);
331 sigmask
= (1L<<nch
->nch_TaskMsgPort
->mp_SigBit
)|SIGBREAKF_CTRL_C
;
332 buf
= nch
->nch_EPInBuf
;
333 psdSendPipe(nch
->nch_EPInPipe
, buf
, 512);
336 sigs
= Wait(sigmask
);
337 while((pp
= (struct PsdPipe
*) GetMsg(nch
->nch_TaskMsgPort
)))
339 if(pp
== nch
->nch_EPInPipe
)
341 if(!(ioerr
= psdGetPipeError(pp
)))
343 len
= psdGetPipeActual(pp
);
344 nParseMidi(nch
, buf
, len
);
346 KPRINTF(1, ("Int Pipe failed %ld\n", ioerr
));
349 psdSendPipe(nch
->nch_EPInPipe
, buf
, 512);
353 } while(!(sigs
& SIGBREAKF_CTRL_C
));
354 KPRINTF(20, ("Going down the river!\n"));
355 psdAbortPipe(nch
->nch_EPInPipe
);
356 psdWaitPipe(nch
->nch_EPInPipe
);
364 /* /// "nSendKey()" */
365 void nSendKey(struct NepClassHid
*nch
, UWORD code
)
367 nch
->nch_FakeEvent
.ie_Class
= IECLASS_RAWKEY
;
368 nch
->nch_FakeEvent
.ie_SubClass
= 0;
369 nch
->nch_FakeEvent
.ie_Code
= code
;
370 nch
->nch_FakeEvent
.ie_NextEvent
= NULL
;
371 nch
->nch_FakeEvent
.ie_Qualifier
= 0;
372 nch
->nch_InpIOReq
->io_Data
= &nch
->nch_FakeEvent
;
373 nch
->nch_InpIOReq
->io_Length
= sizeof(struct InputEvent
);
374 nch
->nch_InpIOReq
->io_Command
= IND_WRITEEVENT
;
375 DoIO((struct IORequest
*) nch
->nch_InpIOReq
);
379 /* /// "nParseMidi()" */
380 void nParseMidi(struct NepClassHid
*nch
, UBYTE
*buf
, ULONG len
)
389 struct ClsGlobalCfg
*cgc
= &nch
->nch_ClsBase
->nh_CurrentCGC
;
393 KPRINTF(1, ("Msg: %02lx %02lx %02lx %02lx\n", buf
[0], buf
[1], buf
[2], buf
[3]));
395 (void)chan
; /* FIXME: Why is 'chan' ignored? */
399 case 0x0: // Miscellaneous function codes. Reserved for future extensions.
400 case 0x1: // Cable events. Reserved for future expansion.
401 case 0x2: // Two-byte System Common messages like MTC, SongSelect, etc.
402 case 0x3: // Three-byte System Common messages like SPP, etc.
403 case 0x4: // SysEx starts or continues
404 case 0x5: // Single-byte System Common Message or SysEx ends with following single byte.
405 case 0x6: // SysEx ends with following two bytes.
406 case 0x7: // SysEx ends with following three bytes.
409 case 0x8: // Note-off
410 KPRINTF(1, ("Note %ld up with speed %ld\n", note
, velocity
));
417 KPRINTF(1, ("Note %ld down with speed %ld\n", note
, velocity
));
422 if(note
< 12 * cgc
->cgc_MidiMinOctave
)
426 octave
= (note
- (12 * cgc
->cgc_MidiMinOctave
)) / 12;
428 if(octave
> cgc
->cgc_KeyMaxOctave
)
430 octave
= cgc
->cgc_KeyMaxOctave
;
432 if((octave
!= nch
->nch_LastOctave
) && (octave
!= nch
->nch_LastOctave
+1))
434 nch
->nch_LastOctave
= octave
; /* go to right octave */
435 if(nch
->nch_LastOctave
> 0)
437 nch
->nch_LastOctave
--; // stay at low octave
440 nSendKey(nch
, 0x50+nch
->nch_LastOctave
);
441 nSendKey(nch
, (IECODE_UP_PREFIX
|0x50)+nch
->nch_LastOctave
);
443 if(octave
== nch
->nch_LastOctave
)
445 iecode
= lowoctave
[note
% 12];
447 if(octave
> nch
->nch_LastOctave
)
449 iecode
= highoctave
[note
% 12];
455 iecode
|= IECODE_UP_PREFIX
;
457 nSendKey(nch
, iecode
);
458 if(cgc
->cgc_AutoKeyUp
&& (!(iecode
& IECODE_UP_PREFIX
)))
460 iecode
|= IECODE_UP_PREFIX
;
461 nSendKey(nch
, iecode
);
466 case 0xA: // Poly-KeyPress
467 case 0xB: // Control Change
468 case 0xC: // Program Change
469 case 0xD: // Channel Pressure
470 case 0xE: // PitchBend Change
471 case 0xF: // Single Byte
477 KPRINTF(1, ("Key up: %08lx\n", keycode));
478 iecode = usbkeymap[keycode];
480 nch->nch_FakeEvent.ie_Class = IECLASS_RAWKEY;
481 nch->nch_FakeEvent.ie_SubClass = 0;
482 nch->nch_FakeEvent.ie_Code = iecode|IECODE_UP_PREFIX;
483 nch->nch_FakeEvent.ie_NextEvent = NULL;
484 nch->nch_FakeEvent.ie_Qualifier = qualifier;
485 nch->nch_InpIOReq->io_Data = &nch->nch_FakeEvent;
486 nch->nch_InpIOReq->io_Length = sizeof(struct InputEvent);
487 nch->nch_InpIOReq->io_Command = IND_WRITEEVENT;
488 DoIO((struct IORequest *) nch->nch_InpIOReq);
496 /* /// "nAllocHid()" */
497 struct NepClassHid
* nAllocHid(void)
499 struct Task
*thistask
;
500 struct NepClassHid
*nch
;
502 thistask
= FindTask(NULL
);
503 nch
= thistask
->tc_UserData
;
506 if(!(nch
->nch_Base
= OpenLibrary("poseidon.library", 4)))
511 psdGetAttrs(PGA_INTERFACE
, nch
->nch_Interface
,
512 IFA_Config
, &nch
->nch_Config
,
513 IFA_InterfaceNum
, &nch
->nch_IfNum
,
515 psdGetAttrs(PGA_CONFIG
, nch
->nch_Config
,
516 CA_Device
, &nch
->nch_Device
,
519 nch
->nch_EPIn
= psdFindEndpoint(nch
->nch_Interface
, NULL
,
521 EA_TransferType
, USEAF_BULK
,
525 KPRINTF(1, ("Ooops!?! No Endpoints defined?\n"));
526 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) libname
,
527 "No Bulk-In Endpoint!");
530 if((nch
->nch_InpMsgPort
= CreateMsgPort()))
532 if((nch
->nch_InpIOReq
= (struct IOStdReq
*) CreateIORequest(nch
->nch_InpMsgPort
, sizeof(struct IOStdReq
))))
534 if(!OpenDevice("input.device", 0, (struct IORequest
*) nch
->nch_InpIOReq
, 0))
536 nch
->nch_InputBase
= (struct Library
*) nch
->nch_InpIOReq
->io_Device
;
537 if((nch
->nch_TaskMsgPort
= CreateMsgPort()))
539 if((nch
->nch_EP0Pipe
= psdAllocPipe(nch
->nch_Device
, nch
->nch_TaskMsgPort
, NULL
)))
541 if((nch
->nch_EPInPipe
= psdAllocPipe(nch
->nch_Device
, nch
->nch_TaskMsgPort
, nch
->nch_EPIn
)))
543 psdSetAttrs(PGA_PIPE
, nch
->nch_EPInPipe
,
544 PPA_NakTimeout
, FALSE
,
545 PPA_AllowRuntPackets
, TRUE
,
548 if((nch
->nch_EPInBuf
= psdAllocVec(1024)))
550 nch
->nch_Task
= thistask
;
553 psdFreePipe(nch
->nch_EPInPipe
);
555 psdFreePipe(nch
->nch_EP0Pipe
);
557 DeleteMsgPort(nch
->nch_TaskMsgPort
);
559 CloseDevice((struct IORequest
*) nch
->nch_InpIOReq
);
561 DeleteIORequest((struct IORequest
*) nch
->nch_InpIOReq
);
563 DeleteMsgPort(nch
->nch_InpMsgPort
);
566 CloseLibrary(nch
->nch_Base
);
568 nch
->nch_Task
= NULL
;
569 if(nch
->nch_ReadySigTask
)
571 Signal(nch
->nch_ReadySigTask
, 1L<<nch
->nch_ReadySignal
);
577 /* /// "nFreeHid()" */
578 void nFreeHid(struct NepClassHid
*nch
)
580 psdFreeVec(nch
->nch_EPInBuf
);
581 psdFreePipe(nch
->nch_EPInPipe
);
582 psdFreePipe(nch
->nch_EP0Pipe
);
583 DeleteMsgPort(nch
->nch_TaskMsgPort
);
584 CloseDevice((struct IORequest
*) nch
->nch_InpIOReq
);
585 DeleteIORequest((struct IORequest
*) nch
->nch_InpIOReq
);
586 DeleteMsgPort(nch
->nch_InpMsgPort
);
587 CloseLibrary(nch
->nch_Base
);
589 nch
->nch_Task
= NULL
;
590 if(nch
->nch_ReadySigTask
)
592 Signal(nch
->nch_ReadySigTask
, 1L<<nch
->nch_ReadySignal
);
597 /**************************************************************************/
601 /* /// "nLoadClassConfig()" */
602 BOOL
nLoadClassConfig(struct NepHidBase
*nh
)
605 struct ClsGlobalCfg
*cgc
;
606 struct PsdIFFContext
*pic
;
608 KPRINTF(10, ("Loading Class Config...\n"));
609 if(!(ps
= OpenLibrary("poseidon.library", 4)))
614 nh
->nh_UsingDefaultCfg
= TRUE
;
615 pic
= psdGetClsCfg(libname
);
618 if((cgc
= psdGetCfgChunk(pic
, AROS_LONG2BE(nh
->nh_CurrentCGC
.cgc_ChunkID
))))
620 CopyMem(((UBYTE
*) cgc
) + 8, ((UBYTE
*) &nh
->nh_CurrentCGC
) + 8, min(AROS_LONG2BE(cgc
->cgc_Length
), AROS_LONG2BE(nh
->nh_CurrentCGC
.cgc_Length
)));
622 nh
->nh_UsingDefaultCfg
= FALSE
;
631 /* /// "nOpenCfgWindow()" */
632 LONG
nOpenCfgWindow(struct NepHidBase
*nh
)
635 KPRINTF(10, ("Opening GUI...\n"));
636 if(!(ps
= OpenLibrary("poseidon.library", 4)))
643 if((nh
->nh_GUITask
= psdSpawnSubTask(MOD_NAME_STRING
" GUI", nGUITask
, nh
)))
656 /* /// "nGUITask()" */
657 AROS_UFH0(void, nGUITask
)
661 struct Task
*thistask
;
662 struct NepHidBase
*nh
;
665 thistask
= FindTask(NULL
);
667 #define ps nh->nh_PsdBase
669 #define IntuitionBase nh->nh_IntBase
671 #define MUIMasterBase nh->nh_MUIBase
673 nh
= thistask
->tc_UserData
;
674 ++nh
->nh_Library
.lib_OpenCnt
;
675 if(!(MUIMasterBase
= OpenLibrary(MUIMASTER_NAME
, MUIMASTER_VMIN
)))
677 KPRINTF(10, ("Couldn't open muimaster.library.\n"));
682 if(!(IntuitionBase
= OpenLibrary("intuition.library", 39)))
684 KPRINTF(10, ("Couldn't open intuition.library.\n"));
688 if(!(ps
= OpenLibrary("poseidon.library", 4)))
690 KPRINTF(10, ("Couldn't open poseidon.library.\n"));
695 nh
->nh_App
= ApplicationObject
,
696 MUIA_Application_Title
, (IPTR
)libname
,
697 MUIA_Application_Version
, (IPTR
)VERSION_STRING
,
698 MUIA_Application_Copyright
, (IPTR
)"©2005-2009 Chris Hodges",
699 MUIA_Application_Author
, (IPTR
)"Chris Hodges <chrisly@platon42.de>",
700 MUIA_Application_Description
, (IPTR
)"Settings for the simplemidi.class",
701 MUIA_Application_Base
, (IPTR
)"SIMPLEMIDI",
702 MUIA_Application_HelpFile
, (IPTR
)"HELP:Poseidon.guide",
703 MUIA_Application_Menustrip
, (IPTR
)MenustripObject
,
704 Child
, (IPTR
)MenuObjectT((IPTR
)"Project"),
705 Child
, (IPTR
)(nh
->nh_AboutMI
= MenuitemObject
,
706 MUIA_Menuitem_Title
, (IPTR
)"About...",
707 MUIA_Menuitem_Shortcut
, (IPTR
)"?",
710 Child
, (IPTR
)MenuObjectT((IPTR
)"Settings"),
711 Child
, (IPTR
)(nh
->nh_UseMI
= MenuitemObject
,
712 MUIA_Menuitem_Title
, (IPTR
)"Save",
713 MUIA_Menuitem_Shortcut
, (IPTR
)"S",
715 Child
, (IPTR
)MenuitemObject
,
716 MUIA_Menuitem_Title
, (IPTR
)NM_BARLABEL
,
718 Child
, (IPTR
)(nh
->nh_MUIPrefsMI
= MenuitemObject
,
719 MUIA_Menuitem_Title
, (IPTR
)"MUI Settings",
720 MUIA_Menuitem_Shortcut
, (IPTR
)"M",
725 SubWindow
, (IPTR
)(nh
->nh_MainWindow
= WindowObject
,
726 MUIA_Window_ID
, MAKE_ID('M','A','I','N'),
727 MUIA_Window_Title
, (IPTR
)libname
,
728 MUIA_HelpNode
, (IPTR
)libname
,
730 WindowContents
, (IPTR
)VGroup
,
731 /* Child, actionobj = NewObject(ActionClass->mcc_Class, 0,
734 Child
, (IPTR
)ColGroup(2), GroupFrameT("Global Settings"),
735 Child
, (IPTR
)Label((IPTR
) "Midi Minimum Octave:"),
736 Child
, (IPTR
)(nh
->nh_MidiMinOctaveObj
= SliderObject
, SliderFrame
,
739 MUIA_Numeric_Max
, 10,
740 MUIA_Numeric_Value
, nh
->nh_CurrentCGC
.cgc_MidiMinOctave
,
742 Child
, (IPTR
)Label((IPTR
) "Maximum Octaves on Keyboard:"),
743 Child
, (IPTR
)(nh
->nh_KeyMaxOctaveObj
= SliderObject
, SliderFrame
,
746 MUIA_Numeric_Max
, 10,
747 MUIA_Numeric_Value
, nh
->nh_CurrentCGC
.cgc_KeyMaxOctave
,
749 Child
, (IPTR
)Label((IPTR
) "Automatic KeyUp Event:"),
751 Child
, (IPTR
)(nh
->nh_AutoKeyUpObj
= ImageObject
, ImageButtonFrame
,
752 MUIA_Background
, MUII_ButtonBack
,
754 MUIA_InputMode
, MUIV_InputMode_Toggle
,
755 MUIA_Image_Spec
, MUII_CheckMark
,
756 MUIA_Image_FreeVert
, TRUE
,
757 MUIA_Selected
, nh
->nh_CurrentCGC
.cgc_AutoKeyUp
,
758 MUIA_ShowSelState
, FALSE
,
760 Child
, (IPTR
)HSpace(0),
763 Child
, (IPTR
)VSpace(0),
765 MUIA_Group_SameWidth
, TRUE
,
766 Child
, (IPTR
)(nh
->nh_UseObj
= TextObject
, ButtonFrame
,
767 MUIA_Background
, MUII_ButtonBack
,
769 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
770 MUIA_Text_Contents
, (IPTR
)"\33c Save ",
772 Child
, (IPTR
)(nh
->nh_CloseObj
= TextObject
, ButtonFrame
,
773 MUIA_Background
, MUII_ButtonBack
,
775 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
776 MUIA_Text_Contents
, (IPTR
)"\33c Use ",
785 KPRINTF(10, ("Couldn't create application\n"));
789 DoMethod(nh
->nh_MainWindow
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
,
790 nh
->nh_App
, 2, MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
791 DoMethod(nh
->nh_UseObj
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
792 nh
->nh_App
, 2, MUIM_Application_ReturnID
, ID_STORE_CONFIG
);
793 DoMethod(nh
->nh_CloseObj
, MUIM_Notify
, MUIA_Pressed
, FALSE
,
794 nh
->nh_App
, 2, MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
796 DoMethod(nh
->nh_AboutMI
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
797 nh
->nh_App
, 2, MUIM_Application_ReturnID
, ID_ABOUT
);
798 DoMethod(nh
->nh_UseMI
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
799 nh
->nh_App
, 2, MUIM_Application_ReturnID
, ID_STORE_CONFIG
);
800 DoMethod(nh
->nh_MUIPrefsMI
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
801 nh
->nh_App
, 2, MUIM_Application_OpenConfigWindow
, 0);
810 get(nh
->nh_App
, MUIA_Application_Iconified
, &iconify
);
811 set(nh
->nh_MainWindow
, MUIA_Window_Open
, TRUE
);
812 get(nh
->nh_MainWindow
, MUIA_Window_Open
, &isopen
);
813 if(!(isopen
|| iconify
))
821 retid
= DoMethod(nh
->nh_App
, MUIM_Application_NewInput
, &sigs
);
824 case ID_STORE_CONFIG
:
825 case MUIV_Application_ReturnID_Quit
:
826 get(nh
->nh_MidiMinOctaveObj
, MUIA_Numeric_Value
, &nh
->nh_CurrentCGC
.cgc_MidiMinOctave
);
827 get(nh
->nh_KeyMaxOctaveObj
, MUIA_Numeric_Value
, &nh
->nh_CurrentCGC
.cgc_KeyMaxOctave
);
828 get(nh
->nh_AutoKeyUpObj
, MUIA_Selected
, &nh
->nh_CurrentCGC
.cgc_AutoKeyUp
);
830 pic
= psdGetClsCfg(libname
);
833 psdSetClsCfg(libname
, NULL
);
834 pic
= psdGetClsCfg(libname
);
838 if(psdAddCfgEntry(pic
, &nh
->nh_CurrentCGC
))
840 if(retid
!= MUIV_Application_ReturnID_Quit
)
842 psdSaveCfgToDisk(NULL
, FALSE
);
844 retid
= MUIV_Application_ReturnID_Quit
;
850 MUI_RequestA(nh
->nh_App
, nh
->nh_MainWindow
, 0, NULL
, "Fabulous!", VERSION_STRING
, NULL
);
853 if(retid
== MUIV_Application_ReturnID_Quit
)
859 sigs
= Wait(sigs
| sigmask
| SIGBREAKF_CTRL_C
);
860 if(sigs
& SIGBREAKF_CTRL_C
)
866 set(nh
->nh_MainWindow
, MUIA_Window_Open
, FALSE
);
874 /* /// "nGUITaskCleanup()" */
875 void nGUITaskCleanup(struct NepHidBase
*nh
)
879 MUI_DisposeObject(nh
->nh_App
);
884 CloseLibrary(MUIMasterBase
);
885 MUIMasterBase
= NULL
;
889 CloseLibrary(IntuitionBase
);
890 IntuitionBase
= NULL
;
898 nh
->nh_GUITask
= NULL
;
899 --nh
->nh_Library
.lib_OpenCnt
;