Documented GVF_SAVE_VAR alongside other flags, and removed a query/doubt
[AROS.git] / rom / usb / classes / bootkeyboard / bootkeyboard.class.c
blob7165c34403a4b9be7e4ea0ae9caf24660f0948fd
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 bootkbd_LoadClassConfig(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 /* /// "bootkbd_AttemptInterfaceBinding()" */
63 struct NepClassHid * bootkbd_AttemptInterfaceBinding(struct NepHidBase *nh, struct PsdInterface *pif)
65 struct Library *ps;
66 IPTR ifclass;
67 IPTR subclass;
68 IPTR 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(bootkbd_ForceInterfaceBinding(nh, pif));
84 return(NULL);
86 /* \\\ */
88 /* /// "bootkbd_ForceInterfaceBinding()" */
89 struct NepClassHid * bootkbd_ForceInterfaceBinding(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 bootkbd_LoadClassConfig(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, bootkbd_HidTask, 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 /* /// "bootkbd_ReleaseInterfaceBinding()" */
143 void bootkbd_ReleaseInterfaceBinding(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, bootkbd)
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, bootkbd)
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, bootkbd)
258 AROS_LIBFUNC_INIT
260 KPRINTF(10, ("Do Method %ld\n", methodid));
261 switch(methodid)
263 case UCM_AttemptInterfaceBinding:
264 return((IPTR) bootkbd_AttemptInterfaceBinding(nh, (struct PsdInterface *) methoddata[0]));
266 case UCM_ForceInterfaceBinding:
267 return((IPTR) bootkbd_ForceInterfaceBinding(nh, (struct PsdInterface *) methoddata[0]));
269 case UCM_ReleaseInterfaceBinding:
270 bootkbd_ReleaseInterfaceBinding(nh, (struct NepClassHid *) methoddata[0]);
271 return(TRUE);
273 case UCM_OpenCfgWindow:
274 return(nOpenCfgWindow(nh));
276 case UCM_ConfigChangedEvent:
277 bootkbd_LoadClassConfig(nh);
278 return(TRUE);
280 default:
281 break;
283 return(0);
284 AROS_LIBFUNC_EXIT
286 /* \\\ */
288 /* /// "bootkbd_LoadClassConfig()" */
289 BOOL bootkbd_LoadClassConfig(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", bootkbd_GUITask, 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 /* /// "bootkbd_HidTask()" */
435 AROS_UFH0(void, bootkbd_HidTask)
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 = bootkbd_AllocHid()))
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 bootkbd_FreeHid(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 /* Reboot machine upon Ctrl-Alt-Del */
808 if((qualifier & IEQUALIFIER_CONTROL) &&
809 (qualifier & (IEQUALIFIER_LALT|IEQUALIFIER_RALT)) &&
810 nch->nch_FakeEvent.ie_Code == RAWKEY_DELETE)
812 KPRINTF(20, ("Reboot!\n"));
813 ShutdownA(SD_ACTION_COLDREBOOT);
816 /* \\\ */
818 /* /// "bootkbd_AllocHid()" */
819 struct NepClassHid * bootkbd_AllocHid(void)
821 struct Task *thistask;
822 struct NepClassHid *nch;
823 LONG ioerr;
825 thistask = FindTask(NULL);
826 nch = thistask->tc_UserData;
829 if(!(nch->nch_Base = OpenLibrary("poseidon.library", 4)))
831 Alert(AG_OpenLib);
832 break;
834 psdGetAttrs(PGA_INTERFACE, nch->nch_Interface,
835 IFA_Config, &nch->nch_Config,
836 IFA_InterfaceNum, &nch->nch_IfNum,
837 TAG_END);
838 psdGetAttrs(PGA_CONFIG, nch->nch_Config,
839 CA_Device, &nch->nch_Device,
840 TAG_END);
842 nch->nch_EP1 = psdFindEndpoint(nch->nch_Interface, NULL,
843 EA_IsIn, TRUE,
844 EA_TransferType, USEAF_INTERRUPT,
845 TAG_END);
846 if(!nch->nch_EP1)
848 KPRINTF(1, ("Ooops!?! No Endpoints defined?\n"));
849 break;
851 psdGetAttrs(PGA_ENDPOINT, nch->nch_EP1,
852 EA_MaxPktSize, &nch->nch_EP1PktSize,
853 TAG_END);
854 if((nch->nch_InpMsgPort = CreateMsgPort()))
856 if((nch->nch_InpIOReq = (struct IOStdReq *) CreateIORequest(nch->nch_InpMsgPort, sizeof(struct IOStdReq))))
858 if(!OpenDevice("input.device", 0, (struct IORequest *) nch->nch_InpIOReq, 0))
860 nch->nch_InputBase = (struct Library *) nch->nch_InpIOReq->io_Device;
861 if((nch->nch_TaskMsgPort = CreateMsgPort()))
863 if((nch->nch_EP0Pipe = psdAllocPipe(nch->nch_Device, nch->nch_TaskMsgPort, NULL)))
865 if((nch->nch_EP1Pipe = psdAllocPipe(nch->nch_Device, nch->nch_TaskMsgPort, nch->nch_EP1)))
867 psdPipeSetup(nch->nch_EP0Pipe, URTF_CLASS|URTF_INTERFACE,
868 UHR_SET_PROTOCOL, HID_PROTO_BOOT, nch->nch_IfNum);
869 ioerr = psdDoPipe(nch->nch_EP0Pipe, NULL, 0);
870 if(!ioerr)
872 psdPipeSetup(nch->nch_EP0Pipe, URTF_CLASS|URTF_INTERFACE,
873 UHR_SET_IDLE, 0, nch->nch_IfNum);
874 ioerr = psdDoPipe(nch->nch_EP0Pipe, NULL, 0);
875 if(ioerr)
877 psdAddErrorMsg(RETURN_WARN, (STRPTR) libname,
878 "SET_IDLE=0 failed: %s (%ld)!",
879 psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
881 if((nch->nch_EP1Buf = psdAllocVec(nch->nch_EP1PktSize)))
883 nch->nch_Task = thistask;
884 return(nch);
886 } else {
887 psdAddErrorMsg(RETURN_FAIL, (STRPTR) libname,
888 "SET_PROTOCOL=BOOT failed: %s (%ld)!",
889 (APTR) psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
891 psdFreePipe(nch->nch_EP1Pipe);
893 psdFreePipe(nch->nch_EP0Pipe);
895 DeleteMsgPort(nch->nch_TaskMsgPort);
897 CloseDevice((struct IORequest *) nch->nch_InpIOReq);
899 DeleteIORequest((struct IORequest *) nch->nch_InpIOReq);
901 DeleteMsgPort(nch->nch_InpMsgPort);
903 } while(FALSE);
904 CloseLibrary(nch->nch_Base);
905 Forbid();
906 nch->nch_Task = NULL;
907 if(nch->nch_ReadySigTask)
909 Signal(nch->nch_ReadySigTask, 1L<<nch->nch_ReadySignal);
911 return(NULL);
913 /* \\\ */
915 /* /// "bootkbd_FreeHid()" */
916 void bootkbd_FreeHid(struct NepClassHid *nch)
918 psdFreeVec(nch->nch_EP1Buf);
919 psdFreePipe(nch->nch_EP1Pipe);
920 psdFreePipe(nch->nch_EP0Pipe);
921 DeleteMsgPort(nch->nch_TaskMsgPort);
922 CloseDevice((struct IORequest *) nch->nch_InpIOReq);
923 DeleteIORequest((struct IORequest *) nch->nch_InpIOReq);
924 DeleteMsgPort(nch->nch_InpMsgPort);
925 CloseLibrary(nch->nch_Base);
926 Forbid();
927 nch->nch_Task = NULL;
928 if(nch->nch_ReadySigTask)
930 Signal(nch->nch_ReadySigTask, 1L<<nch->nch_ReadySignal);
933 /* \\\ */
935 /**************************************************************************/
937 #undef ps
938 #define ps nh->nh_PsdBase
939 #undef IntuitionBase
940 #define IntuitionBase nh->nh_IntBase
941 #undef MUIMasterBase
942 #define MUIMasterBase nh->nh_MUIBase
944 /* /// "bootkbd_GUITask()" */
945 AROS_UFH0(void, bootkbd_GUITask)
947 AROS_USERFUNC_INIT
949 struct Task *thistask;
950 struct NepHidBase *nh;
951 APTR pic;
953 thistask = FindTask(NULL);
955 nh = thistask->tc_UserData;
956 ++nh->nh_Library.lib_OpenCnt;
957 if(!(MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN)))
959 KPRINTF(10, ("Couldn't open muimaster.library.\n"));
960 bootkbd_GUITaskCleanup(nh);
961 return;
964 if(!(IntuitionBase = OpenLibrary("intuition.library", 39)))
966 KPRINTF(10, ("Couldn't open intuition.library.\n"));
967 bootkbd_GUITaskCleanup(nh);
968 return;
970 if(!(ps = OpenLibrary("poseidon.library", 4)))
972 KPRINTF(10, ("Couldn't open poseidon.library.\n"));
973 bootkbd_GUITaskCleanup(nh);
974 return;
977 nh->nh_App = ApplicationObject,
978 MUIA_Application_Title , (IPTR)libname,
979 MUIA_Application_Version , (IPTR)VERSION_STRING,
980 MUIA_Application_Copyright , (IPTR)"©2002-2009 Chris Hodges",
981 MUIA_Application_Author , (IPTR)"Chris Hodges <chrisly@platon42.de>",
982 MUIA_Application_Description, (IPTR)"Settings for the bootkeyboard.class",
983 MUIA_Application_Base , (IPTR)"BOOTKEYBOARD",
984 MUIA_Application_HelpFile , (IPTR)"HELP:Poseidon.guide",
985 MUIA_Application_Menustrip , (IPTR)MenustripObject,
986 Child, (IPTR)MenuObjectT((IPTR)"Project"),
987 Child, (IPTR)(nh->nh_AboutMI = MenuitemObject,
988 MUIA_Menuitem_Title, (IPTR)"About...",
989 MUIA_Menuitem_Shortcut, (IPTR)"?",
990 End),
991 End,
992 Child, (IPTR)MenuObjectT((IPTR)"Settings"),
993 Child, (IPTR)(nh->nh_UseMI = MenuitemObject,
994 MUIA_Menuitem_Title, (IPTR)"Save",
995 MUIA_Menuitem_Shortcut, (IPTR)"S",
996 End),
997 Child, (IPTR)MenuitemObject,
998 MUIA_Menuitem_Title, (IPTR)NM_BARLABEL,
999 End,
1000 Child, (IPTR)(nh->nh_MUIPrefsMI = MenuitemObject,
1001 MUIA_Menuitem_Title, (IPTR)"MUI Settings",
1002 MUIA_Menuitem_Shortcut, (IPTR)"M",
1003 End),
1004 End,
1005 End,
1007 SubWindow, (IPTR)(nh->nh_MainWindow = WindowObject,
1008 MUIA_Window_ID , MAKE_ID('M','A','I','N'),
1009 MUIA_Window_Title, (IPTR)libname,
1010 MUIA_HelpNode, (IPTR)libname,
1012 WindowContents, (IPTR)VGroup,
1013 Child, (IPTR)ColGroup(2), GroupFrameT((IPTR)"Global Settings"),
1014 Child, (IPTR)Label((IPTR) "Hijack ResetHandlers:"),
1015 Child, (IPTR)HGroup,
1016 Child, (IPTR)(nh->nh_RHEnableObj = ImageObject, ImageButtonFrame,
1017 MUIA_Background, MUII_ButtonBack,
1018 MUIA_CycleChain, 1,
1019 MUIA_InputMode, MUIV_InputMode_Toggle,
1020 MUIA_Image_Spec, MUII_CheckMark,
1021 MUIA_Image_FreeVert, TRUE,
1022 MUIA_Selected, nh->nh_CurrentCGC.cgc_RHEnable,
1023 MUIA_ShowSelState, FALSE,
1024 End),
1025 Child, (IPTR)HSpace(0),
1026 End,
1027 Child, (IPTR)Label((IPTR) "Reset delay:"),
1028 Child, (IPTR)(nh->nh_ResetDelayObj = SliderObject, SliderFrame,
1029 MUIA_CycleChain, 1,
1030 MUIA_Numeric_Min, 0,
1031 MUIA_Numeric_Max, 60,
1032 MUIA_Numeric_Value, nh->nh_CurrentCGC.cgc_ResetDelay,
1033 MUIA_Numeric_Format, (IPTR)"%ldsec",
1034 End),
1035 Child, (IPTR)Label((IPTR) "Amiga CapsLock behaviour:"),
1036 Child, (IPTR)HGroup,
1037 Child, (IPTR)(nh->nh_CapsLockObj = ImageObject, ImageButtonFrame,
1038 MUIA_Background, MUII_ButtonBack,
1039 MUIA_CycleChain, 1,
1040 MUIA_InputMode, MUIV_InputMode_Toggle,
1041 MUIA_Image_Spec, MUII_CheckMark,
1042 MUIA_Image_FreeVert, TRUE,
1043 MUIA_Selected, nh->nh_CurrentCGC.cgc_CapsLock,
1044 MUIA_ShowSelState, FALSE,
1045 End),
1046 Child, (IPTR)HSpace(0),
1047 End,
1048 Child, (IPTR)Label((IPTR) "Use standard ISA mapping:"),
1049 Child, (IPTR)HGroup,
1050 Child, (IPTR)(nh->nh_ISAMapObj = ImageObject, ImageButtonFrame,
1051 MUIA_Background, MUII_ButtonBack,
1052 MUIA_CycleChain, 1,
1053 MUIA_InputMode, MUIV_InputMode_Toggle,
1054 MUIA_Image_Spec, MUII_CheckMark,
1055 MUIA_Image_FreeVert, TRUE,
1056 MUIA_Selected, nh->nh_CurrentCGC.cgc_ISAMap,
1057 MUIA_ShowSelState, FALSE,
1058 End),
1059 Child, (IPTR)HSpace(0),
1060 End,
1061 Child, (IPTR)Label((IPTR) "Disable extra key emulation:"),
1062 Child, (IPTR)HGroup,
1063 Child, (IPTR)(nh->nh_ExtraEmulObj = ImageObject, ImageButtonFrame,
1064 MUIA_Background, MUII_ButtonBack,
1065 MUIA_CycleChain, 1,
1066 MUIA_InputMode, MUIV_InputMode_Toggle,
1067 MUIA_Image_Spec, MUII_CheckMark,
1068 MUIA_Image_FreeVert, TRUE,
1069 MUIA_Selected, nh->nh_CurrentCGC.cgc_ExtraEmulDisable,
1070 MUIA_ShowSelState, FALSE,
1071 End),
1072 Child, (IPTR)HSpace(0),
1073 End,
1074 End,
1075 Child, (IPTR)VSpace(0),
1076 Child, (IPTR)HGroup,
1077 MUIA_Group_SameWidth, TRUE,
1078 Child, (IPTR)(nh->nh_UseObj = TextObject, ButtonFrame,
1079 MUIA_Background, MUII_ButtonBack,
1080 MUIA_CycleChain, 1,
1081 MUIA_InputMode, MUIV_InputMode_RelVerify,
1082 MUIA_Text_Contents, (IPTR)"\33c Save ",
1083 End),
1084 Child, (IPTR)(nh->nh_CloseObj = TextObject, ButtonFrame,
1085 MUIA_Background, MUII_ButtonBack,
1086 MUIA_CycleChain, 1,
1087 MUIA_InputMode, MUIV_InputMode_RelVerify,
1088 MUIA_Text_Contents, (IPTR)"\33c Use ",
1089 End),
1090 End,
1091 End,
1092 End),
1093 End;
1095 if(!nh->nh_App)
1097 KPRINTF(10, ("Couldn't create application\n"));
1098 bootkbd_GUITaskCleanup(nh);
1099 return;
1101 DoMethod(nh->nh_MainWindow, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
1102 nh->nh_App, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
1103 DoMethod(nh->nh_UseObj, MUIM_Notify, MUIA_Pressed, FALSE,
1104 nh->nh_App, 2, MUIM_Application_ReturnID, ID_STORE_CONFIG);
1105 DoMethod(nh->nh_CloseObj, MUIM_Notify, MUIA_Pressed, FALSE,
1106 nh->nh_App, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
1108 DoMethod(nh->nh_AboutMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
1109 nh->nh_App, 2, MUIM_Application_ReturnID, ID_ABOUT);
1110 DoMethod(nh->nh_UseMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
1111 nh->nh_App, 2, MUIM_Application_ReturnID, ID_STORE_CONFIG);
1112 DoMethod(nh->nh_RestoreDefMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
1113 nh->nh_App, 2, MUIM_Application_ReturnID, ID_RESTORE_DEF);
1114 DoMethod(nh->nh_MUIPrefsMI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
1115 nh->nh_App, 2, MUIM_Application_OpenConfigWindow, 0);
1118 IPTR isopen = 0;
1119 IPTR iconify = 0;
1120 ULONG sigs;
1121 ULONG sigmask;
1122 LONG retid;
1124 get(nh->nh_App, MUIA_Application_Iconified, &iconify);
1125 set(nh->nh_MainWindow, MUIA_Window_Open, TRUE);
1126 get(nh->nh_MainWindow, MUIA_Window_Open, &isopen);
1127 if(!(isopen || iconify))
1129 bootkbd_GUITaskCleanup(nh);
1130 return;
1132 sigmask = 0;
1135 retid = DoMethod(nh->nh_App, MUIM_Application_NewInput, &sigs);
1136 switch(retid)
1138 case ID_STORE_CONFIG:
1139 case MUIV_Application_ReturnID_Quit:
1140 get(nh->nh_RHEnableObj, MUIA_Selected, &nh->nh_CurrentCGC.cgc_RHEnable);
1141 get(nh->nh_ResetDelayObj, MUIA_Numeric_Value, &nh->nh_CurrentCGC.cgc_ResetDelay);
1142 get(nh->nh_CapsLockObj, MUIA_Selected, &nh->nh_CurrentCGC.cgc_CapsLock);
1143 get(nh->nh_ISAMapObj, MUIA_Selected, &nh->nh_CurrentCGC.cgc_ISAMap);
1144 get(nh->nh_ExtraEmulObj, MUIA_Selected, &nh->nh_CurrentCGC.cgc_ExtraEmulDisable);
1145 pic = psdGetClsCfg(libname);
1146 if(!pic)
1148 psdSetClsCfg(libname, NULL);
1149 pic = psdGetClsCfg(libname);
1151 if(pic)
1153 if(psdAddCfgEntry(pic, &nh->nh_CurrentCGC))
1155 if(retid != MUIV_Application_ReturnID_Quit)
1157 psdSaveCfgToDisk(NULL, FALSE);
1159 retid = MUIV_Application_ReturnID_Quit;
1162 break;
1164 case ID_ABOUT:
1165 MUI_RequestA(nh->nh_App, nh->nh_MainWindow, 0, NULL, "Amazing!", VERSION_STRING, NULL);
1166 break;
1168 if(retid == MUIV_Application_ReturnID_Quit)
1170 break;
1172 if(sigs)
1174 sigs = Wait(sigs | sigmask | SIGBREAKF_CTRL_C);
1175 if(sigs & SIGBREAKF_CTRL_C)
1177 break;
1180 } while(TRUE);
1181 set(nh->nh_MainWindow, MUIA_Window_Open, FALSE);
1183 bootkbd_GUITaskCleanup(nh);
1185 AROS_USERFUNC_EXIT
1187 /* \\\ */
1189 /* /// "bootkbd_GUITaskCleanup()" */
1190 void bootkbd_GUITaskCleanup(struct NepHidBase *nh)
1192 if(nh->nh_App)
1194 MUI_DisposeObject(nh->nh_App);
1195 nh->nh_App = NULL;
1197 if(MUIMasterBase)
1199 CloseLibrary(MUIMasterBase);
1200 MUIMasterBase = NULL;
1202 if(IntuitionBase)
1204 CloseLibrary(IntuitionBase);
1205 IntuitionBase = NULL;
1207 if(ps)
1209 CloseLibrary(ps);
1210 ps = NULL;
1212 Forbid();
1213 nh->nh_GUITask = NULL;
1214 --nh->nh_Library.lib_OpenCnt;
1216 /* \\\ */