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
));
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 /* /// "usbAttemptInterfaceBinding()" */
63 struct NepClassHid
* usbAttemptInterfaceBinding(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(usbForceInterfaceBinding(nh
, pif
));
88 /* /// "usbForceInterfaceBinding()" */
89 struct NepClassHid
* usbForceInterfaceBinding(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 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
);
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 /* /// "usbReleaseInterfaceBinding()" */
143 void usbReleaseInterfaceBinding(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, nep
)
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, nep
)
252 /* /// "usbDoMethodA()" */
253 AROS_LH2(IPTR
, usbDoMethodA
,
254 AROS_LHA(ULONG
, methodid
, D0
),
255 AROS_LHA(IPTR
*, methoddata
, A1
),
256 LIBBASETYPEPTR
, nh
, 7, nep
)
260 KPRINTF(10, ("Do Method %ld\n", 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]);
273 case UCM_OpenCfgWindow
:
274 return(nOpenCfgWindow(nh
));
276 case UCM_ConfigChangedEvent
:
277 nLoadClassConfig(nh
);
288 /* /// "nLoadClassConfig()" */
289 BOOL
nLoadClassConfig(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", nGUITask
, 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 /* /// "nHidTask()" */
435 AROS_UFH0(void, nHidTask
)
439 struct NepClassHid
*nch
;
446 if((nch
= nAllocHid()))
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
);
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
;
809 /* /// "nAllocHid()" */
810 struct NepClassHid
* nAllocHid(void)
812 struct Task
*thistask
;
813 struct NepClassHid
*nch
;
816 thistask
= FindTask(NULL
);
817 nch
= thistask
->tc_UserData
;
820 if(!(nch
->nch_Base
= OpenLibrary("poseidon.library", 4)))
825 psdGetAttrs(PGA_INTERFACE
, nch
->nch_Interface
,
826 IFA_Config
, &nch
->nch_Config
,
827 IFA_InterfaceNum
, &nch
->nch_IfNum
,
829 psdGetAttrs(PGA_CONFIG
, nch
->nch_Config
,
830 CA_Device
, &nch
->nch_Device
,
833 nch
->nch_EP1
= psdFindEndpoint(nch
->nch_Interface
, NULL
,
835 EA_TransferType
, USEAF_INTERRUPT
,
839 KPRINTF(1, ("Ooops!?! No Endpoints defined?\n"));
842 psdGetAttrs(PGA_ENDPOINT
, nch
->nch_EP1
,
843 EA_MaxPktSize
, &nch
->nch_EP1PktSize
,
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);
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);
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
;
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
);
895 CloseLibrary(nch
->nch_Base
);
897 nch
->nch_Task
= NULL
;
898 if(nch
->nch_ReadySigTask
)
900 Signal(nch
->nch_ReadySigTask
, 1L<<nch
->nch_ReadySignal
);
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
);
918 nch
->nch_Task
= NULL
;
919 if(nch
->nch_ReadySigTask
)
921 Signal(nch
->nch_ReadySigTask
, 1L<<nch
->nch_ReadySignal
);
926 /**************************************************************************/
929 #define ps nh->nh_PsdBase
931 #define IntuitionBase nh->nh_IntBase
933 #define MUIMasterBase nh->nh_MUIBase
935 /* /// "nGUITask()" */
936 AROS_UFH0(void, nGUITask
)
940 struct Task
*thistask
;
941 struct NepHidBase
*nh
;
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"));
955 if(!(IntuitionBase
= OpenLibrary("intuition.library", 39)))
957 KPRINTF(10, ("Couldn't open intuition.library.\n"));
961 if(!(ps
= OpenLibrary("poseidon.library", 4)))
963 KPRINTF(10, ("Couldn't open poseidon.library.\n"));
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
, "?",
983 Child
, MenuObjectT("Settings"),
984 Child
, nh
->nh_UseMI
= MenuitemObject
,
985 MUIA_Menuitem_Title
, "Save",
986 MUIA_Menuitem_Shortcut
, "S",
988 Child
, MenuitemObject
,
989 MUIA_Menuitem_Title
, NM_BARLABEL
,
991 Child
, nh
->nh_MUIPrefsMI
= MenuitemObject
,
992 MUIA_Menuitem_Title
, "MUI Settings",
993 MUIA_Menuitem_Shortcut
, "M",
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:"),
1007 Child
, nh
->nh_RHEnableObj
= ImageObject
, ImageButtonFrame
,
1008 MUIA_Background
, MUII_ButtonBack
,
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
,
1018 Child
, Label((IPTR
) "Reset delay:"),
1019 Child
, nh
->nh_ResetDelayObj
= SliderObject
, SliderFrame
,
1021 MUIA_Numeric_Min
, 0,
1022 MUIA_Numeric_Max
, 60,
1023 MUIA_Numeric_Value
, nh
->nh_CurrentCGC
.cgc_ResetDelay
,
1024 MUIA_Numeric_Format
, "%ldsec",
1026 Child
, Label((IPTR
) "Amiga CapsLock behaviour:"),
1028 Child
, nh
->nh_CapsLockObj
= ImageObject
, ImageButtonFrame
,
1029 MUIA_Background
, MUII_ButtonBack
,
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
,
1039 Child
, Label((IPTR
) "Use standard ISA mapping:"),
1041 Child
, nh
->nh_ISAMapObj
= ImageObject
, ImageButtonFrame
,
1042 MUIA_Background
, MUII_ButtonBack
,
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
,
1052 Child
, Label((IPTR
) "Disable extra key emulation:"),
1054 Child
, nh
->nh_ExtraEmulObj
= ImageObject
, ImageButtonFrame
,
1055 MUIA_Background
, MUII_ButtonBack
,
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
,
1068 MUIA_Group_SameWidth
, TRUE
,
1069 Child
, nh
->nh_UseObj
= TextObject
, ButtonFrame
,
1070 MUIA_Background
, MUII_ButtonBack
,
1072 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
1073 MUIA_Text_Contents
, "\33c Save ",
1075 Child
, nh
->nh_CloseObj
= TextObject
, ButtonFrame
,
1076 MUIA_Background
, MUII_ButtonBack
,
1078 MUIA_InputMode
, MUIV_InputMode_RelVerify
,
1079 MUIA_Text_Contents
, "\33c Use ",
1088 KPRINTF(10, ("Couldn't create application\n"));
1089 nGUITaskCleanup(nh
);
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);
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
);
1126 retid
= DoMethod(nh
->nh_App
, MUIM_Application_NewInput
, &sigs
);
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
);
1139 psdSetClsCfg(libname
, NULL
);
1140 pic
= psdGetClsCfg(libname
);
1144 if(psdAddCfgEntry(pic
, &nh
->nh_CurrentCGC
))
1146 if(retid
!= MUIV_Application_ReturnID_Quit
)
1148 psdSaveCfgToDisk(NULL
, FALSE
);
1150 retid
= MUIV_Application_ReturnID_Quit
;
1156 MUI_RequestA(nh
->nh_App
, nh
->nh_MainWindow
, 0, NULL
, "Amazing!", VERSION_STRING
, NULL
);
1159 if(retid
== MUIV_Application_ReturnID_Quit
)
1165 sigs
= Wait(sigs
| sigmask
| SIGBREAKF_CTRL_C
);
1166 if(sigs
& SIGBREAKF_CTRL_C
)
1172 set(nh
->nh_MainWindow
, MUIA_Window_Open
, FALSE
);
1174 nGUITaskCleanup(nh
);
1180 /* /// "nGUITaskCleanup()" */
1181 void nGUITaskCleanup(struct NepHidBase
*nh
)
1185 MUI_DisposeObject(nh
->nh_App
);
1190 CloseLibrary(MUIMasterBase
);
1191 MUIMasterBase
= NULL
;
1195 CloseLibrary(IntuitionBase
);
1196 IntuitionBase
= NULL
;
1204 nh
->nh_GUITask
= NULL
;
1205 --nh
->nh_Library
.lib_OpenCnt
;