2 *----------------------------------------------------------------------------
3 * hid class for poseidon
4 *----------------------------------------------------------------------------
5 * By Chris Hodges <chrisly@platon42.de>
11 #include "hid.class.h"
13 #include <proto/datatypes.h>
15 static LONG
_rand(struct NepHidBase
*nh
)
17 nh
->nh_Seed
= nh
->nh_Seed
* 1103515245 + 12345;
23 const STRPTR
GM_UNIQUENAME(libname
) = MOD_NAME_STRING
;
25 //#define LowLevelBase nh->nh_LowLevelBase
27 static int GM_UNIQUENAME(libInit
)(LIBBASETYPEPTR nh
)
29 struct NepClassHid
*nch
;
30 struct NepHidBase
*ret
= NULL
;
32 KPRINTF(10, ("libInit nh: 0x%08lx SysBase: 0x%08lx\n", nh
, SysBase
));
34 nh
->nh_UtilityBase
= OpenLibrary("utility.library", 39);
36 #define UtilityBase nh->nh_UtilityBase
40 NewList(&nh
->nh_Interfaces
);
41 nch
= &nh
->nh_DummyNCH
;
42 nch
->nch_ClsBase
= nh
;
43 nch
->nch_Interface
= NULL
;
45 nch
->nch_CDC
= AllocVec(sizeof(struct ClsDevCfg
), MEMF_PUBLIC
|MEMF_CLEAR
);
52 CloseLibrary(UtilityBase
);
55 KPRINTF(20, ("libInit: OpenLibrary(\"utility.library\", 39) failed!\n"));
58 KPRINTF(10, ("libInit: Ok\n"));
59 return(ret
? TRUE
: FALSE
);
62 static int GM_UNIQUENAME(libOpen
)(LIBBASETYPEPTR nh
)
64 KPRINTF(10, ("libOpen nh: 0x%08lx\n", nh
));
65 GM_UNIQUENAME(nLoadClassConfig
)(nh
);
69 static int GM_UNIQUENAME(libClose
)(LIBBASETYPEPTR nh
)
71 if(nh
->nh_Library
.lib_OpenCnt
== 0) // FIXME is this 0 or 1? Does AROS decrease it before calling libClose?
74 nh
->nh_ReadySignal
= SIGB_SINGLE
;
75 nh
->nh_ReadySigTask
= FindTask(NULL
);
76 if(nh
->nh_DispatcherTask
)
78 Signal(nh
->nh_DispatcherTask
, SIGBREAKF_CTRL_C
);
81 while(nh
->nh_DispatcherTask
)
83 Wait(1L<<nh
->nh_ReadySignal
);
85 //FreeSignal(nh->nh_ReadySignal);
87 KPRINTF(5, ("libClose: lib_OpenCnt = %ld\n", nh
->nh_Library
.lib_OpenCnt
));
91 static int GM_UNIQUENAME(libExpunge
)(LIBBASETYPEPTR nh
)
93 KPRINTF(10, ("libExpunge nh: 0x%08lx\n", nh
));
95 if(nh
->nh_LowLevelBase
)
99 ourvec
= SetFunction(nh
->nh_LowLevelBase
, -5 * LIB_VECTSIZE
, nh
->nh_LLOldReadJoyPort
);
100 if(ourvec
!= AROS_SLIB_ENTRY(nReadJoyPort
, hid
, 5))
102 SetFunction(nh
->nh_LowLevelBase
, -5 * LIB_VECTSIZE
, ourvec
);
104 return(FALSE
); /* we couldn't remove the patch! */
106 ourvec
= SetFunction(nh
->nh_LowLevelBase
, -22 * LIB_VECTSIZE
, nh
->nh_LLOldSetJoyPortAttrsA
);
107 if(ourvec
!= AROS_SLIB_ENTRY(nSetJoyPortAttrsA
, hid
, 22))
109 SetFunction(nh
->nh_LowLevelBase
, -22 * LIB_VECTSIZE
, ourvec
);
111 return(FALSE
); /* we couldn't remove the patch! */
114 CloseLibrary(nh
->nh_LowLevelBase
);
115 nh
->nh_LowLevelBase
= NULL
;
118 CloseLibrary((struct Library
*) UtilityBase
);
120 FreeVec(nh
->nh_DummyNCH
.nch_CDC
);
122 KPRINTF(5, ("libExpunge: Unloading done! hid.class expunged!\n\n"));
127 ADD2INITLIB(GM_UNIQUENAME(libInit
), 0)
128 ADD2OPENLIB(GM_UNIQUENAME(libOpen
), 0)
129 ADD2CLOSELIB(GM_UNIQUENAME(libClose
), 0)
130 ADD2EXPUNGELIB(GM_UNIQUENAME(libExpunge
), 0)
134 * ***********************************************************************
135 * * Library functions *
136 * ***********************************************************************
139 /* /// "usbAttemptInterfaceBinding()" */
140 struct NepClassHid
* GM_UNIQUENAME(usbAttemptInterfaceBinding
)(struct NepHidBase
*nh
, struct PsdInterface
*pif
)
147 KPRINTF(1, ("nepHidAttemptInterfaceBinding(%08lx)\n", pif
));
148 if((ps
= OpenLibrary("poseidon.library", 4)))
150 psdGetAttrs(PGA_INTERFACE
, pif
,
152 //IFA_SubClass, &subclass,
153 //IFA_Protocol, &proto,
157 if(ifclass
== HID_CLASSCODE
)
159 return(GM_UNIQUENAME(usbForceInterfaceBinding
)(nh
, pif
));
166 /* /// "usbForceInterfaceBinding()" */
167 struct NepClassHid
* GM_UNIQUENAME(usbForceInterfaceBinding
)(struct NepHidBase
*nh
, struct PsdInterface
*pif
)
170 struct NepClassHid
*nch
;
171 struct PsdConfig
*pc
;
172 struct PsdDevice
*pd
;
177 struct Task
*tmptask
;
179 KPRINTF(1, ("nepHidForceInterfaceBinding(%08lx)\n", pif
));
182 if((ps
= OpenLibrary("poseidon.library", 4)))
184 psdGetAttrs(PGA_INTERFACE
, pif
,
186 IFA_IDString
, &ifidstr
,
188 psdGetAttrs(PGA_CONFIG
, pc
,
191 psdGetAttrs(PGA_DEVICE
, pd
,
192 DA_ProductName
, &devname
,
193 DA_IDString
, &devidstr
,
195 if((nch
= psdAllocVec(sizeof(struct NepClassHid
))))
197 nch
->nch_ClsBase
= nh
;
198 nch
->nch_CDC
= psdAllocVec(sizeof(struct ClsDevCfg
));
206 nch
->nch_Device
= pd
;
207 nch
->nch_Interface
= pif
;
208 nch
->nch_DevIDString
= devidstr
;
209 nch
->nch_IfIDString
= ifidstr
;
211 GM_UNIQUENAME(nLoadBindingConfig
)(nch
, FALSE
);
213 psdSafeRawDoFmt(buf
, 64, "hid.class<%08lx>", nch
);
214 nch
->nch_ReadySignal
= SIGB_SINGLE
;
215 nch
->nch_ReadySigTask
= FindTask(NULL
);
216 SetSignal(0, SIGF_SINGLE
);
218 if((tmptask
= psdSpawnSubTask(buf
, GM_UNIQUENAME(nHidTask
), nch
)))
220 psdBorrowLocksWait(tmptask
, 1UL<<nch
->nch_ReadySignal
);
223 nch
->nch_ReadySigTask
= NULL
;
224 //FreeSignal(nch->nch_ReadySignal);
225 psdAddErrorMsg(RETURN_OK
, (STRPTR
) GM_UNIQUENAME(libname
),
226 "HID the road, '%s'!",
229 AddTail(&nh
->nh_Interfaces
, &nch
->nch_Node
);
235 nch
->nch_ReadySigTask
= NULL
;
236 //FreeSignal(nch->nch_ReadySignal);
237 psdFreeVec(nch
->nch_CDC
);
246 /* /// "usbReleaseInterfaceBinding()" */
247 void GM_UNIQUENAME(usbReleaseInterfaceBinding
)(struct NepHidBase
*nh
, struct NepClassHid
*nch
)
250 struct PsdConfig
*pc
;
251 struct PsdDevice
*pd
;
254 KPRINTF(1, ("nepHidReleaseInterfaceBinding(%08lx)\n", nch
));
255 if((ps
= OpenLibrary("poseidon.library", 4)))
258 nch
->nch_ReadySignal
= SIGB_SINGLE
;
259 nch
->nch_ReadySigTask
= FindTask(NULL
);
262 Signal(nch
->nch_GUITask
, SIGBREAKF_CTRL_C
);
265 while(nch
->nch_GUITask
)
267 Wait(1L<<nch
->nch_ReadySignal
);
271 if(nch
->nch_HCGUITask
)
273 Signal(nch
->nch_HCGUITask
, SIGBREAKF_CTRL_C
);
276 while(nch
->nch_HCGUITask
)
278 Wait(1L<<nch
->nch_ReadySignal
);
284 Signal(nch
->nch_Task
, SIGBREAKF_CTRL_C
);
289 Wait(1L<<nch
->nch_ReadySignal
);
291 //FreeSignal(nch->nch_ReadySignal);
292 psdGetAttrs(PGA_INTERFACE
, nch
->nch_Interface
, IFA_Config
, &pc
, TAG_END
);
293 psdGetAttrs(PGA_CONFIG
, pc
, CA_Device
, &pd
, TAG_END
);
294 psdGetAttrs(PGA_DEVICE
, pd
, DA_ProductName
, &devname
, TAG_END
);
295 psdAddErrorMsg(RETURN_OK
, (STRPTR
) GM_UNIQUENAME(libname
),
296 "And don't you come back no more, '%s'!",
299 Remove(&nch
->nch_Node
);
301 psdFreeVec(nch
->nch_CDC
);
308 /* /// "usbGetAttrsA()" */
309 AROS_LH3(LONG
, usbGetAttrsA
,
310 AROS_LHA(ULONG
, type
, D0
),
311 AROS_LHA(APTR
, usbstruct
, A0
),
312 AROS_LHA(struct TagItem
*, tags
, A1
),
313 LIBBASETYPEPTR
, nh
, 5, hid
)
320 KPRINTF(1, ("nepHidGetAttrsA(%ld, %08lx, %08lx)\n", type
, usbstruct
, tags
));
324 if((ti
= FindTagItem(UCCA_Priority
, tags
)))
326 *((SIPTR
*) ti
->ti_Data
) = 0;
329 if((ti
= FindTagItem(UCCA_Description
, tags
)))
331 *((STRPTR
*) ti
->ti_Data
) = "Generic support for human interface devices";
334 if((ti
= FindTagItem(UCCA_HasClassCfgGUI
, tags
)))
336 *((IPTR
*) ti
->ti_Data
) = TRUE
;
339 if((ti
= FindTagItem(UCCA_HasBindingCfgGUI
, tags
)))
341 *((IPTR
*) ti
->ti_Data
) = TRUE
;
344 if((ti
= FindTagItem(UCCA_AfterDOSRestart
, tags
)))
346 *((IPTR
*) ti
->ti_Data
) = FALSE
;
349 if((ti
= FindTagItem(UCCA_UsingDefaultCfg
, tags
)))
351 *((IPTR
*) ti
->ti_Data
) = nh
->nh_DummyNCH
.nch_UsingDefaultCfg
;
354 if((ti
= FindTagItem(UCCA_SupportsSuspend
, tags
)))
356 *((IPTR
*) ti
->ti_Data
) = TRUE
;
362 if((ti
= FindTagItem(UCBA_UsingDefaultCfg
, tags
)))
364 *((IPTR
*) ti
->ti_Data
) = ((struct NepClassHid
*) usbstruct
)->nch_UsingDefaultCfg
;
374 /* /// "usbSetAttrsA()" */
375 AROS_LH3(LONG
, usbSetAttrsA
,
376 AROS_LHA(ULONG
, type
, D0
),
377 AROS_LHA(APTR
, usbstruct
, A0
),
378 AROS_LHA(struct TagItem
*, tags
, A1
),
379 LIBBASETYPEPTR
, nh
, 6, hid
)
387 /* /// "usbDoMethodA()" */
388 AROS_LH2(IPTR
, usbDoMethodA
,
389 AROS_LHA(ULONG
, methodid
, D0
),
390 AROS_LHA(IPTR
*, methoddata
, A1
),
391 LIBBASETYPEPTR
, nh
, 7, hid
)
395 struct NepClassHid
*nch
;
397 KPRINTF(10, ("Do Method %ld\n", methodid
));
400 case UCM_AttemptInterfaceBinding
:
401 return((IPTR
) GM_UNIQUENAME(usbAttemptInterfaceBinding
)(nh
, (struct PsdInterface
*) methoddata
[0]));
403 case UCM_ForceInterfaceBinding
:
404 return((IPTR
) GM_UNIQUENAME(usbForceInterfaceBinding
)(nh
, (struct PsdInterface
*) methoddata
[0]));
406 case UCM_ReleaseInterfaceBinding
:
407 GM_UNIQUENAME(usbReleaseInterfaceBinding
)(nh
, (struct NepClassHid
*) methoddata
[0]);
410 case UCM_OpenCfgWindow
:
411 return(GM_UNIQUENAME(nOpenBindingCfgWindow
)(nh
, &nh
->nh_DummyNCH
));
413 case UCM_OpenBindingCfgWindow
:
414 return(GM_UNIQUENAME(nOpenBindingCfgWindow
)(nh
, (struct NepClassHid
*) methoddata
[0]));
416 case UCM_DOSAvailableEvent
:
420 case UCM_ConfigChangedEvent
:
421 GM_UNIQUENAME(nLoadClassConfig
)(nh
);
424 nch
= (struct NepClassHid
*) nh
->nh_Interfaces
.lh_Head
;
425 while(nch
->nch_Node
.ln_Succ
)
427 GM_UNIQUENAME(nLoadBindingConfig
)(nch
, TRUE
);
428 nch
= (struct NepClassHid
*) nch
->nch_Node
.ln_Succ
;
433 case UCM_AttemptSuspendDevice
:
434 nch
= (struct NepClassHid
*) methoddata
[0];
435 nch
->nch_Running
= FALSE
;
438 case UCM_AttemptResumeDevice
:
439 nch
= (struct NepClassHid
*) methoddata
[0];
440 nch
->nch_Running
= TRUE
;
441 Signal(nch
->nch_Task
, (1L<<nch
->nch_TaskMsgPort
->mp_SigBit
));
452 /* /// "nInstallLLPatch()" */
453 void nInstallLLPatch(struct NepHidBase
*nh
)
455 if(!nh
->nh_LowLevelBase
)
457 if((nh
->nh_LowLevelBase
= OpenLibrary("lowlevel.library", 40)))
460 nh
->nh_LLOldReadJoyPort
= SetFunction(nh
->nh_LowLevelBase
, -5 * LIB_VECTSIZE
, AROS_SLIB_ENTRY(nReadJoyPort
, hid
, 5));
461 nh
->nh_LLOldSetJoyPortAttrsA
= SetFunction(nh
->nh_LowLevelBase
, -22 * LIB_VECTSIZE
, AROS_SLIB_ENTRY(nSetJoyPortAttrsA
, hid
, 22));
468 /* /// "nLoadClassConfig()" */
469 BOOL
GM_UNIQUENAME(nLoadClassConfig
)(struct NepHidBase
*nh
)
471 struct NepClassHid
*nch
= &nh
->nh_DummyNCH
;
473 struct KeymapCfg
*kmc
;
474 struct ClsDevCfg
*cdc
;
475 struct PsdIFFContext
*pic
;
477 KPRINTF(10, ("Loading Class Config...\n"));
482 if(!(ps
= OpenLibrary("poseidon.library", 4)))
488 /* Create default config */
489 kmc
= &nch
->nch_KeymapCfg
;
490 kmc
->kmc_ChunkID
= AROS_LONG2BE(MAKE_ID('K','M','A','P'));
491 kmc
->kmc_Length
= AROS_LONG2BE(sizeof(struct KeymapCfg
)-8);
492 CopyMemQuick(usbkeymap
, kmc
->kmc_Keymap
, AROS_LONG2BE(kmc
->kmc_Length
));
495 cdc
->cdc_ChunkID
= AROS_LONG2BE(MAKE_ID('H','I','D','C'));
496 cdc
->cdc_Length
= AROS_LONG2BE(sizeof(struct ClsDevCfg
)-8);
497 cdc
->cdc_EnableKBReset
= TRUE
;
498 cdc
->cdc_EnableRH
= TRUE
;
499 cdc
->cdc_ResetDelay
= 10;
500 cdc
->cdc_ShellStack
= AROS_STACKSIZE
;
501 strcpy(cdc
->cdc_ShellCon
, "CON:///130/HID Rocket Bay/CLOSE/AUTO/WAIT");
502 cdc
->cdc_PollingMode
= FALSE
;
503 cdc
->cdc_LLPortMode
[1] = 2;
504 cdc
->cdc_HIDCtrlOpen
= FALSE
;
505 strcpy(cdc
->cdc_HIDCtrlRexx
, "HIDCTRL");
506 strcpy(cdc
->cdc_HIDCtrlTitle
, "HID Control");
507 cdc
->cdc_LLRumblePort
= 2;
508 cdc
->cdc_TurboMouse
= 0;
510 nch
->nch_UsingDefaultCfg
= TRUE
;
511 /* try to load default config */
512 pic
= psdGetClsCfg(GM_UNIQUENAME(libname
));
515 cdc
= psdGetCfgChunk(pic
, AROS_LONG2BE(nch
->nch_CDC
->cdc_ChunkID
));
518 CopyMem(((UBYTE
*) cdc
) + 8, ((UBYTE
*) nch
->nch_CDC
) + 8, min(AROS_LONG2BE(cdc
->cdc_Length
), AROS_LONG2BE(nch
->nch_CDC
->cdc_Length
)));
520 nch
->nch_UsingDefaultCfg
= FALSE
;
522 kmc
= psdGetCfgChunk(pic
, AROS_LONG2BE(nch
->nch_KeymapCfg
.kmc_ChunkID
));
525 CopyMem(((UBYTE
*) kmc
) + 8, ((UBYTE
*) &nch
->nch_KeymapCfg
) + 8, min(AROS_LONG2BE(kmc
->kmc_Length
), AROS_LONG2BE(nch
->nch_KeymapCfg
.kmc_Length
)));
527 nch
->nch_UsingDefaultCfg
= FALSE
;
536 /* /// "nCalcConfigCRC()" */
537 ULONG
nCalcConfigCRC(struct NepClassHid
*nch
, struct Library
*ps
, struct PsdIFFContext
*pic
)
539 ULONG
*buf
= (ULONG
*) psdWriteCfg(pic
);
543 UWORD
*ptr
= (UWORD
*) buf
;
544 ULONG len
= (AROS_LONG2BE(buf
[1]) + 8)>>1;
550 crc
= ((crc
<<1)|(crc
>>31))^(*ptr
++);
559 /* /// "nLoadBindingConfig()" */
560 BOOL
GM_UNIQUENAME(nLoadBindingConfig
)(struct NepClassHid
*nch
, BOOL gui
)
562 struct NepHidBase
*nh
= nch
->nch_ClsBase
;
564 struct ClsDevCfg
*cdc
;
565 struct KeymapCfg
*kmc
;
566 struct PsdIFFContext
*pic
;
569 KPRINTF(10, ("Loading Binding Config...\n"));
574 //GM_UNIQUENAME(nLoadClassConfig)(nh);
575 *nch
->nch_CDC
= *nh
->nh_DummyNCH
.nch_CDC
;
576 nch
->nch_KeymapCfg
= nh
->nh_DummyNCH
.nch_KeymapCfg
;
577 nch
->nch_UsingDefaultCfg
= TRUE
;
579 if(!(ps
= OpenLibrary("poseidon.library", 4)))
586 pic
= psdGetUsbDevCfg(GM_UNIQUENAME(libname
), nch
->nch_DevIDString
, nch
->nch_IfIDString
);
589 cdc
= psdGetCfgChunk(pic
, AROS_LONG2BE(nch
->nch_CDC
->cdc_ChunkID
));
592 CopyMem(((UBYTE
*) cdc
) + 8, ((UBYTE
*) nch
->nch_CDC
) + 8, min(AROS_LONG2BE(cdc
->cdc_Length
), AROS_LONG2BE(nch
->nch_CDC
->cdc_Length
)));
594 nch
->nch_UsingDefaultCfg
= FALSE
;
596 kmc
= psdGetCfgChunk(pic
, AROS_LONG2BE(nch
->nch_KeymapCfg
.kmc_ChunkID
));
599 CopyMem(((UBYTE
*) kmc
) + 8, ((UBYTE
*) &nch
->nch_KeymapCfg
) + 8, min(AROS_LONG2BE(kmc
->kmc_Length
), AROS_LONG2BE(nch
->nch_KeymapCfg
.kmc_Length
)));
601 nch
->nch_UsingDefaultCfg
= FALSE
;
603 crc
= nCalcConfigCRC(nch
, ps
, pic
);
605 if(crc
!= nch
->nch_LastCfgCRC
)
607 nch
->nch_ReloadCfg
= TRUE
;
608 nch
->nch_LastCfgCRC
= crc
;
611 Signal(nch
->nch_Task
, (1L<<nch
->nch_TaskMsgPort
->mp_SigBit
));
614 if(gui
&& !nch
->nch_HCGUITask
)
616 psdSpawnSubTask(MOD_NAME_STRING
" Control GUI", GM_UNIQUENAME(nHIDCtrlGUITask
), nch
);
624 /* /// "nOpenBindingCfgWindow()" */
625 LONG
GM_UNIQUENAME(nOpenBindingCfgWindow
)(struct NepHidBase
*nh
, struct NepClassHid
*nch
)
628 KPRINTF(10, ("Opening GUI...\n"));
629 if(!(ps
= OpenLibrary("poseidon.library", 4)))
634 if(!nch
->nch_GUITask
)
636 if((nch
->nch_GUITask
= psdSpawnSubTask(MOD_NAME_STRING
" GUI", GM_UNIQUENAME(nGUITask
), nch
)))
649 /**************************************************************************/
651 /* /// "Keymap Table" */
652 UBYTE usbkeymap
[256] =
654 0xff, 0xff, 0xff, 0xff, 0x20, 0x35, 0x33, 0x22, /* 0x00 */
655 0x12, 0x23, 0x24, 0x25, 0x17, 0x26, 0x27, 0x28, /* 0x08 */
656 0x37, 0x36, 0x18, 0x19, 0x10, 0x13, 0x21, 0x14, /* 0x10 */
657 0x16, 0x34, 0x11, 0x32, 0x15, 0x31, 0x01, 0x02, /* 0x18 */
658 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, /* 0x20 */
659 0x44, 0x45, 0x41, 0x42, 0x40, 0x0b, 0x0c, 0x1a, /* 0x28 */
660 0x1b, 0x0d, 0x2b, 0x29, 0x2a, 0x00, 0x38, 0x39, /* 0x30 */
661 0x3a, 0x62, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, /* 0x38 */
662 0x56, 0x57, 0x58, 0x59, 0x5f, 0x67, 0xff, 0xff, /* 0x40 */
663 0x6e, 0x47, 0x70, 0x48, 0x46, 0x71, 0x49, 0x4e, /* 0x48 */
664 0x4f, 0x4d, 0x4c, 0xff, 0x5c, 0x5d, 0x4a, 0x5e, /* 0x50 */
665 0x43, 0x1d, 0x1e, 0x1f, 0x2d, 0x2e, 0x2f, 0x3d, /* 0x58 */
666 0x3e, 0x3f, 0x0f, 0x3c, 0x30, 0x67, 0xff, 0xff, /* 0x60 */
667 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x68 F13-F24 */
668 0xff, 0xff, 0xff, 0xff, 0xff, 0x5f, 0xff, 0xff, /* 0x70 */
669 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x78 */
670 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x80 */
671 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x88 */
672 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x90 */
673 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x44, 0xff, /* 0x98 */
674 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xa0 */
675 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xa8 */
676 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb0 */
677 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb8 */
678 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xc0 */
679 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xc8 */
680 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xd0 */
681 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xd8 */
682 0x63, 0x60, 0x64, 0x66, 0x63, 0x61, 0x65, 0x67, /* 0xe0 */
683 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xe8 */
684 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xf0 */
685 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* 0xf8 */
691 #define ps nch->nch_Base
693 /* /// "nHidTask()" */
694 AROS_UFH0(void, GM_UNIQUENAME(nHidTask
))
698 struct NepClassHid
*nch
;
712 struct NepHidReport
*nhr
;
713 struct NepHidItem
**nhiptr
;
714 struct NepHidItem
*nhi
;
716 if((nch
= GM_UNIQUENAME(nAllocHid())))
719 if(nch
->nch_ReadySigTask
)
721 Signal(nch
->nch_ReadySigTask
, 1L<<nch
->nch_ReadySignal
);
724 sigmask
= (1L<<nch
->nch_TaskMsgPort
->mp_SigBit
)|SIGBREAKF_CTRL_C
;
726 pp
= nch
->nch_EP0Pipe
;
727 /* initial output states */
729 nhr
= (struct NepHidReport
*) nch
->nch_HidReports
.lh_Head
;
730 while(nhr
->nhr_Node
.ln_Succ
)
732 if(nhr
->nhr_OutItemCount
)
734 bufreal
= nch
->nch_EPOutBuf
;
735 if(nch
->nch_UsesReportID
)
738 psdPipeSetup(pp
, URTF_IN
|URTF_CLASS
|URTF_INTERFACE
,
739 UHR_GET_REPORT
, (ULONG
) nhr
->nhr_ReportID
|0x0200, nch
->nch_IfNum
);
741 psdPipeSetup(pp
, URTF_IN
|URTF_CLASS
|URTF_INTERFACE
,
742 UHR_GET_REPORT
, 0x0200, nch
->nch_IfNum
);
744 if((ioerr
= psdDoPipe(pp
, nch
->nch_EPOutBuf
, (nhr
->nhr_ReportOutSize
+7)>>3)))
746 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
),
747 "GET_REPORT(%lx, %ld) failed: %s (%ld)!",
748 nhr
->nhr_ReportID
|0x0200, (nhr
->nhr_ReportOutSize
+7)>>3,
749 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
751 count
= nhr
->nhr_OutItemCount
;
752 nhiptr
= nhr
->nhr_OutItemMap
;
758 nProcessItem(nch
, nhi
, bufreal
);
761 KPRINTF(10, ("Huh? report %ld, nhiptr == NULL!\n", nhr
->nhr_ReportID
));
765 nhr
= (struct NepHidReport
*) nhr
->nhr_Node
.ln_Succ
;
769 if(nch
->nch_XtraInitItem
)
771 struct NepHidAction
*nha
= (struct NepHidAction
*) nch
->nch_XtraInitItem
->nhi_ActionList
.lh_Head
;
772 while(nha
->nha_Node
.ln_Succ
)
774 KPRINTF(1, ("Executing InitItem %08lx\n", nha
));
775 nDoAction(nch
, nha
, nch
->nch_XtraInitItem
, 0, 1, TRUE
);
776 nha
= (struct NepHidAction
*) nha
->nha_Node
.ln_Succ
;
782 if(!nch
->nch_HCGUITask
)
784 psdSpawnSubTask(MOD_NAME_STRING
" Control GUI", GM_UNIQUENAME(nHIDCtrlGUITask
), nch
);
788 buf
= nch
->nch_EPInBuf
;
789 //nch->nch_CDC->cdc_PollingMode = TRUE;
790 if(!nch
->nch_HasInItems
)
792 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) GM_UNIQUENAME(libname
), "HID Device has no input items, input polling disabled.");
794 nch
->nch_ReloadCfg
= FALSE
;
795 nch
->nch_Running
= TRUE
;
796 nch
->nch_IOStarted
= FALSE
;
799 if(nch
->nch_CDC
->cdc_PollingMode
)
801 sigs
= SetSignal(0, 0);
804 sigs
= SetSignal(0, 0);
805 pp
= nch
->nch_EP0Pipe
;
806 for(rptcount
= 0; rptcount
<= nch
->nch_MaxReportID
; rptcount
++)
808 if(nch
->nch_ReportMap
[rptcount
])
810 if(nch
->nch_UsesReportID
)
812 psdPipeSetup(pp
, URTF_IN
|URTF_CLASS
|URTF_INTERFACE
,
813 UHR_GET_REPORT
, (ULONG
) rptcount
|0x0100, nch
->nch_IfNum
);
815 psdPipeSetup(pp
, URTF_IN
|URTF_CLASS
|URTF_INTERFACE
,
816 UHR_GET_REPORT
, 0x0100, nch
->nch_IfNum
);
818 ioerr
= psdDoPipe(pp
, buf
, nch
->nch_MaxInSize
);
819 if((!ioerr
) || (ioerr
== UHIOERR_RUNTPACKET
))
821 buflen
= psdGetPipeActual(pp
);
822 if(nch
->nch_UsesReportID
)
830 if(reportid
<= nch
->nch_MaxReportID
)
832 if((nhr
= nch
->nch_ReportMap
[reportid
]))
834 KPRINTF(40, ("Report %ld\n", reportid
));
835 count
= nhr
->nhr_InItemCount
;
836 nhiptr
= nhr
->nhr_InItemMap
;
841 if((nhi
= *nhiptr
++))
843 nProcessItem(nch
, nhi
, bufreal
);
845 KPRINTF(10, ("Huh? Hole in Item Lookup Map!\n"));
849 KPRINTF(10, ("Huh? report %ld, count %ld or nhiptr == NULL!\n", reportid
, count
));
852 KPRINTF(10, ("Illegal report ID %ld received!\n", reportid
));
856 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
),
857 "GET_REPORT(%lx, %ld) failed: %s (%ld)!",
858 rptcount
, nch
->nch_MaxInSize
,
859 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
860 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) GM_UNIQUENAME(libname
),
861 "Reverting back to interrupt mode instead of polling!");
863 nch
->nch_CDC
->cdc_PollingMode
= FALSE
;
866 psdSendPipe(nch
->nch_EPInPipe
, buf
, nch
->nch_MaxInSize
);
867 nch
->nch_IOStarted
= TRUE
;
873 psdDelayMS(nch
->nch_EPInInterval
);
876 if(nch
->nch_Running
&& (!nch
->nch_IOStarted
) && nch
->nch_HasInItems
)
878 psdSendPipe(nch
->nch_EPInPipe
, buf
, nch
->nch_MaxInSize
);
879 nch
->nch_IOStarted
= TRUE
;
881 sigs
= Wait(sigmask
);
882 while((pp
= (struct PsdPipe
*) GetMsg(nch
->nch_TaskMsgPort
)))
884 if(pp
== nch
->nch_EPInPipe
)
886 nch
->nch_IOStarted
= FALSE
;
887 ioerr
= psdGetPipeError(pp
);
888 if((!ioerr
) || (ioerr
== UHIOERR_RUNTPACKET
))
890 buflen
= psdGetPipeActual(pp
);
893 if(nch
->nch_WacomMode
)
895 wacomgood
= nParseWacom(nch
, buf
, buflen
);
899 // if the parser failed, use standard methods
900 if(nch
->nch_UsesReportID
)
908 if(reportid
<= nch
->nch_MaxReportID
)
910 if((nhr
= nch
->nch_ReportMap
[reportid
]))
912 KPRINTF(40, ("Report %ld\n", reportid
));
913 count
= nhr
->nhr_InItemCount
;
914 nhiptr
= nhr
->nhr_InItemMap
;
919 if((nhi
= *nhiptr
++))
921 nProcessItem(nch
, nhi
, bufreal
);
923 KPRINTF(10, ("Huh? Hole in Item Lookup Map!\n"));
927 KPRINTF(10, ("Huh? count or nhiptr == NULL!\n"));
931 KPRINTF(10, ("Illegal report ID %ld received!\n", reportid
));
935 //dumpmem(buf, buflen);
937 KPRINTF(10, ("Int Pipe failed %ld\n", ioerr
));
940 if(lastioerr
!= ioerr
)
942 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
),
943 "Interrupt pipe failed: %s (%ld)!",
944 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
950 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) GM_UNIQUENAME(libname
),
951 "That's it, that device pissed me off long enough!");
952 sigs
|= SIGBREAKF_CTRL_C
;
958 psdGetAttrs(PGA_ENDPOINT
, nch
->nch_EPIn
,
959 EA_EndpointNum
, &epnum
,
961 psdPipeSetup(nch
->nch_EP0Pipe
, URTF_STANDARD
|URTF_ENDPOINT
,
962 USR_CLEAR_FEATURE
, UFS_ENDPOINT_HALT
, (ULONG
) epnum
|URTF_IN
);
963 ioerr
= psdDoPipe(nch
->nch_EP0Pipe
, NULL
, 0);
972 if(nch
->nch_TrackEvents
|| nch
->nch_TrackKeyEvents
|| (nch
->nch_ReportValues
&& nch
->nch_ItemChanged
))
976 Signal(nch
->nch_GUITask
, (ULONG
) (1<<nch
->nch_TrackingSignal
));
979 if(!nch
->nch_HIntBase
) /* attempt to open intuition */
981 nch
->nch_HIntBase
= OpenLibrary("intuition.library", 39);
984 /* need to update prefs? */
985 if(nch
->nch_ReloadCfg
)
987 psdAddErrorMsg(RETURN_OK
, (STRPTR
) GM_UNIQUENAME(libname
), "Reloading configuration...");
989 nch
->nch_ReadySignal
= SIGB_SINGLE
;
990 nch
->nch_ReadySigTask
= FindTask(NULL
);
993 Signal(nch
->nch_GUITask
, SIGBREAKF_CTRL_C
);
996 while(nch
->nch_GUITask
)
998 Wait(1L<<nch
->nch_ReadySignal
);
1001 if(nch
->nch_HCGUITask
)
1003 Signal(nch
->nch_HCGUITask
, SIGBREAKF_CTRL_C
);
1006 while(nch
->nch_HCGUITask
)
1008 Wait(1L<<nch
->nch_ReadySignal
);
1010 //FreeSignal(nch->nch_ReadySignal);
1012 nhr
= (struct NepHidReport
*) nch
->nch_HidReports
.lh_Head
;
1013 while(nhr
->nhr_Node
.ln_Succ
)
1015 nFreeReport(nch
, nhr
);
1016 nhr
= (struct NepHidReport
*) nch
->nch_HidReports
.lh_Head
;
1018 psdFreeVec(nch
->nch_ReportMap
);
1019 nch
->nch_ReportMap
= NULL
;
1020 psdFreeVec(nch
->nch_HidDesc
);
1021 nch
->nch_HidDesc
= NULL
;
1023 if(nReadReports(nch
))
1025 nAddExtraReport(nch
);
1028 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) GM_UNIQUENAME(libname
), "Error parsing report descriptors!");
1029 sigs
|= SIGBREAKF_CTRL_C
;
1031 nch
->nch_ReloadCfg
= FALSE
;
1033 } while(!(sigs
& SIGBREAKF_CTRL_C
));
1034 if(nch
->nch_XtraQuitItem
)
1036 struct NepHidAction
*nha
= (struct NepHidAction
*) nch
->nch_XtraQuitItem
->nhi_ActionList
.lh_Head
;
1037 while(nha
->nha_Node
.ln_Succ
)
1039 nDoAction(nch
, nha
, nch
->nch_XtraQuitItem
, 0, 1, TRUE
);
1040 nha
= (struct NepHidAction
*) nha
->nha_Node
.ln_Succ
;
1044 KPRINTF(20, ("Going down the river!\n"));
1045 if(nch
->nch_IOStarted
)
1047 psdAbortPipe(nch
->nch_EPInPipe
);
1048 psdWaitPipe(nch
->nch_EPInPipe
);
1050 GM_UNIQUENAME(nFreeHid
)(nch
);
1057 /* /// "nAllocHid()" */
1058 struct NepClassHid
* GM_UNIQUENAME(nAllocHid
)(void)
1060 struct Task
*thistask
;
1061 struct NepClassHid
*nch
;
1066 thistask
= FindTask(NULL
);
1067 #undef IntuitionBase
1068 nch
= thistask
->tc_UserData
;
1070 NewList(&nch
->nch_HidReports
);
1073 if(!(nch
->nch_Base
= OpenLibrary("poseidon.library", 4)))
1078 if(!(nch
->nch_HIntBase
= OpenLibrary("intuition.library", 39)))
1080 /* we don't mind anymore */
1081 //Alert(AG_OpenLib|AO_Intuition);
1084 #define IntuitionBase nch->nch_HIntBase
1085 psdGetAttrs(PGA_INTERFACE
, nch
->nch_Interface
,
1086 IFA_Config
, &nch
->nch_Config
,
1087 IFA_InterfaceNum
, &nch
->nch_IfNum
,
1088 IFA_SubClass
, &subclass
,
1089 IFA_Protocol
, &protocol
,
1091 psdGetAttrs(PGA_CONFIG
, nch
->nch_Config
,
1092 CA_Device
, &nch
->nch_Device
,
1095 nch
->nch_EPIn
= psdFindEndpoint(nch
->nch_Interface
, NULL
,
1097 EA_TransferType
, USEAF_INTERRUPT
,
1099 nch
->nch_EPOut
= psdFindEndpoint(nch
->nch_Interface
, NULL
,
1101 EA_TransferType
, USEAF_INTERRUPT
,
1104 if((nch
->nch_InpMsgPort
= CreateMsgPort()))
1106 if((nch
->nch_InpIOReq
= (struct IOStdReq
*) CreateIORequest(nch
->nch_InpMsgPort
, sizeof(struct IOStdReq
))))
1108 if(!OpenDevice("input.device", 0, (struct IORequest
*) nch
->nch_InpIOReq
, 0))
1110 nch
->nch_InputBase
= (struct Library
*) nch
->nch_InpIOReq
->io_Device
;
1111 #define InputBase nch->nch_InputBase
1112 nch
->nch_OS4Hack
= TRUE
;
1113 nch
->nch_ClsBase
->nh_OS4Hack
= TRUE
;
1114 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) GM_UNIQUENAME(libname
),
1115 "Using AROS IND_ADDEVENT workaround to fix some mouse & keyboard problems.");
1117 if((nch
->nch_TaskMsgPort
= CreateMsgPort()))
1119 if((nch
->nch_EP0Pipe
= psdAllocPipe(nch
->nch_Device
, nch
->nch_TaskMsgPort
, NULL
)))
1121 psdSetAttrs(PGA_PIPE
, nch
->nch_EP0Pipe
,
1122 PPA_NakTimeout
, TRUE
,
1123 PPA_NakTimeoutTime
, 5000,
1127 psdGetAttrs(PGA_ENDPOINT
, nch
->nch_EPIn
,
1128 EA_Interval
, &nch
->nch_EPInInterval
,
1131 if((nch
->nch_EPInPipe
= psdAllocPipe(nch
->nch_Device
, nch
->nch_TaskMsgPort
, nch
->nch_EPIn
)))
1133 if(nch
->nch_CDC
->cdc_TurboMouse
)
1135 psdSetAttrs(PGA_PIPE
, nch
->nch_EPInPipe
,
1136 PPA_Interval
, 1<<nch
->nch_CDC
->cdc_TurboMouse
,
1137 PPA_AllowRuntPackets
, TRUE
,
1142 nch
->nch_EPInPipe
= NULL
;
1144 if(subclass
== HID_BOOT_SUBCLASS
)
1146 psdPipeSetup(nch
->nch_EP0Pipe
, URTF_CLASS
|URTF_INTERFACE
,
1147 UHR_SET_IDLE
, (ULONG
) ((protocol
== HID_PROTO_KEYBOARD
) ? 64 : 0), nch
->nch_IfNum
);
1148 ioerr
= psdDoPipe(nch
->nch_EP0Pipe
, NULL
, 0);
1151 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) GM_UNIQUENAME(libname
),
1152 "SET_IDLE=0 failed: %s (%ld)!",
1153 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
1156 psdPipeSetup(nch
->nch_EP0Pipe
, URTF_CLASS
|URTF_INTERFACE
,
1157 UHR_SET_PROTOCOL
, HID_PROTO_REPORT
, nch
->nch_IfNum
);
1158 ioerr
= psdDoPipe(nch
->nch_EP0Pipe
, NULL
, 0);
1161 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) GM_UNIQUENAME(libname
),
1162 "SET_PROTOCOL=REPORT failed: %s (%ld)!",
1163 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
1169 psdGetAttrs(PGA_ENDPOINT
, nch
->nch_EPIn
,
1170 EA_EndpointNum
, &epnum
,
1172 psdPipeSetup(nch
->nch_EP0Pipe
, URTF_STANDARD
|URTF_ENDPOINT
,
1173 USR_CLEAR_FEATURE
, UFS_ENDPOINT_HALT
, (ULONG
) epnum
|URTF_IN
);
1174 ioerr
= psdDoPipe(nch
->nch_EP0Pipe
, NULL
, 0);
1177 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) GM_UNIQUENAME(libname
),
1178 "CLEAR_ENDPOINT_HALT %ld failed: %s (%ld)",
1179 epnum
, psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
1183 nQuirkPS3Controller(nch
);
1185 if(nReadReports(nch
))
1188 nAddExtraReport(nch
);
1190 if(!nch
->nch_EPInPipe
)
1192 if(nch
->nch_HasInItems
)
1194 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
),
1195 "This device does not have an interrupt IN endpoint, but it needs one for input items!");
1198 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) GM_UNIQUENAME(libname
), "This device does not have an interrupt IN endpoint!");
1199 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) GM_UNIQUENAME(libname
), "This means it can only be used for OUTPUT, if at all. Check your HID Control window!");
1204 if((nch
->nch_EPInBuf
= psdAllocVec(nch
->nch_MaxInSize
)))
1206 if((nch
->nch_EPOutBuf
= psdAllocVec(nch
->nch_MaxReportSize
)))
1208 nch
->nch_Task
= thistask
;
1211 psdFreeVec(nch
->nch_EPInBuf
);
1215 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) GM_UNIQUENAME(libname
), "Error parsing report descriptors!");
1217 psdFreePipe(nch
->nch_EPInPipe
);
1218 psdFreePipe(nch
->nch_EP0Pipe
);
1220 DeleteMsgPort(nch
->nch_TaskMsgPort
);
1222 CloseDevice((struct IORequest
*) nch
->nch_InpIOReq
);
1224 DeleteIORequest((struct IORequest
*) nch
->nch_InpIOReq
);
1226 DeleteMsgPort(nch
->nch_InpMsgPort
);
1229 CloseLibrary(nch
->nch_HIntBase
);
1230 CloseLibrary(nch
->nch_Base
);
1232 nch
->nch_Task
= NULL
;
1233 if(nch
->nch_ReadySigTask
)
1235 Signal(nch
->nch_ReadySigTask
, 1L<<nch
->nch_ReadySignal
);
1241 /* /// "nFreeHid()" */
1242 void GM_UNIQUENAME(nFreeHid
)(struct NepClassHid
*nch
)
1244 struct NepHidReport
*nhr
;
1245 nhr
= (struct NepHidReport
*) nch
->nch_HidReports
.lh_Head
;
1246 while(nhr
->nhr_Node
.ln_Succ
)
1248 nFreeReport(nch
, nhr
);
1249 nhr
= (struct NepHidReport
*) nch
->nch_HidReports
.lh_Head
;
1251 psdFreeVec(nch
->nch_ReportMap
);
1252 psdFreeVec(nch
->nch_HidDesc
);
1253 psdFreeVec(nch
->nch_EPInBuf
);
1254 psdFreeVec(nch
->nch_EPOutBuf
);
1255 psdFreePipe(nch
->nch_EPInPipe
);
1256 psdFreePipe(nch
->nch_EP0Pipe
);
1257 DeleteMsgPort(nch
->nch_TaskMsgPort
);
1258 CloseDevice((struct IORequest
*) nch
->nch_InpIOReq
);
1259 DeleteIORequest((struct IORequest
*) nch
->nch_InpIOReq
);
1260 DeleteMsgPort(nch
->nch_InpMsgPort
);
1261 CloseLibrary(nch
->nch_HIntBase
);
1262 CloseLibrary(nch
->nch_Base
);
1264 nch
->nch_Task
= NULL
;
1265 if(nch
->nch_ReadySigTask
)
1267 Signal(nch
->nch_ReadySigTask
, 1L<<nch
->nch_ReadySignal
);
1272 /* /// "nFreeItem()" */
1273 void nFreeItem(struct NepClassHid
*nch
, struct NepHidItem
*nhi
)
1275 struct NepHidAction
*nha
;
1279 Remove(&nhi
->nhi_Node
);
1280 psdFreeVec(nhi
->nhi_UsageMap
);
1281 /* Oh, this was an array */
1282 if((lst
= nhi
->nhi_ActionMap
))
1284 /* We need to free all lists available */
1285 count
= nhi
->nhi_MapSize
;
1288 /* And each list can have several entries */
1289 nha
= (struct NepHidAction
*) lst
->lh_Head
;
1290 while(nha
->nha_Node
.ln_Succ
)
1292 Remove(&nha
->nha_Node
);
1294 nha
= (struct NepHidAction
*) lst
->lh_Head
;
1298 psdFreeVec(nhi
->nhi_ActionMap
);
1300 /* Free action list */
1301 nha
= (struct NepHidAction
*) nhi
->nhi_ActionList
.lh_Head
;
1302 while(nha
->nha_Node
.ln_Succ
)
1304 Remove(&nha
->nha_Node
);
1306 nha
= (struct NepHidAction
*) nhi
->nhi_ActionList
.lh_Head
;
1308 psdFreeVec(nhi
->nhi_Buffer
);
1313 /* /// "nCleanCollection()" */
1314 void nCleanCollection(struct NepClassHid
*nch
, struct NepHidCollection
*nhc
)
1316 struct NepHidItem
*nhi
;
1317 struct NepHidAction
*nha
;
1321 nhi
= (struct NepHidItem
*) nhc
->nhc_Items
.lh_Head
;
1322 while(nhi
->nhi_Node
.ln_Succ
)
1324 /* Oh, this was an array */
1325 if((lst
= nhi
->nhi_ActionMap
))
1327 /* We need to free all lists available */
1328 count
= nhi
->nhi_MapSize
;
1331 /* And each list can have several entries */
1332 nha
= (struct NepHidAction
*) lst
->lh_Head
;
1333 while(nha
->nha_Node
.ln_Succ
)
1335 Remove(&nha
->nha_Node
);
1337 nha
= (struct NepHidAction
*) lst
->lh_Head
;
1342 /* Free action list */
1343 nha
= (struct NepHidAction
*) nhi
->nhi_ActionList
.lh_Head
;
1344 while(nha
->nha_Node
.ln_Succ
)
1346 Remove(&nha
->nha_Node
);
1348 nha
= (struct NepHidAction
*) nhi
->nhi_ActionList
.lh_Head
;
1350 nhi
= (struct NepHidItem
*) nhi
->nhi_Node
.ln_Succ
;
1355 /* /// "nFreeReport()" */
1356 void nFreeReport(struct NepClassHid
*nch
, struct NepHidReport
*nhr
)
1358 struct NepHidCollection
*nhc
;
1359 struct NepHidItem
*nhi
;
1361 Remove(&nhr
->nhr_Node
);
1362 nhc
= (struct NepHidCollection
*) nhr
->nhr_Collections
.lh_Head
;
1363 while(nhc
->nhc_Node
.ln_Succ
)
1365 Remove(&nhc
->nhc_Node
);
1366 nhi
= (struct NepHidItem
*) nhc
->nhc_Items
.lh_Head
;
1367 while(nhi
->nhi_Node
.ln_Succ
)
1369 nFreeItem(nch
, nhi
);
1370 nhi
= (struct NepHidItem
*) nhc
->nhc_Items
.lh_Head
;
1372 psdFreeVec(nhc
->nhc_Name
);
1374 nhc
= (struct NepHidCollection
*) nhr
->nhr_Collections
.lh_Head
;
1376 psdFreeVec(nhr
->nhr_InItemMap
);
1377 psdFreeVec(nhr
->nhr_ReportBuf
);
1382 /* /// "nAddItemAction()" */
1383 void nAddItemAction(struct NepClassHid
*nch
, struct PsdIFFContext
*rppic
, struct NepHidItem
*nhi
, UWORD id
)
1385 struct NepHidCollection
*nhc
= nhi
->nhi_Collection
;
1386 NewList(&nhi
->nhi_ActionList
);
1387 SET_WTYPE(&nhi
->nhi_ActionList
, id
+ 0xf001);
1388 AddTail(&nhc
->nhc_Items
, &nhi
->nhi_Node
);
1391 if(!nLoadItem(nch
, rppic
, &nhi
->nhi_ActionList
, 0xf001))
1393 nDetectDefaultAction(nch
, nhi
, &nhi
->nhi_ActionList
, nhc
, nhi
->nhi_Usage
);
1396 nDetectDefaultAction(nch
, nhi
, &nhi
->nhi_ActionList
, nhc
, nhi
->nhi_Usage
);
1401 /* /// "nAddExtraReport()" */
1402 BOOL
nAddExtraReport(struct NepClassHid
*nch
)
1404 struct NepHidCollection
*nhc
;
1405 struct NepHidReport
*nhr
;
1406 struct NepHidItem
*nhi
;
1407 struct PsdIFFContext
*pic
;
1408 struct PsdIFFContext
*rppic
= NULL
;
1412 /* find rumble motors for rumble pack */
1413 if((item
= nFindItemUsage(nch
, 0x080045, REPORT_MAIN_OUTPUT
)))
1415 nch
->nch_RumbleMotors
[0] = nFindItemID(nch
, item
, REPORT_MAIN_OUTPUT
, &pos
);
1417 if((item
= nFindItemUsage(nch
, 0x080046, REPORT_MAIN_OUTPUT
)))
1419 nch
->nch_RumbleMotors
[1] = nFindItemID(nch
, item
, REPORT_MAIN_OUTPUT
, &pos
);
1422 pic
= psdGetUsbDevCfg(GM_UNIQUENAME(libname
), nch
->nch_DevIDString
, nch
->nch_IfIDString
);
1425 rppic
= psdFindCfgForm(pic
, MAKE_ID('X','R','P','T'));
1427 if((nhr
= psdAllocVec(sizeof(struct NepHidReport
))))
1429 NewList(&nhr
->nhr_Collections
);
1430 AddTail(&nch
->nch_HidReports
, &nhr
->nhr_Node
);
1431 nhr
->nhr_ReportID
= 0xffff;
1432 nhr
->nhr_ItemIDBase
= 0xf001;
1433 if((nhc
= psdAllocVec(sizeof(struct NepHidCollection
))))
1435 NewList(&nhc
->nhc_Items
);
1436 AddTail(&nhr
->nhr_Collections
, &nhc
->nhc_Node
);
1437 nhc
->nhc_Report
= nhr
;
1438 nhc
->nhc_Name
= psdCopyStr("[Extra]");
1439 if((nhi
= psdAllocVec(sizeof(struct NepHidItem
))))
1441 nhi
->nhi_Collection
= nhc
;
1442 nhi
->nhi_Type
= REPORT_MAIN_INPUT
;
1443 nhi
->nhi_Flags
= RPF_MAIN_VARIABLE
;
1445 nhi
->nhi_PhysicalMin
= nhi
->nhi_LogicalMin
= 0;
1446 nhi
->nhi_PhysicalMax
= nhi
->nhi_LogicalMax
= 1;
1447 nhi
->nhi_Usage
= 0x1fff0;
1448 nAddItemAction(nch
, rppic
, nhi
, 0xff0);
1449 nch
->nch_XtraInitItem
= nhi
;
1451 if((nhi
= psdAllocVec(sizeof(struct NepHidItem
))))
1453 nhi
->nhi_Collection
= nhc
;
1454 nhi
->nhi_Type
= REPORT_MAIN_INPUT
;
1455 nhi
->nhi_Flags
= RPF_MAIN_VARIABLE
;
1457 nhi
->nhi_PhysicalMin
= nhi
->nhi_LogicalMin
= 0;
1458 nhi
->nhi_PhysicalMax
= nhi
->nhi_LogicalMax
= 1;
1459 nhi
->nhi_Usage
= 0x1fff1;
1460 nAddItemAction(nch
, rppic
, nhi
, 0xff1);
1461 nch
->nch_XtraQuitItem
= nhi
;
1470 /* /// "Wacom Tables" */
1472 static struct WacomCaps WacomCapsTable
[] =
1474 { 0x0000, WACOM_PENPARTNER
, 5040, 3780, 8, "PenPartner" },
1475 { 0x0003, WACOM_PLX
, 20480, 15360, 9, "Cintiq Partner" },
1476 { 0x0010, WACOM_GRAPHIRE
, 10206, 7422, 9, "Graphire" },
1477 { 0x0011, WACOM_GRAPHIRE
, 10206, 7422, 9, "Graphire 2 4x5" },
1478 { 0x0012, WACOM_GRAPHIRE
, 13918, 10206, 9, "Graphire 2 5x7" },
1479 { 0x0013, WACOM_GRAPHIRE
, 10208, 7424, 9, "Graphire 3" },
1480 { 0x0014, WACOM_GRAPHIRE
, 16704, 12064, 9, "Graphire 3 6x8" },
1481 { 0x0015, WACOM_GRAPHIRE4
, 10208, 7424, 9, "Graphire 4 4x5" },
1482 { 0x0016, WACOM_GRAPHIRE4
, 16704, 12064, 9, "Graphire 4 6x8" },
1483 { 0x0020, WACOM_INTUOS
, 12700, 10600, 10, "Intuos 4x5" },
1484 { 0x0021, WACOM_INTUOS
, 20320, 16240, 10, "Intuos 6x8" },
1485 { 0x0022, WACOM_INTUOS
, 30480, 24060, 10, "Intuos 9x12" },
1486 { 0x0023, WACOM_INTUOS
, 30480, 31680, 10, "Intuos 12x12" },
1487 { 0x0024, WACOM_INTUOS
, 45720, 31680, 10, "Intuos 12x18" },
1488 { 0x0030, WACOM_PL
, 5408, 4056, 8, "PL-400" },
1489 { 0x0031, WACOM_PL
, 6144, 4608, 8, "PL-500" },
1490 { 0x0032, WACOM_PL
, 6126, 4604, 8, "PL-600" },
1491 { 0x0033, WACOM_PL
, 6260, 5016, 8, "PL-600 SX" },
1492 { 0x0034, WACOM_PL2
, 6144, 4608, 9, "PL-550" },
1493 { 0x0035, WACOM_PL2
, 7220, 5780, 9, "PL-800" },
1494 { 0x0037, WACOM_PL2
, 6758, 5406, 9, "PL-700" },
1495 { 0x0038, WACOM_PL2
, 6282, 4762, 9, "PL-510" },
1496 { 0x0039, WACOM_PL2
, 34080, 27660, 9, "PL-710" },
1497 { 0x003f, WACOM_CINTIQ
, 87200, 65600, 10, "Cintiq 21 UX" },
1498 { 0x0041, WACOM_INTUOS
, 12700, 10600, 10, "Intuos 2 4x5" },
1499 { 0x0042, WACOM_INTUOS
, 20320, 16240, 10, "Intuos 2 6x8" },
1500 { 0x0043, WACOM_INTUOS
, 30480, 24060, 10, "Intuos 2 9x12" },
1501 { 0x0044, WACOM_INTUOS
, 30480, 31680, 10, "Intuos 2 12x12" },
1502 { 0x0045, WACOM_INTUOS
, 45720, 31680, 10, "Intuos 2 12x18" },
1503 { 0x0047, WACOM_INTUOS
, 20320, 16240, 10, "Intuos 2 6x8" },
1504 { 0x0060, WACOM_GRAPHIRE
, 5104, 3712, 9, "Volito" },
1505 { 0x0061, WACOM_GRAPHIRE
, 3250, 2320, 8, "PenStation 2" },
1506 { 0x0062, WACOM_GRAPHIRE
, 5104, 3712, 9, "Volito 2 4x5" },
1507 { 0x0063, WACOM_GRAPHIRE
, 3248, 2320, 9, "Volito 2 2x3" },
1508 { 0x0064, WACOM_GRAPHIRE
, 3250, 2320, 8, "PenPartner 2" },
1509 { 0x00b0, WACOM_INTUOS3
, 25400, 20320, 10, "Intuos 3 4x5" },
1510 { 0x00b1, WACOM_INTUOS3
, 40640, 30480, 10, "Intuos 3 6x8" },
1511 { 0x00b2, WACOM_INTUOS3
, 60960, 45720, 10, "Intuos 3 9x12" },
1512 { 0x00b5, WACOM_INTUOS3
, 54204, 31750, 10, "Intuos 3 6x11" },
1513 { 0x00c0, WACOM_PL2
, 6858, 5506, 9, "DTF-720" },
1514 { 0xffff, 0, 0, 0, 0, NULL
}
1518 /* /// "nParseWacom()" */
1519 BOOL
nParseWacom(struct NepClassHid
*nch
, UBYTE
*buf
, ULONG len
)
1521 struct WacomReport wr
= { ~0, ~0, 0xffff, 0, 0, 0x80, 0x80, 0 };
1522 struct NepHidItem
*nhi
;
1525 KPRINTF(1, ("Wacom parsing %ld (%ld)...\n", nch
->nch_WacomMode
, len
));
1526 switch(nch
->nch_WacomMode
)
1528 case WACOM_PENPARTNER
:
1530 // 80 40 20 10 08 04 02 01
1531 // 1: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1532 // 2: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1533 // 3: yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
1534 // 4: yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
1536 // 6: [signed pressure]
1537 if((buf
[0] != 2) || (len
< 7))
1541 wr
.wr_PosX
= buf
[1] | (buf
[2]<<8);
1542 wr
.wr_PosY
= buf
[3] | (buf
[4]<<8);
1543 wr
.wr_Pressure
= (((BYTE
*) buf
)[6]) + 127;
1544 wr
.wr_InProximity
= buf
[5] & 0x20 ? 0x00 : 0xff;
1545 if(wr
.wr_InProximity
&& (wr
.wr_Pressure
> 50))
1547 wr
.wr_Buttons
= 0x01;
1551 wr
.wr_Buttons
|= 0x02;
1556 case WACOM_GRAPHIRE
:
1557 case WACOM_GRAPHIRE4
:
1559 // 80 40 20 10 08 04 02 01
1560 // 1: vld tooltype prox mmb rmb lmb
1561 // 2: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1562 // 3: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1563 // 4: yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
1564 // 5: yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
1565 // 6: [wheel bits ] G3 MOUSE
1566 // 6: [distance ] G4 MOUSE
1567 // 7: [distance ] G3 MOUSE
1568 // 7: wh_sgn wheel_bits G4 MOUSE
1569 // 6: [ pressure bits 0-7 ]
1571 if((buf
[0] != 2) || (len
< 8))
1577 wr
.wr_InProximity
= 0xff;
1578 if(buf
[1] & 0x40) // is a mouse
1580 if(buf
[1] & 0x20) // mouse without a scrollwheel
1582 // only two buttons, no wheel
1583 wr
.wr_Buttons
= buf
[1] & 0x03;
1585 // three buttons and wheel
1586 wr
.wr_Buttons
= buf
[1] & 0x07;
1587 if(nch
->nch_WacomMode
== WACOM_GRAPHIRE4
)
1589 wr
.wr_Wheel
= buf
[7] & 0x03;
1592 wr
.wr_Wheel
= -wr
.wr_Wheel
;
1595 wr
.wr_Wheel
= ((BYTE
*) buf
)[6];
1596 KPRINTF(1, ("Wheel %ld\n", wr
.wr_Wheel
));
1600 wr
.wr_Buttons
= buf
[1] & 0x07;
1601 wr
.wr_Pressure
= buf
[6] | ((buf
[7] & 0x01)<<8);
1603 wr
.wr_PosX
= buf
[2] | (buf
[3]<<8);
1604 wr
.wr_PosY
= buf
[4] | (buf
[5]<<8);
1606 wr
.wr_InProximity
= 0;
1615 // 80 40 20 10 08 04 02 01
1616 // 1: 1 1 0 0 mmb rmb tool = pen packet
1617 // 1: 1 1 1 0 0 tool = airbrush
1618 // 1: 1 1 0 1 = mouse
1619 // 1: 1 1 1 0 0 0 = lens?
1620 // 1: 1 1 0 0 0 0 = tool in
1621 // 1: 1 0 0 0 0 0 0 = tool out
1622 // 2: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1623 // 3: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1624 // 4: yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
1625 // 5: yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
1626 // 6: [ pressure/wheel bits 8-6 ]
1627 // 7: [press0-1] [ tiltx 6-1]
1628 // 8: tiltx0 [ tilty 6-0 ]
1632 wr
.wr_PadButtons
= (buf
[5] & 0x0f)|(buf
[6]<<4);
1636 if((buf
[0] != 2) && (buf
[0] != 5) && (buf
[0] != 6))
1640 // needs some improvement on the various tools
1643 wr
.wr_InProximity
= 0xff;
1644 if(nch
->nch_WacomMode
== WACOM_INTUOS
)
1646 wr
.wr_PosX
= (buf
[2]<<8) | buf
[3];
1647 wr
.wr_PosY
= (buf
[4]<<8) | buf
[5];
1650 wr
.wr_Buttons
= (buf
[8] & 0x07) | ((buf
[8] & 0x30)>>1);
1653 wr
.wr_PosX
= (buf
[2]<<9) | (buf
[3] << 1) | ((buf
[9] & 0x02)>>1);
1654 wr
.wr_PosY
= (buf
[4]<<9) | (buf
[5] << 1) | (buf
[9] & 0x01);
1656 if((buf
[1] & 0xa0) == 0xa0)
1658 wr
.wr_TiltX
= ((buf
[7] & 0x3f) << 1) | (buf
[8] >> 7);
1659 wr
.wr_TiltY
= buf
[8] & 0x7f;
1661 tmpval
= (buf
[6] << 2) | ((buf
[7] & 0xc0)>>6);
1662 if((buf
[1] & 0xb8) == 0xa0)
1664 wr
.wr_Pressure
= tmpval
;
1665 wr
.wr_Buttons
= (buf
[1] & 0x06) | ((wr
.wr_Pressure
> 16) ? 1 : 0);
1667 if((buf
[1] & 0xbc) == 0xb4)
1669 wr
.wr_Wheel
= tmpval
;
1672 wr
.wr_InProximity
= 0;
1679 if((buf
[0] != 2) || (len
< 8))
1683 wr
.wr_InProximity
= buf
[1] & 0x40 ? 0xff : 0;
1684 if(wr
.wr_InProximity
)
1686 wr
.wr_Pressure
= (BYTE
) ((buf
[7]<<1) | ((buf
[4] & 0x04)>>2));
1687 if(nch
->nch_WacomMode
== WACOM_PL2
)
1689 wr
.wr_Pressure
<<= 1;
1690 wr
.wr_Pressure
+= ((buf
[4] >> 6) & 1) + 256;
1692 wr
.wr_Pressure
+= 128;
1694 wr
.wr_PosX
= ((buf
[1] & 0x03)<<14) | ((buf
[2] & 0x7f)<<7) | (buf
[3] & 0x7f);
1695 wr
.wr_PosY
= ((buf
[4] & 0x03)<<14) | ((buf
[5] & 0x7f)<<7) | (buf
[6] & 0x7f);
1696 wr
.wr_Buttons
= (buf
[4] & 0x38)>>3;
1702 if((buf
[0] != 2) || (len
< 8))
1706 wr
.wr_InProximity
= 0xff;
1707 wr
.wr_PosX
= buf
[2] | (buf
[3]<<8);
1708 wr
.wr_PosY
= buf
[4] | (buf
[5]<<8);
1709 wr
.wr_Pressure
= buf
[6] | (buf
[7]<<8);
1712 wr
.wr_Buttons
|= 0x01;
1716 wr
.wr_Buttons
|= 0x02;
1724 wr
.wr_PosX
= AROS_LONG2LE(wr
.wr_PosX
);
1725 wr
.wr_PosY
= AROS_LONG2LE(wr
.wr_PosY
);
1726 wr
.wr_Pressure
= AROS_WORD2LE(wr
.wr_Pressure
);
1728 nhi
= (struct NepHidItem
*) nch
->nch_WacomColl
->nhc_Items
.lh_Head
;
1729 while(nhi
->nhi_Node
.ln_Succ
)
1731 nProcessItem(nch
, nhi
, (UBYTE
*) &wr
);
1732 nhi
= (struct NepHidItem
*) nhi
->nhi_Node
.ln_Succ
;
1739 /* /// "nDetectWacom()" */
1740 BOOL
nDetectWacom(struct NepClassHid
*nch
)
1742 struct NepHidCollection
*nhc
;
1743 struct NepHidReport
*nhr
;
1744 struct NepHidItem
*nhi
;
1745 struct PsdIFFContext
*pic
;
1746 struct PsdIFFContext
*rppic
= NULL
;
1747 struct WacomCaps
*wc
;
1754 psdGetAttrs(PGA_DEVICE
, nch
->nch_Device
,
1755 DA_VendorID
, &vendid
,
1756 DA_ProductID
, &prodid
,
1758 if(vendid
!= 0x056a)
1763 for(wc
= WacomCapsTable
; wc
->wc_ProdID
!= prodid
; wc
++)
1765 if(wc
->wc_ProdID
== 0xffff)
1772 case WACOM_PENPARTNER
:
1780 caps
|= WACOM_HASTILT
;
1781 case WACOM_GRAPHIRE4
:
1782 if(wc
->wc_Type
!= WACOM_INTUOS
)
1784 caps
|= WACOM_HASBUTTONS
;
1786 case WACOM_GRAPHIRE
:
1787 caps
|= WACOM_HASWHEEL
;
1791 psdAddErrorMsg(RETURN_OK
, GM_UNIQUENAME(libname
), "Adding Wacom %s support.", wc
->wc_Name
);
1793 pic
= psdGetUsbDevCfg(GM_UNIQUENAME(libname
), nch
->nch_DevIDString
, nch
->nch_IfIDString
);
1796 rppic
= psdFindCfgForm(pic
, MAKE_ID('W','C','O','M'));
1798 if((nhr
= psdAllocVec(sizeof(struct NepHidReport
))))
1800 NewList(&nhr
->nhr_Collections
);
1801 AddTail(&nch
->nch_HidReports
, &nhr
->nhr_Node
);
1802 nhr
->nhr_ReportID
= 0xfffe;
1803 nhr
->nhr_ItemIDBase
= 0xf001;
1804 if((nhc
= psdAllocVec(sizeof(struct NepHidCollection
))))
1806 NewList(&nhc
->nhc_Items
);
1807 AddTail(&nhr
->nhr_Collections
, &nhc
->nhc_Node
);
1808 nhc
->nhc_Report
= nhr
;
1809 nhc
->nhc_Usage
= 0x0d0001;
1810 nhc
->nhc_Name
= psdCopyStr("[Wacom Support]");
1811 nch
->nch_WacomColl
= nhc
;
1812 nch
->nch_WacomMode
= wc
->wc_Type
;
1814 for(butno
= 0; butno
< numbuts
; butno
++)
1816 if((nhi
= psdAllocVec(sizeof(struct NepHidItem
))))
1818 nhi
->nhi_Collection
= nhc
;
1819 nhi
->nhi_Type
= REPORT_MAIN_INPUT
;
1820 nhi
->nhi_Flags
= RPF_MAIN_VARIABLE
;
1821 nhi
->nhi_Offset
= (offsetof(struct WacomReport
, wr_Buttons
)<<3) + butno
;
1824 nhi
->nhi_PhysicalMin
= nhi
->nhi_LogicalMin
= 0;
1825 nhi
->nhi_PhysicalMax
= nhi
->nhi_LogicalMax
= 1;
1826 nhi
->nhi_Usage
= 0x090001+butno
;
1827 nAddItemAction(nch
, rppic
, nhi
, 0xfd0+butno
);
1831 if((nhi
= psdAllocVec(sizeof(struct NepHidItem
))))
1833 nhi
->nhi_Collection
= nhc
;
1834 nhi
->nhi_Type
= REPORT_MAIN_INPUT
;
1835 nhi
->nhi_Flags
= RPF_MAIN_VARIABLE
;
1836 nhi
->nhi_Offset
= offsetof(struct WacomReport
, wr_PosX
)<<3;
1837 nhi
->nhi_Size
= sizeof(((struct WacomReport
*) NULL
)->wr_PosX
)<<3;
1839 nhi
->nhi_PhysicalMin
= nhi
->nhi_LogicalMin
= 0;
1840 nhi
->nhi_PhysicalMax
= nhi
->nhi_LogicalMax
= wc
->wc_ResX
-1;
1841 nhi
->nhi_Usage
= 0x010030;
1842 nAddItemAction(nch
, rppic
, nhi
, 0xfe1);
1845 if((nhi
= psdAllocVec(sizeof(struct NepHidItem
))))
1847 nhi
->nhi_Collection
= nhc
;
1848 nhi
->nhi_Type
= REPORT_MAIN_INPUT
;
1849 nhi
->nhi_Flags
= RPF_MAIN_VARIABLE
;
1850 nhi
->nhi_Offset
= offsetof(struct WacomReport
, wr_PosY
)<<3;
1851 nhi
->nhi_Size
= sizeof(((struct WacomReport
*) NULL
)->wr_PosY
)<<3;
1853 nhi
->nhi_PhysicalMin
= nhi
->nhi_LogicalMin
= 0;
1854 nhi
->nhi_PhysicalMax
= nhi
->nhi_LogicalMax
= wc
->wc_ResY
-1;
1855 nhi
->nhi_Usage
= 0x010031;
1856 nAddItemAction(nch
, rppic
, nhi
, 0xfe2);
1859 if((caps
& WACOM_HASWHEEL
) && ((nhi
= psdAllocVec(sizeof(struct NepHidItem
)))))
1861 nhi
->nhi_Collection
= nhc
;
1862 nhi
->nhi_Type
= REPORT_MAIN_INPUT
;
1863 nhi
->nhi_Flags
= RPF_MAIN_VARIABLE
;
1864 nhi
->nhi_Offset
= offsetof(struct WacomReport
, wr_Wheel
)<<3;
1865 nhi
->nhi_Size
= sizeof(((struct WacomReport
*) NULL
)->wr_Wheel
)<<3;
1867 nhi
->nhi_PhysicalMin
= nhi
->nhi_LogicalMin
= -127;
1868 nhi
->nhi_PhysicalMax
= nhi
->nhi_LogicalMax
= 127;
1869 nhi
->nhi_IsSigned
= TRUE
;
1870 nhi
->nhi_Usage
= 0x010038;
1871 nAddItemAction(nch
, rppic
, nhi
, 0xfe0);
1874 if((nhi
= psdAllocVec(sizeof(struct NepHidItem
))))
1876 nhi
->nhi_Collection
= nhc
;
1877 nhi
->nhi_Type
= REPORT_MAIN_INPUT
;
1878 nhi
->nhi_Flags
= RPF_MAIN_VARIABLE
;
1879 nhi
->nhi_Offset
= offsetof(struct WacomReport
, wr_Pressure
)<<3;
1880 nhi
->nhi_Size
= sizeof(((struct WacomReport
*) NULL
)->wr_Pressure
)<<3;
1882 nhi
->nhi_PhysicalMin
= nhi
->nhi_LogicalMin
= 0;
1883 nhi
->nhi_PhysicalMax
= nhi
->nhi_LogicalMax
= (1UL<<wc
->wc_PressBits
)-1;
1884 nhi
->nhi_Usage
= 0x0d0030;
1885 nAddItemAction(nch
, rppic
, nhi
, 0xfe4);
1888 if((nhi
= psdAllocVec(sizeof(struct NepHidItem
))))
1890 nhi
->nhi_Collection
= nhc
;
1891 nhi
->nhi_Type
= REPORT_MAIN_INPUT
;
1892 nhi
->nhi_Flags
= RPF_MAIN_VARIABLE
;
1893 nhi
->nhi_Offset
= offsetof(struct WacomReport
, wr_InProximity
)<<3;
1896 nhi
->nhi_PhysicalMin
= nhi
->nhi_LogicalMin
= 0;
1897 nhi
->nhi_PhysicalMax
= nhi
->nhi_LogicalMax
= 1;
1898 nhi
->nhi_Usage
= 0x0d0032;
1899 nAddItemAction(nch
, rppic
, nhi
, 0xfe5);
1902 if((caps
& WACOM_HASTILT
) && ((nhi
= psdAllocVec(sizeof(struct NepHidItem
)))))
1904 nhi
->nhi_Collection
= nhc
;
1905 nhi
->nhi_Type
= REPORT_MAIN_INPUT
;
1906 nhi
->nhi_Flags
= RPF_MAIN_VARIABLE
;
1907 nhi
->nhi_Offset
= offsetof(struct WacomReport
, wr_TiltX
)<<3;
1908 nhi
->nhi_Size
= sizeof(((struct WacomReport
*) NULL
)->wr_TiltX
)<<3;
1910 nhi
->nhi_PhysicalMin
= nhi
->nhi_LogicalMin
= 0;
1911 nhi
->nhi_PhysicalMax
= nhi
->nhi_LogicalMax
= 127;
1912 nhi
->nhi_Usage
= 0x0d003d;
1913 nAddItemAction(nch
, rppic
, nhi
, 0xfe6);
1916 if((caps
& WACOM_HASTILT
) && ((nhi
= psdAllocVec(sizeof(struct NepHidItem
)))))
1918 nhi
->nhi_Collection
= nhc
;
1919 nhi
->nhi_Type
= REPORT_MAIN_INPUT
;
1920 nhi
->nhi_Flags
= RPF_MAIN_VARIABLE
;
1921 nhi
->nhi_Offset
= offsetof(struct WacomReport
, wr_TiltY
)<<3;
1922 nhi
->nhi_Size
= sizeof(((struct WacomReport
*) NULL
)->wr_TiltY
)<<3;
1924 nhi
->nhi_PhysicalMin
= nhi
->nhi_LogicalMin
= 0;
1925 nhi
->nhi_PhysicalMax
= nhi
->nhi_LogicalMax
= 127;
1926 nhi
->nhi_Usage
= 0x0d003e;
1927 nAddItemAction(nch
, rppic
, nhi
, 0xfe7);
1930 if(caps
& WACOM_HASBUTTONS
)
1932 for(butno
= 0; butno
< 8; butno
++)
1934 if((nhi
= psdAllocVec(sizeof(struct NepHidItem
))))
1936 nhi
->nhi_Collection
= nhc
;
1937 nhi
->nhi_Type
= REPORT_MAIN_INPUT
;
1938 nhi
->nhi_Flags
= RPF_MAIN_VARIABLE
;
1939 nhi
->nhi_Offset
= (offsetof(struct WacomReport
, wr_PadButtons
)<<3) + butno
;
1942 nhi
->nhi_PhysicalMin
= nhi
->nhi_LogicalMin
= 0;
1943 nhi
->nhi_PhysicalMax
= nhi
->nhi_LogicalMax
= 1;
1944 nhi
->nhi_Usage
= 0x090009+butno
;
1945 nAddItemAction(nch
, rppic
, nhi
, 0xfd8+butno
);
1956 /* /// "nQuirkPS3Controller()" */
1957 void nQuirkPS3Controller(struct NepClassHid
*nch
)
1965 psdGetAttrs(PGA_DEVICE
, nch
->nch_Device
,
1966 DA_VendorID
, &vendid
,
1967 DA_ProductID
, &prodid
,
1970 if(vendid
== 0x054c && prodid
== 0x0268) {
1971 psdPipeSetup(nch
->nch_EP0Pipe
, URTF_IN
|URTF_CLASS
|URTF_INTERFACE
, UHR_GET_REPORT
, 0x03f2, nch
->nch_IfNum
);
1972 ioerr
= psdDoPipe(nch
->nch_EP0Pipe
, buf
, sizeof(buf
));
1974 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) GM_UNIQUENAME(libname
), "Unable to add PS3 controller support!");
1976 psdAddErrorMsg(RETURN_OK
, GM_UNIQUENAME(libname
), "Adding PS3 controller support.");
1982 /* /// "nReadReports()" */
1983 BOOL
nReadReports(struct NepClassHid
*nch
)
1985 struct NepHidReport
*nhr
;
1986 struct NepHidCollection
*nhc
;
1987 struct NepHidItem
*nhi
;
1988 struct PsdDescriptor
*pdd
;
1999 struct List
*alistptr
;
2002 pdd
= psdFindDescriptor(nch
->nch_Device
, NULL
,
2003 DDA_DescriptorType
, UDT_HID
,
2004 DDA_Interface
, nch
->nch_Interface
,
2009 psdGetAttrs(PGA_DESCRIPTOR
, pdd
,
2010 DDA_DescriptorData
, &descdata
,
2013 actlen
= descdata
[0];
2014 memcpy(buf
, descdata
, (size_t) actlen
);
2016 psdAddErrorMsg(RETURN_OK
, (STRPTR
) GM_UNIQUENAME(libname
),
2017 "Using HID Descriptor from initial configuration run.");
2019 psdPipeSetup(nch
->nch_EP0Pipe
, URTF_IN
|URTF_STANDARD
|URTF_INTERFACE
,
2020 USR_GET_DESCRIPTOR
, UDT_HID
<<8, nch
->nch_IfNum
);
2021 ioerr
= psdDoPipe(nch
->nch_EP0Pipe
, buf
, 256);
2022 if(ioerr
== UHIOERR_RUNTPACKET
)
2028 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) GM_UNIQUENAME(libname
),
2029 "GET_HID_DESCRIPTOR(%ld) failed: %s (%ld)!",
2030 256, psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
2032 ioerr
= psdDoPipe(nch
->nch_EP0Pipe
, buf
, 256);
2033 if(ioerr
== UHIOERR_RUNTPACKET
)
2039 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) GM_UNIQUENAME(libname
),
2040 "GET_HID_DESCRIPTOR(%ld) (2nd) failed: %s (%ld)!",
2041 256, psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
2042 psdPipeSetup(nch
->nch_EP0Pipe
, URTF_IN
|URTF_STANDARD
|URTF_INTERFACE
,
2043 USR_GET_DESCRIPTOR
, UDT_HID
<<8, nch
->nch_IfNum
);
2044 ioerr
= psdDoPipe(nch
->nch_EP0Pipe
, buf
, 1);
2047 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) GM_UNIQUENAME(libname
),
2048 "GET_HID_DESCRIPTOR(%ld) (3rd) failed: %s (%ld)!",
2049 1, psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
2052 psdAddErrorMsg(RETURN_OK
, (STRPTR
) GM_UNIQUENAME(libname
), "Burstroem retry successful ;)");
2055 actlen
= psdGetPipeActual(nch
->nch_EP0Pipe
);
2057 if((!ioerr
) || (ioerr
== UHIOERR_OVERFLOW
))
2061 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) GM_UNIQUENAME(libname
),
2062 "bLength field (%ld) probably wrong, fixing to %ld!",
2068 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
),
2069 "Read less than 6 bytes (%ld read) for HID Descriptor!",
2072 if((nch
->nch_HidDesc
= psdAllocVec((ULONG
) buf
[0])))
2074 /*ioerr = psdDoPipe(nch->nch_EP0Pipe, nch->nch_HidDesc, (ULONG) buf[0]);
2077 psdAddErrorMsg(RETURN_WARN, (STRPTR) GM_UNIQUENAME(libname),
2078 "GET_HID_DESCRIPTOR(%ld) failed: %s (%ld)!",
2079 buf[0], psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
2081 ioerr = psdDoPipe(nch->nch_EP0Pipe, nch->nch_HidDesc, (ULONG) buf[0]);
2084 psdAddErrorMsg(RETURN_OK, (STRPTR) GM_UNIQUENAME(libname), "Burstroem retry successful ;)");
2089 CopyMem(buf
, nch
->nch_HidDesc
, (ULONG
) buf
[0]);
2090 //dumpmem(nch->nch_HidDesc, (ULONG) buf);
2091 if(!nch
->nch_HidDesc
->bNumDescriptors
)
2093 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
),
2094 "Device reports that it doesn't have any descriptors!");
2095 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
),
2096 "Debug info: %ld, %02lx, %02lx, %ld, %ld, %02lx, %ld, %ld!",
2097 nch
->nch_HidDesc
->bLength
,
2098 nch
->nch_HidDesc
->bDescriptorType
,
2099 nch
->nch_HidDesc
->bcdHID
,
2100 nch
->nch_HidDesc
->bCountryCode
,
2101 nch
->nch_HidDesc
->bNumDescriptors
,
2102 nch
->nch_HidDesc
->bDescType
,
2103 nch
->nch_HidDesc
->wDescLength
,
2104 nch
->nch_HidDesc
->wPad0
);
2106 if(6 + nch
->nch_HidDesc
->bNumDescriptors
*3 > actlen
)
2108 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
),
2109 "Too few bytes read for HID %ld descriptor (%ld of %ld)!",
2110 nch
->nch_HidDesc
->bNumDescriptors
,
2112 6 + nch
->nch_HidDesc
->bNumDescriptors
*3);
2113 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
),
2114 "Debug info: %ld, %02lx, %02lx, %ld, %ld, %02lx, %ld, %ld!",
2115 nch
->nch_HidDesc
->bLength
,
2116 nch
->nch_HidDesc
->bDescriptorType
,
2117 nch
->nch_HidDesc
->bcdHID
,
2118 nch
->nch_HidDesc
->bCountryCode
,
2119 nch
->nch_HidDesc
->bNumDescriptors
,
2120 nch
->nch_HidDesc
->bDescType
,
2121 nch
->nch_HidDesc
->wDescLength
,
2122 nch
->nch_HidDesc
->wPad0
);
2125 KPRINTF(1, ("%ld Report descriptors\n", nch
->nch_HidDesc
->bNumDescriptors
));
2126 bptr
= &nch
->nch_HidDesc
->bDescType
;
2127 for(num
= 0; num
< nch
->nch_HidDesc
->bNumDescriptors
; num
++)
2129 if(*bptr
== UDT_REPORT
)
2131 if((nhr
= psdAllocVec(sizeof(struct NepHidReport
))))
2133 NewList(&nhr
->nhr_Collections
);
2134 AddTail(&nch
->nch_HidReports
, &nhr
->nhr_Node
);
2136 nhr
->nhr_ReportLength
= bptr
[1] + (bptr
[2]<<8);
2137 if(!nhr
->nhr_ReportLength
)
2139 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
),
2140 "Report Descriptor #%ld is said to have 0 bytes!",
2143 if((nhr
->nhr_ReportBuf
= psdAllocVec(nhr
->nhr_ReportLength
)))
2145 psdPipeSetup(nch
->nch_EP0Pipe
, URTF_IN
|URTF_STANDARD
|URTF_INTERFACE
,
2146 USR_GET_DESCRIPTOR
, (UDT_REPORT
<<8)|num
, nch
->nch_IfNum
);
2147 ioerr
= psdDoPipe(nch
->nch_EP0Pipe
, nhr
->nhr_ReportBuf
, nhr
->nhr_ReportLength
);
2150 //dumpmem(nhr->nhr_ReportBuf, nhr->nhr_ReportLength);
2151 thisres
= nParseReport(nch
, nhr
);
2152 //nDebugReport(nch, nhr);
2155 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
),
2156 "GET_REPORT_DESCRIPTOR(%ld) failed: %s (%ld)!",
2157 nhr
->nhr_ReportLength
, psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
2163 nFreeReport(nch
, nhr
);
2170 psdAddErrorMsg(RETURN_ERROR, (STRPTR) GM_UNIQUENAME(libname),
2171 "GET_HID_DESCRIPTOR(%ld) failed: %s (%ld)!",
2172 buf[0], psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
2175 KPRINTF(1, ("No Hid Descriptor memory!\n"));
2178 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
),
2179 "GET_HID_DESCRIPTOR(%ld) failed: %s (%ld)!",
2180 256, psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
2185 /* Get maximal package size */
2186 nch
->nch_MaxReportID
= 0;
2187 nch
->nch_MaxInSize
= 0;
2188 nch
->nch_MaxOutSize
= 0;
2189 nch
->nch_MaxFeatSize
= 0;
2190 nhr
= (struct NepHidReport
*) nch
->nch_HidReports
.lh_Head
;
2191 while(nhr
->nhr_Node
.ln_Succ
)
2193 KPRINTF(5, ("Report %ld: InBits=%ld, OutBits=%ld, FeatBits=%ld\n",
2194 nhr
->nhr_ReportID
, nhr
->nhr_ReportInSize
,
2195 nhr
->nhr_ReportOutSize
, nhr
->nhr_ReportFeatSize
));
2196 if(nhr
->nhr_ReportID
)
2198 nch
->nch_UsesReportID
= TRUE
;
2199 if(nch
->nch_MaxReportID
< nhr
->nhr_ReportID
)
2201 nch
->nch_MaxReportID
= nhr
->nhr_ReportID
;
2204 repsize
= (nhr
->nhr_ReportInSize
+7)>>3;
2205 if(nch
->nch_MaxInSize
< repsize
)
2207 nch
->nch_MaxInSize
= repsize
;
2209 repsize
= (nhr
->nhr_ReportOutSize
+7)>>3;
2210 if(nch
->nch_MaxOutSize
< repsize
)
2212 nch
->nch_MaxOutSize
= repsize
;
2214 repsize
= (nhr
->nhr_ReportFeatSize
+7)>>3;
2215 if(nch
->nch_MaxFeatSize
< repsize
)
2217 nch
->nch_MaxFeatSize
= repsize
;
2219 nhr
= (struct NepHidReport
*) nhr
->nhr_Node
.ln_Succ
;
2221 if(nch
->nch_UsesReportID
)
2223 nch
->nch_MaxInSize
++;
2224 nch
->nch_MaxOutSize
++;
2225 nch
->nch_MaxFeatSize
++;
2228 nch
->nch_MaxReportSize
= nch
->nch_MaxInSize
;
2229 if(nch
->nch_MaxOutSize
> nch
->nch_MaxReportSize
)
2231 nch
->nch_MaxReportSize
= nch
->nch_MaxOutSize
;
2233 if(nch
->nch_MaxFeatSize
> nch
->nch_MaxReportSize
)
2235 nch
->nch_MaxReportSize
= nch
->nch_MaxFeatSize
;
2238 KPRINTF(5, ("MaxReportID=%ld, MaxReportSize=%ld\n", nch
->nch_MaxReportID
, nch
->nch_MaxReportSize
));
2240 if((nch
->nch_ReportMap
= psdAllocVec((ULONG
) sizeof(struct NepHidReport
*) * (nch
->nch_MaxReportID
+1))))
2242 /* Fill in Report Map */
2243 nhr
= (struct NepHidReport
*) nch
->nch_HidReports
.lh_Head
;
2244 while(nhr
->nhr_Node
.ln_Succ
)
2246 KPRINTF(5, ("Report Map slot %ld/%ld filled with %08lx\n", nhr
->nhr_ReportID
, nch
->nch_MaxReportID
, nhr
));
2247 nch
->nch_ReportMap
[nhr
->nhr_ReportID
] = nhr
;
2248 nhr
= (struct NepHidReport
*) nhr
->nhr_Node
.ln_Succ
;
2251 KPRINTF(10, ("Out of memory for Report Map!\n"));
2258 struct NepHidItem
**nhiptr
;
2259 struct NepHidItem
**nhiinptr
;
2260 struct NepHidItem
**nhioutptr
;
2261 struct NepHidItem
**nhifeatptr
;
2265 nhr
= (struct NepHidReport
*) nch
->nch_HidReports
.lh_Head
;
2266 while(nhr
->nhr_Node
.ln_Succ
)
2268 KPRINTF(1, ("Report %ld:\n", nhr
->nhr_ReportID
));
2269 nhr
->nhr_ItemIDBase
= idnum
;
2270 nhr
->nhr_InItemCount
= nhr
->nhr_OutItemCount
= nhr
->nhr_FeatItemCount
= 0;
2271 nhc
= (struct NepHidCollection
*) nhr
->nhr_Collections
.lh_Head
;
2272 while(nhc
->nhc_Node
.ln_Succ
)
2274 KPRINTF(1, (" Collection %s:\n", nhc
->nhc_Name
));
2275 nhi
= (struct NepHidItem
*) nhc
->nhc_Items
.lh_Head
;
2276 while(nhi
->nhi_Node
.ln_Succ
)
2278 switch(nhi
->nhi_Type
)
2280 case REPORT_MAIN_INPUT
:
2281 KPRINTF(1, (" Input Item %lx:\n", nhi
->nhi_Usage
));
2282 nhr
->nhr_InItemCount
++;
2285 case REPORT_MAIN_OUTPUT
:
2286 KPRINTF(1, (" Output Item %lx:\n", nhi
->nhi_Usage
));
2287 nhr
->nhr_OutItemCount
++;
2290 case REPORT_MAIN_FEATURE
:
2291 KPRINTF(1, (" Feature Item %lx:\n", nhi
->nhi_Usage
));
2292 nhr
->nhr_FeatItemCount
++;
2296 // generate id numbers
2297 SET_WTYPE(&nhi
->nhi_ActionList
, idnum
++);
2298 if(!(nhi
->nhi_Flags
& RPF_MAIN_VARIABLE
))
2300 alistptr
= nhi
->nhi_ActionMap
;
2301 count
= nhi
->nhi_MapSize
;
2304 SET_WTYPE(alistptr
, idnum
++);
2309 nhi
= (struct NepHidItem
*) nhi
->nhi_Node
.ln_Succ
;
2311 nhc
= (struct NepHidCollection
*) nhc
->nhc_Node
.ln_Succ
;
2313 /*psdAddErrorMsg(RETURN_OK, (STRPTR) GM_UNIQUENAME(libname),
2314 "R=%02lx: %ld input items, %ld output items, %ld feature items, %ld items total!",
2315 nhr->nhr_ReportID, nhr->nhr_InItemCount, nhr->nhr_OutItemCount, nhr->nhr_FeatItemCount,
2317 nhr
= (struct NepHidReport
*) nhr
->nhr_Node
.ln_Succ
;
2320 /* Create quick item lookup table */
2321 nhr
= (struct NepHidReport
*) nch
->nch_HidReports
.lh_Head
;
2322 while(nhr
->nhr_Node
.ln_Succ
)
2324 KPRINTF(1, ("Report %ld, allocating %ld/%ld/%ld items\n",
2326 nhr
->nhr_InItemCount
, nhr
->nhr_OutItemCount
, nhr
->nhr_FeatItemCount
));
2327 if((nhiptr
= psdAllocVec(sizeof(struct NepHidItem
*) * (nhr
->nhr_InItemCount
+
2328 nhr
->nhr_OutItemCount
+ nhr
->nhr_FeatItemCount
))))
2330 nhiinptr
= nhr
->nhr_InItemMap
= nhiptr
;
2331 nhioutptr
= nhr
->nhr_OutItemMap
= &nhiptr
[nhr
->nhr_InItemCount
];
2332 nhifeatptr
= nhr
->nhr_FeatItemMap
= &nhioutptr
[nhr
->nhr_OutItemCount
];
2333 nhc
= (struct NepHidCollection
*) nhr
->nhr_Collections
.lh_Head
;
2334 while(nhc
->nhc_Node
.ln_Succ
)
2336 nhi
= (struct NepHidItem
*) nhc
->nhc_Items
.lh_Head
;
2338 while(nhi
->nhi_Node
.ln_Succ
)
2340 /* Add quick lookup entry */
2341 switch(nhi
->nhi_Type
)
2343 case REPORT_MAIN_INPUT
:
2345 nch
->nch_HasInItems
= TRUE
;
2348 case REPORT_MAIN_OUTPUT
:
2352 case REPORT_MAIN_FEATURE
:
2353 *nhifeatptr
++ = nhi
;
2356 nhi
= (struct NepHidItem
*) nhi
->nhi_Node
.ln_Succ
;
2358 nhc
= (struct NepHidCollection
*) nhc
->nhc_Node
.ln_Succ
;
2363 nhr
= (struct NepHidReport
*) nhr
->nhr_Node
.ln_Succ
;
2366 nLoadActionConfig(nch
);
2372 /* /// "nLoadActionConfig()" */
2373 void nLoadActionConfig(struct NepClassHid
*nch
)
2375 struct NepHidReport
*nhr
;
2376 struct NepHidCollection
*nhc
;
2377 struct NepHidItem
*nhi
;
2380 struct List
*alistptr
;
2382 struct PsdIFFContext
*pic
;
2383 struct PsdIFFContext
*rppic
;
2385 pic
= psdGetUsbDevCfg(GM_UNIQUENAME(libname
), nch
->nch_DevIDString
, nch
->nch_IfIDString
);
2388 nch
->nch_LastCfgCRC
= nCalcConfigCRC(nch
, nch
->nch_Base
, pic
);
2390 nch
->nch_LastCfgCRC
= 0;
2393 /* Create default action mapping */
2394 nhr
= (struct NepHidReport
*) nch
->nch_HidReports
.lh_Head
;
2395 while(nhr
->nhr_Node
.ln_Succ
)
2397 KPRINTF(1, ("Report %ld:\n", nhr
->nhr_ReportID
));
2400 rppic
= psdFindCfgForm(pic
, MAKE_ID('R','P','T','0')+nhr
->nhr_ReportID
);
2404 nhc
= (struct NepHidCollection
*) nhr
->nhr_Collections
.lh_Head
;
2405 while(nhc
->nhc_Node
.ln_Succ
)
2407 KPRINTF(1, (" Collection %s:\n", nhc
->nhc_Name
));
2408 nhi
= (struct NepHidItem
*) nhc
->nhc_Items
.lh_Head
;
2409 while(nhi
->nhi_Node
.ln_Succ
)
2411 usageptr
= &nhi
->nhi_Usage
;
2412 alistptr
= &nhi
->nhi_ActionList
;
2415 if(!(nLoadItem(nch
, rppic
, alistptr
, nhr
->nhr_ItemIDBase
)))
2417 nDetectDefaultAction(nch
, nhi
, alistptr
, nhc
, *usageptr
);
2420 nDetectDefaultAction(nch
, nhi
, alistptr
, nhc
, *usageptr
);
2423 if(nhi
->nhi_Flags
& RPF_MAIN_VARIABLE
)
2425 KPRINTF(1, (" Variable %lx: %s\n", nhi
->nhi_Usage
, nNumToStr(nch
, NTS_USAGEID
, nhi
->nhi_Usage
, "unknown")));
2427 usageptr
= nhi
->nhi_UsageMap
;
2428 alistptr
= nhi
->nhi_ActionMap
;
2429 count
= nhi
->nhi_MapSize
;
2430 KPRINTF(1, (" Array %lx: %s\n", *usageptr
, nNumToStr(nch
, NTS_USAGEID
, *usageptr
, "unknown")));
2435 if(!(nLoadItem(nch
, rppic
, alistptr
, nhr
->nhr_ItemIDBase
)))
2437 nDetectDefaultAction(nch
, nhi
, alistptr
, nhc
, *usageptr
);
2440 nDetectDefaultAction(nch
, nhi
, alistptr
, nhc
, *usageptr
);
2446 nhi
= (struct NepHidItem
*) nhi
->nhi_Node
.ln_Succ
;
2448 nhc
= (struct NepHidCollection
*) nhc
->nhc_Node
.ln_Succ
;
2450 nhr
= (struct NepHidReport
*) nhr
->nhr_Node
.ln_Succ
;
2455 /* /// "nDebugMem()" */
2456 void nDebugMem(struct NepClassHid
*nch
, UBYTE
*rptr
, ULONG rptlen
)
2486 } while(cnt
&& rptlen
);
2488 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) GM_UNIQUENAME(libname
), fmtstr
, pos
,
2489 rptr
[0], rptr
[1], rptr
[2], rptr
[3], rptr
[4], rptr
[5], rptr
[6], rptr
[7],
2490 rptr
[8], rptr
[9], rptr
[10], rptr
[11], rptr
[12], rptr
[13], rptr
[14], rptr
[15]);
2497 /* /// "nDebugReport()" */
2498 void nDebugReport(struct NepClassHid
*nch
, struct NepHidReport
*nhr
)
2504 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) GM_UNIQUENAME(libname
), "Can't debug HID Report: nhr=NULL!\n");
2507 rptr
= nhr
->nhr_ReportBuf
;
2508 rptlen
= nhr
->nhr_ReportLength
;
2511 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) GM_UNIQUENAME(libname
), "Can't debug HID Report: ReportBuf=NULL!\n");
2515 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) GM_UNIQUENAME(libname
),
2516 "HID Report %02lx Debug (%ld bytes):", nhr
->nhr_ReportID
, rptlen
);
2517 nDebugMem(nch
, rptr
, rptlen
);
2521 /* /// "nParseReport()" */
2522 BOOL
nParseReport(struct NepClassHid
*nch
, struct NepHidReport
*nhr
)
2524 UBYTE
*rptr
= nhr
->nhr_ReportBuf
;
2525 UBYTE
*rptrend
= &nhr
->nhr_ReportBuf
[nhr
->nhr_ReportLength
];
2526 struct NepHidCollection
*nhc
= NULL
;
2534 ULONG usageid
, designid
, stringid
;
2535 ULONG usagemin
, usagemax
;
2536 ULONG designmin
, designmax
;
2537 ULONG stringmin
, stringmax
;
2544 NewList(&nch
->nch_HidStack
);
2545 NewList(&nch
->nch_HidUsages
);
2546 NewList(&nch
->nch_HidDesigns
);
2547 NewList(&nch
->nch_HidStrings
);
2549 nch
->nch_HidGlobal
.nhg_UsagePage
=
2550 nch
->nch_HidGlobal
.nhg_LogicalMin
=
2551 nch
->nch_HidGlobal
.nhg_LogicalMax
=
2552 nch
->nch_HidGlobal
.nhg_PhysicalMin
=
2553 nch
->nch_HidGlobal
.nhg_PhysicalMax
=
2554 nch
->nch_HidGlobal
.nhg_UnitExp
=
2555 nch
->nch_HidGlobal
.nhg_Unit
= HID_PARAM_UNDEF
;
2557 nch
->nch_HidGlobal
.nhg_ReportID
=
2558 nch
->nch_HidGlobal
.nhg_ReportSize
=
2559 nch
->nch_HidGlobal
.nhg_ReportCount
= 0;
2561 usagemin
= usagemax
=
2562 designmin
= designmax
=
2563 stringmin
= stringmax
= HID_PARAM_UNDEF
;
2565 KPRINTF(1, ("Starting parsing...\n"));
2566 /* Parse the items */
2567 while(rptr
&& (rptr
< rptrend
))
2569 reportpos
= ((IPTR
) rptr
) - ((IPTR
) nhr
->nhr_ReportBuf
);
2570 itag
= *rptr
& REPORT_ITAG_MASK
;
2571 isize
= *rptr
& REPORT_ISIZE_MASK
;
2572 itype
= *rptr
& REPORT_ITYPE_MASK
;
2573 if(*rptr
++ == REPORT_LONGITEM
) /* Is this a long item? */
2578 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) GM_UNIQUENAME(libname
),
2579 "HID Error at %04lx: Long items (%lx, len=%ld) are not specified in the spec!", reportpos
, itag
, len
);
2583 case REPORT_ISIZE_0
:
2588 case REPORT_ISIZE_1
:
2590 data
= *((BYTE
*) rptr
);
2594 case REPORT_ISIZE_2
:
2596 udata
= data
= *rptr
++;
2597 data
|= (*((BYTE
*) rptr
))<<8;
2598 udata
|= (*rptr
++)<<8;
2601 case REPORT_ISIZE_4
:
2604 data
|= (*rptr
++)<<8;
2605 data
|= (*rptr
++)<<16;
2606 data
|= (*rptr
++)<<24;
2613 case REPORT_ITYPE_MAIN
:
2614 //KPRINTF(1, ("Main "));
2615 if(reportid
!= nch
->nch_HidGlobal
.nhg_ReportID
)
2617 struct NepHidReport
*oldnhr
= nhr
;
2620 nhr
= (struct NepHidReport
*) nch
->nch_HidReports
.lh_Head
;
2621 while(nhr
->nhr_Node
.ln_Succ
)
2623 if(nhr
->nhr_ReportID
== nch
->nch_HidGlobal
.nhg_ReportID
)
2627 nhr
= (struct NepHidReport
*) nhr
->nhr_Node
.ln_Succ
;
2629 if(!nhr
->nhr_Node
.ln_Succ
)
2631 if((nhr
= psdAllocVec(sizeof(struct NepHidReport
))))
2633 KPRINTF(1, ("Generating new report ID %ld\n", nch
->nch_HidGlobal
.nhg_ReportID
));
2634 NewList(&nhr
->nhr_Collections
);
2635 nhr
->nhr_ReportID
= nch
->nch_HidGlobal
.nhg_ReportID
;
2636 AddTail(&nch
->nch_HidReports
, &nhr
->nhr_Node
);
2638 KPRINTF(1, ("Out of memory creating new report.\n"));
2643 KPRINTF(1, ("Switched back to report ID %ld\n", nch
->nch_HidGlobal
.nhg_ReportID
));
2647 KPRINTF(1, ("Collection open, checking need for cloning.\n"));
2648 if(nhc
->nhc_Items
.lh_Head
->ln_Succ
)
2650 struct NepHidCollection
*tmpnhc
;
2651 struct NepHidCollection
*newnhc
;
2652 struct NepHidCollection
*childnhc
= NULL
;
2654 KPRINTF(1, ("Not empty, assigning collection to current report and cloning!\n"));
2659 KPRINTF(1, ("Cloning %08lx (%s)\n", tmpnhc
, tmpnhc
->nhc_Name
));
2660 if((newnhc
= psdAllocVec(sizeof(struct NepHidCollection
))))
2666 NewList(&newnhc
->nhc_Items
);
2669 childnhc
->nhc_Parent
= newnhc
;
2671 newnhc
->nhc_Usage
= tmpnhc
->nhc_Usage
;
2672 newnhc
->nhc_Name
= psdCopyStr(tmpnhc
->nhc_Name
);
2674 KPRINTF(10, ("Out of memory cloning nhc!\n"));
2677 AddTail(&oldnhr
->nhr_Collections
, &tmpnhc
->nhc_Node
);
2678 tmpnhc
->nhc_Report
= oldnhr
;
2680 } while((tmpnhc
= nhc
->nhc_Parent
));
2684 KPRINTF(1, ("Setting first report ID %ld\n", nch
->nch_HidGlobal
.nhg_ReportID
));
2685 nhr
->nhr_ReportID
= nch
->nch_HidGlobal
.nhg_ReportID
;
2687 reportid
= nch
->nch_HidGlobal
.nhg_ReportID
;
2691 case REPORT_MAIN_INPUT
:
2692 bitpos
= nhr
->nhr_ReportInSize
;
2694 case REPORT_MAIN_OUTPUT
:
2695 bitpos
= nhr
->nhr_ReportOutSize
;
2697 case REPORT_MAIN_FEATURE
:
2698 bitpos
= nhr
->nhr_ReportFeatSize
;
2703 case REPORT_MAIN_INPUT
:
2704 case REPORT_MAIN_OUTPUT
:
2705 case REPORT_MAIN_FEATURE
:
2707 struct NepHidItem
*nhi
;
2708 struct NepHidUsage
*nhu
;
2709 BOOL fakelogmin
= FALSE
;
2710 BOOL fakelogmax
= FALSE
;
2713 KPRINTF(1, ("%s (%lx)\n", (itag
== REPORT_MAIN_INPUT
) ? "Input" : ((itag
== REPORT_MAIN_OUTPUT
) ? "Output" : "Feature"), udata
));
2716 KPRINTF(10, ("No collection open!\n"));
2717 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) GM_UNIQUENAME(libname
),
2718 "HID Error at %04lx: No collection open!", reportpos
);
2719 nDebugReport(nch
, nhr
);
2723 if(nch
->nch_HidGlobal
.nhg_LogicalMin
== HID_PARAM_UNDEF
)
2725 nch
->nch_HidGlobal
.nhg_LogicalMin
= 0;
2727 if(nch
->nch_HidGlobal
.nhg_LogicalMax
== HID_PARAM_UNDEF
)
2730 if(nch
->nch_HidGlobal
.nhg_ReportSize
< 32)
2732 nch
->nch_HidGlobal
.nhg_LogicalMax
= (1UL<<nch
->nch_HidGlobal
.nhg_ReportSize
)-1;
2734 nch
->nch_HidGlobal
.nhg_LogicalMin
= 0x80000000;
2735 nch
->nch_HidGlobal
.nhg_LogicalMax
= 0x7fffffff;
2737 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
),
2738 "HID Error at %04lx: LogicalMin and Max for item missing, assuming %ld-%ld (%ld)!",
2740 nch
->nch_HidGlobal
.nhg_LogicalMin
,
2741 nch
->nch_HidGlobal
.nhg_LogicalMax
);
2743 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
),
2744 "HID Error at %04lx: LogicalMin for item missing, assuming 0!", reportpos
);
2747 else if(nch
->nch_HidGlobal
.nhg_LogicalMax
== HID_PARAM_UNDEF
)
2750 nch
->nch_HidGlobal
.nhg_LogicalMax
= (1UL<<nch
->nch_HidGlobal
.nhg_ReportSize
)-1;
2751 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
),
2752 "HID Error at %04lx: LogicalMax for item missing, assuming %ld!", reportpos
, nch
->nch_HidGlobal
.nhg_LogicalMax
);
2755 if((nch
->nch_HidGlobal
.nhg_UsagePage
== HID_PARAM_UNDEF
) ||
2756 //(nch->nch_HidGlobal.nhg_LogicalMin == HID_PARAM_UNDEF) ||
2757 //(nch->nch_HidGlobal.nhg_LogicalMax == HID_PARAM_UNDEF) ||
2758 (!nch
->nch_HidGlobal
.nhg_ReportSize
)// ||
2759 //(!nch->nch_HidGlobal.nhg_ReportCount) // ReportCount == 0 seems to be a valid input (sigh), just avoid error message
2762 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
),
2763 "HID Error at %04lx: Mandatory item missing!", reportpos
);
2764 nDebugReport(nch
, nhr
);
2765 KPRINTF(10, ("Mandatory item missing!\n"));
2769 struct List
*alistptr
;
2770 usageid
= designid
= stringid
= HID_PARAM_UNDEF
;
2771 if(udata
& RPF_MAIN_VARIABLE
)
2773 for(count
= 0; count
< nch
->nch_HidGlobal
.nhg_ReportCount
; count
++)
2775 nhu
= (struct NepHidUsage
*) nch
->nch_HidDesigns
.lh_Head
;
2776 if(nhu
->nhu_Node
.ln_Succ
)
2778 designid
= nhu
->nhu_Usage
++;
2779 if(nhu
->nhu_Usage
> nhu
->nhu_UsageMax
)
2781 Remove(&nhu
->nhu_Node
);
2785 nhu
= (struct NepHidUsage
*) nch
->nch_HidStrings
.lh_Head
;
2786 if(nhu
->nhu_Node
.ln_Succ
)
2788 stringid
= nhu
->nhu_Usage
++;
2789 if(nhu
->nhu_Usage
> nhu
->nhu_UsageMax
)
2791 Remove(&nhu
->nhu_Node
);
2795 nhu
= (struct NepHidUsage
*) nch
->nch_HidUsages
.lh_Head
;
2796 if(nhu
->nhu_Node
.ln_Succ
)
2798 usageid
= nhu
->nhu_Usage
++;
2799 if(nhu
->nhu_Usage
> nhu
->nhu_UsageMax
)
2801 KPRINTF(1, ("Removing usage %08lx\n", nhu
));
2802 Remove(&nhu
->nhu_Node
);
2806 if(usageid
!= HID_PARAM_UNDEF
)
2808 if((nhi
= psdAllocVec(sizeof(struct NepHidItem
))))
2810 nhi
->nhi_Collection
= nhc
;
2811 nhi
->nhi_Type
= itag
;
2812 nhi
->nhi_Flags
= udata
;
2813 nhi
->nhi_Offset
= bitpos
;
2814 nhi
->nhi_Size
= nch
->nch_HidGlobal
.nhg_ReportSize
;
2816 nhi
->nhi_LogicalMin
= nch
->nch_HidGlobal
.nhg_LogicalMin
;
2817 nhi
->nhi_LogicalMax
= nch
->nch_HidGlobal
.nhg_LogicalMax
;
2818 nhi
->nhi_IsSigned
= (nhi
->nhi_LogicalMin
< 0) || (nhi
->nhi_LogicalMax
< 0);
2819 nhi
->nhi_PhysicalMin
= nch
->nch_HidGlobal
.nhg_PhysicalMin
;
2820 nhi
->nhi_PhysicalMax
= nch
->nch_HidGlobal
.nhg_PhysicalMax
;
2821 nhi
->nhi_UnitExp
= nch
->nch_HidGlobal
.nhg_UnitExp
;
2822 nhi
->nhi_Unit
= nch
->nch_HidGlobal
.nhg_Unit
;
2823 nhi
->nhi_Usage
= usageid
;
2824 nhi
->nhi_DesignIndex
= designid
;
2825 nhi
->nhi_StringIndex
= stringid
;
2826 NewList(&nhi
->nhi_ActionList
);
2827 AddTail(&nhc
->nhc_Items
, &nhi
->nhi_Node
);
2828 KPRINTF(1, ("New Variable Item: %ld.%ld (%ld-%ld) %lx\n",
2829 nhi
->nhi_Offset
>>3, nhi
->nhi_Offset
& 7,
2830 nhi
->nhi_LogicalMin
, nhi
->nhi_LogicalMax
,
2834 bitpos
+= nch
->nch_HidGlobal
.nhg_ReportSize
;
2837 nhu
= (struct NepHidUsage
*) nch
->nch_HidUsages
.lh_Head
;
2838 if(nhu
->nhu_Node
.ln_Succ
)
2840 if((nhi
= psdAllocVec(sizeof(struct NepHidItem
))))
2842 nhi
->nhi_Collection
= nhc
;
2843 nhi
->nhi_Type
= itag
;
2844 nhi
->nhi_Flags
= udata
;
2845 nhi
->nhi_Offset
= bitpos
;
2846 nhi
->nhi_Size
= nch
->nch_HidGlobal
.nhg_ReportSize
;
2847 nhi
->nhi_Count
= nch
->nch_HidGlobal
.nhg_ReportCount
;
2849 nhi
->nhi_LogicalMin
= nch
->nch_HidGlobal
.nhg_LogicalMin
;
2850 nhi
->nhi_LogicalMax
= nch
->nch_HidGlobal
.nhg_LogicalMax
;
2852 nhi
->nhi_MapSize
= (nhi
->nhi_LogicalMax
- nhi
->nhi_LogicalMin
)+1;
2853 nhi
->nhi_UsageMap
= psdAllocVec(sizeof(ULONG
) * nhi
->nhi_MapSize
);
2854 nhi
->nhi_ActionMap
= psdAllocVec(sizeof(struct List
) * nhi
->nhi_MapSize
);
2855 nhi
->nhi_Buffer
= psdAllocVec(2 * sizeof(LONG
) * nhi
->nhi_Count
);
2856 nhi
->nhi_OldBuffer
= &nhi
->nhi_Buffer
[nhi
->nhi_Count
];
2857 nhi
->nhi_PhysicalMin
= nch
->nch_HidGlobal
.nhg_PhysicalMin
;
2858 nhi
->nhi_PhysicalMax
= nch
->nch_HidGlobal
.nhg_PhysicalMax
;
2859 nhi
->nhi_UnitExp
= nch
->nch_HidGlobal
.nhg_UnitExp
;
2860 nhi
->nhi_Unit
= nch
->nch_HidGlobal
.nhg_Unit
;
2862 usageptr
= nhi
->nhi_UsageMap
;
2863 alistptr
= nhi
->nhi_ActionMap
;
2864 if(!(usageptr
&& alistptr
&& nhi
->nhi_Buffer
))
2866 psdFreeVec(usageptr
);
2867 psdFreeVec(alistptr
);
2868 psdFreeVec(nhi
->nhi_Buffer
);
2870 KPRINTF(10, ("Out of memory\n"));
2875 nhi
->nhi_Usage
= nhi
->nhi_DesignIndex
= nhi
->nhi_StringIndex
= HID_PARAM_UNDEF
;
2876 NewList(&nhi
->nhi_ActionList
);
2878 KPRINTF(1, ("New Array(%ld*%ld) Item: %ld.%ld (%ld-%ld)\n",
2879 nhi
->nhi_Count
, nhi
->nhi_MapSize
,
2880 nhi
->nhi_Offset
>>3, nhi
->nhi_Offset
& 7,
2881 nhi
->nhi_LogicalMin
, nhi
->nhi_LogicalMax
));
2883 nhi
->nhi_SameUsages
= TRUE
;
2884 for (count
= nhi
->nhi_MapSize
; count
; count
--)
2886 nhu
= (struct NepHidUsage
*) nch
->nch_HidDesigns
.lh_Head
;
2887 if(nhu
->nhu_Node
.ln_Succ
)
2889 designid
= nhu
->nhu_Usage
++;
2890 if(nhu
->nhu_Usage
> nhu
->nhu_UsageMax
)
2892 Remove(&nhu
->nhu_Node
);
2896 nhu
= (struct NepHidUsage
*) nch
->nch_HidStrings
.lh_Head
;
2897 if(nhu
->nhu_Node
.ln_Succ
)
2899 stringid
= nhu
->nhu_Usage
++;
2900 if(nhu
->nhu_Usage
> nhu
->nhu_UsageMax
)
2902 Remove(&nhu
->nhu_Node
);
2906 nhu
= (struct NepHidUsage
*) nch
->nch_HidUsages
.lh_Head
;
2907 if(nhu
->nhu_Node
.ln_Succ
)
2909 usageid
= nhu
->nhu_Usage
++;
2910 if(nhu
->nhu_Usage
> nhu
->nhu_UsageMax
)
2912 KPRINTF(1, ("Removing usage %08lx\n", nhu
));
2913 Remove(&nhu
->nhu_Node
);
2918 // check if usages are all the same
2919 if(count
< nhi
->nhi_MapSize
)
2921 if(usageid
!= usageptr
[-1])
2923 nhi
->nhi_SameUsages
= FALSE
;
2927 *usageptr
++ = usageid
;
2932 if(nhi
->nhi_SameUsages
)
2934 // if it's all the same, we can assign a usage id to this array
2935 nhi
->nhi_Usage
= nhi
->nhi_UsageMap
[0];
2937 if(nhi
->nhi_MapSize
)
2939 AddTail(&nhc
->nhc_Items
, &nhi
->nhi_Node
);
2942 } /* FIXME: Clean string/delimiter stack if no usage? */
2943 bitpos
+= nch
->nch_HidGlobal
.nhg_ReportSize
* nch
->nch_HidGlobal
.nhg_ReportCount
;
2948 nch
->nch_HidGlobal
.nhg_LogicalMin
= HID_PARAM_UNDEF
;
2952 nch
->nch_HidGlobal
.nhg_LogicalMax
= HID_PARAM_UNDEF
;
2957 case REPORT_MAIN_COLLECT
:
2959 struct NepHidUsage
*nhu
;
2960 struct NepHidCollection
*oldnhc
= nhc
;
2961 KPRINTF(1, ("Collection(%lx)\n", udata
));
2962 if((nhc
= psdAllocVec(sizeof(struct NepHidCollection
))))
2964 NewList(&nhc
->nhc_Items
);
2965 nhc
->nhc_Parent
= oldnhc
;
2966 nhu
= (struct NepHidUsage
*) nch
->nch_HidUsages
.lh_Head
;
2967 if(nhu
->nhu_Node
.ln_Succ
)
2969 nhc
->nhc_Usage
= nhu
->nhu_Usage
;
2970 nhc
->nhc_Name
= nGetUsageName(nch
, nhu
->nhu_Usage
);
2974 nhc
->nhc_Usage
= nhc
->nhc_Parent
->nhc_Usage
;
2975 nhc
->nhc_Name
= psdCopyStr(nhc
->nhc_Parent
->nhc_Name
);
2977 nhc
->nhc_Name
= psdCopyStr("Argl!");
2981 node
= nch
->nch_HidUsages
.lh_Head
;
2982 while(node
->ln_Succ
)
2984 KPRINTF(1, ("Removing usage %08lx\n", node
));
2987 node
= nch
->nch_HidUsages
.lh_Head
;
2993 case REPORT_MAIN_ENDCOLL
:
2994 KPRINTF(1, ("EndCollection(%lx)\n", udata
));
2997 /* Get rid of empty collection */
2998 //if(!nhc->nhc_Items.lh_Head->ln_Succ)
2999 if(0) /* don't do this, we might need the parent collection! */
3001 struct NepHidCollection
*oldnhc
= nhc
;
3002 KPRINTF(1, ("Deleting empty collection %lx (%s)\n", nhc
, nhc
->nhc_Name
));
3003 nhc
= nhc
->nhc_Parent
;
3004 psdFreeVec(oldnhc
->nhc_Name
);
3007 AddTail(&nhr
->nhr_Collections
, &nhc
->nhc_Node
);
3008 nhc
->nhc_Report
= nhr
;
3009 nhc
= nhc
->nhc_Parent
;
3015 KPRINTF(1, ("Reserved_%02lx(%lx)\n", itag
, data
));
3016 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) GM_UNIQUENAME(libname
),
3017 "HID Error at %04lx: Reserved_MAIN_%02lx(%lx)", reportpos
, itag
, data
);
3018 nDebugReport(nch
, nhr
);
3022 /* Remove remaining usages */
3023 node
= nch
->nch_HidUsages
.lh_Head
;
3024 while(node
->ln_Succ
)
3026 KPRINTF(1, ("MainEnd: Removing usage %08lx\n", node
));
3029 node
= nch
->nch_HidUsages
.lh_Head
;
3031 /* Remove remaining designators */
3032 node
= nch
->nch_HidDesigns
.lh_Head
;
3033 while(node
->ln_Succ
)
3035 KPRINTF(1, ("MainEnd: Removing designator %08lx\n", node
));
3038 node
= nch
->nch_HidDesigns
.lh_Head
;
3040 /* Remove remaining strings */
3041 node
= nch
->nch_HidStrings
.lh_Head
;
3042 while(node
->ln_Succ
)
3044 KPRINTF(1, ("MainEnd: Removing strings %08lx\n", node
));
3047 node
= nch
->nch_HidStrings
.lh_Head
;
3052 case REPORT_MAIN_INPUT
:
3053 nhr
->nhr_ReportInSize
= bitpos
;
3055 case REPORT_MAIN_OUTPUT
:
3056 nhr
->nhr_ReportOutSize
= bitpos
;
3058 case REPORT_MAIN_FEATURE
:
3059 nhr
->nhr_ReportFeatSize
= bitpos
;
3065 case REPORT_ITYPE_GLOBAL
:
3066 //KPRINTF(1, ("Global "));
3069 case REPORT_GLOB_USAGE
:
3070 KPRINTF(1, ("Usage Page(%ld) %s\n", udata
, nNumToStr(nch
, NTS_USAGEPAGE
, udata
, "unknown")));
3071 nch
->nch_HidGlobal
.nhg_UsagePage
= udata
;
3074 case REPORT_GLOB_LOGMIN
:
3075 KPRINTF(1, ("LogMin(%ld)\n", data
));
3076 nch
->nch_HidGlobal
.nhg_LogicalMin
= data
;
3079 case REPORT_GLOB_LOGMAX
:
3080 KPRINTF(1, ("LogMax(%ld)\n", data
));
3081 nch
->nch_HidGlobal
.nhg_LogicalMax
= data
;
3084 case REPORT_GLOB_PHYMIN
:
3085 KPRINTF(1, ("PhyMin(%ld)\n", data
));
3086 nch
->nch_HidGlobal
.nhg_PhysicalMin
= data
;
3089 case REPORT_GLOB_PHYMAX
:
3090 KPRINTF(1, ("PhyMax(%ld)\n", data
));
3091 nch
->nch_HidGlobal
.nhg_PhysicalMax
= data
;
3094 case REPORT_GLOB_UNITEXP
:
3095 KPRINTF(1, ("UnitExp(%ld)\n", data
));
3096 nch
->nch_HidGlobal
.nhg_UnitExp
= data
;
3099 case REPORT_GLOB_UNIT
:
3100 KPRINTF(1, ("Unit(%ld)\n", data
));
3101 nch
->nch_HidGlobal
.nhg_Unit
= data
;
3104 case REPORT_GLOB_RPSIZE
:
3105 KPRINTF(1, ("ReportSize(%ld)\n", udata
));
3106 nch
->nch_HidGlobal
.nhg_ReportSize
= udata
;
3109 case REPORT_GLOB_RPID
:
3110 KPRINTF(1, ("ReportID(%ld)\n", udata
));
3111 nch
->nch_HidGlobal
.nhg_ReportID
= udata
;
3114 case REPORT_GLOB_RPCOUNT
:
3115 KPRINTF(1, ("ReportCount(%ld)\n", udata
));
3116 nch
->nch_HidGlobal
.nhg_ReportCount
= udata
;
3119 case REPORT_GLOB_PUSH
:
3121 struct NepHidGlobal
*nhg
= psdAllocVec(sizeof(struct NepHidGlobal
));
3122 KPRINTF(1, ("Push(%ld)\n", data
));
3125 *nhg
= nch
->nch_HidGlobal
;
3126 AddTail(&nch
->nch_HidStack
, &nhg
->nhg_Node
);
3128 KPRINTF(10, ("Out of HID stack memory!\n"));
3134 case REPORT_GLOB_POP
:
3136 struct NepHidGlobal
*nhg
= (struct NepHidGlobal
*) nch
->nch_HidStack
.lh_Tail
;
3137 KPRINTF(1, ("Pop(%ld)\n", data
));
3138 if(nhg
->nhg_Node
.ln_Pred
)
3140 nch
->nch_HidGlobal
= *nhg
;
3141 Remove(&nhg
->nhg_Node
);
3144 KPRINTF(10, ("Pop from HID stack without push!\n"));
3145 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) GM_UNIQUENAME(libname
),
3146 "HID Error at %04lx: Pop from HID stack without push!", reportpos
);
3147 nDebugReport(nch
, nhr
);
3154 KPRINTF(1, ("Reserved_%02lx(%lx)\n", itag
, data
));
3155 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) GM_UNIQUENAME(libname
),
3156 "HID Error at %04lx: Reserved_GLOBAL_%02lx(%lx)", reportpos
, itag
, data
);
3157 nDebugReport(nch
, nhr
);
3163 case REPORT_ITYPE_LOCAL
:
3164 //KPRINTF(1, ("Local "));
3167 case REPORT_LOCL_USAGE
:
3170 udata
|= nch
->nch_HidGlobal
.nhg_UsagePage
<<16;
3172 KPRINTF(1, ("Usage (%lx) %s\n", udata
, nNumToStr(nch
, NTS_USAGEID
, udata
, "unknown")));
3173 if(!nAddUsage(nch
, &nch
->nch_HidUsages
, udata
, udata
))
3179 case REPORT_LOCL_USEMIN
:
3182 udata
|= nch
->nch_HidGlobal
.nhg_UsagePage
<<16;
3184 KPRINTF(1, ("UsageMin (%lx) %s\n", udata
, nNumToStr(nch
, NTS_USAGEID
, udata
, "unknown")));
3186 if(usagemax
!= HID_PARAM_UNDEF
)
3188 if(!nAddUsage(nch
, &nch
->nch_HidUsages
, usagemin
, usagemax
))
3192 usagemin
= usagemax
= HID_PARAM_UNDEF
;
3196 case REPORT_LOCL_USEMAX
:
3199 udata
|= nch
->nch_HidGlobal
.nhg_UsagePage
<<16;
3201 KPRINTF(1, ("UsageMax (%lx) %s\n", udata
, nNumToStr(nch
, NTS_USAGEID
, udata
, "unknown")));
3203 if(usagemin
!= HID_PARAM_UNDEF
)
3205 if(!nAddUsage(nch
, &nch
->nch_HidUsages
, usagemin
, usagemax
))
3209 usagemin
= usagemax
= HID_PARAM_UNDEF
;
3213 case REPORT_LOCL_DESIDX
:
3214 KPRINTF(1, ("Designator index (%lx) %s\n", udata
, nNumToStr(nch
, NTS_USAGEID
, udata
, "unknown")));
3215 if(!nAddUsage(nch
, &nch
->nch_HidDesigns
, udata
, udata
))
3221 case REPORT_LOCL_DESMIN
:
3222 KPRINTF(1, ("DesignMin (%lx) %s\n", udata
, nNumToStr(nch
, NTS_USAGEID
, udata
, "unknown")));
3224 if(designmax
!= HID_PARAM_UNDEF
)
3226 if(!nAddUsage(nch
, &nch
->nch_HidDesigns
, designmin
, designmax
))
3230 designmin
= designmax
= HID_PARAM_UNDEF
;
3234 case REPORT_LOCL_DESMAX
:
3235 KPRINTF(1, ("DesignMax (%lx) %s\n", udata
, nNumToStr(nch
, NTS_USAGEID
, udata
, "unknown")));
3237 if(designmax
!= HID_PARAM_UNDEF
)
3239 if(!nAddUsage(nch
, &nch
->nch_HidDesigns
, designmin
, designmax
))
3243 designmin
= designmax
= HID_PARAM_UNDEF
;
3247 case REPORT_LOCL_STRIDX
:
3248 KPRINTF(1, ("String index (%lx) %s\n", udata
, nNumToStr(nch
, NTS_USAGEID
, udata
, "unknown")));
3249 if(!nAddUsage(nch
, &nch
->nch_HidStrings
, udata
, udata
))
3253 psdAddErrorMsg(RETURN_OK
, (STRPTR
) GM_UNIQUENAME(libname
),
3254 "HID String Index %ld", udata
);
3257 case REPORT_LOCL_STRMIN
:
3258 KPRINTF(1, ("StringMin (%lx) %s\n", udata
, nNumToStr(nch
, NTS_USAGEID
, udata
, "unknown")));
3260 if(stringmax
!= HID_PARAM_UNDEF
)
3262 psdAddErrorMsg(RETURN_OK
, (STRPTR
) GM_UNIQUENAME(libname
),
3263 "HID String Index Range %ld - %ld", stringmin
, stringmax
);
3264 if(!nAddUsage(nch
, &nch
->nch_HidStrings
, stringmin
, stringmax
))
3268 stringmin
= stringmax
= HID_PARAM_UNDEF
;
3272 case REPORT_LOCL_STRMAX
:
3273 KPRINTF(1, ("StringMax (%lx) %s\n", udata
, nNumToStr(nch
, NTS_USAGEID
, udata
, "unknown")));
3275 if(stringmin
!= HID_PARAM_UNDEF
)
3277 psdAddErrorMsg(RETURN_OK
, (STRPTR
) GM_UNIQUENAME(libname
),
3278 "HID String Index Range %ld - %ld", stringmin
, stringmax
);
3279 if(!nAddUsage(nch
, &nch
->nch_HidStrings
, stringmin
, stringmax
))
3283 stringmin
= stringmax
= HID_PARAM_UNDEF
;
3287 case REPORT_LOCL_DELIM
:
3288 KPRINTF(1, ("Delimiter (%ld)\n", udata
));
3295 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) GM_UNIQUENAME(libname
), "HID Report Delimiters not really supported!");
3299 KPRINTF(1, ("Reserved_%02lx(%lx)\n", itag
, udata
));
3300 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) GM_UNIQUENAME(libname
),
3301 "HID Error at %04lx: Reserved_LOCAL_%02lx(%lx)", reportpos
, itag
, udata
);
3302 nDebugReport(nch
, nhr
);
3309 KPRINTF(1, ("Reserved!\n"));
3310 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) GM_UNIQUENAME(libname
),
3311 "HID Error at %04lx: Reserved_%02lx", reportpos
, itag
);
3312 nDebugReport(nch
, nhr
);
3317 KPRINTF(1, ("Parsing done, status %lx.\n", rptr
));
3319 /* Remove remaining stack frame */
3320 node
= nch
->nch_HidStack
.lh_Head
;
3321 while(node
->ln_Succ
)
3323 KPRINTF(1, ("Removing stack frame %08lx\n", node
));
3326 node
= nch
->nch_HidStack
.lh_Head
;
3328 /* Remove remaining usages */
3329 node
= nch
->nch_HidUsages
.lh_Head
;
3330 while(node
->ln_Succ
)
3332 KPRINTF(1, ("Removing usage %08lx\n", node
));
3335 node
= nch
->nch_HidUsages
.lh_Head
;
3337 /* Remove remaining designators */
3338 node
= nch
->nch_HidDesigns
.lh_Head
;
3339 while(node
->ln_Succ
)
3341 KPRINTF(1, ("Removing designator %08lx\n", node
));
3344 node
= nch
->nch_HidDesigns
.lh_Head
;
3346 /* Remove remaining strings */
3347 node
= nch
->nch_HidStrings
.lh_Head
;
3348 while(node
->ln_Succ
)
3350 KPRINTF(1, ("Removing strings %08lx\n", node
));
3353 node
= nch
->nch_HidStrings
.lh_Head
;
3355 //nDebugReport(nch, nhr);
3356 return((BOOL
) (rptr
? TRUE
: FALSE
));
3360 /* /// "nFindCollID()" */
3361 BOOL
nFindCollID(struct NepClassHid
*nch
, struct NepHidCollection
*nhc
, ULONG collidmin
, ULONG collidmax
)
3365 if((nhc
->nhc_Usage
>= collidmin
) && (nhc
->nhc_Usage
<= collidmax
))
3369 } while((nhc
= nhc
->nhc_Parent
));
3374 /* /// "nFindItemID()" */
3375 struct NepHidItem
* nFindItemID(struct NepClassHid
*nch
, UWORD id
, UWORD itype
, ULONG
*pos
)
3377 struct NepHidReport
*nhr
= (struct NepHidReport
*) nch
->nch_HidReports
.lh_Head
;
3378 struct NepHidItem
*nhi
;
3379 struct NepHidItem
**nhiptr
;
3380 struct List
*alistptr
;
3385 if(itype
== REPORT_MAIN_OUTPUT
)
3389 else if(itype
== REPORT_MAIN_FEATURE
)
3395 while(nhr
->nhr_Node
.ln_Succ
)
3400 if((icount
= nhr
->nhr_FeatItemCount
))
3402 nhiptr
= nhr
->nhr_FeatItemMap
;
3405 if((icount
= nhr
->nhr_OutItemCount
))
3407 nhiptr
= nhr
->nhr_OutItemMap
;
3415 if(GET_WTYPE(&nhi
->nhi_ActionList
) == id
)
3420 if(!(nhi
->nhi_Flags
& RPF_MAIN_VARIABLE
))
3422 alistptr
= nhi
->nhi_ActionMap
;
3423 count
= nhi
->nhi_MapSize
;
3426 if(GET_WTYPE(alistptr
) == id
)
3428 *pos
= nhi
->nhi_MapSize
- count
;
3437 nhr
= (struct NepHidReport
*) nhr
->nhr_Node
.ln_Succ
;
3443 /* /// "nFindItemUsage()" */
3444 UWORD
nFindItemUsage(struct NepClassHid
*nch
, ULONG usage
, UWORD itype
)
3446 struct NepHidReport
*nhr
= (struct NepHidReport
*) nch
->nch_HidReports
.lh_Head
;
3447 struct NepHidItem
*nhi
;
3448 struct NepHidItem
**nhiptr
;
3450 struct List
*alistptr
;
3455 if(itype
== REPORT_MAIN_OUTPUT
)
3459 else if(itype
== REPORT_MAIN_FEATURE
)
3466 while(nhr
->nhr_Node
.ln_Succ
)
3471 if((icount
= nhr
->nhr_FeatItemCount
))
3473 nhiptr
= nhr
->nhr_FeatItemMap
;
3476 if((icount
= nhr
->nhr_OutItemCount
))
3478 nhiptr
= nhr
->nhr_OutItemMap
;
3486 if(nhi
->nhi_Usage
== usage
)
3488 return(GET_WTYPE(&nhi
->nhi_ActionList
));
3490 if(!(nhi
->nhi_Flags
& RPF_MAIN_VARIABLE
))
3492 usageptr
= nhi
->nhi_UsageMap
;
3493 alistptr
= nhi
->nhi_ActionMap
;
3494 count
= nhi
->nhi_MapSize
;
3497 if(*usageptr
== usage
)
3499 return GET_WTYPE(alistptr
);
3508 nhr
= (struct NepHidReport
*) nhr
->nhr_Node
.ln_Succ
;
3514 /* /// "UsbToPs2 Mapping" */
3515 const struct UsbToPs2Map usbtops2map
[] =
3517 { 0x010081, 0x5e }, // System Power Down
3518 { 0x010082, 0x5f }, // System Sleep
3519 { 0x010083, 0x63 }, // System Wake Up
3521 { 0x070046, 0x4c }, // Keyboard Print Screen
3522 { 0x070047, 0x64 }, // Keyboard Scroll Lock
3523 { 0x070048, 0x45 }, // Keyboard Pause
3524 { 0x070049, 0x0a }, // Keyboard Insert
3526 { 0x070066, 0x5e }, // Keyboard Power
3528 { 0x07007A, 0x08 }, // Keyboard Undo
3529 { 0x07007B, 0x17 }, // Keyboard Cut
3530 { 0x07007C, 0x18 }, // Keyboard Copy
3531 { 0x07007D, 0x0a }, // Keyboard Paste
3532 { 0x07007F, 0x20 }, // Keyboard Mute
3533 { 0x070080, 0x30 }, // Keyboard Volume Up
3534 { 0x070081, 0x2e }, // Keyboard Volume Down
3536 { 0x0C0030, 0x5e }, // Power
3537 { 0x0C0032, 0x5f }, // Sleep
3538 { 0x0C0033, 0x5f }, // Sleep After
3539 { 0x0C0034, 0x5f }, // Sleep Mode
3541 { 0x0C0094, 0x40 }, // Quit
3542 { 0x0C0095, 0x3b }, // Help
3543 { 0x0C00B0, 0x22 }, // Play
3544 { 0x0C00B1, 0x22 }, // Pause
3545 { 0x0C00B5, 0x19 }, // Scan Next Track
3546 { 0x0C00B6, 0x10 }, // Scan Previous Track
3547 { 0x0C00B7, 0x24 }, // Stop
3548 { 0x0C00CC, 0x24 }, // Stop/Eject
3549 { 0x0C00CD, 0x22 }, // Play/Pause
3550 { 0x0C00CE, 0x22 }, // Play/Skip
3552 { 0x0C00E2, 0x20 }, // Mute
3553 { 0x0C00E9, 0x30 }, // Volume Increment
3554 { 0x0C00EA, 0x2e }, // Volume Decrement
3556 { 0x0C0183, 0x6d }, // AL Consumer Control Configuration
3557 { 0x0C0184, 0x13 }, // AL Word Processor
3558 { 0x0C0185, 0x13 }, // AL Text Editor
3559 { 0x0C0186, 0x14 }, // AL Spreadsheet
3560 { 0x0C018A, 0x6c }, // AL Email Reader
3561 { 0x0C018F, 0x3d }, // AL Task/Project Manager
3562 { 0x0C0192, 0x21 }, // AL Calculator
3563 { 0x0C0194, 0x3c }, // AL Local Machine Browser
3564 { 0x0C0196, 0x3c }, // AL Internet Browser
3565 { 0x0C019B, 0x16 }, // AL Logon
3566 { 0x0C019C, 0x16 }, // AL Logoff
3567 { 0x0C019D, 0x16 }, // AL Logon/Logoff
3568 { 0x0C01A1, 0x3d }, // AL Process/Task Manager
3569 { 0x0C01A3, 0x1e }, // AL Next Task/Application
3570 { 0x0C01A4, 0x09 }, // AL Previous Task/Application
3571 { 0x0C01A6, 0x3b }, // AL Integrated Help Center
3572 { 0x0C01A7, 0x6b }, // AL Documents
3573 { 0x0C01A8, 0x23 }, // AL Thesaurus
3574 { 0x0C01A9, 0x23 }, // AL Dictionary
3575 { 0x0C01AB, 0x23 }, // AL Spell Check
3576 { 0x0C01AC, 0x23 }, // AL Grammar Check
3577 { 0x0C01B4, 0x05 }, // AL File Browser
3578 { 0x0C01BD, 0x3b }, // AL OEM Features/ Tips/Tutorial Browser
3579 { 0x0C01BE, 0x3b }, // AL OEM Help
3581 { 0x0C0201, 0x3e }, // AC New
3582 { 0x0C0202, 0x3f }, // AC Open
3583 { 0x0C0203, 0x40 }, // AC Close
3584 { 0x0C0204, 0x40 }, // AC Exit
3585 { 0x0C0207, 0x57 }, // AC Save
3586 { 0x0C0208, 0x58 }, // AC Print
3587 { 0x0C021A, 0x08 }, // AC Undo
3588 { 0x0C021B, 0x18 }, // AC Copy
3589 { 0x0C021C, 0x17 }, // AC Cut
3590 { 0x0C021D, 0x0a }, // AC Paste
3591 { 0x0C021F, 0x65 }, // AC Find
3592 { 0x0C0220, 0x65 }, // AC Find and Replace
3593 { 0x0C0221, 0x65 }, // AC Search
3594 { 0x0C0223, 0x32 }, // AC Home
3595 { 0x0C0224, 0x6a }, // AC Back
3596 { 0x0C0225, 0x69 }, // AC Forward
3597 { 0x0C0226, 0x68 }, // AC Stop
3598 { 0x0C0227, 0x67 }, // AC Refresh
3599 { 0x0C0228, 0x6a }, // AC Previous Link
3600 { 0x0C0229, 0x69 }, // AC Next Link
3601 { 0x0C022A, 0x66 }, // AC Bookmarks
3602 { 0x0C022B, 0x66 }, // AC History
3603 { 0x0C022C, 0x66 }, // AC Subscriptions
3604 { 0x0C0279, 0x07 }, // AC Redo/Repeat
3605 { 0x0C0288, 0x43 }, // AC Send To
3606 { 0x0C0289, 0x41 }, // AC Reply
3607 { 0x0C028A, 0x41 }, // AC Reply All
3608 { 0x0C028B, 0x42 }, // AC Forward Msg
3609 { 0x0C028C, 0x43 }, // AC Send
3615 /* /// "nDetectDefaultAction()" */
3616 BOOL
nDetectDefaultAction(struct NepClassHid
*nch
, struct NepHidItem
*nhi
, struct List
*lst
, struct NepHidCollection
*nhc
, ULONG uid
)
3619 UWORD usageid
= uid
;
3620 struct NepHidAction
*nha
;
3621 struct WacomCaps
*wc
;
3622 const struct UsbToPs2Map
*utp
= usbtops2map
;
3626 case 0x01: /* generic desktop page */
3627 if(usageid
== 0xfff0) /* extra init */
3629 /* AipTek USB Tablets Support */
3635 psdGetAttrs(PGA_DEVICE
, nch
->nch_Device
,
3636 DA_VendorID
, &vendid
,
3637 DA_ProductID
, &prodid
,
3639 if((vendid
== 0x08ca) &&
3640 ((prodid
== 0x0001) || (prodid
== 0x0010) ||
3641 ((prodid
>= 0x0020) && (prodid
<= 0x0024))) &&
3642 (!nhi
->nhi_ActionList
.lh_Head
->ln_Succ
))
3644 psdAddErrorMsg(RETURN_OK
, (STRPTR
) GM_UNIQUENAME(libname
),
3645 "Generating special AipTek USB Tablet init sequence.");
3646 command
= nFindItemUsage(nch
, 0x0D003F, REPORT_MAIN_FEATURE
);
3647 data
= nFindItemUsage(nch
, 0x0D0040, REPORT_MAIN_FEATURE
);
3650 /* set resolution to 500DPI */
3651 if((nha
= nAllocAction(nch
, lst
, HUA_FEATURE
|HUA_ANY
)))
3653 nha
->nha_FeatOp
= HUAT_ASSIGN
;
3654 nha
->nha_FeatItem
= command
;
3655 nha
->nha_ValEnable
= TRUE
;
3656 nha
->nha_ValVar
= HUAT_CONST
;
3657 nha
->nha_ValConst
= 0x18;
3659 if((nha
= nAllocAction(nch
, lst
, HUA_FEATURE
|HUA_ANY
)))
3661 nha
->nha_FeatOp
= HUAT_ASSIGN
;
3662 nha
->nha_FeatItem
= data
;
3663 nha
->nha_ValEnable
= TRUE
;
3664 nha
->nha_ValVar
= HUAT_CONST
;
3665 nha
->nha_ValConst
= 0x04;
3667 if((nha
= nAllocAction(nch
, lst
, HUA_MISC
|HUA_ANY
)))
3669 nha
->nha_MiscMode
= HUAT_FLUSHEVENTS
;
3672 /* set absolute tablet mode */
3673 if((nha
= nAllocAction(nch
, lst
, HUA_FEATURE
|HUA_ANY
)))
3675 nha
->nha_FeatOp
= HUAT_ASSIGN
;
3676 nha
->nha_FeatItem
= command
;
3677 nha
->nha_ValEnable
= TRUE
;
3678 nha
->nha_ValVar
= HUAT_CONST
;
3679 nha
->nha_ValConst
= 0x10;
3681 if((nha
= nAllocAction(nch
, lst
, HUA_FEATURE
|HUA_ANY
)))
3683 nha
->nha_FeatOp
= HUAT_ASSIGN
;
3684 nha
->nha_FeatItem
= data
;
3685 nha
->nha_ValEnable
= TRUE
;
3686 nha
->nha_ValVar
= HUAT_CONST
;
3687 nha
->nha_ValConst
= 0x01;
3689 if((nha
= nAllocAction(nch
, lst
, HUA_MISC
|HUA_ANY
)))
3691 nha
->nha_MiscMode
= HUAT_FLUSHEVENTS
;
3694 /* enable macro keys */
3695 if((nha
= nAllocAction(nch
, lst
, HUA_FEATURE
|HUA_ANY
)))
3697 nha
->nha_FeatOp
= HUAT_ASSIGN
;
3698 nha
->nha_FeatItem
= command
;
3699 nha
->nha_ValEnable
= TRUE
;
3700 nha
->nha_ValVar
= HUAT_CONST
;
3701 nha
->nha_ValConst
= 0x11;
3703 if((nha
= nAllocAction(nch
, lst
, HUA_FEATURE
|HUA_ANY
)))
3705 nha
->nha_FeatOp
= HUAT_ASSIGN
;
3706 nha
->nha_FeatItem
= data
;
3707 nha
->nha_ValEnable
= TRUE
;
3708 nha
->nha_ValVar
= HUAT_CONST
;
3709 nha
->nha_ValConst
= 0x02;
3711 if((nha
= nAllocAction(nch
, lst
, HUA_MISC
|HUA_ANY
)))
3713 nha
->nha_MiscMode
= HUAT_FLUSHEVENTS
;
3716 /* enable auto gain */
3717 if((nha
= nAllocAction(nch
, lst
, HUA_FEATURE
|HUA_ANY
)))
3719 nha
->nha_FeatOp
= HUAT_ASSIGN
;
3720 nha
->nha_FeatItem
= command
;
3721 nha
->nha_ValEnable
= TRUE
;
3722 nha
->nha_ValVar
= HUAT_CONST
;
3723 nha
->nha_ValConst
= 0x12;
3725 if((nha
= nAllocAction(nch
, lst
, HUA_FEATURE
|HUA_ANY
)))
3727 nha
->nha_FeatOp
= HUAT_ASSIGN
;
3728 nha
->nha_FeatItem
= data
;
3729 nha
->nha_ValEnable
= TRUE
;
3730 nha
->nha_ValVar
= HUAT_CONST
;
3731 nha
->nha_ValConst
= 0xff;
3733 /*if((nha = nAllocAction(nch, lst, HUA_MISC|HUA_ANY)))
3735 nha->nha_MiscMode = HUAT_FLUSHEVENTS;
3738 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
),
3739 "AipTek: No command (%ld) or data (%ld) feature!", command
, data
);
3742 if(vendid
== 0x056a)
3744 for(wc
= WacomCapsTable
; wc
->wc_ProdID
!= prodid
; wc
++)
3746 if(wc
->wc_ProdID
== 0xffff)
3757 psdAddErrorMsg(RETURN_OK
, (STRPTR
) GM_UNIQUENAME(libname
),
3758 "Generating special Wacom USB Tablet init sequence.");
3759 command
= nFindItemUsage(nch
, 0xff000001, REPORT_MAIN_FEATURE
);
3762 /* activate returning of absolute tablet data */
3763 if((nha
= nAllocAction(nch
, lst
, HUA_FEATURE
|HUA_ANY
)))
3765 nha
->nha_FeatOp
= HUAT_ASSIGN
;
3766 nha
->nha_FeatItem
= command
;
3767 nha
->nha_ValEnable
= TRUE
;
3768 nha
->nha_ValVar
= HUAT_CONST
;
3769 nha
->nha_ValConst
= 0x02;
3771 if((nha
= nAllocAction(nch
, lst
, HUA_MISC
|HUA_ANY
)))
3773 nha
->nha_MiscMode
= HUAT_FLUSHEVENTS
;
3775 if((nha
= nAllocAction(nch
, lst
, HUA_FEATURE
|HUA_ANY
)))
3777 nha
->nha_FeatOp
= HUAT_ASSIGN
;
3778 nha
->nha_FeatItem
= command
;
3779 nha
->nha_ValEnable
= TRUE
;
3780 nha
->nha_ValVar
= HUAT_CONST
;
3781 nha
->nha_ValConst
= 0x02;
3786 if((vendid
== 0x046d) &&
3787 (!nhi
->nhi_ActionList
.lh_Head
->ln_Succ
))
3789 command
= nFindItemUsage(nch
, 0xff000001, REPORT_MAIN_OUTPUT
);
3792 psdAddErrorMsg(RETURN_OK
, (STRPTR
) GM_UNIQUENAME(libname
),
3793 "Adding special HID2HCI Logitech Bluetooth init sequence, but deactivated!");
3794 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) GM_UNIQUENAME(libname
),
3795 "This init sequence would disable HID usage and enable pure Bluetooth use!");
3796 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) GM_UNIQUENAME(libname
),
3797 "If you want to use this dongle for Bluetooth, switch the NOP-Startup-Actions to type Output!");
3798 // send three commands to output report 0x10
3799 if((nha
= nAllocAction(nch
, lst
, HUA_NOP
|HUA_ANY
)))
3801 nha
->nha_OutItem
= command
;
3802 strcpy(nha
->nha_OutArray
, "0xff, 0x80, 0x80, 0x01, 0x00, 0x00");
3804 if((nha
= nAllocAction(nch
, lst
, HUA_MISC
|HUA_ANY
)))
3806 nha
->nha_MiscMode
= HUAT_FLUSHEVENTS
;
3808 if((nha
= nAllocAction(nch
, lst
, HUA_NOP
|HUA_ANY
)))
3810 nha
->nha_OutItem
= command
;
3811 strcpy(nha
->nha_OutArray
, "0xff, 0x80, 0x00, 0x00, 0x30, 0x00");
3813 if((nha
= nAllocAction(nch
, lst
, HUA_MISC
|HUA_ANY
)))
3815 nha
->nha_MiscMode
= HUAT_FLUSHEVENTS
;
3817 if((nha
= nAllocAction(nch
, lst
, HUA_NOP
|HUA_ANY
)))
3819 nha
->nha_OutItem
= command
;
3820 strcpy(nha
->nha_OutArray
, "0xff, 0x81, 0x80, 0x00, 0x00, 0x00");
3826 if(nFindCollID(nch
, nhc
, 0x010002, 0x010002) || /* Mice */
3827 nFindCollID(nch
, nhc
, 0x0d0001, 0x0d000d)) /* Tablets */
3831 case 0x30: /* Mouse X */
3832 if((nha
= nAllocAction(nch
, lst
, HUA_MOUSEPOS
|HUA_ALWAYS
)))
3834 if(nhi
->nhi_Flags
& RPF_MAIN_RELATIVE
)
3836 nha
->nha_MouseAxis
= HUAT_DELTAX
;
3838 nha
->nha_MouseAxis
= HUAT_ABSX
;
3839 nha
->nha_ClipEnable
= TRUE
;
3840 nha
->nha_ClipMin
= 5;
3841 nha
->nha_ClipMax
= 95;
3842 nha
->nha_ClipStretch
= TRUE
;
3847 case 0x31: /* Mouse Y */
3848 if((nha
= nAllocAction(nch
, lst
, HUA_MOUSEPOS
|HUA_ALWAYS
)))
3850 if(nhi
->nhi_Flags
& RPF_MAIN_RELATIVE
)
3852 nha
->nha_MouseAxis
= HUAT_DELTAY
;
3854 nha
->nha_MouseAxis
= HUAT_ABSY
;
3855 nha
->nha_ClipEnable
= TRUE
;
3856 nha
->nha_ClipMin
= 5;
3857 nha
->nha_ClipMax
= 95;
3858 nha
->nha_ClipStretch
= TRUE
;
3863 case 0x38: /* Wheel */
3864 if((nha
= nAllocAction(nch
, lst
, HUA_WHEEL
|HUA_ALWAYS
)))
3866 nha
->nha_WheelMode
= HUAT_DELTAY
;
3867 nha
->nha_WheelDist
= 1;
3873 if(nFindCollID(nch
, nhc
, 0x010004, 0x010005)) /* Joystick, Game Pad */
3877 case 0x39: /* Hatswitch */
3878 if((nha
= nAllocAction(nch
, lst
, HUA_DIGJOY
|HUA_NAN
)))
3880 nha
->nha_JoypadOp
= HUAT_CLEAR
;
3881 nha
->nha_JoypadFeat
= HUAT_HATSWITCH
;
3882 nha
->nha_JoypadPort
= 1;
3884 if((nha
= nAllocAction(nch
, lst
, HUA_DIGJOY
|HUA_ALWAYS
)))
3886 nha
->nha_JoypadOp
= HUAT_ASSIGN
;
3887 nha
->nha_JoypadFeat
= HUAT_HATSWITCH
;
3888 nha
->nha_JoypadPort
= 1;
3892 case 0x30: /* X axis */
3893 case 0x35: /* Z rotation */
3894 case 0x31: /* Y axis */
3895 case 0x32: /* Z axis */
3897 ULONG minpos
= ((nhi
->nhi_LogicalMax
- nhi
->nhi_LogicalMin
+ 1)>>2) + nhi
->nhi_LogicalMin
;
3898 ULONG maxpos
= (((nhi
->nhi_LogicalMax
- nhi
->nhi_LogicalMin
+ 1)*3)>>2) + nhi
->nhi_LogicalMin
;
3902 if((usageid
== 0x30) || (usageid
== 0x35))
3904 negaxis
= HUAT_LEFT
;
3905 posaxis
= HUAT_RIGHT
;
3906 alogaxis
= HUAT_ABSX
;
3909 posaxis
= HUAT_DOWN
;
3910 alogaxis
= HUAT_ABSY
;
3912 if((nha
= nAllocAction(nch
, lst
, HUA_DIGJOY
|HUA_ANY
)))
3914 nha
->nha_CCEnable
= TRUE
;
3915 nha
->nha_CCCond
= HUAT_GT
;
3916 nha
->nha_CCConst2
= minpos
;
3917 nha
->nha_JoypadOp
= HUAT_CLEAR
;
3918 nha
->nha_JoypadFeat
= negaxis
;
3919 nha
->nha_JoypadPort
= 1;
3921 if((nha
= nAllocAction(nch
, lst
, HUA_DIGJOY
|HUA_ANY
)))
3923 nha
->nha_CCEnable
= TRUE
;
3924 nha
->nha_CCCond
= HUAT_LE
;
3925 nha
->nha_CCConst2
= minpos
;
3926 nha
->nha_JoypadOp
= HUAT_SET
;
3927 nha
->nha_JoypadFeat
= negaxis
;
3928 nha
->nha_JoypadPort
= 1;
3930 if((nha
= nAllocAction(nch
, lst
, HUA_DIGJOY
|HUA_ANY
)))
3932 nha
->nha_CCEnable
= TRUE
;
3933 nha
->nha_CCCond
= HUAT_LT
;
3934 nha
->nha_CCConst2
= maxpos
;
3935 nha
->nha_JoypadOp
= HUAT_CLEAR
;
3936 nha
->nha_JoypadFeat
= posaxis
;
3937 nha
->nha_JoypadPort
= 1;
3939 if((nha
= nAllocAction(nch
, lst
, HUA_DIGJOY
|HUA_ANY
)))
3941 nha
->nha_CCEnable
= TRUE
;
3942 nha
->nha_CCCond
= HUAT_GE
;
3943 nha
->nha_CCConst2
= maxpos
;
3944 nha
->nha_JoypadOp
= HUAT_SET
;
3945 nha
->nha_JoypadFeat
= posaxis
;
3946 nha
->nha_JoypadPort
= 1;
3948 if((nha
= nAllocAction(nch
, lst
, HUA_ANALOGJOY
|HUA_ANY
)))
3950 nha
->nha_APadFeat
= alogaxis
;
3951 nha
->nha_JoypadPort
= 1;
3958 if(nFindCollID(nch
, nhc
, 0x010008, 0x010008) && (nhi
->nhi_Flags
& RPF_MAIN_RELATIVE
)) /* Multi-axis controller */
3962 case 0x30: /* Mouse X */
3963 if((nha
= nAllocAction(nch
, lst
, HUA_MOUSEPOS
|HUA_ALWAYS
)))
3965 nha
->nha_MouseAxis
= HUAT_DELTAX
;
3966 nha
->nha_ClipEnable
= TRUE
;
3967 nha
->nha_ClipMin
= 10;
3968 nha
->nha_ClipMax
= 45;
3969 nha
->nha_ClipStretch
= TRUE
;
3970 nha
->nha_ScaleEnable
= TRUE
;
3971 nha
->nha_ScaleMin
= -32;
3972 nha
->nha_ScaleMax
= 0;
3973 nha
->nha_CCEnable
= TRUE
;
3974 nha
->nha_CCVar1
= HUAT_OITEMVALUE
;
3975 nha
->nha_CCCond
= HUAT_LT
;
3976 nha
->nha_CCConst2
= 0;
3978 if((nha
= nAllocAction(nch
, lst
, HUA_MOUSEPOS
|HUA_ALWAYS
)))
3980 nha
->nha_MouseAxis
= HUAT_DELTAX
;
3981 nha
->nha_ClipEnable
= TRUE
;
3982 nha
->nha_ClipMin
= 55;
3983 nha
->nha_ClipMax
= 90;
3984 nha
->nha_ClipStretch
= TRUE
;
3985 nha
->nha_ScaleEnable
= TRUE
;
3986 nha
->nha_ScaleMin
= 0;
3987 nha
->nha_ScaleMax
= 32;
3988 nha
->nha_CCEnable
= TRUE
;
3989 nha
->nha_CCVar1
= HUAT_OITEMVALUE
;
3990 nha
->nha_CCCond
= HUAT_GT
;
3991 nha
->nha_CCConst2
= 0;
3995 case 0x31: /* Mouse Y */
3996 if((nha
= nAllocAction(nch
, lst
, HUA_MOUSEPOS
|HUA_ALWAYS
)))
3998 nha
->nha_MouseAxis
= HUAT_DELTAY
;
3999 nha
->nha_ClipEnable
= TRUE
;
4000 nha
->nha_ClipMin
= 10;
4001 nha
->nha_ClipMax
= 45;
4002 nha
->nha_ClipStretch
= TRUE
;
4003 nha
->nha_ScaleEnable
= TRUE
;
4004 nha
->nha_ScaleMin
= -32;
4005 nha
->nha_ScaleMax
= 0;
4006 nha
->nha_CCEnable
= TRUE
;
4007 nha
->nha_CCVar1
= HUAT_OITEMVALUE
;
4008 nha
->nha_CCCond
= HUAT_LT
;
4009 nha
->nha_CCConst2
= 0;
4011 if((nha
= nAllocAction(nch
, lst
, HUA_MOUSEPOS
|HUA_ALWAYS
)))
4013 nha
->nha_MouseAxis
= HUAT_DELTAY
;
4014 nha
->nha_ClipEnable
= TRUE
;
4015 nha
->nha_ClipMin
= 55;
4016 nha
->nha_ClipMax
= 90;
4017 nha
->nha_ClipStretch
= TRUE
;
4018 nha
->nha_ScaleEnable
= TRUE
;
4019 nha
->nha_ScaleMin
= 0;
4020 nha
->nha_ScaleMax
= 32;
4021 nha
->nha_CCEnable
= TRUE
;
4022 nha
->nha_CCVar1
= HUAT_OITEMVALUE
;
4023 nha
->nha_CCCond
= HUAT_GT
;
4024 nha
->nha_CCConst2
= 0;
4028 case 0x32: /* Mouse Z */
4030 LONG minpos
= (((nhi
->nhi_LogicalMax
- nhi
->nhi_LogicalMin
+ 1)*3)>>3) + nhi
->nhi_LogicalMin
;
4031 LONG maxpos
= (((nhi
->nhi_LogicalMax
- nhi
->nhi_LogicalMin
+ 1)*5)>>3) + nhi
->nhi_LogicalMin
;
4032 UWORD led
= nFindItemUsage(nch
, 0x08004B, REPORT_MAIN_OUTPUT
); // blue LED
4035 if((nha
= nAllocAction(nch
, lst
, HUA_BUTTONS
|HUA_ANY
)))
4037 nha
->nha_ButtonMode
= HUAT_SET
;
4038 nha
->nha_ButtonNo
= 1;
4039 nha
->nha_CCEnable
= TRUE
;
4040 nha
->nha_CCCond
= HUAT_GT
;
4041 nha
->nha_CCConst2
= maxpos
;
4043 if(led
&& ((nha
= nAllocAction(nch
, lst
, HUA_OUTPUT
|HUA_ANY
))))
4045 nha
->nha_OutOp
= HUAT_SET
;
4046 nha
->nha_OutItem
= led
;
4047 nha
->nha_CCEnable
= TRUE
;
4048 nha
->nha_CCCond
= HUAT_GT
;
4049 nha
->nha_CCConst2
= maxpos
;
4051 if((nha
= nAllocAction(nch
, lst
, HUA_BUTTONS
|HUA_ANY
)))
4053 nha
->nha_ButtonMode
= HUAT_CLEAR
;
4054 nha
->nha_ButtonNo
= 1;
4055 nha
->nha_CCEnable
= TRUE
;
4056 nha
->nha_CCCond
= HUAT_LT
;
4057 nha
->nha_CCConst2
= maxpos
;
4059 if(led
&& ((nha
= nAllocAction(nch
, lst
, HUA_OUTPUT
|HUA_ANY
))))
4061 nha
->nha_OutOp
= HUAT_CLEAR
;
4062 nha
->nha_OutItem
= led
;
4063 nha
->nha_CCEnable
= TRUE
;
4064 nha
->nha_CCCond
= HUAT_LT
;
4065 nha
->nha_CCConst2
= maxpos
;
4070 if((nha
= nAllocAction(nch
, lst
, HUA_BUTTONS
|HUA_ANY
)))
4072 nha
->nha_ButtonMode
= HUAT_SET
;
4073 nha
->nha_ButtonNo
= 2;
4074 nha
->nha_CCEnable
= TRUE
;
4075 nha
->nha_CCCond
= HUAT_LT
;
4076 nha
->nha_CCConst2
= minpos
;
4078 if((nha
= nAllocAction(nch
, lst
, HUA_BUTTONS
|HUA_ANY
)))
4080 nha
->nha_ButtonMode
= HUAT_CLEAR
;
4081 nha
->nha_ButtonNo
= 2;
4082 nha
->nha_CCEnable
= TRUE
;
4083 nha
->nha_CCCond
= HUAT_GT
;
4084 nha
->nha_CCConst2
= minpos
;
4090 case 0x35: /* Z rotation */
4092 LONG minpos
= (((nhi
->nhi_LogicalMax
- nhi
->nhi_LogicalMin
+ 1)*2)>>3) + nhi
->nhi_LogicalMin
;
4093 LONG maxpos
= (((nhi
->nhi_LogicalMax
- nhi
->nhi_LogicalMin
+ 1)*6)>>3) + nhi
->nhi_LogicalMin
;
4096 if((nha
= nAllocAction(nch
, lst
, HUA_WHEEL
|HUA_ANY
)))
4098 nha
->nha_WheelMode
= HUAT_DOWN
;
4099 nha
->nha_WheelDist
= 1;
4100 nha
->nha_CCEnable
= TRUE
;
4101 nha
->nha_CCCond
= HUAT_GT
;
4102 nha
->nha_CCConst2
= maxpos
;
4107 if((nha
= nAllocAction(nch
, lst
, HUA_WHEEL
|HUA_ANY
)))
4109 nha
->nha_WheelMode
= HUAT_UP
;
4110 nha
->nha_WheelDist
= 1;
4111 nha
->nha_CCEnable
= TRUE
;
4112 nha
->nha_CCCond
= HUAT_LT
;
4113 nha
->nha_CCConst2
= minpos
;
4122 case 0x09: /* Button page */
4123 if(nFindCollID(nch
, nhc
, 0x010002, 0x010002) || /* Mice */
4124 nFindCollID(nch
, nhc
, 0x0d0001, 0x0d000d) || /* Tablets */
4125 nFindCollID(nch
, nhc
, 0x010008, 0x010008)) /* Multi-Axis controller */
4127 if(usageid
&& (usageid
< 6))
4129 if((nha
= nAllocAction(nch
, lst
, HUA_BUTTONS
|HUA_ANY
)))
4131 nha
->nha_ButtonMode
= HUAT_ASSIGN
;
4132 nha
->nha_ButtonNo
= usageid
;
4136 if(nFindCollID(nch
, nhc
, 0x010004, 0x010005)) /* Joystick, Game Pad */
4138 if(usageid
&& (usageid
< 8))
4140 if((nha
= nAllocAction(nch
, lst
, HUA_DIGJOY
|HUA_ANY
)))
4142 nha
->nha_JoypadOp
= HUAT_ASSIGN
;
4143 nha
->nha_JoypadFeat
= HUAT_RED
+ usageid
- 1;
4144 nha
->nha_JoypadPort
= 1;
4150 case 0x07: /* keyboard page */
4153 case 0x39: /* Caps lock */
4156 if((nha
= nAllocAction(nch
, lst
, HUA_QUALIFIER
|HUA_DOWNEVENT
)))
4158 nha
->nha_QualMode
= HUAT_TOGGLE
;
4159 nha
->nha_Qualifier
= IEQUALIFIERB_CAPSLOCK
;
4161 if((led
= nFindItemUsage(nch
, 0x080002, REPORT_MAIN_OUTPUT
)))
4163 if((nha
= nAllocAction(nch
, lst
, HUA_OUTPUT
|HUA_DOWNEVENT
)))
4165 nha
->nha_OutOp
= HUAT_SET
;
4166 nha
->nha_OutItem
= led
;
4167 nha
->nha_CCEnable
= TRUE
;
4168 nha
->nha_CCVar1
= HUAT_QUALIFIERS
;
4169 nha
->nha_CCCond
= HUAT_BWAND
;
4170 nha
->nha_CCVar2
= HUAT_CONST
;
4171 nha
->nha_CCConst2
= IEQUALIFIER_CAPSLOCK
;
4173 if((nha
= nAllocAction(nch
, lst
, HUA_OUTPUT
|HUA_DOWNEVENT
)))
4175 nha
->nha_OutOp
= HUAT_CLEAR
;
4176 nha
->nha_OutItem
= led
;
4177 nha
->nha_CCEnable
= TRUE
;
4178 nha
->nha_CCVar1
= HUAT_QUALIFIERS
;
4179 nha
->nha_CCCond
= HUAT_BWNAND
;
4180 nha
->nha_CCVar2
= HUAT_CONST
;
4181 nha
->nha_CCConst2
= IEQUALIFIER_CAPSLOCK
;
4187 case 0xe0: /* Left control */
4188 if((nha
= nAllocAction(nch
, lst
, HUA_QUALIFIER
|HUA_ANY
)))
4190 nha
->nha_QualMode
= HUAT_ASSIGN
;
4191 nha
->nha_Qualifier
= IEQUALIFIERB_CONTROL
;
4195 case 0xe1: /* Left shift */
4196 if((nha
= nAllocAction(nch
, lst
, HUA_QUALIFIER
|HUA_ANY
)))
4198 nha
->nha_QualMode
= HUAT_ASSIGN
;
4199 nha
->nha_Qualifier
= IEQUALIFIERB_LSHIFT
;
4203 case 0xe2: /* Left alt */
4204 if((nha
= nAllocAction(nch
, lst
, HUA_QUALIFIER
|HUA_ANY
)))
4206 nha
->nha_QualMode
= HUAT_ASSIGN
;
4207 nha
->nha_Qualifier
= IEQUALIFIERB_LALT
;
4211 case 0xe3: /* Left GUI */
4212 if((nha
= nAllocAction(nch
, lst
, HUA_QUALIFIER
|HUA_ANY
)))
4214 nha
->nha_QualMode
= HUAT_ASSIGN
;
4215 nha
->nha_Qualifier
= IEQUALIFIERB_LCOMMAND
;
4219 case 0xe4: /* Right control */
4220 if((nha
= nAllocAction(nch
, lst
, HUA_QUALIFIER
|HUA_ANY
)))
4222 nha
->nha_QualMode
= HUAT_ASSIGN
;
4223 nha
->nha_Qualifier
= IEQUALIFIERB_CONTROL
;
4227 case 0xe5: /* Right shift */
4228 if((nha
= nAllocAction(nch
, lst
, HUA_QUALIFIER
|HUA_ANY
)))
4230 nha
->nha_QualMode
= HUAT_ASSIGN
;
4231 nha
->nha_Qualifier
= IEQUALIFIERB_RSHIFT
;
4235 case 0xe6: /* Right alt */
4236 if((nha
= nAllocAction(nch
, lst
, HUA_QUALIFIER
|HUA_ANY
)))
4238 nha
->nha_QualMode
= HUAT_ASSIGN
;
4239 nha
->nha_Qualifier
= IEQUALIFIERB_RALT
;
4243 case 0x45: /* F12 */
4244 case 0x65: /* Application */
4245 case 0xe7: /* Right GUI */
4246 if((nha
= nAllocAction(nch
, lst
, HUA_QUALIFIER
|HUA_ANY
)))
4248 nha
->nha_QualMode
= HUAT_ASSIGN
;
4249 nha
->nha_Qualifier
= IEQUALIFIERB_RCOMMAND
;
4253 nha
= nAllocAction(nch
, lst
, HUA_KEYMAP
|HUA_ANY
);
4256 case 0x0d: /* digitizer/tablet page */
4259 case 0x30: /* Tip pressure */
4260 case 0x31: /* Barrel pressure */
4261 if((nha
= nAllocAction(nch
, lst
, HUA_TABLET
|HUA_ALWAYS
)))
4263 nha
->nha_TabletAxis
= HUAT_PRESSURE
;
4267 case 0x32: /* In Range */
4268 case 0x37: /* Data Valid */
4269 if((nha
= nAllocAction(nch
, lst
, HUA_TABLET
|HUA_ALWAYS
)))
4271 nha
->nha_TabletAxis
= HUAT_PROX
;
4275 case 0x3D: /* X Tilt */
4276 if((nha
= nAllocAction(nch
, lst
, HUA_TABLET
|HUA_ALWAYS
)))
4278 nha
->nha_TabletAxis
= HUAT_XROT
;
4282 case 0x3E: /* Y Tilt */
4283 if((nha
= nAllocAction(nch
, lst
, HUA_TABLET
|HUA_ALWAYS
)))
4285 nha
->nha_TabletAxis
= HUAT_YROT
;
4289 case 0x42: /* Tip switch */
4290 if((nha
= nAllocAction(nch
, lst
, HUA_BUTTONS
|HUA_ANY
)))
4292 nha
->nha_ButtonMode
= HUAT_ASSIGN
;
4293 nha
->nha_ButtonNo
= 1;
4297 case 0x44: /* Barrel switch */
4298 if((nha
= nAllocAction(nch
, lst
, HUA_BUTTONS
|HUA_ANY
)))
4300 nha
->nha_ButtonMode
= HUAT_ASSIGN
;
4301 nha
->nha_ButtonNo
= 2;
4305 case 0x46: /* Tablet pick */
4306 if((nha
= nAllocAction(nch
, lst
, HUA_BUTTONS
|HUA_ANY
)))
4308 nha
->nha_ButtonMode
= HUAT_ASSIGN
;
4309 nha
->nha_ButtonNo
= 3;
4315 while(utp
->utp_UsageID
&& (utp
->utp_UsageID
<= uid
))
4317 if(utp
->utp_UsageID
== uid
)
4319 if((nha
= nAllocAction(nch
, lst
, HUA_EXTRAWKEY
|HUA_DOWNEVENT
)))
4321 nha
->nha_RawKey
= utp
->utp_ExtCode
;
4323 if((nha
= nAllocAction(nch
, lst
, HUA_EXTRAWKEY
|HUA_UPEVENT
)))
4325 nha
->nha_RawKey
= utp
->utp_ExtCode
|IECODE_UP_PREFIX
;
4334 /* /// "nCheckForDefaultAction()" */
4335 BOOL
nCheckForDefaultAction(struct NepClassHid
*nch
, struct NepHidItem
*nhi
, struct List
*lst
, struct NepHidCollection
*nhc
, ULONG uid
)
4338 struct NepHidAction
*nha
;
4339 struct NepHidAction
*nhadef
;
4340 struct List tmplist
;
4343 nDetectDefaultAction(nch
, nhi
, &tmplist
, nhc
, nhi
->nhi_Usage
);
4344 nha
= (struct NepHidAction
*) nhi
->nhi_ActionList
.lh_Head
;
4345 nhadef
= (struct NepHidAction
*) tmplist
.lh_Head
;
4346 while(nha
->nha_Node
.ln_Succ
)
4348 if(nhadef
->nha_Node
.ln_Succ
)
4350 nhadef
->nha_IsDefault
= nha
->nha_IsDefault
;
4351 if(memcmp(&nha
->nha_Type
, &nhadef
->nha_Type
, sizeof(struct NepHidAction
)-offsetof(struct NepHidAction
, nha_Type
)))
4353 nha
->nha_IsDefault
= FALSE
;
4356 nha
->nha_IsDefault
= TRUE
;
4358 nhadef
= (struct NepHidAction
*) nhadef
->nha_Node
.ln_Succ
;
4361 nha
->nha_IsDefault
= FALSE
;
4363 nha
= (struct NepHidAction
*) nha
->nha_Node
.ln_Succ
;
4365 nhadef
= (struct NepHidAction
*) tmplist
.lh_Head
;
4366 while(nhadef
->nha_Node
.ln_Succ
)
4368 Remove(&nhadef
->nha_Node
);
4370 nhadef
= (struct NepHidAction
*) tmplist
.lh_Head
;
4376 /* /// "nAllocAction()" */
4377 struct NepHidAction
* nAllocAction(struct NepClassHid
*nch
, struct List
*lst
, UWORD utype
)
4379 struct NepHidAction
*nha
= psdAllocVec(sizeof(struct NepHidAction
));
4382 KPRINTF(1, ("New action %lx\n", nha
));
4383 nha
->nha_Type
= utype
;
4384 nha
->nha_ButtonNo
= 1;
4385 nha
->nha_SoundVolume
= 64;
4386 nha
->nha_ClipMax
= 100;
4387 nha
->nha_CCVar1
= HUAT_EITEMVALUE
;
4388 nha
->nha_CCVar2
= HUAT_CONST
;
4389 AddTail(lst
, &nha
->nha_Node
);
4396 /* /// "nAddUsage()" */
4397 BOOL
nAddUsage(struct NepClassHid
*nch
, struct List
*list
, ULONG umin
, ULONG umax
)
4399 struct NepHidUsage
*nhu
;
4402 KPRINTF(10, ("UsageMin %lx > UsageMax %lx\n", umin
, umax
));
4405 if((nhu
= psdAllocVec(sizeof(struct NepHidUsage
))))
4407 AddTail(list
, &nhu
->nhu_Node
);
4408 nhu
->nhu_Usage
= umin
;
4409 nhu
->nhu_UsageMax
= umax
;
4412 KPRINTF(10, ("Out of memory during usage allocation.\n"));
4418 /* /// "nGetUsageName()" */
4419 STRPTR
nGetUsageName(struct NepClassHid
*nch
, ULONG uid
)
4423 uname
= nNumToStr(nch
, NTS_USAGEID
, uid
, NULL
);
4426 return(psdCopyStr(uname
));
4428 uname
= nNumToStr(nch
, NTS_USAGEPAGE
, uid
>>16, "unknown");
4429 return(psdCopyStrFmt("%s (0x%lx)", uname
, uid
));
4433 /* /// "nGenerateOutReport()" */
4434 void nGenerateOutReport(struct NepClassHid
*nch
, struct NepHidReport
*nhr
, UBYTE
*buf
)
4436 struct NepHidItem
**nhiptr
= nhr
->nhr_OutItemMap
;
4439 for(cnt
= 0; cnt
< nhr
->nhr_OutItemCount
; cnt
++)
4441 nEncodeItemBuffer(nch
, *nhiptr
++, buf
);
4446 /* /// "nGenerateFeatReport()" */
4447 void nGenerateFeatReport(struct NepClassHid
*nch
, struct NepHidReport
*nhr
, UBYTE
*buf
)
4449 struct NepHidItem
**nhiptr
= nhr
->nhr_FeatItemMap
;
4452 for(cnt
= 0; cnt
< nhr
->nhr_FeatItemCount
; cnt
++)
4454 nEncodeItemBuffer(nch
, *nhiptr
++, buf
);
4459 /* /// "nEncodeItemBuffer()" */
4460 void nEncodeItemBuffer(struct NepClassHid
*nch
, struct NepHidItem
*nhi
, UBYTE
*buf
)
4469 ioffset
= nhi
->nhi_Offset
;
4470 isize
= nhi
->nhi_Size
;
4471 if(nhi
->nhi_Flags
& RPF_MAIN_VARIABLE
)
4473 //KPRINTF(1, ("Processing var %08lx (%ld@%ld)...\n", nhi, isize, ioffset));
4474 value
= nhi
->nhi_OldValue
;
4475 if(value
< nhi
->nhi_LogicalMin
)
4477 value
= nhi
->nhi_LogicalMin
;
4479 else if(value
> nhi
->nhi_LogicalMax
)
4481 value
= nhi
->nhi_LogicalMax
;
4483 if(((ioffset
& 7) == 0) && (isize
== 8))
4485 buf
[ioffset
>>3] = value
;
4489 buf
[ioffset
>>3] &= ~(1UL<<(ioffset
& 7));
4492 buf
[ioffset
>>3] |= (1UL<<(ioffset
& 7));
4495 /* I know this routine is dead slow, but hopefully, this is only a very uncommon case */
4501 buf
[ioffset
>>3] &= ~(1UL<<(ioffset
& 7));
4504 buf
[ioffset
>>3] |= (1UL<<(ioffset
& 7));
4510 acount
= nhi
->nhi_Count
;
4511 KPRINTF(1, ("Processing arr %08lx (%ld@%ld) * %ld...\n", nhi
, isize
, ioffset
, acount
));
4512 /* first generate the values */
4513 valptr
= nhi
->nhi_Buffer
;
4514 if(((ioffset
& 7) == 0) && (isize
== 8))
4519 buf
[count
++] = *valptr
++;
4526 buf
[ioffset
>>3] &= ~(1UL<<(ioffset
& 7));
4529 buf
[ioffset
>>3] |= (1UL<<(ioffset
& 7));
4534 /* I know this routine is dead slow, but hopefully, this is only a very uncommon case */
4543 buf
[ioffset
>>3] &= ~(1UL<<(ioffset
& 7));
4546 buf
[ioffset
>>3] |= (1UL<<(ioffset
& 7));
4557 /* /// "nParseArrayString()" */
4558 void nParseArrayString(struct NepClassHid
*nch
, struct NepHidItem
*nhi
, STRPTR str
)
4561 LONG
*valptr
= nhi
->nhi_Buffer
;
4563 BOOL issigned
= FALSE
;
4567 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
), "Parse error: Empty array value string not allowed.");
4570 acount
= nhi
->nhi_Count
;
4573 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
), "Parse error: Target array has no space!");
4576 // mode == 0 -> start
4577 // mode == 1 -> decimal value
4578 // mode == 2 -> hex value
4579 // mode == 3 -> ascii character
4580 // mode == 4 -> string
4581 // mode == 5 -> waiting for termination
4583 while(*str
&& acount
)
4589 if((ch
== '0') && (*str
== 'x'))
4596 if((ch
>= '0') && (ch
<= '9'))
4623 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
), "Parse error: Syntax error in S0!");
4626 case 1: // decimal value
4627 if((ch
>= '0') && (ch
<= '9'))
4632 *valptr
-= ch
- '0';
4634 *valptr
+= ch
- '0';
4650 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
), "Parse error: Syntax error in S1!");
4653 case 2: // hex value
4654 if((ch
>= '0') && (ch
<= '9'))
4657 *valptr
+= ch
- '0';
4660 else if((ch
>= 'a') && (ch
<= 'f'))
4663 *valptr
+= ch
- 'a' + 10;
4666 else if((ch
>= 'A') && (ch
<= 'F'))
4669 *valptr
+= ch
- 'A' + 10;
4679 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
), "Parse error: Syntax error in S2!");
4682 case 3: // ascii character
4690 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
), "Parse error: Syntax error in S3!");
4703 case 5: // waiting for termination
4715 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
), "Parse error: Syntax error in S5!");
4723 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
), "Parse error: Syntax error in S3!");
4736 psdAddErrorMsg(RETURN_WARN
, (STRPTR
) GM_UNIQUENAME(libname
), "Parse error: Excessive elements ignored!");
4741 /* /// "nProcessItem()" */
4742 BOOL
nProcessItem(struct NepClassHid
*nch
, struct NepHidItem
*nhi
, UBYTE
*buf
)
4747 ULONG ioffset
= nhi
->nhi_Offset
;
4748 ULONG isize
= nhi
->nhi_Size
;
4749 UBYTE
*bobuf
= &buf
[ioffset
>>3];
4754 BOOL bytealigned
= ((ioffset
& 7) == 0);
4755 struct NepHidAction
*nha
;
4757 if(nhi
->nhi_Flags
& RPF_MAIN_VARIABLE
)
4759 //KPRINTF(1, ("Processing var %08lx (%ld@%ld)...\n", nhi, isize, ioffset));
4760 if(bytealigned
&& (isize
== 8))
4762 if(nhi
->nhi_IsSigned
)
4764 value
= *((BYTE
*) bobuf
);
4771 value
= (buf
[ioffset
>>3]>>(ioffset
& 7)) & 1;
4773 else if(bytealigned
&& (isize
== 16))
4775 if(nhi
->nhi_IsSigned
)
4777 value
= (*bobuf
)|((((BYTE
*) bobuf
)[1])<<8);
4779 value
= (*bobuf
)|(bobuf
[1]<<8);
4782 else if(bytealigned
&& (isize
== 32))
4784 value
= bobuf
[0]|(bobuf
[1]<<8)|(bobuf
[2]<<16)|(bobuf
[3]<<24);
4786 /* I know this routine is dead slow, but hopefully, this is only a very uncommon case */
4790 if(nhi
->nhi_IsSigned
)
4794 if((buf
[ioffset
>>3]>>(ioffset
& 7)) & 1)
4803 value
|= (buf
[ioffset
>>3]>>(ioffset
& 7)) & 1;
4806 if((value
>= nhi
->nhi_LogicalMin
) && (value
<= nhi
->nhi_LogicalMax
))
4808 ULONG currmicros
= 0;
4810 if(nhi
->nhi_OldValue
!= value
)
4812 if((nhi
->nhi_Usage
> 0x070000) && (nhi
->nhi_Usage
< 0x0700E8))
4814 nch
->nch_LastUSBKey
= nhi
->nhi_Usage
;
4816 nch
->nch_LastItem
= nhi
;
4817 nch
->nch_LastItemAList
= &nhi
->nhi_ActionList
;
4820 if(nch
->nch_HIntBase
)
4822 CurrentTime(&currsecs
, &currmicros
);
4823 if(!DoubleClick(nhi
->nhi_LastSeconds
, nhi
->nhi_LastMicros
, currsecs
, currmicros
))
4825 nhi
->nhi_ClickCount
= 0;
4827 if(nhi
->nhi_OldValue
< value
)
4829 if(nhi
->nhi_LastSeconds
|| nhi
->nhi_LastMicros
)
4831 if(DoubleClick(nhi
->nhi_LastSeconds
, nhi
->nhi_LastMicros
, currsecs
, currmicros
))
4833 nhi
->nhi_ClickCount
++;
4835 nhi
->nhi_ClickCount
= 1;
4838 nhi
->nhi_ClickCount
= 1;
4840 nhi
->nhi_HoldSeconds
= nhi
->nhi_LastSeconds
= currsecs
;
4841 nhi
->nhi_HoldMicros
= nhi
->nhi_LastMicros
= currmicros
;
4844 /* no intuition library */
4845 nhi
->nhi_ClickCount
= 0;
4846 if(nhi
->nhi_OldValue
< value
)
4848 nhi
->nhi_ClickCount
= 1;
4851 nha
= (struct NepHidAction
*) nhi
->nhi_ActionList
.lh_Head
;
4852 while(nha
->nha_Node
.ln_Succ
)
4854 if((nhi
->nhi_OldValue
!= value
) || ((nha
->nha_Type
& HUA_TRIGMASK
) == HUA_ALWAYS
))
4856 nDoAction(nch
, nha
, nhi
, nhi
->nhi_Usage
, value
, (nhi
->nhi_OldValue
< value
) || ((nha
->nha_Type
& HUA_TRIGMASK
) == HUA_ALWAYS
));
4858 nha
= (struct NepHidAction
*) nha
->nha_Node
.ln_Succ
;
4860 if(nhi
->nhi_OldValue
> value
)
4862 nhi
->nhi_HoldSeconds
= 0;
4863 nhi
->nhi_HoldMicros
= 0;
4865 if((nhi
->nhi_OldValue
!= value
) && nch
->nch_ReportValues
&&
4866 nch
->nch_GUICurrentItem
&& (nch
->nch_GUICurrentItem
->nhgi_Item
== nhi
))
4868 nch
->nch_ItemChanged
= TRUE
;
4870 nhi
->nhi_OldValue
= value
;
4873 nha
= (struct NepHidAction
*) nhi
->nhi_ActionList
.lh_Head
;
4874 while(nha
->nha_Node
.ln_Succ
)
4876 if((nha
->nha_Type
& HUA_TRIGMASK
) == HUA_NAN
)
4878 nDoAction(nch
, nha
, nhi
, nhi
->nhi_Usage
, nhi
->nhi_OldValue
, 0);
4880 nha
= (struct NepHidAction
*) nha
->nha_Node
.ln_Succ
;
4884 nhi
->nhi_HoldSeconds
= nhi
->nhi_LastSeconds
= 0;
4885 nhi
->nhi_HoldMicros
= nhi
->nhi_LastMicros
= 0;
4886 acount
= nhi
->nhi_Count
;
4887 KPRINTF(1, ("Processing arr %08lx (%ld@%ld) * %ld...\n", nhi
, isize
, ioffset
, acount
));
4888 /* first generate the values */
4889 valptr
= nhi
->nhi_Buffer
;
4890 if(bytealigned
&& (isize
== 8))
4893 if(nhi
->nhi_IsSigned
)
4897 *valptr
++ = ((BYTE
*) buf
)[count
++];
4902 *valptr
++ = buf
[count
++];
4910 *valptr
++ = (buf
[ioffset
>>3]>>(ioffset
& 7)) & 1;
4914 /* I know this routine is dead slow, but hopefully, this is only a very uncommon case */
4920 if(nhi
->nhi_IsSigned
)
4924 if((buf
[ioffset
>>3]>>(ioffset
& 7)) & 1)
4933 value
|= (buf
[ioffset
>>3]>>(ioffset
& 7)) & 1;
4940 /* Look for up events first */
4944 value
= nhi
->nhi_OldBuffer
[acount
];
4945 if((value
>= nhi
->nhi_LogicalMin
) && (value
<= nhi
->nhi_LogicalMax
))
4947 valptr
= nhi
->nhi_Buffer
;
4948 count
= nhi
->nhi_Count
;
4952 if(*valptr
++ == value
)
4958 /* Not found in the new array, so generate up event */
4961 KPRINTF(1, ("Up event %ld\n", acount
));
4962 usage
= nhi
->nhi_UsageMap
[value
- nhi
->nhi_LogicalMin
];
4963 if(value
|| nhi
->nhi_LogicalMin
)
4965 nch
->nch_LastItem
= nhi
;
4966 nch
->nch_LastItemAList
= &nhi
->nhi_ActionMap
[value
- nhi
->nhi_LogicalMin
];
4968 nha
= (struct NepHidAction
*) nhi
->nhi_ActionMap
[value
- nhi
->nhi_LogicalMin
].lh_Head
;
4969 if(!nha
->nha_Node
.ln_Succ
) /* Use default, no override defined */
4971 nha
= (struct NepHidAction
*) nhi
->nhi_ActionList
.lh_Head
;
4973 nhi
->nhi_OldValue
= nhi
->nhi_LogicalMin
- 1;
4974 while(nha
->nha_Node
.ln_Succ
)
4976 nDoAction(nch
, nha
, nhi
, usage
, value
, FALSE
);
4977 nha
= (struct NepHidAction
*) nha
->nha_Node
.ln_Succ
;
4982 } while(++acount
< nhi
->nhi_Count
);
4984 /* Look for down events */
4988 value
= nhi
->nhi_Buffer
[acount
];
4989 //KPRINTF(1, ("[%ld] = %ld\n", acount, value));
4990 if((value
>= nhi
->nhi_LogicalMin
) && (value
<= nhi
->nhi_LogicalMax
))
4992 valptr
= nhi
->nhi_OldBuffer
;
4993 count
= nhi
->nhi_Count
;
4997 if(*valptr
++ == value
)
5003 /* Not found in the old array, so generate down event */
5006 KPRINTF(1, ("Down event %ld\n", acount
));
5007 usage
= nhi
->nhi_UsageMap
[value
- nhi
->nhi_LogicalMin
];
5008 if(value
|| nhi
->nhi_LogicalMin
)
5010 if((usage
> 0x070000) && (usage
< 0x0700E8))
5012 nch
->nch_LastUSBKey
= usage
;
5014 nch
->nch_LastItem
= nhi
;
5015 nch
->nch_LastItemAList
= &nhi
->nhi_ActionMap
[value
- nhi
->nhi_LogicalMin
];
5018 nha
= (struct NepHidAction
*) nhi
->nhi_ActionMap
[value
- nhi
->nhi_LogicalMin
].lh_Head
;
5019 if(!nha
->nha_Node
.ln_Succ
) /* Use default, no override defined */
5021 nha
= (struct NepHidAction
*) nhi
->nhi_ActionList
.lh_Head
;
5023 nhi
->nhi_OldValue
= nhi
->nhi_LogicalMin
- 1;
5024 while(nha
->nha_Node
.ln_Succ
)
5026 nDoAction(nch
, nha
, nhi
, usage
, value
, TRUE
);
5027 nha
= (struct NepHidAction
*) nha
->nha_Node
.ln_Succ
;
5032 } while(++acount
< nhi
->nhi_Count
);
5033 /* Copy new array */
5034 CopyMemQuick(nhi
->nhi_Buffer
, nhi
->nhi_OldBuffer
, sizeof(LONG
) * nhi
->nhi_Count
);
5040 static ULONG LLHatswitchEncoding
[8] = { JPF_JOY_UP
, JPF_JOY_UP
|JPF_JOY_RIGHT
, JPF_JOY_RIGHT
, JPF_JOY_RIGHT
|JPF_JOY_DOWN
,
5041 JPF_JOY_DOWN
, JPF_JOY_DOWN
|JPF_JOY_LEFT
, JPF_JOY_LEFT
, JPF_JOY_LEFT
|JPF_JOY_UP
};
5043 /* /// "nDoAction()" */
5044 BOOL
nDoAction(struct NepClassHid
*nch
, struct NepHidAction
*nha
, struct NepHidItem
*nhi
, ULONG uid
, LONG value
, BOOL downevent
)
5046 UWORD atype
= nha
->nha_Type
& HUA_ATYPEMASK
;
5049 LONG clipmin
, clipmax
;
5050 LONG origvalue
= value
;
5052 if(nch
->nch_DisableActions
)
5057 // bail out early as nothing below will affect this
5058 if(!(((nha
->nha_Type
& HUA_DOWNEVENT
) && downevent
) ||
5059 ((nha
->nha_Type
& HUA_UPEVENT
) && !downevent
) ||
5060 ((nha
->nha_Type
& HUA_TRIGMASK
) == HUA_ALWAYS
) ||
5061 ((nha
->nha_Type
& HUA_TRIGMASK
) == HUA_NAN
)))
5066 if(nha
->nha_AbsToRel
)
5068 value
= value
- nhi
->nhi_OldValue
;
5069 nhi
->nhi_RealMin
= nhi
->nhi_LogicalMin
- nhi
->nhi_LogicalMax
;
5070 nhi
->nhi_RealMax
= nhi
->nhi_LogicalMax
- nhi
->nhi_LogicalMin
;
5072 nhi
->nhi_RealMin
= nhi
->nhi_LogicalMin
;
5073 nhi
->nhi_RealMax
= nhi
->nhi_LogicalMax
;
5076 if(nha
->nha_ClipEnable
)
5078 if(nha
->nha_ClipMin
== nha
->nha_ClipMax
)
5080 /* shrink to a point */
5081 value
= ((nha
->nha_ClipMin
* (nhi
->nhi_RealMax
- nhi
->nhi_RealMin
)) / 100) + nhi
->nhi_RealMin
;
5083 if(nha
->nha_ClipMin
< nha
->nha_ClipMax
)
5085 /* normal clipping */
5086 clipmin
= ((nha
->nha_ClipMin
* (nhi
->nhi_RealMax
- nhi
->nhi_RealMin
)) / 100) + nhi
->nhi_RealMin
;
5087 clipmax
= ((nha
->nha_ClipMax
* (nhi
->nhi_RealMax
- nhi
->nhi_RealMin
)) / 100) + nhi
->nhi_RealMin
;
5089 /* inverse clipping */
5090 value
= nhi
->nhi_RealMax
- value
;
5091 clipmin
= ((nha
->nha_ClipMax
* (nhi
->nhi_RealMax
- nhi
->nhi_RealMin
)) / 100) + nhi
->nhi_RealMin
;
5092 clipmax
= ((nha
->nha_ClipMin
* (nhi
->nhi_RealMax
- nhi
->nhi_RealMin
)) / 100) + nhi
->nhi_RealMin
;
5103 if(nha
->nha_ClipStretch
&& (clipmax
- clipmin
))
5105 value
= (((value
- clipmin
) * (nhi
->nhi_RealMax
- nhi
->nhi_RealMin
)) /
5106 (clipmax
- clipmin
)) + nhi
->nhi_RealMin
;
5111 if(nha
->nha_ScaleEnable
&& (nha
->nha_ScaleMax
!= nha
->nha_ScaleMin
))
5113 value
= (((value
- nhi
->nhi_RealMin
) * (nha
->nha_ScaleMax
- nha
->nha_ScaleMin
)) /
5114 (nhi
->nhi_RealMax
- nhi
->nhi_RealMin
)) + nha
->nha_ScaleMin
;
5115 nhi
->nhi_RealMin
= nha
->nha_ScaleMin
;
5116 nhi
->nhi_RealMax
= nha
->nha_ScaleMax
;
5119 if(nha
->nha_CCEnable
)
5125 switch(nha
->nha_CCVar1
)
5127 case HUAT_EITEMVALUE
:
5131 case HUAT_OITEMVALUE
:
5136 var1
= nha
->nha_CCConst1
;
5139 case HUAT_CLICKCOUNT
:
5140 var1
= nhi
->nhi_ClickCount
;
5143 case HUAT_CLICKTIME
:
5148 if(nhi
->nhi_HoldSeconds
|| nhi
->nhi_HoldMicros
)
5150 CurrentTime(&currsecs
, &currmicros
);
5151 var1
= (currsecs
- nhi
->nhi_HoldSeconds
) * 1000;
5152 if(nhi
->nhi_HoldMicros
<= currmicros
)
5154 var1
+= (currmicros
- nhi
->nhi_HoldMicros
) / 1000;
5156 var1
-= (nhi
->nhi_HoldMicros
- currmicros
) / 1000;
5164 case HUAT_QUALIFIERS
:
5165 var1
= nch
->nch_KeyQualifiers
;
5169 var1
= nch
->nch_KeyQualifiers
|PeekQualifier();
5172 case HUAT_RANDOMBIT
:
5173 var1
= _rand(nch
->nch_ClsBase
) & 1;
5176 case HUAT_RANDOMVAL
:
5177 var1
= _rand(nch
->nch_ClsBase
);
5185 CurrentTime(&currsecs
, &currmicros
);
5186 var1
= (currsecs
* 1000) + (currmicros
/ 1000);
5190 case HUAT_LOCALVAR1
:
5191 case HUAT_LOCALVAR2
:
5192 case HUAT_LOCALVAR3
:
5193 case HUAT_LOCALVAR4
:
5194 case HUAT_LOCALVAR5
:
5195 case HUAT_LOCALVAR6
:
5196 case HUAT_LOCALVAR7
:
5197 case HUAT_LOCALVAR8
:
5198 var1
= nch
->nch_LocalVars
[nha
->nha_CCVar1
- HUAT_LOCALVAR1
];
5209 var1
= nch
->nch_ClsBase
->nh_GlobalVars
[nha
->nha_CCVar1
- HUAT_GLOBVARA
];
5212 switch(nha
->nha_CCVar2
)
5214 case HUAT_EITEMVALUE
:
5218 case HUAT_OITEMVALUE
:
5223 var2
= nha
->nha_CCConst2
;
5226 case HUAT_CLICKCOUNT
:
5227 var2
= nhi
->nhi_ClickCount
;
5230 case HUAT_CLICKTIME
:
5235 if(nhi
->nhi_HoldSeconds
|| nhi
->nhi_HoldMicros
)
5237 CurrentTime(&currsecs
, &currmicros
);
5238 var2
= (currsecs
- nhi
->nhi_HoldSeconds
) * 1000;
5239 if(nhi
->nhi_HoldMicros
<= currmicros
)
5241 var2
+= (currmicros
- nhi
->nhi_HoldMicros
) / 1000;
5243 var2
-= (nhi
->nhi_HoldMicros
- currmicros
) / 1000;
5251 case HUAT_QUALIFIERS
:
5252 var2
= nch
->nch_KeyQualifiers
;
5256 var2
= nch
->nch_KeyQualifiers
|PeekQualifier();
5259 case HUAT_RANDOMBIT
:
5260 var2
= _rand(nch
->nch_ClsBase
) & 1;
5263 case HUAT_RANDOMVAL
:
5264 var2
= _rand(nch
->nch_ClsBase
);
5272 CurrentTime(&currsecs
, &currmicros
);
5273 var2
= (currsecs
* 1000) + (currmicros
/ 1000);
5277 case HUAT_LOCALVAR1
:
5278 case HUAT_LOCALVAR2
:
5279 case HUAT_LOCALVAR3
:
5280 case HUAT_LOCALVAR4
:
5281 case HUAT_LOCALVAR5
:
5282 case HUAT_LOCALVAR6
:
5283 case HUAT_LOCALVAR7
:
5284 case HUAT_LOCALVAR8
:
5285 var2
= nch
->nch_LocalVars
[nha
->nha_CCVar2
- HUAT_LOCALVAR1
];
5296 var2
= nch
->nch_ClsBase
->nh_GlobalVars
[nha
->nha_CCVar2
- HUAT_GLOBVARA
];
5299 switch(nha
->nha_CCCond
)
5302 cond
= (var1
== var2
);
5306 cond
= (var1
!= var2
);
5310 cond
= (var1
< var2
);
5314 cond
= (var1
<= var2
);
5318 cond
= (var1
> var2
);
5322 cond
= (var1
>= var2
);
5326 cond
= (var1
&& var2
);
5330 cond
= !(var1
&& var2
);
5334 cond
= (var1
|| var2
);
5338 cond
= (var1
&& (!var2
)) || ((!var1
) && var2
);
5342 cond
= (var1
&& (!var2
));
5346 cond
= (var1
& var2
) ? TRUE
: FALSE
;
5350 cond
= (var1
& var2
) ? FALSE
: TRUE
;
5354 cond
= (var1
| var2
) ? TRUE
: FALSE
;
5358 cond
= (var1
^ var2
) ? TRUE
: FALSE
;
5362 cond
= (var1
& (~var2
)) ? TRUE
: FALSE
;
5372 if(nha
->nha_ValEnable
)
5374 switch(nha
->nha_ValVar
)
5376 case HUAT_EITEMVALUE
:
5380 case HUAT_OITEMVALUE
:
5385 value
= nha
->nha_ValConst
;
5388 case HUAT_CLICKCOUNT
:
5389 value
= nhi
->nhi_ClickCount
;
5392 case HUAT_CLICKTIME
:
5397 if(nhi
->nhi_HoldSeconds
|| nhi
->nhi_HoldMicros
)
5399 CurrentTime(&currsecs
, &currmicros
);
5400 value
= (currsecs
- nhi
->nhi_HoldSeconds
) * 1000;
5401 if(nhi
->nhi_HoldMicros
<= currmicros
)
5403 value
+= (currmicros
- nhi
->nhi_HoldMicros
) / 1000;
5405 value
-= (nhi
->nhi_HoldMicros
- currmicros
) / 1000;
5413 case HUAT_QUALIFIERS
:
5414 value
= nch
->nch_KeyQualifiers
;
5418 value
= nch
->nch_KeyQualifiers
|PeekQualifier();
5421 case HUAT_RANDOMBIT
:
5422 value
= _rand(nch
->nch_ClsBase
) & 1;
5425 case HUAT_RANDOMVAL
:
5426 value
= _rand(nch
->nch_ClsBase
);
5434 CurrentTime(&currsecs
, &currmicros
);
5435 value
= (currsecs
* 1000) + (currmicros
/ 1000);
5439 case HUAT_LOCALVAR1
:
5440 case HUAT_LOCALVAR2
:
5441 case HUAT_LOCALVAR3
:
5442 case HUAT_LOCALVAR4
:
5443 case HUAT_LOCALVAR5
:
5444 case HUAT_LOCALVAR6
:
5445 case HUAT_LOCALVAR7
:
5446 case HUAT_LOCALVAR8
:
5447 value
= nch
->nch_LocalVars
[nha
->nha_ValVar
- HUAT_LOCALVAR1
];
5458 value
= nch
->nch_ClsBase
->nh_GlobalVars
[nha
->nha_ValVar
- HUAT_GLOBVARA
];
5462 //KPRINTF(1, ("Call for action(%04lx) %lx = %ld %s\n", atype, uid, value, downevent ? "down" : "up"));
5470 struct ActionMsg
*am
;
5471 if(!nch
->nch_ClsBase
->nh_DTaskMsgPort
)
5473 nInstallLastActionHero(nch
);
5475 if(nch
->nch_ClsBase
->nh_DTaskMsgPort
)
5477 if((am
= AllocVec(sizeof(struct ActionMsg
), MEMF_PUBLIC
)))
5479 am
->am_Msg
.mn_Length
= sizeof(struct ActionMsg
);
5480 am
->am_Msg
.mn_ReplyPort
= NULL
;
5482 am
->am_Action
= nha
;
5483 PutMsg(nch
->nch_ClsBase
->nh_DTaskMsgPort
, &am
->am_Msg
);
5490 nSendRawKey(nch
, nha
->nha_RawKey
);
5496 if((uid
> 0x70000) && (uid
< 0x700e8))
5498 iecode
= nch
->nch_KeymapCfg
.kmc_Keymap
[uid
& 0xff];
5499 KPRINTF(1,("Key %ld %s\n", iecode
, downevent
? "DOWN" : "UP"));
5500 nch
->nch_FakeEvent
.ie_Class
= IECLASS_RAWKEY
;
5501 nch
->nch_FakeEvent
.ie_SubClass
= 0;
5502 nSendRawKey(nch
, downevent
? iecode
: iecode
|IECODE_UP_PREFIX
);
5508 switch(nha
->nha_MouseAxis
)
5511 nch
->nch_NewMouseRel
= TRUE
;
5512 nch
->nch_MouseDeltaX
+= value
;
5516 nch
->nch_NewMouseRel
= TRUE
;
5517 nch
->nch_MouseDeltaY
+= value
;
5521 if(nch
->nch_MouseRangeY
)
5523 nch
->nch_NewMouseAbs
= TRUE
;
5525 nch
->nch_MouseAbsX
= value
- nhi
->nhi_RealMin
;
5526 nch
->nch_MouseRangeX
= (nhi
->nhi_RealMax
- nhi
->nhi_RealMin
) + 1;
5530 if(nch
->nch_MouseRangeX
)
5532 nch
->nch_NewMouseAbs
= TRUE
;
5534 nch
->nch_MouseAbsY
= value
- nhi
->nhi_RealMin
;
5535 nch
->nch_MouseRangeY
= (nhi
->nhi_RealMax
- nhi
->nhi_RealMin
) + 1;
5541 qualmask
= 1<<nha
->nha_Qualifier
;
5542 switch(nha
->nha_QualMode
)
5545 nch
->nch_KeyQualifiers
|= qualmask
;
5549 nch
->nch_KeyQualifiers
&= ~qualmask
;
5553 nch
->nch_KeyQualifiers
^= qualmask
;
5557 nch
->nch_KeyQualifiers
&= ~qualmask
;
5560 nch
->nch_KeyQualifiers
|= qualmask
;
5568 UWORD iecode
= IECODE_NOBUTTON
;
5570 BOOL newmouse
= FALSE
;
5572 switch(nha
->nha_ButtonNo
)
5575 iequal
= IEQUALIFIER_LEFTBUTTON
;
5576 iecode
= IECODE_LBUTTON
;
5580 iequal
= IEQUALIFIER_RBUTTON
;
5581 iecode
= IECODE_RBUTTON
;
5585 iequal
= IEQUALIFIER_MIDBUTTON
;
5586 iecode
= IECODE_MBUTTON
;
5590 iecode
= RAWKEY_NM_BUTTON_FOURTH
;
5595 switch(nha
->nha_ButtonMode
)
5598 if((!newmouse
) && (nch
->nch_KeyQualifiers
& iequal
))
5601 iecode
= IECODE_NOBUTTON
;
5603 nch
->nch_KeyQualifiers
|= iequal
;
5604 nch
->nch_MouseButtons
|= 1<<(nha
->nha_ButtonNo
-1);
5609 if(newmouse
|| (nch
->nch_KeyQualifiers
& iequal
))
5611 nch
->nch_KeyQualifiers
&= ~iequal
;
5612 nch
->nch_MouseButtons
&= ~(1<<(nha
->nha_ButtonNo
-1));
5614 iecode
|= IECODE_UP_PREFIX
;
5617 iecode
= IECODE_NOBUTTON
;
5624 if(nch
->nch_MouseButtons
& (1<<(nha
->nha_ButtonNo
-1)))
5626 nch
->nch_MouseButtons
&= ~(1<<(nha
->nha_ButtonNo
-1));
5627 iecode
|= IECODE_UP_PREFIX
;
5629 nch
->nch_MouseButtons
|= 1<<(nha
->nha_ButtonNo
-1);
5632 if(nch
->nch_KeyQualifiers
& iequal
)
5634 nch
->nch_KeyQualifiers
&= ~iequal
;
5635 nch
->nch_MouseButtons
&= ~(1<<(nha
->nha_ButtonNo
-1));
5637 iecode
|= IECODE_UP_PREFIX
;
5639 nch
->nch_KeyQualifiers
|= iequal
;
5640 nch
->nch_MouseButtons
|= 1<<(nha
->nha_ButtonNo
-1);
5648 if((!newmouse
) && (nch
->nch_KeyQualifiers
& iequal
))
5651 iecode
= IECODE_NOBUTTON
;
5653 nch
->nch_KeyQualifiers
|= iequal
;
5654 nch
->nch_MouseButtons
|= 1<<(nha
->nha_ButtonNo
-1);
5657 if(newmouse
|| (nch
->nch_KeyQualifiers
& iequal
))
5659 nch
->nch_KeyQualifiers
&= ~iequal
;
5660 nch
->nch_MouseButtons
&= ~(1<<(nha
->nha_ButtonNo
-1));
5662 iecode
|= IECODE_UP_PREFIX
;
5665 iecode
= IECODE_NOBUTTON
;
5671 iecode
= IECODE_NOBUTTON
;
5674 if(iecode
!= IECODE_NOBUTTON
)
5678 nSendRawKey(nch
, iecode
);
5680 nch
->nch_FakeEvent
.ie_Class
= IECLASS_NEWMOUSE
;
5681 nch
->nch_FakeEvent
.ie_SubClass
= 0;
5682 nch
->nch_FakeEvent
.ie_Code
= iecode
;
5683 nch
->nch_FakeEvent
.ie_NextEvent
= NULL
;
5684 nch
->nch_FakeEvent
.ie_Qualifier
= nch
->nch_KeyQualifiers
;
5685 nch
->nch_InpIOReq
->io_Data
= &nch
->nch_FakeEvent
;
5686 nch
->nch_InpIOReq
->io_Length
= sizeof(struct InputEvent
);
5687 nch
->nch_InpIOReq
->io_Command
= IND_WRITEEVENT
;
5688 DoIO((struct IORequest
*) nch
->nch_InpIOReq
);
5690 nch
->nch_FakeEvent
.ie_X
= nch
->nch_MouseDeltaX
;
5691 nch
->nch_FakeEvent
.ie_Y
= nch
->nch_MouseDeltaY
;
5692 nch
->nch_FakeEvent
.ie_Class
= IECLASS_RAWMOUSE
;
5693 nch
->nch_FakeEvent
.ie_SubClass
= 0;
5694 nch
->nch_FakeEvent
.ie_Code
= iecode
;
5695 nch
->nch_FakeEvent
.ie_NextEvent
= NULL
;
5696 nch
->nch_FakeEvent
.ie_Qualifier
= nch
->nch_KeyQualifiers
|IEQUALIFIER_RELATIVEMOUSE
;
5697 nch
->nch_InpIOReq
->io_Data
= &nch
->nch_FakeEvent
;
5698 nch
->nch_InpIOReq
->io_Length
= sizeof(struct InputEvent
);
5699 nch
->nch_InpIOReq
->io_Command
= nch
->nch_OS4Hack
? IND_ADDEVENT
: IND_WRITEEVENT
;
5700 DoIO((struct IORequest
*) nch
->nch_InpIOReq
);
5701 nch
->nch_NewMouseRel
= FALSE
;
5702 nch
->nch_MouseDeltaX
= 0;
5703 nch
->nch_MouseDeltaY
= 0;
5711 KPRINTF(1, ("Tablet!\n"));
5712 switch(nha
->nha_TabletAxis
)
5715 nch
->nch_MouseAbsZ
= value
- nhi
->nhi_RealMin
;
5716 nch
->nch_MouseRangeZ
= (nhi
->nhi_RealMax
- nhi
->nhi_RealMin
) + 1;
5720 if(nhi
->nhi_RealMax
)
5722 nch
->nch_TabPressure
= ((0x1fffffff / nhi
->nhi_RealMax
)*value
)<<2;
5723 nch
->nch_VldPressure
= TRUE
;
5728 if(nhi
->nhi_RealMax
)
5730 nch
->nch_TabRotX
= ((0x3fffffff / nhi
->nhi_RealMax
)*value
)<<2;
5731 nch
->nch_VldRotX
= TRUE
;
5736 if(nhi
->nhi_RealMax
)
5738 nch
->nch_TabRotY
= ((0x3fffffff / nhi
->nhi_RealMax
)*value
)<<2;
5739 nch
->nch_VldRotY
= TRUE
;
5744 if(nhi
->nhi_RealMax
)
5746 nch
->nch_TabRotZ
= ((0x3fffffff / nhi
->nhi_RealMax
)*value
)<<2;
5747 nch
->nch_VldRotZ
= TRUE
;
5752 nch
->nch_TabProx
= value
;
5753 nch
->nch_VldProx
= TRUE
;
5756 if(nch
->nch_MouseRangeX
&& nch
->nch_MouseRangeY
)
5758 nch
->nch_NewMouseAbs
= TRUE
;
5765 UWORD wheeldist
= 0;
5766 UWORD wheeliecode
= IECODE_NOBUTTON
;
5767 switch(nha
->nha_WheelMode
)
5772 wheeliecode
= RAWKEY_NM_WHEEL_LEFT
;
5777 wheeliecode
= RAWKEY_NM_WHEEL_RIGHT
;
5785 wheeliecode
= RAWKEY_NM_WHEEL_UP
;
5790 wheeliecode
= RAWKEY_NM_WHEEL_DOWN
;
5796 wheeliecode
= RAWKEY_NM_WHEEL_LEFT
;
5797 wheeldist
= nha
->nha_WheelDist
;
5801 wheeliecode
= RAWKEY_NM_WHEEL_RIGHT
;
5802 wheeldist
= nha
->nha_WheelDist
;
5806 wheeliecode
= RAWKEY_NM_WHEEL_UP
;
5807 wheeldist
= nha
->nha_WheelDist
;
5811 wheeliecode
= RAWKEY_NM_WHEEL_DOWN
;
5812 wheeldist
= nha
->nha_WheelDist
;
5815 if(wheeliecode
!= IECODE_NOBUTTON
)
5821 KPRINTF(1, ("Doing wheel %ld\n", wheeliecode
));
5822 nSendRawKey(nch
, wheeliecode
);
5824 nch
->nch_FakeEvent
.ie_Class
= IECLASS_NEWMOUSE
;
5825 nch
->nch_FakeEvent
.ie_SubClass
= 0;
5826 nch
->nch_FakeEvent
.ie_Code
= wheeliecode
;
5827 nch
->nch_FakeEvent
.ie_NextEvent
= NULL
;
5828 nch
->nch_FakeEvent
.ie_Qualifier
= nch
->nch_KeyQualifiers
;
5829 nch
->nch_InpIOReq
->io_Data
= &nch
->nch_FakeEvent
;
5830 nch
->nch_InpIOReq
->io_Length
= sizeof(struct InputEvent
);
5831 nch
->nch_InpIOReq
->io_Command
= IND_WRITEEVENT
;
5832 DoIO((struct IORequest
*) nch
->nch_InpIOReq
);
5836 nSendRawKey(nch
, wheeliecode
|IECODE_UP_PREFIX
);
5838 nch
->nch_FakeEvent
.ie_Class
= IECLASS_NEWMOUSE
;
5839 nch
->nch_FakeEvent
.ie_SubClass
= 0;
5840 nch
->nch_FakeEvent
.ie_Code
= wheeliecode
|IECODE_UP_PREFIX
;
5841 nch
->nch_FakeEvent
.ie_NextEvent
= NULL
;
5842 nch
->nch_FakeEvent
.ie_Qualifier
= nch
->nch_KeyQualifiers
;
5843 nch
->nch_InpIOReq
->io_Data
= &nch
->nch_FakeEvent
;
5844 nch
->nch_InpIOReq
->io_Length
= sizeof(struct InputEvent
);
5845 nch
->nch_InpIOReq
->io_Command
= IND_WRITEEVENT
;
5846 DoIO((struct IORequest
*) nch
->nch_InpIOReq
);
5857 ULONG
*stateptr
= &nch
->nch_LLPortState
[nha
->nha_JoypadPort
];
5859 switch(nha
->nha_JoypadFeat
)
5862 mask
= JPF_JOY_LEFT
;
5866 mask
= JPF_JOY_RIGHT
;
5874 mask
= JPF_JOY_DOWN
;
5878 mask
= JPF_BUTTON_RED
;
5882 mask
= JPF_BUTTON_BLUE
;
5886 mask
= JPF_BUTTON_GREEN
;
5890 mask
= JPF_BUTTON_YELLOW
;
5894 mask
= JPF_BUTTON_FORWARD
;
5898 mask
= JPF_BUTTON_REVERSE
;
5902 mask
= JPF_BUTTON_PLAY
;
5905 case HUAT_HATSWITCH
:
5906 mask
= JP_DIRECTION_MASK
;
5907 stateptr
= &nch
->nch_LLHatswitch
[nha
->nha_JoypadPort
];
5911 /* oldval = *stateptr; */
5912 switch(nha
->nha_JoypadOp
)
5927 if(nha
->nha_JoypadFeat
== HUAT_HATSWITCH
)
5929 value
-= nhi
->nhi_RealMin
;
5930 if((value
>= 0) && (value
< 8))
5932 mask
= LLHatswitchEncoding
[value
];
5936 /*oldval = *stateptr;
5937 oldval &= ~JP_DIRECTION_MASK;
5939 *stateptr = oldval;*/
5956 ULONG
*stateptr
= &nch
->nch_LLAnalogue
[nha
->nha_JoypadPort
];
5957 if((nhi
->nhi_RealMin
!= 0) || (nhi
->nhi_RealMax
!= 255))
5960 value
-= nhi
->nhi_RealMin
;
5962 value
/= (nhi
->nhi_RealMax
- nhi
->nhi_RealMin
);
5964 switch(nha
->nha_APadFeat
)
5967 *stateptr
= (*stateptr
& ~JP_XAXIS_MASK
) | (value
& JP_XAXIS_MASK
) | JP_TYPE_ANALOGUE
;
5971 *stateptr
= (*stateptr
& ~JP_YAXIS_MASK
) | ((value
<<8) & JP_YAXIS_MASK
) | JP_TYPE_ANALOGUE
;
5980 struct NepHidItem
*nhi
;
5982 nhi
= nFindItemID(nch
, nha
->nha_OutItem
, REPORT_MAIN_OUTPUT
, &pos
);
5985 if(nhi
->nhi_Flags
& RPF_MAIN_VARIABLE
)
5987 switch(nha
->nha_OutOp
)
5990 nhi
->nhi_OldValue
= TRUE
;
5994 nhi
->nhi_OldValue
= FALSE
;
5998 nhi
->nhi_OldValue
= nhi
->nhi_OldValue
? FALSE
: TRUE
;
6002 nhi
->nhi_OldValue
= value
;
6006 nParseArrayString(nch
, nhi
, nha
->nha_OutArray
);
6008 nhi
->nhi_Collection
->nhc_Report
->nhr_OutTouched
= TRUE
;
6009 nch
->nch_OutFeatTouched
= TRUE
;
6017 struct NepHidItem
*nhi
;
6019 nhi
= nFindItemID(nch
, nha
->nha_FeatItem
, REPORT_MAIN_FEATURE
, &pos
);
6022 if(nhi
->nhi_Flags
& RPF_MAIN_VARIABLE
)
6024 switch(nha
->nha_FeatOp
)
6027 nhi
->nhi_OldValue
= TRUE
;
6031 nhi
->nhi_OldValue
= FALSE
;
6035 nhi
->nhi_OldValue
= nhi
->nhi_OldValue
? FALSE
: TRUE
;
6039 nhi
->nhi_OldValue
= value
;
6043 nParseArrayString(nch
, nhi
, nha
->nha_OutArray
);
6045 nhi
->nhi_Collection
->nhc_Report
->nhr_FeatTouched
= TRUE
;
6046 nch
->nch_OutFeatTouched
= TRUE
;
6052 nch
->nch_FakeEvent
.ie_Class
= IECLASS_NULL
;
6053 nch
->nch_FakeEvent
.ie_SubClass
= 0;
6054 nch
->nch_FakeEvent
.ie_Code
= IECODE_NOBUTTON
;
6055 nch
->nch_FakeEvent
.ie_NextEvent
= NULL
;
6056 nch
->nch_FakeEvent
.ie_Qualifier
= nch
->nch_KeyQualifiers
;
6057 nch
->nch_InpIOReq
->io_Data
= &nch
->nch_FakeEvent
;
6058 nch
->nch_InpIOReq
->io_Length
= sizeof(struct InputEvent
);
6059 nch
->nch_InpIOReq
->io_Command
= IND_WRITEEVENT
;
6060 switch(nha
->nha_MiscMode
)
6062 case HUAT_DISPLAYBEEP
:
6063 case HUAT_WIN2FRONT
:
6065 case HUAT_ZIPWINDOW
:
6066 case HUAT_SCREENCYCLE
:
6068 case HUAT_ACTWINDOW
:
6070 struct ActionMsg
*am
;
6071 if(!nch
->nch_ClsBase
->nh_DTaskMsgPort
)
6073 nInstallLastActionHero(nch
);
6075 if(nch
->nch_ClsBase
->nh_DTaskMsgPort
)
6077 if((am
= AllocVec(sizeof(struct ActionMsg
), MEMF_PUBLIC
)))
6079 am
->am_Msg
.mn_Length
= sizeof(struct ActionMsg
);
6080 am
->am_Msg
.mn_ReplyPort
= NULL
;
6082 am
->am_Action
= nha
;
6083 PutMsg(nch
->nch_ClsBase
->nh_DTaskMsgPort
, &am
->am_Msg
);
6089 case HUAT_CLOSEWINDOW
:
6090 nch
->nch_FakeEvent
.ie_Class
= IECLASS_CLOSEWINDOW
;
6091 DoIO((struct IORequest
*) nch
->nch_InpIOReq
);
6095 nch
->nch_CDC
->cdc_EnableKBReset
= TRUE
;
6096 nch
->nch_KeyQualifiers
|= IEQUALIFIER_CONTROL
|IEQUALIFIER_LCOMMAND
|IEQUALIFIER_RCOMMAND
;
6100 case HUAT_FLUSHEVENTS
:
6111 LONG
*tarvarptr
= NULL
;
6113 switch(nha
->nha_TarVar
)
6115 case HUAT_LOCALVAR1
:
6116 case HUAT_LOCALVAR2
:
6117 case HUAT_LOCALVAR3
:
6118 case HUAT_LOCALVAR4
:
6119 case HUAT_LOCALVAR5
:
6120 case HUAT_LOCALVAR6
:
6121 case HUAT_LOCALVAR7
:
6122 case HUAT_LOCALVAR8
:
6123 tarvarptr
= &nch
->nch_LocalVars
[nha
->nha_TarVar
- HUAT_LOCALVAR1
];
6134 tarvarptr
= &nch
->nch_ClsBase
->nh_GlobalVars
[nha
->nha_TarVar
- HUAT_GLOBVARA
];
6141 switch(nha
->nha_TarVarOp
)
6148 *tarvarptr
+= value
;
6152 *tarvarptr
-= value
;
6156 *tarvarptr
*= value
;
6162 *tarvarptr
/= value
;
6174 *tarvarptr
= *tarvarptr
&& value
;
6178 *tarvarptr
= !(*tarvarptr
&& value
);
6182 *tarvarptr
= *tarvarptr
&& (!value
);
6186 *tarvarptr
= *tarvarptr
|| value
;
6190 *tarvarptr
= (*tarvarptr
^ value
) ? TRUE
: FALSE
;
6194 *tarvarptr
&= value
;
6198 *tarvarptr
= ~(*tarvarptr
& value
);
6202 *tarvarptr
&= ~value
;
6206 *tarvarptr
|= value
;
6210 *tarvarptr
^= value
;
6214 *tarvarptr
<<= value
;
6218 *tarvarptr
>>= value
;
6225 #if 0 // FIXME looks like AROS does not support this (yet?)
6226 nch
->nch_FakeEvent
.ie_Class
= IECLASS_EXTRAWKEY
;
6227 nch
->nch_FakeEvent
.ie_SubClass
= 0;
6228 nch
->nch_FakeEvent
.ie_Code
= nha
->nha_RawKey
;
6229 // using ie.dead.ie_prev1DownCode instead of ie_extkey.ie_extkey1
6230 nch
->nch_FakeEvent
.ie_position
.ie_dead
.ie_prev1DownCode
= 0xe0;
6231 nch
->nch_FakeEvent
.ie_position
.ie_dead
.ie_prev1DownQual
= nha
->nha_RawKey
;
6232 nch
->nch_FakeEvent
.ie_NextEvent
= NULL
;
6233 nch
->nch_FakeEvent
.ie_Qualifier
= nch
->nch_KeyQualifiers
;
6234 nch
->nch_InpIOReq
->io_Data
= &nch
->nch_FakeEvent
;
6235 nch
->nch_InpIOReq
->io_Length
= sizeof(struct InputEvent
);
6236 nch
->nch_InpIOReq
->io_Command
= IND_WRITEEVENT
;
6237 DoIO((struct IORequest
*) nch
->nch_InpIOReq
);
6246 /* /// "nFlushEvents()" */
6247 void nFlushEvents(struct NepClassHid
*nch
)
6253 struct NepHidReport
*nhr
;
6255 /* output/feature pipes */
6256 if(nch
->nch_OutFeatTouched
)
6258 nch
->nch_OutFeatTouched
= FALSE
;
6259 pp
= nch
->nch_EP0Pipe
;
6260 nhr
= (struct NepHidReport
*) nch
->nch_HidReports
.lh_Head
;
6261 while(nhr
->nhr_Node
.ln_Succ
)
6263 if(nhr
->nhr_OutTouched
)
6265 KPRINTF(1, ("Out Report %ld touched...\n", nhr
->nhr_ReportID
));
6266 buflen
= (nhr
->nhr_ReportOutSize
+7)>>3;
6267 if(nch
->nch_UsesReportID
)
6269 *nch
->nch_EPOutBuf
= nhr
->nhr_ReportID
;
6270 nGenerateOutReport(nch
, nhr
, nch
->nch_EPOutBuf
+1);
6272 psdPipeSetup(pp
, URTF_OUT
|URTF_CLASS
|URTF_INTERFACE
,
6273 UHR_SET_REPORT
, (ULONG
) nhr
->nhr_ReportID
|0x0200, nch
->nch_IfNum
);
6275 nGenerateOutReport(nch
, nhr
, nch
->nch_EPOutBuf
);
6276 psdPipeSetup(pp
, URTF_OUT
|URTF_CLASS
|URTF_INTERFACE
,
6277 UHR_SET_REPORT
, 0x0200, nch
->nch_IfNum
);
6279 KPRINTF(1, ("Len: %ld [%02lx %02lx]", buflen
, nch
->nch_EPOutBuf
[0], nch
->nch_EPOutBuf
[1]));
6280 /*psdAddErrorMsg(RETURN_WARN, (STRPTR) GM_UNIQUENAME(libname),
6281 "HID OUT Report %02lx Debug (%ld bytes):", nhr->nhr_ReportID, buflen);
6282 nDebugMem(nch, nch->nch_EPOutBuf, buflen);*/
6284 if((ioerr
= psdDoPipe(pp
, nch
->nch_EPOutBuf
, buflen
)))
6286 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
),
6287 "SET_REPORT(%lx, %ld) failed: %s (%ld)!",
6288 nhr
->nhr_ReportID
|0x0200, buflen
,
6289 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
6291 nhr
->nhr_OutTouched
= FALSE
;
6293 if(nhr
->nhr_FeatTouched
)
6295 KPRINTF(1, ("Feat Report %ld touched...\n", nhr
->nhr_ReportID
));
6296 buflen
= (nhr
->nhr_ReportFeatSize
+7)>>3;
6297 if(nch
->nch_UsesReportID
)
6299 *nch
->nch_EPOutBuf
= nhr
->nhr_ReportID
;
6300 nGenerateFeatReport(nch
, nhr
, nch
->nch_EPOutBuf
+1);
6302 psdPipeSetup(pp
, URTF_OUT
|URTF_CLASS
|URTF_INTERFACE
,
6303 UHR_SET_REPORT
, (ULONG
) nhr
->nhr_ReportID
|0x0300, nch
->nch_IfNum
);
6305 nGenerateFeatReport(nch
, nhr
, nch
->nch_EPOutBuf
);
6306 psdPipeSetup(pp
, URTF_OUT
|URTF_CLASS
|URTF_INTERFACE
,
6307 UHR_SET_REPORT
, 0x0300, nch
->nch_IfNum
);
6309 KPRINTF(1, ("Len: %ld [%02lx %02lx]", buflen
, nch
->nch_EPOutBuf
[0], nch
->nch_EPOutBuf
[1]));
6310 if((ioerr
= psdDoPipe(pp
, nch
->nch_EPOutBuf
, buflen
)))
6312 psdAddErrorMsg(RETURN_ERROR
, (STRPTR
) GM_UNIQUENAME(libname
),
6313 "SET_REPORT(%lx, %ld) failed: %s (%ld)!",
6314 nhr
->nhr_ReportID
|0x0300, buflen
,
6315 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
6317 psdAddErrorMsg(RETURN_OK, (STRPTR) GM_UNIQUENAME(libname),
6318 "SET_REPORT(%lx, %ld)=%02lx%02lx okay!",
6319 nhr->nhr_ReportID|0x0300, buflen,
6320 nch->nch_EPOutBuf[1], nch->nch_EPOutBuf[2]);
6322 nhr
->nhr_FeatTouched
= FALSE
;
6324 nhr
= (struct NepHidReport
*) nhr
->nhr_Node
.ln_Succ
;
6327 if(nch
->nch_NewMouseRel
&& (nch
->nch_MouseDeltaX
|| nch
->nch_MouseDeltaY
))
6329 KPRINTF(1, ("Mouse rel movement...\n"));
6330 nch
->nch_FakeEvent
.ie_X
= nch
->nch_MouseDeltaX
;
6331 nch
->nch_FakeEvent
.ie_Y
= nch
->nch_MouseDeltaY
;
6332 nch
->nch_FakeEvent
.ie_Class
= IECLASS_RAWMOUSE
;
6333 nch
->nch_FakeEvent
.ie_SubClass
= 0;
6334 nch
->nch_FakeEvent
.ie_Code
= IECODE_NOBUTTON
;
6335 nch
->nch_FakeEvent
.ie_NextEvent
= NULL
;
6336 nch
->nch_FakeEvent
.ie_Qualifier
= nch
->nch_KeyQualifiers
|IEQUALIFIER_RELATIVEMOUSE
;
6337 nch
->nch_InpIOReq
->io_Data
= &nch
->nch_FakeEvent
;
6338 nch
->nch_InpIOReq
->io_Length
= sizeof(struct InputEvent
);
6339 nch
->nch_InpIOReq
->io_Command
= nch
->nch_OS4Hack
? IND_ADDEVENT
: IND_WRITEEVENT
;
6340 DoIO((struct IORequest
*) nch
->nch_InpIOReq
);
6341 nch
->nch_NewMouseRel
= FALSE
;
6342 nch
->nch_MouseDeltaX
= 0;
6343 nch
->nch_MouseDeltaY
= 0;
6345 if(nch
->nch_NewMouseAbs
)
6347 ULONG
*tagptr
= nch
->nch_TabTags
;
6348 KPRINTF(1, ("Mouse abs movement...\n"));
6349 nch
->nch_FakeEvent
.ie_EventAddress
= &nch
->nch_TabletEvent
;
6350 nch
->nch_TabletEvent
.ient_RangeX
= nch
->nch_MouseRangeX
;
6351 nch
->nch_TabletEvent
.ient_RangeY
= nch
->nch_MouseRangeY
;
6352 nch
->nch_TabletEvent
.ient_TabletX
= nch
->nch_MouseAbsX
;
6353 nch
->nch_TabletEvent
.ient_TabletY
= nch
->nch_MouseAbsY
;
6354 nch
->nch_TabletEvent
.ient_TagList
= (struct TagItem
*) tagptr
;
6355 if(nch
->nch_MouseRangeZ
)
6357 KPRINTF(1, ("AbsZ %ld\n", nch
->nch_MouseAbsZ
));
6358 *tagptr
++ = TABLETA_TabletZ
;
6359 *tagptr
++ = nch
->nch_MouseAbsZ
;
6360 *tagptr
++ = TABLETA_RangeZ
;
6361 *tagptr
++ = nch
->nch_MouseRangeZ
;
6363 if(nch
->nch_VldRotX
)
6365 KPRINTF(1, ("AngleX %ld\n", nch
->nch_TabRotX
));
6366 *tagptr
++ = TABLETA_AngleX
;
6367 *tagptr
++ = nch
->nch_TabRotX
;
6369 if(nch
->nch_VldRotY
)
6371 KPRINTF(1, ("AngleY %ld\n", nch
->nch_TabRotY
));
6372 *tagptr
++ = TABLETA_AngleY
;
6373 *tagptr
++ = nch
->nch_TabRotY
;
6375 if(nch
->nch_VldRotZ
)
6377 KPRINTF(1, ("AngleZ %ld\n", nch
->nch_TabRotZ
));
6378 *tagptr
++ = TABLETA_AngleZ
;
6379 *tagptr
++ = nch
->nch_TabRotZ
;
6381 if(nch
->nch_VldPressure
)
6383 KPRINTF(1, ("Pressure %ld\n", nch
->nch_TabPressure
));
6384 *tagptr
++ = TABLETA_Pressure
;
6385 *tagptr
++ = nch
->nch_TabPressure
;
6387 *tagptr
++ = TABLETA_ButtonBits
;
6388 *tagptr
++ = nch
->nch_MouseButtons
;
6389 if(nch
->nch_VldProx
)
6391 KPRINTF(1, ("InProx %ld\n", nch
->nch_TabProx
));
6392 *tagptr
++ = TABLETA_InProximity
;
6393 *tagptr
++ = nch
->nch_TabProx
;
6396 nch
->nch_FakeEvent
.ie_Class
= IECLASS_NEWPOINTERPOS
;
6397 nch
->nch_FakeEvent
.ie_SubClass
= IESUBCLASS_NEWTABLET
;
6398 nch
->nch_FakeEvent
.ie_Code
= IECODE_NOBUTTON
;
6399 nch
->nch_FakeEvent
.ie_NextEvent
= NULL
;
6400 nch
->nch_FakeEvent
.ie_Qualifier
= nch
->nch_KeyQualifiers
;
6401 nch
->nch_InpIOReq
->io_Data
= &nch
->nch_FakeEvent
;
6402 nch
->nch_InpIOReq
->io_Length
= sizeof(struct InputEvent
);
6403 nch
->nch_InpIOReq
->io_Command
= IND_WRITEEVENT
;
6404 DoIO((struct IORequest
*) nch
->nch_InpIOReq
);
6405 nch
->nch_NewMouseAbs
= FALSE
;
6411 /* /// "nSendRawKey()" */
6412 void nSendRawKey(struct NepClassHid
*nch
, UWORD key
)
6414 nch
->nch_FakeEvent
.ie_Class
= IECLASS_RAWKEY
;
6415 nch
->nch_FakeEvent
.ie_SubClass
= 0;
6416 nch
->nch_FakeEvent
.ie_Code
= key
;
6417 nch
->nch_FakeEvent
.ie_NextEvent
= NULL
;
6418 nch
->nch_FakeEvent
.ie_Qualifier
= nch
->nch_KeyQualifiers
;
6419 nch
->nch_InpIOReq
->io_Data
= &nch
->nch_FakeEvent
;
6420 nch
->nch_InpIOReq
->io_Length
= sizeof(struct InputEvent
);
6421 nch
->nch_InpIOReq
->io_Command
= nch
->nch_OS4Hack
? IND_ADDEVENT
: IND_WRITEEVENT
;
6422 DoIO((struct IORequest
*) nch
->nch_InpIOReq
);
6426 /* /// "nCheckReset()" */
6427 void nCheckReset(struct NepClassHid
*nch
)
6429 if(nch
->nch_CDC
->cdc_EnableKBReset
&&
6430 (nch
->nch_KeyQualifiers
& (IEQUALIFIER_CONTROL
|IEQUALIFIER_LCOMMAND
|IEQUALIFIER_RCOMMAND
)) ==
6431 (IEQUALIFIER_CONTROL
|IEQUALIFIER_LCOMMAND
|IEQUALIFIER_RCOMMAND
))
6434 struct IOStdReq
*ioreq
;
6435 struct Interrupt tempint
;
6437 struct List
*listhead
= NULL
;
6438 BOOL haskbh
= FALSE
;
6439 KPRINTF(20, ("Reboot!\n"));
6441 if(nch
->nch_CDC
->cdc_EnableRH
)
6443 if((mp
= CreateMsgPort()))
6445 if((ioreq
= (struct IOStdReq
*) CreateIORequest(mp
, sizeof(struct IOStdReq
))))
6447 if(!OpenDevice("keyboard.device", 0, (struct IORequest
*) ioreq
, 0))
6449 /* Find list header of reset handlers */
6450 tempint
.is_Node
.ln_Pred
= NULL
;
6451 tempint
.is_Node
.ln_Succ
= NULL
;
6452 tempint
.is_Node
.ln_Type
= NT_INTERRUPT
;
6453 tempint
.is_Node
.ln_Pri
= 32;
6454 tempint
.is_Node
.ln_Name
= "";
6455 tempint
.is_Code
= NULL
;
6456 ioreq
->io_Command
= KBD_ADDRESETHANDLER
;
6457 ioreq
->io_Data
= &tempint
;
6459 DoIO((struct IORequest
*) ioreq
);
6460 if((node
= tempint
.is_Node
.ln_Pred
))
6462 while(node
->ln_Pred
)
6464 node
= node
->ln_Pred
;
6466 listhead
= (struct List
*) node
;
6468 ioreq
->io_Command
= KBD_REMRESETHANDLER
;
6469 DoIO((struct IORequest
*) ioreq
);
6473 node
= listhead
->lh_Head
;
6474 while(node
->ln_Succ
)
6476 KPRINTF(20, ("Kicking %s\n", node
->ln_Name
));
6477 Cause((struct Interrupt
*) node
);
6479 node
= node
->ln_Succ
;
6481 KPRINTF(20, ("Done... awaiting doom\n"));
6484 psdDelayMS(nch
->nch_CDC
->cdc_ResetDelay
*1000);
6487 KPRINTF(20, ("Reset handler list not found!\n"));
6489 CloseDevice((struct IORequest
*) ioreq
);
6491 DeleteIORequest((struct IORequest
*) ioreq
);
6498 else if(nch
->nch_CDC
->cdc_EnableKBReset
&&
6499 (nch
->nch_KeyQualifiers
& IEQUALIFIER_CONTROL
) &&
6500 (nch
->nch_KeyQualifiers
& (IEQUALIFIER_LALT
|IEQUALIFIER_RALT
)) &&
6501 nch
->nch_FakeEvent
.ie_Code
== RAWKEY_DELETE
)
6503 KPRINTF(20, ("Reboot!\n"));
6504 ShutdownA(SD_ACTION_COLDREBOOT
);
6509 /* /// "nLoadItem()" */
6510 BOOL
nLoadItem(struct NepClassHid
*nch
, struct PsdIFFContext
*rppic
, struct List
*lst
, UWORD idbase
)
6512 struct PsdIFFContext
*itpic
;
6513 struct PsdIFFContext
*actpic
;
6514 struct NepHidAction
*nha
;
6517 struct NepHidActionChunk
*nhac
;
6520 psdSafeRawDoFmt((STRPTR
) buf
, 8, "I%03lx", GET_WTYPE(lst
) - idbase
+ 1);
6521 newform
[0] = AROS_LONG2BE(ID_FORM
);
6522 newform
[1] = AROS_LONG2BE(4);
6524 itpic
= psdFindCfgForm(rppic
, AROS_LONG2BE(newform
[2]));
6529 actpic
= psdFindCfgForm(itpic
, MAKE_ID('A','C','T','N'));
6532 if((nhac
= psdGetCfgChunk(actpic
, MAKE_ID('A','C','D','F'))))
6534 if((nha
= nAllocAction(nch
, lst
, 0)))
6536 CopyMem(&nhac
->nhac_Type
, &nha
->nha_Type
, min(AROS_LONG2BE(nhac
->nhac_Length
), sizeof(struct NepHidActionChunk
) - 8));
6537 if((tmpstr
= psdGetStringChunk(actpic
, MAKE_ID('S','N','D','F'))))
6539 strncpy(nha
->nha_SoundFile
, tmpstr
, 255);
6542 if((tmpstr
= psdGetStringChunk(actpic
, MAKE_ID('V','A','N','S'))))
6544 strncpy(nha
->nha_VanillaString
, tmpstr
, 79);
6547 if((tmpstr
= psdGetStringChunk(actpic
, MAKE_ID('K','E','Y','S'))))
6549 strncpy(nha
->nha_KeyString
, tmpstr
, 79);
6552 if((tmpstr
= psdGetStringChunk(actpic
, MAKE_ID('E','X','E','S'))))
6554 strncpy(nha
->nha_ExeString
, tmpstr
, 79);
6557 if((tmpstr
= psdGetStringChunk(actpic
, MAKE_ID('O','A','R','R'))))
6559 strncpy(nha
->nha_OutArray
, tmpstr
, 255);
6565 actpic
= psdNextCfgForm(actpic
);
6571 /* /// "nSaveItem()" */
6572 struct PsdIFFContext
* nSaveItem(struct NepClassHid
*nch
, struct PsdIFFContext
*rppic
, struct List
*lst
, UWORD idbase
)
6574 struct PsdIFFContext
*itpic
;
6575 struct PsdIFFContext
*actpic
;
6576 struct NepHidAction
*nha
;
6579 struct NepHidActionChunk nhac
;
6580 BOOL isdefault
= TRUE
;
6582 if(!lst
->lh_Head
->ln_Succ
)
6586 nha
= (struct NepHidAction
*) lst
->lh_Head
;
6587 while(nha
->nha_Node
.ln_Succ
)
6589 if(!nha
->nha_IsDefault
)
6593 nha
= (struct NepHidAction
*) nha
->nha_Node
.ln_Succ
;
6599 psdSafeRawDoFmt((STRPTR
) buf
, 8, "I%03lx", GET_WTYPE(lst
) - idbase
+ 1);
6600 newform
[0] = AROS_LONG2BE(ID_FORM
);
6601 newform
[1] = AROS_LONG2BE(4);
6603 itpic
= psdFindCfgForm(rppic
, AROS_LONG2BE(newform
[2]));
6606 itpic
= psdAddCfgEntry(rppic
, newform
);
6612 nhac
.nhac_ID
= AROS_LONG2BE(MAKE_ID('A','C','D','F'));
6613 nhac
.nhac_Length
= AROS_LONG2BE(sizeof(struct NepHidActionChunk
)-8);
6614 nha
= (struct NepHidAction
*) lst
->lh_Head
;
6615 while(nha
->nha_Node
.ln_Succ
)
6617 if(!nha
->nha_IsDefault
)
6621 newform
[2] = AROS_LONG2BE(MAKE_ID('A','C','T','N'));
6622 actpic
= psdAddCfgEntry(itpic
, newform
);
6627 CopyMem(&nha
->nha_Type
, &nhac
.nhac_Type
, sizeof(struct NepHidActionChunk
)-8);
6628 psdAddCfgEntry(actpic
, &nhac
);
6629 if(*nha
->nha_SoundFile
)
6631 psdAddStringChunk(actpic
, MAKE_ID('S','N','D','F'), nha
->nha_SoundFile
);
6633 if(*nha
->nha_VanillaString
)
6635 psdAddStringChunk(actpic
, MAKE_ID('V','A','N','S'), nha
->nha_VanillaString
);
6637 if(*nha
->nha_KeyString
)
6639 psdAddStringChunk(actpic
, MAKE_ID('K','E','Y','S'), nha
->nha_KeyString
);
6641 if(*nha
->nha_ExeString
)
6643 psdAddStringChunk(actpic
, MAKE_ID('E','X','E','S'), nha
->nha_ExeString
);
6645 if(*nha
->nha_OutArray
)
6647 psdAddStringChunk(actpic
, MAKE_ID('O','A','R','R'), nha
->nha_OutArray
);
6649 nha
= (struct NepHidAction
*) nha
->nha_Node
.ln_Succ
;
6655 /* /// "nReadJoyPort()" */
6656 AROS_LH1(ULONG
, nReadJoyPort
,
6657 AROS_LHA(ULONG
, port
, D0
),
6658 struct Library
*, LowLevelBase
, 5, hid
)
6662 struct NepHidBase
*nh
;
6663 struct NepClassHid
*nch
;
6664 ULONG result
= JP_TYPE_NOTAVAIL
;
6667 if(!(nh
= (struct NepHidBase
*) FindName(&SysBase
->LibList
, GM_UNIQUENAME(libname
))))
6672 result
= AROS_CALL1(ULONG
, nh
->nh_LLOldReadJoyPort
,
6673 AROS_LCA(ULONG
, port
, D0
),
6674 struct Library
*, nh
->nh_LowLevelBase
);
6676 KPRINTF(40, ("Before %08lx\n", result
));
6680 nch
= (struct NepClassHid
*) nh
->nh_Interfaces
.lh_Head
;
6681 while(nch
->nch_Node
.ln_Succ
)
6683 mode
= nch
->nch_CDC
->cdc_LLPortMode
[port
];
6684 if(nh
->nh_LLAnalogueOverride
[port
] && nch
->nch_LLAnalogue
[port
])
6691 // case 0: /* don't touch */
6694 case 1: /* overwrite with USB */
6695 result
= nch
->nch_LLPortState
[port
] | nch
->nch_LLHatswitch
[port
] | JP_TYPE_GAMECTLR
;
6698 case 2: /* merge with USB */
6699 if(((result
& JP_TYPE_MASK
) == JP_TYPE_GAMECTLR
) ||
6700 ((result
& JP_TYPE_MASK
) == JP_TYPE_JOYSTK
) ||
6701 ((result
& JP_TYPE_MASK
) == JP_TYPE_UNKNOWN
) ||
6704 result
= (result
& (JP_BUTTON_MASK
|JP_DIRECTION_MASK
)) | nch
->nch_LLPortState
[port
] | nch
->nch_LLHatswitch
[port
] | JP_TYPE_GAMECTLR
;
6708 case 3: /* disable */
6709 result
= JP_TYPE_NOTAVAIL
;
6712 case 4: /* overwrite with analogue USB */
6713 if(nch
->nch_LLAnalogue
[port
])
6715 result
= (nch
->nch_LLPortState
[port
] & ~JP_DIRECTION_MASK
) | (nch
->nch_LLAnalogue
[port
] & JP_XYAXIS_MASK
) | nch
->nch_LLHatswitch
[port
] | JP_TYPE_ANALOGUE
;
6719 nch
= (struct NepClassHid
*) nch
->nch_Node
.ln_Succ
;
6723 if((port
>= JP_ANALOGUE_PORT_MAGIC
) && (port
< (JP_ANALOGUE_PORT_MAGIC
|4)))
6727 nch
= (struct NepClassHid
*) nh
->nh_Interfaces
.lh_Head
;
6728 while(nch
->nch_Node
.ln_Succ
)
6730 if(nch
->nch_LLAnalogue
[port
])
6732 result
= (nch
->nch_LLPortState
[port
] & ~JP_DIRECTION_MASK
) | (nch
->nch_LLAnalogue
[port
] & JP_XYAXIS_MASK
) | nch
->nch_LLHatswitch
[port
] | JP_TYPE_ANALOGUE
;
6734 nch
= (struct NepClassHid
*) nch
->nch_Node
.ln_Succ
;
6738 KPRINTF(40, ("And after %08lx\n", result
));
6745 /* /// "nSetJoyPortAttrsA()" */
6746 AROS_LH2(ULONG
, nSetJoyPortAttrsA
,
6747 AROS_LHA(ULONG
, port
, D0
),
6748 AROS_LHA(struct TagItem
*, tags
, A1
),
6749 struct Library
*, LowLevelBase
, 22, hid
)
6753 struct NepHidBase
*nh
;
6754 struct TagItem
*typetag
;
6755 struct TagItem
*motortags
[2];
6756 struct TagItem
*motorofftag
;
6757 ULONG result
= FALSE
;
6759 if(!(nh
= (struct NepHidBase
*) FindName(&SysBase
->LibList
, GM_UNIQUENAME(libname
))))
6764 result
= AROS_CALL2(ULONG
, nh
->nh_LLOldSetJoyPortAttrsA
,
6765 AROS_LCA(ULONG
, port
, D0
),
6766 AROS_LCA(struct TagItem
*, tags
, A1
),
6767 struct Library
*, nh
->nh_LowLevelBase
);
6769 KPRINTF(40, ("Before %08lx\n", result
));
6772 typetag
= FindTagItem(SJA_Type
, tags
);
6775 if(typetag
->ti_Data
== SJA_TYPE_ANALOGUE
)
6777 nh
->nh_LLAnalogueOverride
[port
] = TRUE
;
6779 nh
->nh_LLAnalogueOverride
[port
] = FALSE
;
6783 typetag
= FindTagItem(SJA_Reinitialize
, tags
);
6786 if(typetag
->ti_Data
)
6788 nh
->nh_LLAnalogueOverride
[port
] = FALSE
;
6791 motortags
[0] = FindTagItem(SJA_RumbleSetSlowMotor
, tags
);
6792 motortags
[1] = FindTagItem(SJA_RumbleSetFastMotor
, tags
);
6793 motorofftag
= FindTagItem(SJA_RumbleOff
, tags
);
6794 if(motortags
[0] || motortags
[1] || motorofftag
)
6796 struct NepHidItem
*nhi
;
6797 struct NepClassHid
*nch
;
6798 struct TagItem nulltag
= { 0, 0 };
6803 if(motorofftag
->ti_Data
)
6805 motortags
[0] = &nulltag
;
6806 motortags
[1] = &nulltag
;
6810 nch
= (struct NepClassHid
*) nh
->nh_Interfaces
.lh_Head
;
6811 while(nch
->nch_Node
.ln_Succ
)
6813 if(nch
->nch_CDC
->cdc_LLRumblePort
== port
+1)
6815 for(cnt
= 0; cnt
< 2; cnt
++)
6817 if(motortags
[cnt
] && ((nhi
= nch
->nch_RumbleMotors
[cnt
])))
6819 if(nhi
->nhi_OldValue
!= motortags
[cnt
]->ti_Data
)
6821 nhi
->nhi_OldValue
= motortags
[cnt
]->ti_Data
;
6822 nhi
->nhi_Collection
->nhc_Report
->nhr_OutTouched
= TRUE
;
6823 nch
->nch_OutFeatTouched
= TRUE
;
6830 Signal(nch
->nch_Task
, (1L<<nch
->nch_TaskMsgPort
->mp_SigBit
));
6834 nch
= (struct NepClassHid
*) nch
->nch_Node
.ln_Succ
;
6840 KPRINTF(40, ("And after %08lx\n", result
));
6848 /* /// "nInstallLastActionHero()" */
6849 void nInstallLastActionHero(struct NepClassHid
*nch
)
6851 struct NepHidBase
*nh
= nch
->nch_ClsBase
;
6853 if(!nh
->nh_DispatcherTask
)
6855 nh
->nh_ReadySignal
= SIGB_SINGLE
;
6856 nh
->nh_ReadySigTask
= FindTask(NULL
);
6857 SetSignal(0, SIGF_SINGLE
);
6858 if(psdSpawnSubTask("Last Action Hero", GM_UNIQUENAME(nDispatcherTask
), nh
))
6860 Wait(1L<<nh
->nh_ReadySignal
);
6861 if(!nh
->nh_DispatcherTask
)
6863 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) GM_UNIQUENAME(libname
),
6864 "It's your fault! I'm sure! Couldn't create subtask for launching!");
6866 psdAddErrorMsg(RETURN_OK
, (STRPTR
) GM_UNIQUENAME(libname
),
6867 "Last Action Hero successfully launched!");
6870 psdAddErrorMsg(RETURN_FAIL
, (STRPTR
) GM_UNIQUENAME(libname
),
6871 "It's your fault! I'm sure! Couldn't create subtask for launching!");
6873 nh
->nh_ReadySigTask
= NULL
;
6874 //FreeSignal(nh->nh_ReadySignal);
6879 /************************************************************************/
6883 /* /// "nDispatcherTask()" */
6884 AROS_UFH0(void, GM_UNIQUENAME(nDispatcherTask
))
6888 struct NepHidBase
*nh
;
6889 struct Task
*thistask
;
6890 struct ActionMsg
*am
;
6891 struct NepHidSound
*nhs
;
6893 thistask
= FindTask(NULL
);
6896 #undef IntuitionBase
6898 #undef DataTypesBase
6899 nh
= thistask
->tc_UserData
;
6900 NewList(&nh
->nh_Sounds
);
6901 if((nh
->nh_InpMsgPort
= CreateMsgPort()))
6903 if((nh
->nh_InpIOReq
= (struct IOStdReq
*) CreateIORequest(nh
->nh_InpMsgPort
, sizeof(struct IOStdReq
))))
6905 if(!OpenDevice("input.device", 0, (struct IORequest
*) nh
->nh_InpIOReq
, 0))
6907 if((nh
->nh_DOSBase
= OpenLibrary("dos.library", 39)))
6909 if((nh
->nh_IntBase
= (struct IntuitionBase
*) OpenLibrary("intuition.library", 39)))
6911 #define IntuitionBase nh->nh_IntBase
6912 if((nh
->nh_DTBase
= OpenLibrary("datatypes.library", 39)))
6914 if((nh
->nh_CxBase
= OpenLibrary("commodities.library", 39)))
6916 if((nh
->nh_LayersBase
= OpenLibrary("layers.library", 39)))
6918 #define CxBase nh->nh_CxBase
6919 #define DOSBase nh->nh_DOSBase
6920 #define DataTypesBase nh->nh_DTBase
6921 #define LayersBase nh->nh_LayersBase
6922 if((nh
->nh_DTaskMsgPort
= CreateMsgPort()))
6924 nh
->nh_DispatcherTask
= thistask
;
6926 if(nh
->nh_ReadySigTask
)
6928 Signal(nh
->nh_ReadySigTask
, 1L<<nh
->nh_ReadySignal
);
6932 nLastActionHero(nh
);
6935 while((am
= (struct ActionMsg
*) GetMsg(nh
->nh_DTaskMsgPort
)))
6939 nhs
= (struct NepHidSound
*) nh
->nh_Sounds
.lh_Head
;
6940 while(nhs
->nhs_Node
.ln_Succ
)
6942 nFreeSound(nh
, nhs
);
6943 nhs
= (struct NepHidSound
*) nh
->nh_Sounds
.lh_Head
;
6945 DeleteMsgPort(nh
->nh_DTaskMsgPort
);
6946 nh
->nh_DTaskMsgPort
= NULL
;
6949 CloseLibrary(nh
->nh_LayersBase
);
6950 nh
->nh_LayersBase
= NULL
;
6952 CloseLibrary(nh
->nh_CxBase
);
6953 nh
->nh_CxBase
= NULL
;
6955 CloseLibrary(nh
->nh_DTBase
);
6956 nh
->nh_DTBase
= NULL
;
6958 CloseLibrary((struct Library
*) nh
->nh_IntBase
);
6959 nh
->nh_IntBase
= NULL
;
6961 CloseLibrary((struct Library
*) nh
->nh_DOSBase
);
6962 nh
->nh_DOSBase
= NULL
;
6964 CloseDevice((struct IORequest
*) nh
->nh_InpIOReq
);
6966 DeleteIORequest((struct IORequest
*) nh
->nh_InpIOReq
);
6967 nh
->nh_InpIOReq
= NULL
;
6969 DeleteMsgPort(nh
->nh_InpMsgPort
);
6970 nh
->nh_InpMsgPort
= NULL
;
6973 if(nh
->nh_ReadySigTask
)
6975 Signal(nh
->nh_ReadySigTask
, 1L<<nh
->nh_ReadySignal
);
6977 nh
->nh_DispatcherTask
= NULL
;
6983 /* /// "nLastActionHero()" */
6984 void nLastActionHero(struct NepHidBase
*nh
)
6988 struct ActionMsg
*am
;
6989 struct NepHidAction
*nha
;
6990 struct NepClassHid
*nch
;
6991 struct Window
*actwindow
;
6992 struct Screen
*actscreen
;
6995 sigmask
= (1L<<nh
->nh_DTaskMsgPort
->mp_SigBit
)|SIGBREAKF_CTRL_C
;
6998 while((am
= (struct ActionMsg
*) GetMsg(nh
->nh_DTaskMsgPort
)))
7001 nha
= am
->am_Action
;
7002 switch(nha
->nha_Type
& HUA_ATYPEMASK
)
7006 strcpy(&buf
[1], nha
->nha_VanillaString
);
7008 if(!nSendKeyString(nh
, buf
))
7010 nEasyRequest(nh
, "'%s' is no good. Really.", "Argl!", nha
->nha_VanillaString
);
7015 if(!nSendKeyString(nh
, nha
->nha_KeyString
))
7017 nEasyRequest(nh
, "Don't you ever say\n'%s'\nto me again!", "Terribly sorry!", nha
->nha_KeyString
);
7022 nPlaySound(nh
, nha
);
7029 if((fhandle
= Open(nch
->nch_CDC
->cdc_ShellCon
, MODE_READWRITE
)))
7031 ioerr
= SystemTags(nha
->nha_ExeString
,
7034 SYS_Asynch
, nha
->nha_ShellAsync
,
7035 NP_StackSize
, nch
->nch_CDC
->cdc_ShellStack
,
7039 nEasyRequest(nh
, "Offender survived execution of\n'%s'\nwith error code %ld.", "Get me a shotgun then!", nha
->nha_ExeString
, ioerr
);
7041 if((!nha
->nha_ShellAsync
) || ioerr
)
7046 nEasyRequest(nh
, "Do you really think\n'%s'\nis a nice and witty\nconsole window? Well, it's not!", "I'll use that string to hang myself!", nch
->nch_CDC
->cdc_ShellCon
);
7052 switch(nha
->nha_MiscMode
)
7054 case HUAT_ACTWINDOW
:
7056 struct Layer
*toplayer
;
7057 intlock
= LockIBase(0);
7058 actscreen
= nh
->nh_IntBase
->ActiveScreen
;
7059 actwindow
= nh
->nh_IntBase
->ActiveWindow
;
7060 UnlockIBase(intlock
);
7063 LockLayerInfo(&actscreen
->LayerInfo
);
7064 toplayer
= WhichLayer(&actscreen
->LayerInfo
, (LONG
) actscreen
->MouseX
, (LONG
) actscreen
->MouseY
);
7065 UnlockLayerInfo(&actscreen
->LayerInfo
);
7069 if(toplayer
->Window
&& (actwindow
!= toplayer
->Window
))
7071 ActivateWindow(toplayer
->Window
);
7078 case HUAT_DISPLAYBEEP
:
7086 case HUAT_SCREENCYCLE
:
7087 intlock
= LockIBase(0);
7088 actscreen
= nh
->nh_IntBase
->FirstScreen
;
7089 UnlockIBase(intlock
);
7092 ScreenToBack(actscreen
);
7096 case HUAT_WIN2FRONT
:
7097 intlock
= LockIBase(0);
7098 actwindow
= nh
->nh_IntBase
->ActiveWindow
;
7099 UnlockIBase(intlock
);
7102 WindowToFront(actwindow
);
7107 intlock
= LockIBase(0);
7108 actwindow
= nh
->nh_IntBase
->ActiveWindow
;
7109 UnlockIBase(intlock
);
7112 WindowToBack(actwindow
);
7116 case HUAT_ZIPWINDOW
:
7117 intlock
= LockIBase(0);
7118 actwindow
= nh
->nh_IntBase
->ActiveWindow
;
7119 UnlockIBase(intlock
);
7122 ZipWindow(actwindow
);
7132 sigs
= Wait(sigmask
);
7133 } while(!(sigs
& SIGBREAKF_CTRL_C
));
7137 /* /// "nLoadSound()" */
7138 struct NepHidSound
* nLoadSound(struct NepHidBase
*nh
, STRPTR name
)
7140 struct NepHidSound
*nhs
;
7141 if((nhs
= AllocVec(sizeof(struct NepHidSound
), MEMF_PUBLIC
|MEMF_CLEAR
)))
7143 if((nhs
->nhs_Node
.ln_Name
= AllocVec((ULONG
) strlen(name
)+1, MEMF_PUBLIC
)))
7145 strcpy(nhs
->nhs_Node
.ln_Name
, name
);
7146 AddTail(&nh
->nh_Sounds
, &nhs
->nhs_Node
);
7147 nhs
->nhs_DTHandle
= NewDTObject(name
,
7148 DTA_SourceType
, DTST_FILE
,
7149 DTA_GroupID
, GID_SOUND
,
7152 if(!nhs
->nhs_DTHandle
)
7154 nEasyRequest(nh
, "Does '%s' make a sound\nin the woods, when it was chopped\nbut nobody was looking at it?", "No! Couldn't load it!", name
);
7164 /* /// "nPlaySound()" */
7165 BOOL
nPlaySound(struct NepHidBase
*nh
, struct NepHidAction
*nha
)
7167 struct NepHidSound
*nhs
;
7168 struct dtTrigger playmsg
;
7169 nhs
= (struct NepHidSound
*) FindName(&nh
->nh_Sounds
, nha
->nha_SoundFile
);
7172 nhs
= nLoadSound(nh
, nha
->nha_SoundFile
);
7178 if(!nhs
->nhs_DTHandle
)
7183 SetAttrs(nhs
->nhs_DTHandle
,
7184 SDTA_Volume
, nha
->nha_SoundVolume
,
7186 playmsg
.MethodID
= DTM_TRIGGER
;
7187 playmsg
.dtt_GInfo
= NULL
;
7188 playmsg
.dtt_Function
= STM_PLAY
;
7189 playmsg
.dtt_Data
= NULL
;
7190 DoMethodA(nhs
->nhs_DTHandle
, (Msg
) &playmsg
);
7195 /* /// "nFreeSound()" */
7196 void nFreeSound(struct NepHidBase
*nh
, struct NepHidSound
*nhs
)
7198 Remove(&nhs
->nhs_Node
);
7199 if(nhs
->nhs_DTHandle
)
7201 DisposeDTObject(nhs
->nhs_DTHandle
);
7203 FreeVec(nhs
->nhs_Node
.ln_Name
);
7208 /* /// "nInvertString()" */
7209 struct InputEvent
*nInvertString(struct NepHidBase
*nh
, STRPTR str
, struct KeyMap
*km
)
7211 struct InputEvent
*prior
= NULL
;
7212 struct InputEvent
*ne
;
7213 struct InputXpression tmpIX
;
7215 BOOL freeevents
= FALSE
;
7219 if(!str
) return(NULL
);
7220 if(!(*str
)) return(NULL
);
7223 if((ne
= AllocMem(sizeof(struct InputEvent
), MEMF_CLEAR
)))
7225 ne
->ie_NextEvent
= prior
;
7230 case '<': /* do angles */
7238 if(!ParseIX(oldsptr
, &tmpIX
))
7241 prior
->ie_Class
= tmpIX
.ix_Class
;
7242 prior
->ie_Code
= tmpIX
.ix_Code
;
7243 prior
->ie_Qualifier
= tmpIX
.ix_Qualifier
;
7252 case '\\': /* do escape sequences */
7275 if(freeevents
) break;
7276 /* note that this break is missing on purpose */
7277 default: /* normal key translation */
7278 InvertKeyMap((ULONG
) cc
, prior
, km
);
7284 } while(*str
&& (!freeevents
));
7287 nFreeIEvents(nh
, prior
);
7294 /* /// "nFreeIEvents()" */
7295 void nFreeIEvents(struct NepHidBase
*nh
, struct InputEvent
*event
)
7297 struct InputEvent
*next
;
7300 next
= event
->ie_NextEvent
;
7301 FreeMem(event
, sizeof(struct InputEvent
));
7307 /* /// "nSendKeyString()" */
7308 BOOL
nSendKeyString(struct NepHidBase
*nh
, STRPTR str
)
7310 struct InputEvent
*events
= nInvertString(nh
, str
, NULL
);
7311 struct InputEvent
*eptr
= events
;
7312 struct InputEvent lastevent
;
7322 eptr
= eptr
->ie_NextEvent
;
7327 for(lstpos
= --count
; lstpos
; lstpos
--)
7328 eptr
= eptr
->ie_NextEvent
;
7330 nh
->nh_FakeEvent
= *eptr
;
7331 nh
->nh_FakeEvent
.ie_NextEvent
= NULL
;
7332 nh
->nh_InpIOReq
->io_Data
= &nh
->nh_FakeEvent
;
7333 nh
->nh_InpIOReq
->io_Length
= sizeof(struct InputEvent
);
7334 nh
->nh_InpIOReq
->io_Command
= nh
->nh_OS4Hack
? IND_ADDEVENT
: IND_WRITEEVENT
;
7335 DoIO((struct IORequest
*) nh
->nh_InpIOReq
);
7337 nh
->nh_FakeEvent
.ie_Code
|= IECODE_UP_PREFIX
;
7338 nh
->nh_InpIOReq
->io_Data
= &nh
->nh_FakeEvent
;
7339 nh
->nh_InpIOReq
->io_Length
= sizeof(struct InputEvent
);
7340 nh
->nh_InpIOReq
->io_Command
= nh
->nh_OS4Hack
? IND_ADDEVENT
: IND_WRITEEVENT
;
7341 DoIO((struct IORequest
*) nh
->nh_InpIOReq
);
7343 lastevent
.ie_Class
= IECLASS_RAWKEY
;
7344 lastevent
.ie_SubClass
= 0;
7345 lastevent
.ie_Code
= 0xFF;
7346 lastevent
.ie_NextEvent
= NULL
;
7347 lastevent
.ie_Qualifier
= 0;
7348 nh
->nh_InpIOReq
->io_Data
= &lastevent
;
7349 nh
->nh_InpIOReq
->io_Length
= sizeof(struct InputEvent
);
7350 nh
->nh_InpIOReq
->io_Command
= nh
->nh_OS4Hack
? IND_ADDEVENT
: IND_WRITEEVENT
;
7351 DoIO((struct IORequest
*) nh
->nh_InpIOReq
);
7352 nFreeIEvents(nh
, events
);
7357 /* /// "nEasyRequest()" */
7358 LONG
nEasyRequest(struct NepHidBase
*nh
, STRPTR body
, STRPTR gadgets
, ...)
7362 AROS_SLOWSTACKFORMAT_PRE(gadgets
);
7363 ret
= nEasyRequestA(nh
, body
, gadgets
, AROS_SLOWSTACKFORMAT_ARG(gadgets
));
7364 AROS_SLOWSTACKFORMAT_POST(gadgets
);
7370 /* /// "nEasyRequestA()" */
7371 LONG
nEasyRequestA(struct NepHidBase
*nh
, STRPTR body
, STRPTR gadgets
, RAWARG params
)
7373 struct EasyStruct es
;
7374 es
.es_StructSize
= sizeof(struct EasyStruct
);
7376 es
.es_Title
= GM_UNIQUENAME(libname
);
7377 es
.es_TextFormat
= body
;
7378 es
.es_GadgetFormat
= gadgets
;
7379 return(EasyRequestArgs(NULL
, &es
, NULL
, params
));