Initial import of work-in-progress of Poseidon port.
[cake.git] / rom / usb / classes / bootkeyboard / bootkeyboard.class.c
blobbe88504306c686d35d1456ecfa6ed5669b1eb2e6
1 /*
2 *----------------------------------------------------------------------------
3 * bootkeyboard class for poseidon
4 *----------------------------------------------------------------------------
5 * By Chris Hodges <chrisly@platon42.de>
6 */
8 #include "debug.h"
10 #include "bootkeyboard.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 KPRINTF(20, ("libInit: OpenLibrary(\"utility.library\", 39) failed!\n"));
26 return FALSE;
29 KPRINTF(10, ("libInit: Ok\n"));
30 return TRUE;
33 static int libOpen(LIBBASETYPEPTR nh)
35 KPRINTF(10, ("libOpen nh: 0x%08lx\n", nh));
36 nLoadClassConfig(nh);
38 return TRUE;
41 static int libExpunge(LIBBASETYPEPTR nh)
43 KPRINTF(10, ("libExpunge nh: 0x%08lx SysBase: 0x%08lx\n", nh, SysBase));
45 CloseLibrary(UtilityBase);
46 nh->nh_UtilityBase = NULL;
48 return TRUE;
51 ADD2INITLIB(libInit, 0)
52 ADD2OPENLIB(libOpen, 0)
53 ADD2EXPUNGELIB(libExpunge, 0)
54 /* \\\ */
57 * ***********************************************************************
58 * * Library functions *
59 * ***********************************************************************
62 /* /// "usbAttemptInterfaceBinding()" */
63 struct NepClassHid * usbAttemptInterfaceBinding(struct NepHidBase *nh, struct PsdInterface *pif)
65 struct Library *ps;
66 ULONG ifclass;
67 ULONG subclass;
68 ULONG proto;
70 KPRINTF(1, ("nepHidAttemptInterfaceBinding(%08lx)\n", pif));
71 if((ps = OpenLibrary("poseidon.library", 4)))
73 psdGetAttrs(PGA_INTERFACE, pif,
74 IFA_Class, &ifclass,
75 IFA_SubClass, &subclass,
76 IFA_Protocol, &proto,
77 TAG_DONE);
78 CloseLibrary(ps);
79 if((ifclass == HID_CLASSCODE) && (subclass == HID_BOOT_SUBCLASS) && (proto == HID_PROTO_KEYBOARD))
81 return(usbForceInterfaceBinding(nh, pif));
84 return(NULL);
86 /* \\\ */
88 /* /// "usbForceInterfaceBinding()" */
89 struct NepClassHid * usbForceInterfaceBinding(struct NepHidBase *nh, struct PsdInterface *pif)
91 struct Library *ps;
92 struct NepClassHid *nch;
93 struct PsdConfig *pc;
94 struct PsdDevice *pd;
95 STRPTR devname;
96 UBYTE buf[64];
97 struct Task *tmptask;
99 KPRINTF(1, ("nepHidAttemptInterfaceBinding(%08lx)\n", pif));
100 if((ps = OpenLibrary("poseidon.library", 4)))
102 if((nch = psdAllocVec(sizeof(struct NepClassHid))))
104 nch->nch_ClsBase = nh;
105 nch->nch_Device = NULL;
106 nch->nch_Interface = pif;
108 nLoadClassConfig(nh);
110 psdSafeRawDoFmt(buf, 64, "bootkeyboard.class<%08lx>", nch);
111 nch->nch_ReadySignal = SIGB_SINGLE;
112 nch->nch_ReadySigTask = FindTask(NULL);
113 SetSignal(0, SIGF_SINGLE);
114 if((tmptask = psdSpawnSubTask(buf, nHidTask, nch)))
116 psdBorrowLocksWait(tmptask, 1UL<<nch->nch_ReadySignal);
117 if(nch->nch_Task)
119 nch->nch_ReadySigTask = NULL;
120 //FreeSignal(nch->nch_ReadySignal);
121 psdGetAttrs(PGA_INTERFACE, pif, IFA_Config, &pc, TAG_END);
122 psdGetAttrs(PGA_CONFIG, pc, CA_Device, &pd, TAG_END);
123 psdGetAttrs(PGA_DEVICE, pd, DA_ProductName, &devname, TAG_END);
124 psdAddErrorMsg(RETURN_OK, (STRPTR) libname,
125 "I've got my fingers on '%s'!",
126 devname);
128 CloseLibrary(ps);
129 return(nch);
132 nch->nch_ReadySigTask = NULL;
133 //FreeSignal(nch->nch_ReadySignal);
134 psdFreeVec(nch);
136 CloseLibrary(ps);
138 return(NULL);
140 /* \\\ */
142 /* /// "usbReleaseInterfaceBinding()" */
143 void usbReleaseInterfaceBinding(struct NepHidBase *nh, struct NepClassHid *nch)
145 struct Library *ps;
146 struct PsdConfig *pc;
147 struct PsdDevice *pd;
148 STRPTR devname;
150 KPRINTF(1, ("nepHidReleaseInterfaceBinding(%08lx)\n", nch));
151 if((ps = OpenLibrary("poseidon.library", 4)))
153 Forbid();
154 nch->nch_ReadySignal = SIGB_SINGLE;
155 nch->nch_ReadySigTask = FindTask(NULL);
156 if(nch->nch_Task)
158 Signal(nch->nch_Task, SIGBREAKF_CTRL_C);
160 Permit();
161 while(nch->nch_Task)
163 Wait(1L<<nch->nch_ReadySignal);
165 //FreeSignal(nch->nch_ReadySignal);
166 psdGetAttrs(PGA_INTERFACE, nch->nch_Interface, IFA_Config, &pc, TAG_END);
167 psdGetAttrs(PGA_CONFIG, pc, CA_Device, &pd, TAG_END);
168 psdGetAttrs(PGA_DEVICE, pd, DA_ProductName, &devname, TAG_END);
169 psdAddErrorMsg(RETURN_OK, (STRPTR) libname,
170 "I lost my keys to '%s'!",
171 devname);
172 psdFreeVec(nch);
173 CloseLibrary(ps);
176 /* \\\ */
178 /* /// "usbGetAttrsA()" */
179 AROS_LH3(LONG, usbGetAttrsA,
180 AROS_LHA(ULONG, type, D0),
181 AROS_LHA(APTR, usbstruct, A0),
182 AROS_LHA(struct TagItem *, tags, A1),
183 LIBBASETYPEPTR, nh, 5, nep)
185 AROS_LIBFUNC_INIT
187 struct TagItem *ti;
188 LONG count = 0;
190 KPRINTF(1, ("nepHidGetAttrsA(%ld, %08lx, %08lx)\n", type, usbstruct, tags));
191 switch(type)
193 case UGA_CLASS:
194 if((ti = FindTagItem(UCCA_Priority, tags)))
196 *((IPTR *) ti->ti_Data) = -100;
197 count++;
199 if((ti = FindTagItem(UCCA_Description, tags)))
201 *((STRPTR *) ti->ti_Data) = "Support for keyboards in boot protocol mode";
202 count++;
204 if((ti = FindTagItem(UCCA_HasClassCfgGUI, tags)))
206 *((IPTR *) ti->ti_Data) = TRUE;
207 count++;
209 if((ti = FindTagItem(UCCA_HasBindingCfgGUI, tags)))
211 *((IPTR *) ti->ti_Data) = FALSE;
212 count++;
214 if((ti = FindTagItem(UCCA_AfterDOSRestart, tags)))
216 *((IPTR *) ti->ti_Data) = TRUE;
217 count++;
219 if((ti = FindTagItem(UCCA_UsingDefaultCfg, tags)))
221 *((IPTR *) ti->ti_Data) = nh->nh_UsingDefaultCfg;
222 count++;
224 break;
226 case UGA_BINDING:
227 if((ti = FindTagItem(UCBA_UsingDefaultCfg, tags)))
229 *((IPTR *) ti->ti_Data) = FALSE;
230 count++;
232 break;
234 return(count);
235 AROS_LIBFUNC_EXIT
237 /* \\\ */
239 /* /// "usbSetAttrsA()" */
240 AROS_LH3(LONG, usbSetAttrsA,
241 AROS_LHA(ULONG, type, D0),
242 AROS_LHA(APTR, usbstruct, A0),
243 AROS_LHA(struct TagItem *, tags, A1),
244 LIBBASETYPEPTR, nh, 6, nep)
246 AROS_LIBFUNC_INIT
247 return(0);
248 AROS_LIBFUNC_EXIT
250 /* \\\ */
252 /* /// "usbDoMethodA()" */
253 AROS_LH2(IPTR, usbDoMethodA,
254 AROS_LHA(ULONG, methodid, D0),
255 AROS_LHA(IPTR *, methoddata, A1),
256 LIBBASETYPEPTR, nh, 7, nep)
258 AROS_LIBFUNC_INIT
260 KPRINTF(10, ("Do Method %ld\n", methodid));
261 switch(methodid)
263 case UCM_AttemptInterfaceBinding:
264 return((IPTR) usbAttemptInterfaceBinding(nh, (struct PsdInterface *) methoddata[0]));
266 case UCM_ForceInterfaceBinding:
267 return((IPTR) usbForceInterfaceBinding(nh, (struct PsdInterface *) methoddata[0]));
269 case UCM_ReleaseInterfaceBinding:
270 usbReleaseInterfaceBinding(nh, (struct NepClassHid *) methoddata[0]);
271 return(TRUE);
273 case UCM_OpenCfgWindow:
274 return(nOpenCfgWindow(nh));
276 case UCM_ConfigChangedEvent:
277 nLoadClassConfig(nh);
278 return(TRUE);
280 default:
281 break;
283 return(0);
284 AROS_LIBFUNC_EXIT
286 /* \\\ */
288 /* /// "nLoadClassConfig()" */
289 BOOL nLoadClassConfig(struct NepHidBase *nh)
291 struct Library *ps;
292 struct ClsGlobalCfg *cgc;
293 struct PsdIFFContext *pic;
295 KPRINTF(10, ("Loading Class Config...\n"));
296 if(nh->nh_GUITask)
298 return(FALSE);
300 if(!(ps = OpenLibrary("poseidon.library", 4)))
302 return(FALSE);
304 Forbid();
305 /* Create default config */
306 nh->nh_CurrentCGC.cgc_ChunkID = AROS_LONG2BE(MAKE_ID('B','K','E','Y'));
307 nh->nh_CurrentCGC.cgc_Length = AROS_LONG2BE(sizeof(struct ClsGlobalCfg)-8);
308 nh->nh_CurrentCGC.cgc_RHEnable = TRUE;
309 nh->nh_CurrentCGC.cgc_ResetDelay = 10;
310 nh->nh_CurrentCGC.cgc_CapsLock = FALSE;
311 nh->nh_CurrentCGC.cgc_ISAMap = FALSE;
312 nh->nh_CurrentCGC.cgc_ExtraEmulDisable = FALSE;
313 nh->nh_UsingDefaultCfg = TRUE;
314 pic = psdGetClsCfg(libname);
315 if(pic)
317 if((cgc = psdGetCfgChunk(pic, nh->nh_CurrentCGC.cgc_ChunkID)))
319 CopyMem(((UBYTE *) cgc) + 8, ((UBYTE *) &nh->nh_CurrentCGC) + 8, min(AROS_LONG2BE(cgc->cgc_Length), AROS_LONG2BE(nh->nh_CurrentCGC.cgc_Length)));
320 psdFreeVec(cgc);
321 nh->nh_UsingDefaultCfg = FALSE;
324 Permit();
325 CloseLibrary(ps);
326 return(FALSE);
328 /* \\\ */
330 /* /// "nOpenCfgWindow()" */
331 LONG nOpenCfgWindow(struct NepHidBase *nh)
333 struct Library *ps;
334 KPRINTF(10, ("Opening GUI...\n"));
335 if(!(ps = OpenLibrary("poseidon.library", 4)))
337 return(FALSE);
339 Forbid();
340 if(!nh->nh_GUITask)
342 if((nh->nh_GUITask = psdSpawnSubTask(MOD_NAME_STRING " GUI", nGUITask, nh)))
344 Permit();
345 CloseLibrary(ps);
346 return(TRUE);
349 Permit();
350 CloseLibrary(ps);
351 return(FALSE);
353 /* \\\ */
355 /**************************************************************************/
357 /* /// "Keymap Table" */
358 static const UBYTE usbkeymap[] =
360 0xff, 0xff, 0xff, 0xff, 0x20, 0x35, 0x33, 0x22, /* 0x00 */
361 0x12, 0x23, 0x24, 0x25, 0x17, 0x26, 0x27, 0x28, /* 0x08 */
362 0x37, 0x36, 0x18, 0x19, 0x10, 0x13, 0x21, 0x14, /* 0x10 */
363 0x16, 0x34, 0x11, 0x32, 0x15, 0x31, 0x01, 0x02, /* 0x18 */
364 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, /* 0x20 */
365 0x44, 0x45, 0x41, 0x42, 0x40, 0x0b, 0x0c, 0x1a, /* 0x28 */
366 0x1b, 0x0d, 0x2b, 0x29, 0x2a, 0x00, 0x38, 0x39, /* 0x30 */
367 0x3a, 0x62, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, /* 0x38 */
368 0x56, 0x57, 0x58, 0x59, 0xff, 0x5f, 0xff, 0xff, /* 0x40 */
369 0xff, 0xff, 0xff, 0xff, 0x46, 0xff, 0xff, 0x4e, /* 0x48 */
370 0x4f, 0x4d, 0x4c, 0xff, 0x5c, 0x5d, 0x4a, 0x5e, /* 0x50 */
371 0x43, 0x1d, 0x1e, 0x1f, 0x2d, 0x2e, 0x2f, 0x3d, /* 0x58 */
372 0x3e, 0x3f, 0x0f, 0x3c, 0x30, 0xff, 0xff, 0xff, /* 0x60 */
373 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x68 F13-F24 */
374 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x70 */
375 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x78 */
376 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x80 */
377 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x88 */
378 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x90 */
379 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x44, 0xff, /* 0x98 */
380 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xa0 */
381 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xa8 */
382 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb0 */
383 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb8 */
384 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xc0 */
385 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xc8 */
386 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xd0 */
387 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xd8 */
388 0x63, 0x60, 0x64, 0x66, 0x63, 0x61, 0x65, 0x67, /* 0xe0 */
389 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xe8 */
390 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xf0 */
391 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* 0xf8 */
394 static const UBYTE usbisakeymap[] =
396 0xff, 0xff, 0xff, 0xff, 0x20, 0x35, 0x33, 0x22, /* 0x00 */
397 0x12, 0x23, 0x24, 0x25, 0x17, 0x26, 0x27, 0x28, /* 0x08 */
398 0x37, 0x36, 0x18, 0x19, 0x10, 0x13, 0x21, 0x14, /* 0x10 */
399 0x16, 0x34, 0x11, 0x32, 0x15, 0x31, 0x01, 0x02, /* 0x18 */
400 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, /* 0x20 */
401 0x44, 0x45, 0x41, 0x42, 0x40, 0x0b, 0x0c, 0x1a, /* 0x28 */
402 0x1b, 0x0d, 0x2b, 0x29, 0x2a, 0x00, 0x38, 0x39, /* 0x30 */
403 0x3a, 0x62, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, /* 0x38 */
404 0x56, 0x57, 0x58, 0x59, 0x4b, 0x6f, 0xff, 0xff, /* 0x40 */
405 0x6e, 0x47, 0x70, 0x48, 0x46, 0x71, 0x49, 0x4e, /* 0x48 */
406 0x4f, 0x4d, 0x4c, 0xff, 0x5c, 0x5d, 0x4a, 0x5e, /* 0x50 */
407 0x43, 0x1d, 0x1e, 0x1f, 0x2d, 0x2e, 0x2f, 0x3d, /* 0x58 */
408 0x3e, 0x3f, 0x0f, 0x3c, 0x30, 0xff, 0xff, 0xff, /* 0x60 */
409 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x68 F13-F24 */
410 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x70 */
411 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x78 */
412 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x80 */
413 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x88 */
414 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x90 */
415 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x44, 0xff, /* 0x98 */
416 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xa0 */
417 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xa8 */
418 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb0 */
419 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb8 */
420 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xc0 */
421 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xc8 */
422 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xd0 */
423 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xd8 */
424 0x63, 0x60, 0x64, 0x66, 0x63, 0x61, 0x65, 0x67, /* 0xe0 */
425 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xe8 */
426 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xf0 */
427 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* 0xf8 */
429 /* \\\ */
431 #undef ps
432 #define ps nch->nch_Base
434 /* /// "nHidTask()" */
435 AROS_UFH0(void, nHidTask)
437 AROS_USERFUNC_INIT
439 struct NepClassHid *nch;
440 struct PsdPipe *pp;
441 ULONG sigmask;
442 ULONG sigs;
443 UBYTE *buf;
444 LONG ioerr;
446 if((nch = nAllocHid()))
448 Forbid();
449 if(nch->nch_ReadySigTask)
451 Signal(nch->nch_ReadySigTask, 1L<<nch->nch_ReadySignal);
453 Permit();
454 sigmask = (1L<<nch->nch_TaskMsgPort->mp_SigBit)|SIGBREAKF_CTRL_C;
455 buf = nch->nch_EP1Buf;
456 psdSendPipe(nch->nch_EP1Pipe, buf, nch->nch_EP1PktSize);
459 sigs = Wait(sigmask);
460 while((pp = (struct PsdPipe *) GetMsg(nch->nch_TaskMsgPort)))
462 if(pp == nch->nch_EP1Pipe)
464 if(!(ioerr = psdGetPipeError(pp)))
466 nParseKeys(nch, buf);
467 } else {
468 KPRINTF(1, ("Int Pipe failed %ld\n", ioerr));
469 psdDelayMS(200);
471 psdSendPipe(nch->nch_EP1Pipe, buf, nch->nch_EP1PktSize);
472 break;
475 } while(!(sigs & SIGBREAKF_CTRL_C));
476 KPRINTF(20, ("Going down the river!\n"));
477 memset(buf, 0, 8);
478 nParseKeys(nch, buf);
480 psdAbortPipe(nch->nch_EP1Pipe);
481 psdWaitPipe(nch->nch_EP1Pipe);
482 nFreeHid(nch);
484 AROS_USERFUNC_EXIT
486 /* \\\ */
488 /* /// "nParseKeys()" */
489 void nParseKeys(struct NepClassHid *nch, UBYTE *buf)
491 UWORD iecode;
492 UWORD qualcode = 0;
493 ULONG oldqual;
494 ULONG qualifier = 0;
495 UWORD keyqual = buf[0];
496 UWORD nkey, nkey2;
497 UWORD keycode;
498 BOOL keydown;
499 BOOL keyup;
500 BOOL bonuskey;
501 BOOL sentkey = FALSE;
503 if(keyqual & 0x11) qualifier |= IEQUALIFIER_CONTROL;
504 if(keyqual & 0x02) qualifier |= IEQUALIFIER_LSHIFT;
505 if(keyqual & 0x04) qualifier |= IEQUALIFIER_LALT;
506 if(keyqual & 0x08) qualifier |= IEQUALIFIER_LCOMMAND;
507 if(keyqual & 0x20) qualifier |= IEQUALIFIER_RSHIFT;
508 if(keyqual & 0x40) qualifier |= IEQUALIFIER_RALT;
509 if(keyqual & 0x80) qualifier |= IEQUALIFIER_RCOMMAND;
510 if(!nch->nch_ClsBase->nh_CurrentCGC.cgc_CapsLock)
512 if(qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
514 nch->nch_CapsLock = FALSE;
517 if(nch->nch_CapsLock) qualifier |= IEQUALIFIER_CAPSLOCK;
518 if((qualifier & (IEQUALIFIER_CONTROL|IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND)) ==
519 (IEQUALIFIER_CONTROL|IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND))
521 struct MsgPort *mp;
522 struct IOStdReq *ioreq;
523 struct Interrupt tempint;
524 struct Node *node;
525 struct List *listhead = NULL;
526 KPRINTF(20, ("Reboot!\n"));
528 if(nch->nch_ClsBase->nh_CurrentCGC.cgc_RHEnable)
530 if((mp = CreateMsgPort()))
532 if((ioreq = (struct IOStdReq *) CreateIORequest(mp, sizeof(struct IOStdReq))))
534 if(!OpenDevice("keyboard.device", 0, (struct IORequest *) ioreq, 0))
536 /* Find list header of reset handlers */
537 tempint.is_Node.ln_Pred = NULL;
538 tempint.is_Node.ln_Succ = NULL;
539 tempint.is_Node.ln_Pri = 32;
540 tempint.is_Code = NULL;
541 ioreq->io_Command = KBD_ADDRESETHANDLER;
542 ioreq->io_Data = &tempint;
543 Forbid();
544 DoIO((struct IORequest *) ioreq);
545 if((node = tempint.is_Node.ln_Pred))
547 while(node->ln_Pred)
549 node = node->ln_Pred;
551 listhead = (struct List *) node;
553 ioreq->io_Command = KBD_REMRESETHANDLER;
554 DoIO((struct IORequest *) ioreq);
555 Permit();
556 if(listhead)
558 node = listhead->lh_Head;
559 while(node->ln_Succ)
561 KPRINTF(20, ("Kicking %s\n", node->ln_Name));
562 Cause((struct Interrupt *) node);
563 node = node->ln_Succ;
565 KPRINTF(20, ("Done... awaiting doom\n"));
566 psdDelayMS(nch->nch_ClsBase->nh_CurrentCGC.cgc_ResetDelay*1000);
567 } else {
568 KPRINTF(20, ("Reset handler list not found!\n"));
570 CloseDevice((struct IORequest *) ioreq);
572 DeleteIORequest((struct IORequest *) ioreq);
574 DeleteMsgPort(mp);
577 ColdReboot();
579 if(qualifier != nch->nch_OldQualifier)
581 switch(qualifier^nch->nch_OldQualifier)
583 case IEQUALIFIER_LSHIFT:
584 qualcode = 0x60;
585 break;
586 case IEQUALIFIER_RSHIFT:
587 qualcode = 0x61;
588 break;
589 case IEQUALIFIER_CAPSLOCK:
590 qualcode = 0x62;
591 break;
592 case IEQUALIFIER_CONTROL:
593 qualcode = 0x63;
594 break;
595 case IEQUALIFIER_LALT:
596 qualcode = 0x64;
597 break;
598 case IEQUALIFIER_RALT:
599 qualcode = 0x65;
600 break;
601 case IEQUALIFIER_LCOMMAND:
602 qualcode = 0x66;
603 break;
604 case IEQUALIFIER_RCOMMAND:
605 qualcode = 0x67;
606 break;
607 default:
608 qualcode = 0xFF;
609 break;
613 KPRINTF(1, ("Qualifier %08lx\n", qualifier));
614 for(nkey = 2; nkey < 8; nkey++)
616 keycode = nch->nch_OldKeyArray[nkey];
617 if(!keycode)
619 continue;
621 /* Check, if key is still there */
622 keyup = TRUE;
623 for(nkey2 = 2; nkey2 < 8; nkey2++)
625 if(buf[nkey2] == keycode)
627 keyup = FALSE;
628 break;
631 if(keyup)
633 KPRINTF(1, ("Key up: %08lx\n", keycode));
634 iecode = nch->nch_ClsBase->nh_CurrentCGC.cgc_ISAMap ? usbisakeymap[keycode] : usbkeymap[keycode];
635 oldqual = qualifier;
636 if(!nch->nch_ClsBase->nh_CurrentCGC.cgc_ExtraEmulDisable)
638 bonuskey = TRUE;
639 switch(keycode)
641 case 0x49: /* Insert */
642 iecode = usbkeymap[0x19];
643 qualifier |= IEQUALIFIER_RCOMMAND;
644 qualcode = 0x67;
645 break;
646 case 0x4A: /* Pos 1 */
647 iecode = usbkeymap[0x50];
648 qualifier |= IEQUALIFIER_LSHIFT;
649 qualcode = 0x60;
650 break;
651 case 0x4D: /* End */
652 iecode = usbkeymap[0x4F];
653 qualifier |= IEQUALIFIER_LSHIFT;
654 qualcode = 0x60;
655 break;
656 case 0x4B: /* Page Up */
657 iecode = usbkeymap[0x52];
658 qualifier |= IEQUALIFIER_LSHIFT;
659 qualcode = 0x60;
660 break;
661 case 0x4E: /* Page Down */
662 iecode = usbkeymap[0x51];
663 qualifier |= IEQUALIFIER_LSHIFT;
664 qualcode = 0x60;
665 break;
666 case 0x48: /* Pause / Break */
667 /* *** FIXME *** should be a vanilla key for keymapping compatibility */
668 iecode = usbkeymap[0x06];
669 qualifier |= IEQUALIFIER_CONTROL;
670 qualcode = 0x63;
671 break;
672 default:
673 bonuskey = FALSE;
675 } else {
676 bonuskey = FALSE;
678 nch->nch_FakeEvent.ie_Class = IECLASS_RAWKEY;
679 nch->nch_FakeEvent.ie_SubClass = 0;
680 nch->nch_FakeEvent.ie_Code = iecode|IECODE_UP_PREFIX;
681 nch->nch_FakeEvent.ie_NextEvent = NULL;
682 nch->nch_FakeEvent.ie_Qualifier = qualifier;
683 nch->nch_InpIOReq->io_Data = &nch->nch_FakeEvent;
684 nch->nch_InpIOReq->io_Length = sizeof(struct InputEvent);
685 nch->nch_InpIOReq->io_Command = IND_WRITEEVENT;
686 DoIO((struct IORequest *) nch->nch_InpIOReq);
687 if(bonuskey)
689 qualifier = oldqual;
690 nch->nch_FakeEvent.ie_Class = IECLASS_RAWKEY;
691 nch->nch_FakeEvent.ie_SubClass = 0;
692 nch->nch_FakeEvent.ie_Code = qualcode|IECODE_UP_PREFIX;
693 nch->nch_FakeEvent.ie_NextEvent = NULL;
694 nch->nch_FakeEvent.ie_Qualifier = qualifier;
695 nch->nch_InpIOReq->io_Data = &nch->nch_FakeEvent;
696 nch->nch_InpIOReq->io_Length = sizeof(struct InputEvent);
697 nch->nch_InpIOReq->io_Command = IND_WRITEEVENT;
698 DoIO((struct IORequest *) nch->nch_InpIOReq);
700 sentkey = TRUE;
705 for(nkey = 2; nkey < 8; nkey++)
707 keycode = buf[nkey];
708 if(!keycode)
710 continue;
712 KPRINTF(1, ("Key down: %08lx\n", keycode));
713 /* Check, if key was there previously */
714 keydown = TRUE;
715 for(nkey2 = 2; nkey2 < 8; nkey2++)
717 if(nch->nch_OldKeyArray[nkey2] == keycode)
719 keydown = FALSE;
720 break;
723 if(keydown)
725 iecode = nch->nch_ClsBase->nh_CurrentCGC.cgc_ISAMap ? usbisakeymap[keycode] : usbkeymap[keycode];
726 if(!nch->nch_ClsBase->nh_CurrentCGC.cgc_ExtraEmulDisable)
728 switch(keycode)
730 case 0x49: /* Insert */
731 iecode = usbkeymap[0x19];
732 qualifier |= IEQUALIFIER_RCOMMAND;
733 break;
734 case 0x4A: /* Pos 1 */
735 iecode = usbkeymap[0x50];
736 qualifier |= IEQUALIFIER_LSHIFT;
737 break;
738 case 0x4D: /* End */
739 iecode = usbkeymap[0x4F];
740 qualifier |= IEQUALIFIER_LSHIFT;
741 break;
742 case 0x4B: /* Page Up */
743 iecode = usbkeymap[0x52];
744 qualifier |= IEQUALIFIER_LSHIFT;
745 break;
746 case 0x4E: /* Page Down */
747 iecode = usbkeymap[0x51];
748 qualifier |= IEQUALIFIER_LSHIFT;
749 break;
750 case 0x48: /* Pause / Break */
751 /* *** FIXME *** should be a vanilla key for keymapping compatibility */
752 iecode = usbkeymap[0x06];
753 qualifier |= IEQUALIFIER_CONTROL;
754 break;
757 if(keycode == 0x39) /* Caps Lock */
759 if(nch->nch_ClsBase->nh_CurrentCGC.cgc_CapsLock)
761 nch->nch_CapsLock = !nch->nch_CapsLock;
762 } else {
763 nch->nch_CapsLock = TRUE;
765 if(nch->nch_CapsLock)
767 qualifier |= IEQUALIFIER_CAPSLOCK;
771 nch->nch_FakeEvent.ie_Class = IECLASS_RAWKEY;
772 nch->nch_FakeEvent.ie_SubClass = 0;
773 nch->nch_FakeEvent.ie_Code = iecode;
774 nch->nch_FakeEvent.ie_NextEvent = NULL;
775 nch->nch_FakeEvent.ie_Qualifier = qualifier;
776 nch->nch_InpIOReq->io_Data = &nch->nch_FakeEvent;
777 nch->nch_InpIOReq->io_Length = sizeof(struct InputEvent);
778 nch->nch_InpIOReq->io_Command = IND_WRITEEVENT;
779 DoIO((struct IORequest *) nch->nch_InpIOReq);
780 nch->nch_FakeEvent.ie_position.ie_dead.ie_prev2DownCode = nch->nch_FakeEvent.ie_position.ie_dead.ie_prev1DownCode;
781 nch->nch_FakeEvent.ie_position.ie_dead.ie_prev2DownQual = nch->nch_FakeEvent.ie_position.ie_dead.ie_prev1DownQual;
782 nch->nch_FakeEvent.ie_position.ie_dead.ie_prev1DownCode = iecode;
783 nch->nch_FakeEvent.ie_position.ie_dead.ie_prev1DownQual = qualifier;
784 sentkey = TRUE;
785 break;
788 /* copy old keymap */
789 for(nkey = 2; nkey < nch->nch_EP1PktSize; nkey++)
791 nch->nch_OldKeyArray[nkey] = buf[nkey];
793 if((!sentkey) && (nch->nch_OldQualifier != qualifier))
795 nch->nch_FakeEvent.ie_Class = IECLASS_RAWKEY;
796 nch->nch_FakeEvent.ie_SubClass = 0;
797 nch->nch_FakeEvent.ie_Code = qualcode;
798 nch->nch_FakeEvent.ie_NextEvent = NULL;
799 nch->nch_FakeEvent.ie_Qualifier = qualifier;
800 nch->nch_InpIOReq->io_Data = &nch->nch_FakeEvent;
801 nch->nch_InpIOReq->io_Length = sizeof(struct InputEvent);
802 nch->nch_InpIOReq->io_Command = IND_WRITEEVENT;
803 DoIO((struct IORequest *) nch->nch_InpIOReq);
805 nch->nch_OldQualifier = qualifier;
807 /* \\\ */
809 /* /// "nAllocHid()" */
810 struct NepClassHid * nAllocHid(void)
812 struct Task *thistask;
813 struct NepClassHid *nch;
814 LONG ioerr;
816 thistask = FindTask(NULL);
817 nch = thistask->tc_UserData;
820 if(!(nch->nch_Base = OpenLibrary("poseidon.library", 4)))
822 Alert(AG_OpenLib);
823 break;
825 psdGetAttrs(PGA_INTERFACE, nch->nch_Interface,
826 IFA_Config, &nch->nch_Config,
827 IFA_InterfaceNum, &nch->nch_IfNum,
828 TAG_END);
829 psdGetAttrs(PGA_CONFIG, nch->nch_Config,
830 CA_Device, &nch->nch_Device,
831 TAG_END);
833 nch->nch_EP1 = psdFindEndpoint(nch->nch_Interface, NULL,
834 EA_IsIn, TRUE,
835 EA_TransferType, USEAF_INTERRUPT,
836 TAG_END);
837 if(!nch->nch_EP1)
839 KPRINTF(1, ("Ooops!?! No Endpoints defined?\n"));
840 break;
842 psdGetAttrs(PGA_ENDPOINT, nch->nch_EP1,
843 EA_MaxPktSize, &nch->nch_EP1PktSize,
844 TAG_END);
845 if((nch->nch_InpMsgPort = CreateMsgPort()))
847 if((nch->nch_InpIOReq = (struct IOStdReq *) CreateIORequest(nch->nch_InpMsgPort, sizeof(struct IOStdReq))))
849 if(!OpenDevice("input.device", 0, (struct IORequest *) nch->nch_InpIOReq, 0))
851 nch->nch_InputBase = (struct Library *) nch->nch_InpIOReq->io_Device;
852 if((nch->nch_TaskMsgPort = CreateMsgPort()))
854 if((nch->nch_EP0Pipe = psdAllocPipe(nch->nch_Device, nch->nch_TaskMsgPort, NULL)))
856 if((nch->nch_EP1Pipe = psdAllocPipe(nch->nch_Device, nch->nch_TaskMsgPort, nch->nch_EP1)))
858 psdPipeSetup(nch->nch_EP0Pipe, URTF_CLASS|URTF_INTERFACE,
859 UHR_SET_PROTOCOL, HID_PROTO_BOOT, nch->nch_IfNum);
860 ioerr = psdDoPipe(nch->nch_EP0Pipe, NULL, 0);
861 if(!ioerr)
863 psdPipeSetup(nch->nch_EP0Pipe, URTF_CLASS|URTF_INTERFACE,
864 UHR_SET_IDLE, 0, nch->nch_IfNum);
865 ioerr = psdDoPipe(nch->nch_EP0Pipe, NULL, 0);
866 if(ioerr)
868 psdAddErrorMsg(RETURN_WARN, (STRPTR) libname,
869 "SET_IDLE=0 failed: %s (%ld)!",
870 psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
872 if((nch->nch_EP1Buf = psdAllocVec(nch->nch_EP1PktSize)))
874 nch->nch_Task = thistask;
875 return(nch);
877 } else {
878 psdAddErrorMsg(RETURN_FAIL, (STRPTR) libname,
879 "SET_PROTOCOL=BOOT failed: %s (%ld)!",
880 (APTR) psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
882 psdFreePipe(nch->nch_EP1Pipe);
884 psdFreePipe(nch->nch_EP0Pipe);
886 DeleteMsgPort(nch->nch_TaskMsgPort);
888 CloseDevice((struct IORequest *) nch->nch_InpIOReq);
890 DeleteIORequest((struct IORequest *) nch->nch_InpIOReq);
892 DeleteMsgPort(nch->nch_InpMsgPort);
894 } while(FALSE);
895 CloseLibrary(nch->nch_Base);
896 Forbid();
897 nch->nch_Task = NULL;
898 if(nch->nch_ReadySigTask)
900 Signal(nch->nch_ReadySigTask, 1L<<nch->nch_ReadySignal);
902 return(NULL);
904 /* \\\ */
906 /* /// "nFreeHid()" */
907 void nFreeHid(struct NepClassHid *nch)
909 psdFreeVec(nch->nch_EP1Buf);
910 psdFreePipe(nch->nch_EP1Pipe);
911 psdFreePipe(nch->nch_EP0Pipe);
912 DeleteMsgPort(nch->nch_TaskMsgPort);
913 CloseDevice((struct IORequest *) nch->nch_InpIOReq);
914 DeleteIORequest((struct IORequest *) nch->nch_InpIOReq);
915 DeleteMsgPort(nch->nch_InpMsgPort);
916 CloseLibrary(nch->nch_Base);
917 Forbid();
918 nch->nch_Task = NULL;
919 if(nch->nch_ReadySigTask)
921 Signal(nch->nch_ReadySigTask, 1L<<nch->nch_ReadySignal);
924 /* \\\ */
926 /**************************************************************************/
928 #undef ps
929 #define ps nh->nh_PsdBase
930 #undef IntuitionBase
931 #define IntuitionBase nh->nh_IntBase
932 #undef MUIMasterBase
933 #define MUIMasterBase nh->nh_MUIBase
935 /* /// "nGUITask()" */
936 AROS_UFH0(void, nGUITask)
938 AROS_USERFUNC_INIT
940 struct Task *thistask;
941 struct NepHidBase *nh;
942 APTR pic;
944 thistask = FindTask(NULL);
946 nh = thistask->tc_UserData;
947 ++nh->nh_Library.lib_OpenCnt;
948 if(!(MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN)))
950 KPRINTF(10, ("Couldn't open muimaster.library.\n"));
951 nGUITaskCleanup(nh);
952 return;
955 if(!(IntuitionBase = OpenLibrary("intuition.library", 39)))
957 KPRINTF(10, ("Couldn't open intuition.library.\n"));
958 nGUITaskCleanup(nh);
959 return;
961 if(!(ps = OpenLibrary("poseidon.library", 4)))
963 KPRINTF(10, ("Couldn't open poseidon.library.\n"));
964 nGUITaskCleanup(nh);
965 return;
968 nh->nh_App = ApplicationObject,
969 MUIA_Application_Title , libname,
970 MUIA_Application_Version , VERSION_STRING,
971 MUIA_Application_Copyright , "©2002-2009 Chris Hodges",
972 MUIA_Application_Author , "Chris Hodges <chrisly@platon42.de>",
973 MUIA_Application_Description, "Settings for the bootkeyboard.class",
974 MUIA_Application_Base , "BOOTKEYBOARD",
975 MUIA_Application_HelpFile , "HELP:Poseidon.guide",
976 MUIA_Application_Menustrip , MenustripObject,
977 Child, MenuObjectT("Project"),
978 Child, nh->nh_AboutMI = MenuitemObject,
979 MUIA_Menuitem_Title, "About...",
980 MUIA_Menuitem_Shortcut, "?",
981 End,
982 End,
983 Child, MenuObjectT("Settings"),
984 Child, nh->nh_UseMI = MenuitemObject,
985 MUIA_Menuitem_Title, "Save",
986 MUIA_Menuitem_Shortcut, "S",
987 End,
988 Child, MenuitemObject,
989 MUIA_Menuitem_Title, NM_BARLABEL,
990 End,
991 Child, nh->nh_MUIPrefsMI = MenuitemObject,
992 MUIA_Menuitem_Title, "MUI Settings",
993 MUIA_Menuitem_Shortcut, "M",
994 End,
995 End,
996 End,
998 SubWindow, nh->nh_MainWindow = WindowObject,
999 MUIA_Window_ID , MAKE_ID('M','A','I','N'),
1000 MUIA_Window_Title, libname,
1001 MUIA_HelpNode, libname,
1003 WindowContents, VGroup,
1004 Child, ColGroup(2), GroupFrameT("Global Settings"),
1005 Child, Label((IPTR) "Hijack ResetHandlers:"),
1006 Child, HGroup,
1007 Child, nh->nh_RHEnableObj = ImageObject, ImageButtonFrame,
1008 MUIA_Background, MUII_ButtonBack,
1009 MUIA_CycleChain, 1,
1010 MUIA_InputMode, MUIV_InputMode_Toggle,
1011 MUIA_Image_Spec, MUII_CheckMark,
1012 MUIA_Image_FreeVert, TRUE,
1013 MUIA_Selected, nh->nh_CurrentCGC.cgc_RHEnable,
1014 MUIA_ShowSelState, FALSE,
1015 End,
1016 Child, HSpace(0),
1017 End,
1018 Child, Label((IPTR) "Reset delay:"),
1019 Child, nh->nh_ResetDelayObj = SliderObject, SliderFrame,
1020 MUIA_CycleChain, 1,
1021 MUIA_Numeric_Min, 0,
1022 MUIA_Numeric_Max, 60,
1023 MUIA_Numeric_Value, nh->nh_CurrentCGC.cgc_ResetDelay,
1024 MUIA_Numeric_Format, "%ldsec",
1025 End,
1026 Child, Label((IPTR) "Amiga CapsLock behaviour:"),
1027 Child, HGroup,
1028 Child, nh->nh_CapsLockObj = ImageObject, ImageButtonFrame,
1029 MUIA_Background, MUII_ButtonBack,
1030 MUIA_CycleChain, 1,
1031 MUIA_InputMode, MUIV_InputMode_Toggle,
1032 MUIA_Image_Spec, MUII_CheckMark,
1033 MUIA_Image_FreeVert, TRUE,
1034 MUIA_Selected, nh->nh_CurrentCGC.cgc_CapsLock,
1035 MUIA_ShowSelState, FALSE,
1036 End,
1037 Child, HSpace(0),
1038 End,
1039 Child, Label((IPTR) "Use standard ISA mapping:"),
1040 Child, HGroup,
1041 Child, nh->nh_ISAMapObj = ImageObject, ImageButtonFrame,
1042 MUIA_Background, MUII_ButtonBack,
1043 MUIA_CycleChain, 1,
1044 MUIA_InputMode, MUIV_InputMode_Toggle,
1045 MUIA_Image_Spec, MUII_CheckMark,
1046 MUIA_Image_FreeVert, TRUE,
1047 MUIA_Selected, nh->nh_CurrentCGC.cgc_ISAMap,
1048 MUIA_ShowSelState, FALSE,
1049 End,
1050 Child, HSpace(0),
1051 End,
1052 Child, Label((IPTR) "Disable extra key emulation:"),
1053 Child, HGroup,
1054 Child, nh->nh_ExtraEmulObj = ImageObject, ImageButtonFrame,
1055 MUIA_Background, MUII_ButtonBack,
1056 MUIA_CycleChain, 1,
1057 MUIA_InputMode, MUIV_InputMode_Toggle,
1058 MUIA_Image_Spec, MUII_CheckMark,
1059 MUIA_Image_FreeVert, TRUE,
1060 MUIA_Selected, nh->nh_CurrentCGC.cgc_ExtraEmulDisable,
1061 MUIA_ShowSelState, FALSE,
1062 End,
1063 Child, HSpace(0),
1064 End,
1065 End,
1066 Child, VSpace(0),
1067 Child, HGroup,
1068 MUIA_Group_SameWidth, TRUE,
1069 Child, nh->nh_UseObj = TextObject, ButtonFrame,
1070 MUIA_Background, MUII_ButtonBack,
1071 MUIA_CycleChain, 1,
1072 MUIA_InputMode, MUIV_InputMode_RelVerify,
1073 MUIA_Text_Contents, "\33c Save ",
1074 End,
1075 Child, nh->nh_CloseObj = TextObject, ButtonFrame,
1076 MUIA_Background, MUII_ButtonBack,
1077 MUIA_CycleChain, 1,
1078 MUIA_InputMode, MUIV_InputMode_RelVerify,
1079 MUIA_Text_Contents, "\33c Use ",
1080 End,
1081 End,
1082 End,
1083 End,
1084 End;
1086 if(!nh->nh_App)
1088 KPRINTF(10, ("Couldn't create application\n"));
1089 nGUITaskCleanup(nh);
1090 return;
1092 DoMethod(nh->nh_MainWindow, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
1093 nh->nh_App, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
1094 DoMethod(nh->nh_UseObj, MUIM_Notify, MUIA_Pressed, FALSE,
1095 nh->nh_App, 2, MUIM_Application_ReturnID, ID_STORE_CONFIG);
1096 DoMethod(nh->nh_CloseObj, MUIM_Notify, MUIA_Pressed, FALSE,
1097 nh->nh_App, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
1099 DoMethod(nh->nh_AboutMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
1100 nh->nh_App, 2, MUIM_Application_ReturnID, ID_ABOUT);
1101 DoMethod(nh->nh_UseMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
1102 nh->nh_App, 2, MUIM_Application_ReturnID, ID_STORE_CONFIG);
1103 DoMethod(nh->nh_RestoreDefMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
1104 nh->nh_App, 2, MUIM_Application_ReturnID, ID_RESTORE_DEF);
1105 DoMethod(nh->nh_MUIPrefsMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
1106 nh->nh_App, 2, MUIM_Application_OpenConfigWindow, 0);
1109 ULONG isopen;
1110 ULONG iconify;
1111 ULONG sigs;
1112 ULONG sigmask;
1113 LONG retid;
1115 get(nh->nh_App, MUIA_Application_Iconified, &iconify);
1116 set(nh->nh_MainWindow, MUIA_Window_Open, TRUE);
1117 get(nh->nh_MainWindow, MUIA_Window_Open, &isopen);
1118 if(!(isopen || iconify))
1120 nGUITaskCleanup(nh);
1121 return;
1123 sigmask = 0;
1126 retid = DoMethod(nh->nh_App, MUIM_Application_NewInput, &sigs);
1127 switch(retid)
1129 case ID_STORE_CONFIG:
1130 case MUIV_Application_ReturnID_Quit:
1131 get(nh->nh_RHEnableObj, MUIA_Selected, &nh->nh_CurrentCGC.cgc_RHEnable);
1132 get(nh->nh_ResetDelayObj, MUIA_Numeric_Value, &nh->nh_CurrentCGC.cgc_ResetDelay);
1133 get(nh->nh_CapsLockObj, MUIA_Selected, &nh->nh_CurrentCGC.cgc_CapsLock);
1134 get(nh->nh_ISAMapObj, MUIA_Selected, &nh->nh_CurrentCGC.cgc_ISAMap);
1135 get(nh->nh_ExtraEmulObj, MUIA_Selected, &nh->nh_CurrentCGC.cgc_ExtraEmulDisable);
1136 pic = psdGetClsCfg(libname);
1137 if(!pic)
1139 psdSetClsCfg(libname, NULL);
1140 pic = psdGetClsCfg(libname);
1142 if(pic)
1144 if(psdAddCfgEntry(pic, &nh->nh_CurrentCGC))
1146 if(retid != MUIV_Application_ReturnID_Quit)
1148 psdSaveCfgToDisk(NULL, FALSE);
1150 retid = MUIV_Application_ReturnID_Quit;
1153 break;
1155 case ID_ABOUT:
1156 MUI_RequestA(nh->nh_App, nh->nh_MainWindow, 0, NULL, "Amazing!", VERSION_STRING, NULL);
1157 break;
1159 if(retid == MUIV_Application_ReturnID_Quit)
1161 break;
1163 if(sigs)
1165 sigs = Wait(sigs | sigmask | SIGBREAKF_CTRL_C);
1166 if(sigs & SIGBREAKF_CTRL_C)
1168 break;
1171 } while(TRUE);
1172 set(nh->nh_MainWindow, MUIA_Window_Open, FALSE);
1174 nGUITaskCleanup(nh);
1176 AROS_USERFUNC_EXIT
1178 /* \\\ */
1180 /* /// "nGUITaskCleanup()" */
1181 void nGUITaskCleanup(struct NepHidBase *nh)
1183 if(nh->nh_App)
1185 MUI_DisposeObject(nh->nh_App);
1186 nh->nh_App = NULL;
1188 if(MUIMasterBase)
1190 CloseLibrary(MUIMasterBase);
1191 MUIMasterBase = NULL;
1193 if(IntuitionBase)
1195 CloseLibrary(IntuitionBase);
1196 IntuitionBase = NULL;
1198 if(ps)
1200 CloseLibrary(ps);
1201 ps = NULL;
1203 Forbid();
1204 nh->nh_GUITask = NULL;
1205 --nh->nh_Library.lib_OpenCnt;
1207 /* \\\ */