2 *----------------------------------------------------------------------------
3 * bootkeyboard class for poseidon
4 *----------------------------------------------------------------------------
5 * By Chris Hodges <chrisly@platon42.de>
10 #include "bootkeyboard.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 KPRINTF(20, ("libInit: OpenLibrary(\"utility.library\", 39) failed!\n"));
29 KPRINTF(10, ("libInit: Ok\n"));
33 static int libOpen(LIBBASETYPEPTR nh
)
35 KPRINTF(10, ("libOpen nh: 0x%08lx\n", nh
));
36 bootkbd_LoadClassConfig(nh
);
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
;
51 ADD2INITLIB(libInit
, 0)
52 ADD2OPENLIB(libOpen
, 0)
53 ADD2EXPUNGELIB(libExpunge
, 0)
57 * ***********************************************************************
58 * * Library functions *
59 * ***********************************************************************
62 /* /// "bootkbd_AttemptInterfaceBinding()" */
63 struct NepClassHid
* bootkbd_AttemptInterfaceBinding(struct NepHidBase
*nh
, struct PsdInterface
*pif
)
70 KPRINTF(1, ("nepHidAttemptInterfaceBinding(%08lx)\n", pif
));
71 if((ps
= OpenLibrary("poseidon.library", 4)))
73 psdGetAttrs(PGA_INTERFACE
, pif
,
75 IFA_SubClass
, &subclass
,
79 if((ifclass
== HID_CLASSCODE
) && (subclass
== HID_BOOT_SUBCLASS
) && (proto
== HID_PROTO_KEYBOARD
))
81 return(bootkbd_ForceInterfaceBinding(nh
, pif
));
88 /* /// "bootkbd_ForceInterfaceBinding()" */
89 struct NepClassHid
* bootkbd_ForceInterfaceBinding(struct NepHidBase
*nh
, struct PsdInterface
*pif
)
92 struct NepClassHid
*nch
;
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
);
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'!",
132 nch
->nch_ReadySigTask
= NULL
;
133 //FreeSignal(nch->nch_ReadySignal);
142 /* /// "bootkbd_ReleaseInterfaceBinding()" */
143 void bootkbd_ReleaseInterfaceBinding(struct NepHidBase
*nh
, struct NepClassHid
*nch
)
146 struct PsdConfig
*pc
;
147 struct PsdDevice
*pd
;
150 KPRINTF(1, ("nepHidReleaseInterfaceBinding(%08lx)\n", nch
));
151 if((ps
= OpenLibrary("poseidon.library", 4)))
154 nch
->nch_ReadySignal
= SIGB_SINGLE
;
155 nch
->nch_ReadySigTask
= FindTask(NULL
);
158 Signal(nch
->nch_Task
, SIGBREAKF_CTRL_C
);
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'!",
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
)
190 KPRINTF(1, ("nepHidGetAttrsA(%ld, %08lx, %08lx)\n", type
, usbstruct
, tags
));
194 if((ti
= FindTagItem(UCCA_Priority
, tags
)))
196 *((IPTR
*) ti
->ti_Data
) = -100;
199 if((ti
= FindTagItem(UCCA_Description
, tags
)))
201 *((STRPTR
*) ti
->ti_Data
) = "Support for keyboards in boot protocol mode";
204 if((ti
= FindTagItem(UCCA_HasClassCfgGUI
, tags
)))
206 *((IPTR
*) ti
->ti_Data
) = TRUE
;
209 if((ti
= FindTagItem(UCCA_HasBindingCfgGUI
, tags
)))
211 *((IPTR
*) ti
->ti_Data
) = FALSE
;
214 if((ti
= FindTagItem(UCCA_AfterDOSRestart
, tags
)))
216 *((IPTR
*) ti
->ti_Data
) = TRUE
;
219 if((ti
= FindTagItem(UCCA_UsingDefaultCfg
, tags
)))
221 *((IPTR
*) ti
->ti_Data
) = nh
->nh_UsingDefaultCfg
;
227 if((ti
= FindTagItem(UCBA_UsingDefaultCfg
, tags
)))
229 *((IPTR
*) ti
->ti_Data
) = FALSE
;
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
)
252 /* /// "usbDoMethodA()" */
253 AROS_LH2(IPTR
, usbDoMethodA
,
254 AROS_LHA(ULONG
, methodid
, D0
),
255 AROS_LHA(IPTR
*, methoddata
, A1
),
256 LIBBASETYPEPTR
, nh
, 7, bootkbd
)
260 KPRINTF(10, ("Do Method %ld\n", 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]);
273 case UCM_OpenCfgWindow
:
274 return(nOpenCfgWindow(nh
));
276 case UCM_ConfigChangedEvent
:
277 bootkbd_LoadClassConfig(nh
);
288 /* /// "bootkbd_LoadClassConfig()" */
289 BOOL
bootkbd_LoadClassConfig(struct NepHidBase
*nh
)
292 struct ClsGlobalCfg
*cgc
;
293 struct PsdIFFContext
*pic
;
295 KPRINTF(10, ("Loading Class Config...\n"));
300 if(!(ps
= OpenLibrary("poseidon.library", 4)))
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
);
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
)));
321 nh
->nh_UsingDefaultCfg
= FALSE
;
330 /* /// "nOpenCfgWindow()" */
331 LONG
nOpenCfgWindow(struct NepHidBase
*nh
)
334 KPRINTF(10, ("Opening GUI...\n"));
335 if(!(ps
= OpenLibrary("poseidon.library", 4)))
342 if((nh
->nh_GUITask
= psdSpawnSubTask(MOD_NAME_STRING
" GUI", bootkbd_GUITask
, nh
)))
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 */
432 #define ps nch->nch_Base
434 /* /// "bootkbd_HidTask()" */
435 AROS_UFH0(void, bootkbd_HidTask
)
439 struct NepClassHid
*nch
;
446 if((nch
= bootkbd_AllocHid()))
449 if(nch
->nch_ReadySigTask
)
451 Signal(nch
->nch_ReadySigTask
, 1L<<nch
->nch_ReadySignal
);
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
);
468 KPRINTF(1, ("Int Pipe failed %ld\n", ioerr
));
471 psdSendPipe(nch
->nch_EP1Pipe
, buf
, nch
->nch_EP1PktSize
);
475 } while(!(sigs
& SIGBREAKF_CTRL_C
));
476 KPRINTF(20, ("Going down the river!\n"));
478 nParseKeys(nch
, buf
);
480 psdAbortPipe(nch
->nch_EP1Pipe
);
481 psdWaitPipe(nch
->nch_EP1Pipe
);
482 bootkbd_FreeHid(nch
);
488 /* /// "nParseKeys()" */
489 void nParseKeys(struct NepClassHid
*nch
, UBYTE
*buf
)
495 UWORD keyqual
= buf
[0];
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
))
522 struct IOStdReq
*ioreq
;
523 struct Interrupt tempint
;
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
;
544 DoIO((struct IORequest
*) ioreq
);
545 if((node
= tempint
.is_Node
.ln_Pred
))
549 node
= node
->ln_Pred
;
551 listhead
= (struct List
*) node
;
553 ioreq
->io_Command
= KBD_REMRESETHANDLER
;
554 DoIO((struct IORequest
*) ioreq
);
558 node
= listhead
->lh_Head
;
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);
568 KPRINTF(20, ("Reset handler list not found!\n"));
570 CloseDevice((struct IORequest
*) ioreq
);
572 DeleteIORequest((struct IORequest
*) ioreq
);
579 if(qualifier
!= nch
->nch_OldQualifier
)
581 switch(qualifier
^nch
->nch_OldQualifier
)
583 case IEQUALIFIER_LSHIFT
:
586 case IEQUALIFIER_RSHIFT
:
589 case IEQUALIFIER_CAPSLOCK
:
592 case IEQUALIFIER_CONTROL
:
595 case IEQUALIFIER_LALT
:
598 case IEQUALIFIER_RALT
:
601 case IEQUALIFIER_LCOMMAND
:
604 case IEQUALIFIER_RCOMMAND
:
613 KPRINTF(1, ("Qualifier %08lx\n", qualifier
));
614 for(nkey
= 2; nkey
< 8; nkey
++)
616 keycode
= nch
->nch_OldKeyArray
[nkey
];
621 /* Check, if key is still there */
623 for(nkey2
= 2; nkey2
< 8; nkey2
++)
625 if(buf
[nkey2
] == keycode
)
633 KPRINTF(1, ("Key up: %08lx\n", keycode
));
634 iecode
= nch
->nch_ClsBase
->nh_CurrentCGC
.cgc_ISAMap
? usbisakeymap
[keycode
] : usbkeymap
[keycode
];
636 if(!nch
->nch_ClsBase
->nh_CurrentCGC
.cgc_ExtraEmulDisable
)
641 case 0x49: /* Insert */
642 iecode
= usbkeymap
[0x19];
643 qualifier
|= IEQUALIFIER_RCOMMAND
;
646 case 0x4A: /* Pos 1 */
647 iecode
= usbkeymap
[0x50];
648 qualifier
|= IEQUALIFIER_LSHIFT
;
652 iecode
= usbkeymap
[0x4F];
653 qualifier
|= IEQUALIFIER_LSHIFT
;
656 case 0x4B: /* Page Up */
657 iecode
= usbkeymap
[0x52];
658 qualifier
|= IEQUALIFIER_LSHIFT
;
661 case 0x4E: /* Page Down */
662 iecode
= usbkeymap
[0x51];
663 qualifier
|= IEQUALIFIER_LSHIFT
;
666 case 0x48: /* Pause / Break */
667 /* *** FIXME *** should be a vanilla key for keymapping compatibility */
668 iecode
= usbkeymap
[0x06];
669 qualifier
|= IEQUALIFIER_CONTROL
;
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
);
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
);
705 for(nkey
= 2; nkey
< 8; nkey
++)
712 KPRINTF(1, ("Key down: %08lx\n", keycode
));
713 /* Check, if key was there previously */
715 for(nkey2
= 2; nkey2
< 8; nkey2
++)
717 if(nch
->nch_OldKeyArray
[nkey2
] == keycode
)
725 iecode
= nch
->nch_ClsBase
->nh_CurrentCGC
.cgc_ISAMap
? usbisakeymap
[keycode
] : usbkeymap
[keycode
];
726 if(!nch
->nch_ClsBase
->nh_CurrentCGC
.cgc_ExtraEmulDisable
)
730 case 0x49: /* Insert */
731 iecode
= usbkeymap
[0x19];
732 qualifier
|= IEQUALIFIER_RCOMMAND
;
734 case 0x4A: /* Pos 1 */
735 iecode
= usbkeymap
[0x50];
736 qualifier
|= IEQUALIFIER_LSHIFT
;
739 iecode
= usbkeymap
[0x4F];
740 qualifier
|= IEQUALIFIER_LSHIFT
;
742 case 0x4B: /* Page Up */
743 iecode
= usbkeymap
[0x52];
744 qualifier
|= IEQUALIFIER_LSHIFT
;
746 case 0x4E: /* Page Down */
747 iecode
= usbkeymap
[0x51];
748 qualifier
|= IEQUALIFIER_LSHIFT
;
750 case 0x48: /* Pause / Break */
751 /* *** FIXME *** should be a vanilla key for keymapping compatibility */
752 iecode
= usbkeymap
[0x06];
753 qualifier
|= IEQUALIFIER_CONTROL
;
757 if(keycode
== 0x39) /* Caps Lock */
759 if(nch
->nch_ClsBase
->nh_CurrentCGC
.cgc_CapsLock
)
761 nch
->nch_CapsLock
= !nch
->nch_CapsLock
;
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
;
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
);
818 /* /// "bootkbd_AllocHid()" */
819 struct NepClassHid
* bootkbd_AllocHid(void)
821 struct Task
*thistask
;
822 struct NepClassHid
*nch
;
825 thistask
= FindTask(NULL
);
826 nch
= thistask
->tc_UserData
;
829 if(!(nch
->nch_Base
= OpenLibrary("poseidon.library", 4)))
834 psdGetAttrs(PGA_INTERFACE
, nch
->nch_Interface
,
835 IFA_Config
, &nch
->nch_Config
,
836 IFA_InterfaceNum
, &nch
->nch_IfNum
,
838 psdGetAttrs(PGA_CONFIG
, nch
->nch_Config
,
839 CA_Device
, &nch
->nch_Device
,
842 nch
->nch_EP1
= psdFindEndpoint(nch
->nch_Interface
, NULL
,
844 EA_TransferType
, USEAF_INTERRUPT
,
848 KPRINTF(1, ("Ooops!?! No Endpoints defined?\n"));
851 psdGetAttrs(PGA_ENDPOINT
, nch
->nch_EP1
,
852 EA_MaxPktSize
, &nch
->nch_EP1PktSize
,
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);
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);
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
;
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
);
904 CloseLibrary(nch
->nch_Base
);
906 nch
->nch_Task
= NULL
;
907 if(nch
->nch_ReadySigTask
)
909 Signal(nch
->nch_ReadySigTask
, 1L<<nch
->nch_ReadySignal
);
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
);
927 nch
->nch_Task
= NULL
;
928 if(nch
->nch_ReadySigTask
)
930 Signal(nch
->nch_ReadySigTask
, 1L<<nch
->nch_ReadySignal
);
935 /**************************************************************************/
938 #define ps nh->nh_PsdBase
940 #define IntuitionBase nh->nh_IntBase
942 #define MUIMasterBase nh->nh_MUIBase
944 /* /// "bootkbd_GUITask()" */
945 AROS_UFH0(void, bootkbd_GUITask
)
949 struct Task
*thistask
;
950 struct NepHidBase
*nh
;
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
);
964 if(!(IntuitionBase
= OpenLibrary("intuition.library", 39)))
966 KPRINTF(10, ("Couldn't open intuition.library.\n"));
967 bootkbd_GUITaskCleanup(nh
);
970 if(!(ps
= OpenLibrary("poseidon.library", 4)))
972 KPRINTF(10, ("Couldn't open poseidon.library.\n"));
973 bootkbd_GUITaskCleanup(nh
);
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
)"?",
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",
997 Child
, (IPTR
)MenuitemObject
,
998 MUIA_Menuitem_Title
, (IPTR
)NM_BARLABEL
,
1000 Child
, (IPTR
)(nh
->nh_MUIPrefsMI
= MenuitemObject
,
1001 MUIA_Menuitem_Title
, (IPTR
)"MUI Settings",
1002 MUIA_Menuitem_Shortcut
, (IPTR
)"M",
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
,
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
,
1025 Child
, (IPTR
)HSpace(0),
1027 Child
, (IPTR
)Label((IPTR
) "Reset delay:"),
1028 Child
, (IPTR
)(nh
->nh_ResetDelayObj
= SliderObject
, SliderFrame
,
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",
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
,
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
,
1046 Child
, (IPTR
)HSpace(0),
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
,
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
,
1059 Child
, (IPTR
)HSpace(0),
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
,
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
,
1072 Child
, (IPTR
)HSpace(0),
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
,
1081 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
1082 MUIA_Text_Contents
, (IPTR
)"\33c Save ",
1084 Child
, (IPTR
)(nh
->nh_CloseObj
= TextObject
, ButtonFrame
,
1085 MUIA_Background
, MUII_ButtonBack
,
1087 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
1088 MUIA_Text_Contents
, (IPTR
)"\33c Use ",
1097 KPRINTF(10, ("Couldn't create application\n"));
1098 bootkbd_GUITaskCleanup(nh
);
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);
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
);
1135 retid
= DoMethod(nh
->nh_App
, MUIM_Application_NewInput
, &sigs
);
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
);
1148 psdSetClsCfg(libname
, NULL
);
1149 pic
= psdGetClsCfg(libname
);
1153 if(psdAddCfgEntry(pic
, &nh
->nh_CurrentCGC
))
1155 if(retid
!= MUIV_Application_ReturnID_Quit
)
1157 psdSaveCfgToDisk(NULL
, FALSE
);
1159 retid
= MUIV_Application_ReturnID_Quit
;
1165 MUI_RequestA(nh
->nh_App
, nh
->nh_MainWindow
, 0, NULL
, "Amazing!", VERSION_STRING
, NULL
);
1168 if(retid
== MUIV_Application_ReturnID_Quit
)
1174 sigs
= Wait(sigs
| sigmask
| SIGBREAKF_CTRL_C
);
1175 if(sigs
& SIGBREAKF_CTRL_C
)
1181 set(nh
->nh_MainWindow
, MUIA_Window_Open
, FALSE
);
1183 bootkbd_GUITaskCleanup(nh
);
1189 /* /// "bootkbd_GUITaskCleanup()" */
1190 void bootkbd_GUITaskCleanup(struct NepHidBase
*nh
)
1194 MUI_DisposeObject(nh
->nh_App
);
1199 CloseLibrary(MUIMasterBase
);
1200 MUIMasterBase
= NULL
;
1204 CloseLibrary(IntuitionBase
);
1205 IntuitionBase
= NULL
;
1213 nh
->nh_GUITask
= NULL
;
1214 --nh
->nh_Library
.lib_OpenCnt
;