3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998,1999 Lionel Ulmer
9 * - Tomb Raider 2 Demo:
10 * Playable using keyboard only.
11 * - WingCommander Prophecy Demo:
12 * Doesn't get Input Focus.
14 * - Fallout : works great in X and DGA mode
16 * FIXME: The keyboard handling needs to (and will) be merged into keyboard.c
17 * (The current implementation is currently only a proof of concept and
26 #ifdef HAVE_SYS_SIGNAL_H
27 # include <sys/signal.h>
30 #include <sys/fcntl.h>
31 #include <sys/ioctl.h>
33 #ifdef HAVE_SYS_ERRNO_H
34 # include <sys/errno.h>
36 #ifdef HAVE_LINUX_JOYSTICK_H
37 # include <linux/joystick.h>
38 # define JOYDEV "/dev/js0"
40 #include "wine/obj_base.h"
41 #include "debugtools.h"
48 #include "sysmetrics.h"
53 DEFAULT_DEBUG_CHANNEL(dinput)
56 extern BYTE InputKeyStateTable[256];
57 extern int min_keycode, max_keycode;
58 extern WORD keyc2vkey[256];
60 static ICOM_VTABLE(IDirectInputA) ddiavt;
61 static ICOM_VTABLE(IDirectInputDevice2A) SysKeyboardAvt;
62 static ICOM_VTABLE(IDirectInputDevice2A) SysMouseAvt;
64 typedef struct IDirectInputAImpl IDirectInputAImpl;
65 typedef struct IDirectInputDevice2AImpl IDirectInputDevice2AImpl;
66 typedef struct SysKeyboardAImpl SysKeyboardAImpl;
67 typedef struct SysMouseAImpl SysMouseAImpl;
69 struct IDirectInputDevice2AImpl
71 ICOM_VFIELD(IDirectInputDevice2A);
76 struct SysKeyboardAImpl
78 /* IDirectInputDevice2AImpl */
79 ICOM_VFIELD(IDirectInputDevice2A);
82 /* SysKeyboardAImpl */
84 KEYBOARD_CONFIG initial_config;
88 #ifdef HAVE_LINUX_22_JOYSTICK_API
89 typedef struct JoystickAImpl JoystickAImpl;
90 static ICOM_VTABLE(IDirectInputDevice2A) JoystickAvt;
93 /* IDirectInputDevice2AImpl */
94 ICOM_VFIELD(IDirectInputDevice2A);
98 /* joystick private */
102 LONG lMin,lMax,deadzone;
103 LPDIDEVICEOBJECTDATA data_queue;
104 int queue_pos, queue_len;
111 /* IDirectInputDevice2AImpl */
112 ICOM_VFIELD(IDirectInputDevice2A);
119 /* Previous position for relative moves */
121 LPMOUSE_EVENT_PROC prev_handler;
123 DWORD win_centerX, win_centerY;
124 LPDIDEVICEOBJECTDATA data_queue;
125 int queue_pos, queue_len;
129 CRITICAL_SECTION crit;
131 /* This is for mouse reporting. */
132 struct DIMOUSESTATE2 m_state;
135 static int evsequence=0;
138 /* UIDs for Wine "drivers".
139 When enumerating each device supporting DInput, they have two UIDs :
142 #ifdef HAVE_LINUX_22_JOYSTICK_API
143 static GUID DInput_Wine_Joystick_GUID = { /* 9e573ed9-7734-11d2-8d4a-23903fb6bdf7 */
147 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
150 static GUID DInput_Wine_Mouse_GUID = { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */
154 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
156 static GUID DInput_Wine_Keyboard_GUID = { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */
160 {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41}
163 /* FIXME: This is ugly and not thread safe :/ */
164 static IDirectInputDevice2A* current_lock = NULL;
166 /******************************************************************************
167 * Various debugging tools
169 static void _dump_cooperativelevel(DWORD dwFlags) {
175 #define FE(x) { x, #x},
179 FE(DISCL_NONEXCLUSIVE)
181 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
182 if (flags[i].mask & dwFlags)
183 DPRINTF("%s ",flags[i].name);
187 struct IDirectInputAImpl
189 ICOM_VFIELD(IDirectInputA);
193 /******************************************************************************
194 * DirectInputCreate32A
196 HRESULT WINAPI DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA *ppDI, LPUNKNOWN punkOuter)
198 IDirectInputAImpl* This;
199 TRACE("(0x%08lx,%04lx,%p,%p)\n",
200 (DWORD)hinst,dwVersion,ppDI,punkOuter
202 This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl));
204 ICOM_VTBL(This) = &ddiavt;
205 *ppDI=(IDirectInputA*)This;
208 /******************************************************************************
209 * IDirectInputA_EnumDevices
211 static HRESULT WINAPI IDirectInputAImpl_EnumDevices(
212 LPDIRECTINPUTA iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback,
213 LPVOID pvRef, DWORD dwFlags
216 ICOM_THIS(IDirectInputAImpl,iface);
217 DIDEVICEINSTANCEA devInstance;
220 TRACE("(this=%p,0x%04lx,%p,%p,%04lx)\n", This, dwDevType, lpCallback, pvRef, dwFlags);
222 devInstance.dwSize = sizeof(DIDEVICEINSTANCEA);
223 if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_KEYBOARD)) {
224 /* Return keyboard */
225 devInstance.guidInstance = GUID_SysKeyboard;/* DInput's GUID */
226 devInstance.guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */
227 devInstance.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8);
228 strcpy(devInstance.tszInstanceName, "Keyboard");
229 strcpy(devInstance.tszProductName, "Wine Keyboard");
231 ret = lpCallback(&devInstance, pvRef);
232 TRACE("Keyboard registered\n");
233 if (ret == DIENUM_STOP)
237 if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_MOUSE)) {
239 devInstance.guidInstance = GUID_SysMouse;/* DInput's GUID */
240 devInstance.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */
241 devInstance.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_UNKNOWN << 8);
242 strcpy(devInstance.tszInstanceName, "Mouse");
243 strcpy(devInstance.tszProductName, "Wine Mouse");
245 ret = lpCallback(&devInstance, pvRef);
246 TRACE("Mouse registered\n");
247 if (ret == DIENUM_STOP)
250 if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_JOYSTICK)) {
251 /* check whether we have a joystick */
252 #ifdef HAVE_LINUX_22_JOYSTICK_API
253 if ( (access(JOYDEV,O_RDONLY)!=-1) ||
254 (errno!=ENODEV && errno!=ENOENT)
256 /* Return joystick */
257 devInstance.guidInstance = GUID_Joystick;
258 devInstance.guidProduct = DInput_Wine_Joystick_GUID;
259 /* we only support traditional joysticks for now */
260 devInstance.dwDevType = DIDEVTYPE_JOYSTICK | DIDEVTYPEJOYSTICK_TRADITIONAL;
261 strcpy(devInstance.tszInstanceName, "Joystick");
262 /* ioctl JSIOCGNAME(len) */
263 strcpy(devInstance.tszProductName, "Wine Joystick");
265 ret = lpCallback(&devInstance,pvRef);
266 TRACE("Joystick registered\n");
267 if (ret == DIENUM_STOP)
275 static ULONG WINAPI IDirectInputAImpl_AddRef(LPDIRECTINPUTA iface)
277 ICOM_THIS(IDirectInputAImpl,iface);
278 return ++(This->ref);
281 static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUTA iface)
283 ICOM_THIS(IDirectInputAImpl,iface);
284 if (!(--This->ref)) {
285 HeapFree(GetProcessHeap(),0,This);
291 static HRESULT WINAPI IDirectInputAImpl_CreateDevice(
292 LPDIRECTINPUTA iface,REFGUID rguid,LPDIRECTINPUTDEVICEA* pdev,
295 ICOM_THIS(IDirectInputAImpl,iface);
298 WINE_StringFromCLSID(rguid,xbuf);
299 TRACE("(this=%p,%s,%p,%p)\n",This,xbuf,pdev,punk);
300 if ((!memcmp(&GUID_SysKeyboard,rguid,sizeof(GUID_SysKeyboard))) || /* Generic Keyboard */
301 (!memcmp(&DInput_Wine_Keyboard_GUID,rguid,sizeof(GUID_SysKeyboard)))) { /* Wine Keyboard */
302 SysKeyboardAImpl* newDevice;
303 newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysKeyboardAImpl));
305 ICOM_VTBL(newDevice) = &SysKeyboardAvt;
306 memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
307 memset(newDevice->keystate,0,256);
308 *pdev=(IDirectInputDeviceA*)newDevice;
311 if ((!memcmp(&GUID_SysMouse,rguid,sizeof(GUID_SysMouse))) || /* Generic Mouse */
312 (!memcmp(&DInput_Wine_Mouse_GUID,rguid,sizeof(GUID_SysMouse)))) { /* Wine Mouse */
313 SysMouseAImpl* newDevice;
314 newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysMouseAImpl));
316 ICOM_VTBL(newDevice) = &SysMouseAvt;
317 InitializeCriticalSection(&(newDevice->crit));
318 MakeCriticalSectionGlobal(&(newDevice->crit));
319 memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
320 *pdev=(IDirectInputDeviceA*)newDevice;
323 #ifdef HAVE_LINUX_22_JOYSTICK_API
324 if ((!memcmp(&GUID_Joystick,rguid,sizeof(GUID_Joystick))) ||
325 (!memcmp(&DInput_Wine_Joystick_GUID,rguid,sizeof(GUID_Joystick)))) {
326 JoystickAImpl* newDevice;
327 newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickAImpl));
329 ICOM_VTBL(newDevice) = &JoystickAvt;
330 newDevice->joyfd = -1;
331 memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
332 *pdev=(IDirectInputDeviceA*)newDevice;
339 static HRESULT WINAPI IDirectInputAImpl_QueryInterface(
340 LPDIRECTINPUTA iface,REFIID riid,LPVOID *ppobj
342 ICOM_THIS(IDirectInputAImpl,iface);
345 WINE_StringFromCLSID(riid,xbuf);
346 TRACE("(this=%p,%s,%p)\n",This,xbuf,ppobj);
347 if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
348 IDirectInputA_AddRef(iface);
352 if (!memcmp(&IID_IDirectInputA,riid,sizeof(*riid))) {
353 IDirectInputA_AddRef(iface);
360 static HRESULT WINAPI IDirectInputAImpl_Initialize(
361 LPDIRECTINPUTA iface,HINSTANCE hinst,DWORD x
363 return DIERR_ALREADYINITIALIZED;
366 static HRESULT WINAPI IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUTA iface,
368 ICOM_THIS(IDirectInputAImpl,iface);
371 WINE_StringFromCLSID(rguid,xbuf);
372 FIXME("(%p)->(%s): stub\n",This,xbuf);
377 static HRESULT WINAPI IDirectInputAImpl_RunControlPanel(LPDIRECTINPUTA iface,
380 ICOM_THIS(IDirectInputAImpl,iface);
381 FIXME("(%p)->(%08lx,%08lx): stub\n",This, (DWORD) hwndOwner, dwFlags);
386 static ICOM_VTABLE(IDirectInputA) ddiavt =
388 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
389 IDirectInputAImpl_QueryInterface,
390 IDirectInputAImpl_AddRef,
391 IDirectInputAImpl_Release,
392 IDirectInputAImpl_CreateDevice,
393 IDirectInputAImpl_EnumDevices,
394 IDirectInputAImpl_GetDeviceStatus,
395 IDirectInputAImpl_RunControlPanel,
396 IDirectInputAImpl_Initialize
399 /******************************************************************************
400 * IDirectInputDeviceA
403 static HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat(
404 LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df
408 TRACE(dinput,"(this=%p,%p)\n",This,df);
410 TRACE(dinput,"df.dwSize=%ld\n",df->dwSize);
411 TRACE(dinput,"(df.dwObjsize=%ld)\n",df->dwObjSize);
412 TRACE(dinput,"(df.dwFlags=0x%08lx)\n",df->dwFlags);
413 TRACE(dinput,"(df.dwDataSize=%ld)\n",df->dwDataSize);
414 TRACE(dinput,"(df.dwNumObjs=%ld)\n",df->dwNumObjs);
416 for (i=0;i<df->dwNumObjs;i++) {
419 if (df->rgodf[i].pguid)
420 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
422 strcpy(xbuf,"<no guid>");
423 TRACE(dinput,"df.rgodf[%d].guid %s\n",i,xbuf);
424 TRACE(dinput,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
425 TRACE(dinput,"dwType 0x%02lx,dwInstance %ld\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
426 TRACE(dinput,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
432 static HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel(
433 LPDIRECTINPUTDEVICE2A iface,HWND hwnd,DWORD dwflags
435 ICOM_THIS(IDirectInputDevice2AImpl,iface);
436 TRACE("(this=%p,0x%08lx,0x%08lx)\n",This,(DWORD)hwnd,dwflags);
437 if (TRACE_ON(dinput))
438 _dump_cooperativelevel(dwflags);
442 static HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification(
443 LPDIRECTINPUTDEVICE2A iface,HANDLE hnd
445 ICOM_THIS(IDirectInputDevice2AImpl,iface);
446 FIXME("(this=%p,0x%08lx): stub\n",This,(DWORD)hnd);
450 static ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE2A iface)
452 ICOM_THIS(IDirectInputDevice2AImpl,iface);
456 HeapFree(GetProcessHeap(),0,This);
460 static HRESULT WINAPI SysKeyboardAImpl_SetProperty(
461 LPDIRECTINPUTDEVICE2A iface,REFGUID rguid,LPCDIPROPHEADER ph
464 ICOM_THIS(SysKeyboardAImpl,iface);
468 WINE_StringFromCLSID(rguid,xbuf);
470 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
471 TRACE("(this=%p,%s,%p)\n",This,xbuf,ph);
472 TRACE("(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
473 ph->dwSize,ph->dwHeaderSize,ph->dwObj,ph->dwHow);
474 if (!HIWORD(rguid)) {
475 switch ((DWORD)rguid) {
476 case (DWORD) DIPROP_BUFFERSIZE: {
477 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
479 TRACE("(buffersize=%ld)\n",pd->dwData);
483 WARN("Unknown type %ld\n",(DWORD)rguid);
490 static HRESULT WINAPI SysKeyboardAImpl_GetDeviceState(
491 LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr
494 return KEYBOARD_Driver->pGetDIState(len, ptr)?DI_OK:E_FAIL;
497 static HRESULT WINAPI SysKeyboardAImpl_GetDeviceData(
498 LPDIRECTINPUTDEVICE2A iface,DWORD dodsize,LPDIDEVICEOBJECTDATA dod,
499 LPDWORD entries,DWORD flags
502 ICOM_THIS(SysKeyboardAImpl,iface);
506 TRACE("(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
507 This,dodsize,dod,entries,entries?*entries:0,flags);
509 ret=KEYBOARD_Driver->pGetDIData(
510 This->keystate, dodsize, dod, entries, flags)?DI_OK:E_FAIL;
511 for (i=0;i<*entries;i++) {
512 dod[i].dwTimeStamp = GetTickCount();
513 dod[i].dwSequence = evsequence++;
518 static HRESULT WINAPI SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface)
520 ICOM_THIS(SysKeyboardAImpl,iface);
522 TRACE("(this=%p)\n",This);
524 if (This->acquired == 0) {
525 KEYBOARD_CONFIG no_auto;
527 /* Save the original config */
528 KEYBOARD_Driver->pGetKeyboardConfig(&(This->initial_config));
530 /* Now, remove auto-repeat */
531 no_auto.auto_repeat = FALSE;
532 KEYBOARD_Driver->pSetKeyboardConfig(&no_auto, WINE_KEYBOARD_CONFIG_AUTO_REPEAT);
540 static HRESULT WINAPI SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface)
542 ICOM_THIS(SysKeyboardAImpl,iface);
543 TRACE("(this=%p)\n",This);
545 if (This->acquired == 1) {
546 /* Restore the original configuration */
547 KEYBOARD_Driver->pSetKeyboardConfig(&(This->initial_config), 0xFFFFFFFF);
550 ERR("Unacquiring a not-acquired device !!!\n");
556 static HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface(
557 LPDIRECTINPUTDEVICE2A iface,REFIID riid,LPVOID *ppobj
560 ICOM_THIS(IDirectInputDevice2AImpl,iface);
563 WINE_StringFromCLSID(riid,xbuf);
564 TRACE("(this=%p,%s,%p)\n",This,xbuf,ppobj);
565 if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
566 IDirectInputDevice2_AddRef(iface);
570 if (!memcmp(&IID_IDirectInputDeviceA,riid,sizeof(*riid))) {
571 IDirectInputDevice2_AddRef(iface);
575 if (!memcmp(&IID_IDirectInputDevice2A,riid,sizeof(*riid))) {
576 IDirectInputDevice2_AddRef(iface);
583 static ULONG WINAPI IDirectInputDevice2AImpl_AddRef(
584 LPDIRECTINPUTDEVICE2A iface)
586 ICOM_THIS(IDirectInputDevice2AImpl,iface);
590 static HRESULT WINAPI IDirectInputDevice2AImpl_GetCapabilities(
591 LPDIRECTINPUTDEVICE2A iface,
592 LPDIDEVCAPS lpDIDevCaps)
594 lpDIDevCaps->dwFlags = DIDC_ATTACHED;
599 static HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects(
600 LPDIRECTINPUTDEVICE2A iface,
601 LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
608 lpCallback(NULL, lpvRef);
613 static HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty(
614 LPDIRECTINPUTDEVICE2A iface,
616 LPDIPROPHEADER pdiph)
622 static HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo(
623 LPDIRECTINPUTDEVICE2A iface,
624 LPDIDEVICEOBJECTINSTANCEA pdidoi,
632 static HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo(
633 LPDIRECTINPUTDEVICE2A iface,
634 LPDIDEVICEINSTANCEA pdidi)
640 static HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel(
641 LPDIRECTINPUTDEVICE2A iface,
649 static HRESULT WINAPI IDirectInputDevice2AImpl_Initialize(
650 LPDIRECTINPUTDEVICE2A iface,
659 /******************************************************************************
660 * IDirectInputDevice2A
663 static HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect(
664 LPDIRECTINPUTDEVICE2A iface,
667 LPDIRECTINPUTEFFECT *ppdef,
674 static HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects(
675 LPDIRECTINPUTDEVICE2A iface,
676 LPDIENUMEFFECTSCALLBACKA lpCallback,
682 lpCallback(NULL, lpvRef);
686 static HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo(
687 LPDIRECTINPUTDEVICE2A iface,
688 LPDIEFFECTINFOA lpdei,
695 static HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState(
696 LPDIRECTINPUTDEVICE2A iface,
703 static HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand(
704 LPDIRECTINPUTDEVICE2A iface,
711 static HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects(
712 LPDIRECTINPUTDEVICE2A iface,
713 LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback,
719 lpCallback(NULL, lpvRef);
723 static HRESULT WINAPI IDirectInputDevice2AImpl_Escape(
724 LPDIRECTINPUTDEVICE2A iface,
725 LPDIEFFESCAPE lpDIEEsc)
731 static HRESULT WINAPI IDirectInputDevice2AImpl_Poll(
732 LPDIRECTINPUTDEVICE2A iface)
738 static HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData(
739 LPDIRECTINPUTDEVICE2A iface,
741 LPDIDEVICEOBJECTDATA rgdod,
749 /******************************************************************************
750 * SysMouseA (DInput Mouse support)
753 /******************************************************************************
754 * Release : release the mouse buffer.
756 static ULONG WINAPI SysMouseAImpl_Release(LPDIRECTINPUTDEVICE2A iface)
758 ICOM_THIS(SysMouseAImpl,iface);
764 /* Free the data queue */
765 if (This->data_queue != NULL)
766 HeapFree(GetProcessHeap(),0,This->data_queue);
768 /* Install the previous event handler (in case of releasing an aquired
770 if (This->prev_handler != NULL)
771 MOUSE_Enable(This->prev_handler);
772 DeleteCriticalSection(&(This->crit));
774 HeapFree(GetProcessHeap(),0,This);
779 /******************************************************************************
780 * SetCooperativeLevel : store the window in which we will do our
783 static HRESULT WINAPI SysMouseAImpl_SetCooperativeLevel(
784 LPDIRECTINPUTDEVICE2A iface,HWND hwnd,DWORD dwflags
787 ICOM_THIS(SysMouseAImpl,iface);
789 TRACE("(this=%p,0x%08lx,0x%08lx)\n",This,(DWORD)hwnd,dwflags);
791 if (TRACE_ON(dinput))
792 _dump_cooperativelevel(dwflags);
794 /* Store the window which asks for the mouse */
801 /******************************************************************************
802 * SetDataFormat : the application can choose the format of the data
803 * the device driver sends back with GetDeviceState.
805 * For the moment, only the "standard" configuration (c_dfDIMouse) is supported
806 * in absolute and relative mode.
808 static HRESULT WINAPI SysMouseAImpl_SetDataFormat(
809 LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df
812 ICOM_THIS(SysMouseAImpl,iface);
815 TRACE("(this=%p,%p)\n",This,df);
817 TRACE("(df.dwSize=%ld)\n",df->dwSize);
818 TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize);
819 TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags);
820 TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize);
821 TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs);
823 for (i=0;i<df->dwNumObjs;i++) {
826 if (df->rgodf[i].pguid)
827 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
829 strcpy(xbuf,"<no guid>");
830 TRACE("df.rgodf[%d].guid %s (%p)\n",i,xbuf, df->rgodf[i].pguid);
831 TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
832 TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
833 TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
836 /* Check size of data format to prevent crashes if the applications
837 sends a smaller buffer */
838 if ((df->dwDataSize != sizeof(struct DIMOUSESTATE)) &&
839 (df->dwDataSize != sizeof(struct DIMOUSESTATE2))) {
840 FIXME("non-standard mouse configuration not supported yet.");
841 return DIERR_INVALIDPARAM;
844 /* For the moment, ignore these fields and return always as if
845 c_dfDIMouse was passed as format... */
847 /* Check if the mouse is in absolute or relative mode */
848 if (df->dwFlags == DIDF_ABSAXIS)
850 else if (df->dwFlags == DIDF_RELAXIS)
853 ERR("Neither absolute nor relative flag set.");
855 This->df = HeapAlloc(GetProcessHeap(),0,df->dwSize+(df->dwNumObjs*df->dwObjSize));
856 memcpy(This->df,df,df->dwSize+(df->dwNumObjs*df->dwObjSize));
860 #define GEN_EVENT(offset,data,xtime,seq) \
862 if (This->queue_pos < This->queue_len) { \
863 This->data_queue[This->queue_pos].dwOfs = offset; \
864 This->data_queue[This->queue_pos].dwData = data; \
865 This->data_queue[This->queue_pos].dwTimeStamp = xtime; \
866 This->data_queue[This->queue_pos].dwSequence = seq; \
872 /* Our private mouse event handler */
873 static void WINAPI dinput_mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
874 DWORD cButtons, DWORD dwExtraInfo )
876 DWORD posX, posY, keyState, xtime, extra;
877 SysMouseAImpl* This = (SysMouseAImpl*) current_lock;
879 EnterCriticalSection(&(This->crit));
880 /* Mouse moved -> send event if asked */
882 SetEvent(This->hEvent);
884 if ( !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_MOUSEEVENT) )
885 && ((WINE_MOUSEEVENT *)dwExtraInfo)->magic == WINE_MOUSEEVENT_MAGIC ) {
886 WINE_MOUSEEVENT *wme = (WINE_MOUSEEVENT *)dwExtraInfo;
887 keyState = wme->keyState;
889 extra = (DWORD)wme->hWnd;
891 if ((dwFlags & MOUSEEVENTF_MOVE) &&
892 (dwFlags & MOUSEEVENTF_ABSOLUTE)) {
893 posX = (dx * GetSystemMetrics(SM_CXSCREEN)) >> 16;
894 posY = (dy * GetSystemMetrics(SM_CYSCREEN)) >> 16;
900 ERR("Mouse event not supported...\n");
901 LeaveCriticalSection(&(This->crit));
905 TRACE(" %ld %ld ", posX, posY);
907 if ( dwFlags & MOUSEEVENTF_MOVE ) {
908 if (This->absolute) {
909 if (posX != This->prevX)
910 GEN_EVENT(DIMOFS_X, posX, xtime, 0);
911 if (posY != This->prevY)
912 GEN_EVENT(DIMOFS_Y, posY, xtime, 0);
914 /* Relative mouse input : the real fun starts here... */
915 if (This->need_warp) {
916 if (posX != This->prevX)
917 GEN_EVENT(DIMOFS_X, posX - This->prevX, xtime, evsequence++);
918 if (posY != This->prevY)
919 GEN_EVENT(DIMOFS_Y, posY - This->prevY, xtime, evsequence++);
921 /* This is the first time the event handler has been called after a
922 GetData of GetState. */
923 if (posX != This->win_centerX) {
924 GEN_EVENT(DIMOFS_X, posX - This->win_centerX, xtime, evsequence++);
928 if (posY != This->win_centerY) {
929 GEN_EVENT(DIMOFS_Y, posY - This->win_centerY, xtime, evsequence++);
935 if ( dwFlags & MOUSEEVENTF_LEFTDOWN ) {
936 if (TRACE_ON(dinput))
939 GEN_EVENT(DIMOFS_BUTTON0, 0xFF, xtime, evsequence++);
940 This->m_state.rgbButtons[0] = 0xFF;
942 if ( dwFlags & MOUSEEVENTF_LEFTUP ) {
943 if (TRACE_ON(dinput))
946 GEN_EVENT(DIMOFS_BUTTON0, 0x00, xtime, evsequence++);
947 This->m_state.rgbButtons[0] = 0x00;
949 if ( dwFlags & MOUSEEVENTF_RIGHTDOWN ) {
950 if (TRACE_ON(dinput))
953 GEN_EVENT(DIMOFS_BUTTON1, 0xFF, xtime, evsequence++);
954 This->m_state.rgbButtons[1] = 0xFF;
956 if ( dwFlags & MOUSEEVENTF_RIGHTUP ) {
957 if (TRACE_ON(dinput))
960 GEN_EVENT(DIMOFS_BUTTON1, 0x00, xtime, evsequence++);
961 This->m_state.rgbButtons[1] = 0x00;
963 if ( dwFlags & MOUSEEVENTF_MIDDLEDOWN ) {
964 if (TRACE_ON(dinput))
967 GEN_EVENT(DIMOFS_BUTTON2, 0xFF, xtime, evsequence++);
968 This->m_state.rgbButtons[2] = 0xFF;
970 if ( dwFlags & MOUSEEVENTF_MIDDLEUP ) {
971 if (TRACE_ON(dinput))
974 GEN_EVENT(DIMOFS_BUTTON2, 0x00, xtime, evsequence++);
975 This->m_state.rgbButtons[2] = 0x00;
977 if (TRACE_ON(dinput))
983 if (This->absolute) {
984 This->m_state.lX = posX;
985 This->m_state.lY = posY;
987 This->m_state.lX = posX - This->win_centerX;
988 This->m_state.lY = posY - This->win_centerY;
991 LeaveCriticalSection(&(This->crit));
996 /******************************************************************************
997 * Acquire : gets exclusive control of the mouse
999 static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface)
1001 ICOM_THIS(SysMouseAImpl,iface);
1004 TRACE("(this=%p)\n",This);
1006 if (This->acquired == 0) {
1010 /* This stores the current mouse handler. */
1011 This->prev_handler = mouse_event;
1013 /* Store (in a global variable) the current lock */
1014 current_lock = (IDirectInputDevice2A*)This;
1016 /* Init the mouse state */
1017 This->m_state.lX = PosX;
1018 This->m_state.lY = PosY;
1019 This->m_state.lZ = 0;
1020 This->m_state.rgbButtons[0] = (MouseButtonsStates[0] ? 0xFF : 0x00);
1021 This->m_state.rgbButtons[1] = (MouseButtonsStates[1] ? 0xFF : 0x00);
1022 This->m_state.rgbButtons[2] = (MouseButtonsStates[2] ? 0xFF : 0x00);
1023 for (i = 0; i < 8; i++)
1024 This->m_state.rgbButtons[i] = 0x00;
1026 /* Install our own mouse event handler */
1027 MOUSE_Enable(dinput_mouse_event);
1029 /* Get the window dimension and find the center */
1030 GetWindowRect(This->win, &rect);
1031 This->win_centerX = (rect.right - rect.left) / 2;
1032 This->win_centerY = (rect.bottom - rect.top ) / 2;
1034 /* Warp the mouse to the center of the window */
1035 TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
1036 point.x = This->win_centerX;
1037 point.y = This->win_centerY;
1038 MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
1039 DISPLAY_MoveCursor(point.x, point.y);
1046 /******************************************************************************
1047 * Unacquire : frees the mouse
1049 static HRESULT WINAPI SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface)
1051 ICOM_THIS(SysMouseAImpl,iface);
1053 TRACE("(this=%p)\n",This);
1055 /* Reinstall previous mouse event handler */
1056 MOUSE_Enable(This->prev_handler);
1057 This->prev_handler = NULL;
1060 current_lock = NULL;
1062 /* Unacquire device */
1068 /******************************************************************************
1069 * GetDeviceState : returns the "state" of the mouse.
1071 * For the moment, only the "standard" return structure (DIMOUSESTATE) is
1074 static HRESULT WINAPI SysMouseAImpl_GetDeviceState(
1075 LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr
1077 ICOM_THIS(SysMouseAImpl,iface);
1079 EnterCriticalSection(&(This->crit));
1080 TRACE("(this=%p,0x%08lx,%p): \n",This,len,ptr);
1082 /* Check if the buffer is big enough */
1083 if ((len != sizeof(struct DIMOUSESTATE)) &&
1084 (len != sizeof(struct DIMOUSESTATE2))) {
1085 FIXME("unsupported state structure.");
1086 LeaveCriticalSection(&(This->crit));
1087 return DIERR_INVALIDPARAM;
1090 /* Copy the current mouse state */
1091 memcpy(ptr, &(This->m_state), len);
1093 /* Check if we need to do a mouse warping */
1094 if (This->need_warp) {
1097 TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
1098 point.x = This->win_centerX;
1099 point.y = This->win_centerY;
1100 MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
1101 DISPLAY_MoveCursor(point.x, point.y);
1103 This->need_warp = 0;
1106 LeaveCriticalSection(&(This->crit));
1108 TRACE("(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n",
1109 This->m_state.lX, This->m_state.lY,
1110 This->m_state.rgbButtons[0], This->m_state.rgbButtons[2], This->m_state.rgbButtons[1]);
1115 /******************************************************************************
1116 * GetDeviceState : gets buffered input data.
1118 static HRESULT WINAPI SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface,
1120 LPDIDEVICEOBJECTDATA dod,
1124 ICOM_THIS(SysMouseAImpl,iface);
1126 EnterCriticalSection(&(This->crit));
1127 TRACE("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx)\n",This,dodsize,*entries,flags);
1129 if (flags & DIGDD_PEEK)
1130 FIXME("DIGDD_PEEK\n");
1133 *entries = This->queue_pos;
1134 This->queue_pos = 0;
1136 /* Check for buffer overflow */
1137 if (This->queue_pos > *entries) {
1138 WARN("Buffer overflow not handled properly yet...\n");
1139 This->queue_pos = *entries;
1141 if (dodsize != sizeof(DIDEVICEOBJECTDATA)) {
1142 ERR("Wrong structure size !\n");
1143 LeaveCriticalSection(&(This->crit));
1144 return DIERR_INVALIDPARAM;
1147 if (This->queue_pos)
1148 TRACE("Application retrieving %d event(s).\n", This->queue_pos);
1150 /* Copy the buffered data into the application queue */
1151 memcpy(dod, This->data_queue, This->queue_pos * dodsize);
1152 *entries = This->queue_pos;
1154 /* Reset the event queue */
1155 This->queue_pos = 0;
1157 LeaveCriticalSection(&(This->crit));
1159 #if 0 /* FIXME: seems to create motion events, which fire back at us. */
1160 /* Check if we need to do a mouse warping */
1161 if (This->need_warp) {
1164 TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
1165 point.x = This->win_centerX;
1166 point.y = This->win_centerY;
1167 MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
1169 DISPLAY_MoveCursor(point.x, point.y);
1171 This->need_warp = 0;
1177 /******************************************************************************
1178 * SetProperty : change input device properties
1180 static HRESULT WINAPI SysMouseAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface,
1184 ICOM_THIS(SysMouseAImpl,iface);
1188 WINE_StringFromCLSID(rguid,xbuf);
1190 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
1192 TRACE("(this=%p,%s,%p)\n",This,xbuf,ph);
1194 if (!HIWORD(rguid)) {
1195 switch ((DWORD)rguid) {
1196 case (DWORD) DIPROP_BUFFERSIZE: {
1197 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
1199 TRACE("buffersize = %ld\n",pd->dwData);
1201 This->data_queue = (LPDIDEVICEOBJECTDATA)HeapAlloc(GetProcessHeap(),0,
1202 pd->dwData * sizeof(DIDEVICEOBJECTDATA));
1203 This->queue_pos = 0;
1204 This->queue_len = pd->dwData;
1208 FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,xbuf);
1216 /******************************************************************************
1217 * SetEventNotification : specifies event to be sent on state change
1219 static HRESULT WINAPI SysMouseAImpl_SetEventNotification(LPDIRECTINPUTDEVICE2A iface,
1221 ICOM_THIS(SysMouseAImpl,iface);
1223 TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd);
1230 #ifdef HAVE_LINUX_22_JOYSTICK_API
1231 /******************************************************************************
1234 static ULONG WINAPI JoystickAImpl_Release(LPDIRECTINPUTDEVICE2A iface)
1236 ICOM_THIS(JoystickAImpl,iface);
1241 HeapFree(GetProcessHeap(),0,This);
1245 /******************************************************************************
1246 * SetDataFormat : the application can choose the format of the data
1247 * the device driver sends back with GetDeviceState.
1249 static HRESULT WINAPI JoystickAImpl_SetDataFormat(
1250 LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df
1253 ICOM_THIS(JoystickAImpl,iface);
1256 TRACE("(this=%p,%p)\n",This,df);
1258 TRACE("(df.dwSize=%ld)\n",df->dwSize);
1259 TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize);
1260 TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags);
1261 TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize);
1262 TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs);
1264 for (i=0;i<df->dwNumObjs;i++) {
1267 if (df->rgodf[i].pguid)
1268 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
1270 strcpy(xbuf,"<no guid>");
1271 TRACE("df.rgodf[%d].guid %s (%p)\n",i,xbuf, df->rgodf[i].pguid);
1272 TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
1273 TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
1274 TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
1276 This->df = HeapAlloc(GetProcessHeap(),0,df->dwSize+(df->dwNumObjs*df->dwObjSize));
1277 memcpy(This->df,df,df->dwSize+(df->dwNumObjs*df->dwObjSize));
1281 /******************************************************************************
1282 * Acquire : gets exclusive control of the joystick
1284 static HRESULT WINAPI JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface)
1286 ICOM_THIS(JoystickAImpl,iface);
1288 TRACE("(this=%p)\n",This);
1289 if (This->joyfd!=-1)
1291 This->joyfd=open(JOYDEV,O_RDONLY);
1292 if (This->joyfd==-1)
1293 return DIERR_NOTFOUND;
1297 /******************************************************************************
1298 * Unacquire : frees the joystick
1300 static HRESULT WINAPI JoystickAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface)
1302 ICOM_THIS(JoystickAImpl,iface);
1304 TRACE("(this=%p)\n",This);
1305 if (This->joyfd!=-1) {
1312 #define map_axis(val) ((val+32768)*(This->lMax-This->lMin)/65536+This->lMin)
1314 static void joy_polldev(JoystickAImpl *This) {
1317 struct js_event jse;
1319 if (This->joyfd==-1)
1322 memset(&tv,0,sizeof(tv));
1323 FD_ZERO(&readfds);FD_SET(This->joyfd,&readfds);
1324 if (1>select(This->joyfd+1,&readfds,NULL,NULL,&tv))
1326 /* we have one event, so we can read */
1327 if (sizeof(jse)!=read(This->joyfd,&jse,sizeof(jse))) {
1330 TRACE("js_event: type 0x%x, number %d, value %d\n",jse.type,jse.number,jse.value);
1331 if (jse.type & JS_EVENT_BUTTON) {
1332 GEN_EVENT(DIJOFS_BUTTON(jse.number),jse.value?0x80:0x00,jse.time,evsequence++);
1333 This->js.rgbButtons[jse.number] = jse.value?0x80:0x00;
1335 if (jse.type & JS_EVENT_AXIS) {
1336 switch (jse.number) {
1338 GEN_EVENT(jse.number*4,jse.value,jse.time,evsequence++);
1339 This->js.lX = map_axis(jse.value);
1342 GEN_EVENT(jse.number*4,jse.value,jse.time,evsequence++);
1343 This->js.lY = map_axis(jse.value);
1346 GEN_EVENT(jse.number*4,jse.value,jse.time,evsequence++);
1347 This->js.lZ = map_axis(jse.value);
1350 FIXME("more then 3 axes (%d) not handled!\n",jse.number);
1357 /******************************************************************************
1358 * GetDeviceState : returns the "state" of the joystick.
1361 static HRESULT WINAPI JoystickAImpl_GetDeviceState(
1362 LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr
1364 ICOM_THIS(JoystickAImpl,iface);
1367 TRACE("(this=%p,0x%08lx,%p)\n",This,len,ptr);
1368 if (len != sizeof(DIJOYSTATE)) {
1369 FIXME("len %ld is not sizeof(DIJOYSTATE), unsupported format.\n",len);
1371 memcpy(ptr,&(This->js),len);
1372 This->queue_pos = 0;
1376 /******************************************************************************
1377 * GetDeviceState : gets buffered input data.
1379 static HRESULT WINAPI JoystickAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface,
1381 LPDIDEVICEOBJECTDATA dod,
1385 ICOM_THIS(JoystickAImpl,iface);
1387 FIXME("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx),STUB!\n",This,dodsize,*entries,flags);
1390 if (flags & DIGDD_PEEK)
1391 FIXME("DIGDD_PEEK\n");
1399 /******************************************************************************
1400 * SetProperty : change input device properties
1402 static HRESULT WINAPI JoystickAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface,
1406 ICOM_THIS(JoystickAImpl,iface);
1410 WINE_StringFromCLSID(rguid,xbuf);
1412 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
1414 FIXME("(this=%p,%s,%p)\n",This,xbuf,ph);
1415 FIXME("ph.dwSize = %ld, ph.dwHeaderSize =%ld, ph.dwObj = %ld, ph.dwHow= %ld\n",ph->dwSize, ph->dwHeaderSize,ph->dwObj,ph->dwHow);
1417 if (!HIWORD(rguid)) {
1418 switch ((DWORD)rguid) {
1419 case (DWORD) DIPROP_BUFFERSIZE: {
1420 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
1422 FIXME("buffersize = %ld\n",pd->dwData);
1425 case (DWORD)DIPROP_RANGE: {
1426 LPCDIPROPRANGE pr = (LPCDIPROPRANGE)ph;
1428 FIXME("proprange(%ld,%ld)\n",pr->lMin,pr->lMax);
1429 This->lMin = pr->lMin;
1430 This->lMax = pr->lMax;
1433 case (DWORD)DIPROP_DEADZONE: {
1434 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
1436 FIXME("deadzone(%ld)\n",pd->dwData);
1437 This->deadzone = pd->dwData;
1441 FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,xbuf);
1448 /******************************************************************************
1449 * SetEventNotification : specifies event to be sent on state change
1451 static HRESULT WINAPI JoystickAImpl_SetEventNotification(
1452 LPDIRECTINPUTDEVICE2A iface, HANDLE hnd
1454 ICOM_THIS(JoystickAImpl,iface);
1456 TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd);
1461 static HRESULT WINAPI JoystickAImpl_GetCapabilities(
1462 LPDIRECTINPUTDEVICE2A iface,
1463 LPDIDEVCAPS lpDIDevCaps)
1465 ICOM_THIS(JoystickAImpl,iface);
1467 int xfd = This->joyfd;
1469 TRACE("%p->(%p)\n",iface,lpDIDevCaps);
1471 xfd = open(JOYDEV,O_RDONLY);
1472 lpDIDevCaps->dwFlags = DIDC_ATTACHED;
1473 lpDIDevCaps->dwDevType = DIDEVTYPE_JOYSTICK;
1475 if (-1==ioctl(xfd,JSIOCGAXES,&axes))
1477 lpDIDevCaps->dwAxes = axes;
1479 #ifdef JSIOCGBUTTONS
1480 if (-1==ioctl(xfd,JSIOCGAXES,&buttons))
1482 lpDIDevCaps->dwButtons = buttons;
1484 if (xfd!=This->joyfd)
1488 static HRESULT WINAPI JoystickAImpl_Poll(LPDIRECTINPUTDEVICE2A iface) {
1489 ICOM_THIS(JoystickAImpl,iface);
1490 TRACE("(),stub!\n");
1497 /****************************************************************************/
1498 /****************************************************************************/
1500 static ICOM_VTABLE(IDirectInputDevice2A) SysKeyboardAvt =
1502 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1503 IDirectInputDevice2AImpl_QueryInterface,
1504 IDirectInputDevice2AImpl_AddRef,
1505 IDirectInputDevice2AImpl_Release,
1506 IDirectInputDevice2AImpl_GetCapabilities,
1507 IDirectInputDevice2AImpl_EnumObjects,
1508 IDirectInputDevice2AImpl_GetProperty,
1509 SysKeyboardAImpl_SetProperty,
1510 SysKeyboardAImpl_Acquire,
1511 SysKeyboardAImpl_Unacquire,
1512 SysKeyboardAImpl_GetDeviceState,
1513 SysKeyboardAImpl_GetDeviceData,
1514 IDirectInputDevice2AImpl_SetDataFormat,
1515 IDirectInputDevice2AImpl_SetEventNotification,
1516 IDirectInputDevice2AImpl_SetCooperativeLevel,
1517 IDirectInputDevice2AImpl_GetObjectInfo,
1518 IDirectInputDevice2AImpl_GetDeviceInfo,
1519 IDirectInputDevice2AImpl_RunControlPanel,
1520 IDirectInputDevice2AImpl_Initialize,
1521 IDirectInputDevice2AImpl_CreateEffect,
1522 IDirectInputDevice2AImpl_EnumEffects,
1523 IDirectInputDevice2AImpl_GetEffectInfo,
1524 IDirectInputDevice2AImpl_GetForceFeedbackState,
1525 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
1526 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
1527 IDirectInputDevice2AImpl_Escape,
1528 IDirectInputDevice2AImpl_Poll,
1529 IDirectInputDevice2AImpl_SendDeviceData,
1532 static ICOM_VTABLE(IDirectInputDevice2A) SysMouseAvt =
1534 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1535 IDirectInputDevice2AImpl_QueryInterface,
1536 IDirectInputDevice2AImpl_AddRef,
1537 SysMouseAImpl_Release,
1538 IDirectInputDevice2AImpl_GetCapabilities,
1539 IDirectInputDevice2AImpl_EnumObjects,
1540 IDirectInputDevice2AImpl_GetProperty,
1541 SysMouseAImpl_SetProperty,
1542 SysMouseAImpl_Acquire,
1543 SysMouseAImpl_Unacquire,
1544 SysMouseAImpl_GetDeviceState,
1545 SysMouseAImpl_GetDeviceData,
1546 SysMouseAImpl_SetDataFormat,
1547 SysMouseAImpl_SetEventNotification,
1548 SysMouseAImpl_SetCooperativeLevel,
1549 IDirectInputDevice2AImpl_GetObjectInfo,
1550 IDirectInputDevice2AImpl_GetDeviceInfo,
1551 IDirectInputDevice2AImpl_RunControlPanel,
1552 IDirectInputDevice2AImpl_Initialize,
1553 IDirectInputDevice2AImpl_CreateEffect,
1554 IDirectInputDevice2AImpl_EnumEffects,
1555 IDirectInputDevice2AImpl_GetEffectInfo,
1556 IDirectInputDevice2AImpl_GetForceFeedbackState,
1557 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
1558 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
1559 IDirectInputDevice2AImpl_Escape,
1560 IDirectInputDevice2AImpl_Poll,
1561 IDirectInputDevice2AImpl_SendDeviceData,
1564 #ifdef HAVE_LINUX_22_JOYSTICK_API
1565 static ICOM_VTABLE(IDirectInputDevice2A) JoystickAvt =
1567 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1568 IDirectInputDevice2AImpl_QueryInterface,
1569 IDirectInputDevice2AImpl_AddRef,
1570 JoystickAImpl_Release,
1571 JoystickAImpl_GetCapabilities,
1572 IDirectInputDevice2AImpl_EnumObjects,
1573 IDirectInputDevice2AImpl_GetProperty,
1574 JoystickAImpl_SetProperty,
1575 JoystickAImpl_Acquire,
1576 JoystickAImpl_Unacquire,
1577 JoystickAImpl_GetDeviceState,
1578 JoystickAImpl_GetDeviceData,
1579 JoystickAImpl_SetDataFormat,
1580 JoystickAImpl_SetEventNotification,
1581 IDirectInputDevice2AImpl_SetCooperativeLevel,
1582 IDirectInputDevice2AImpl_GetObjectInfo,
1583 IDirectInputDevice2AImpl_GetDeviceInfo,
1584 IDirectInputDevice2AImpl_RunControlPanel,
1585 IDirectInputDevice2AImpl_Initialize,
1586 IDirectInputDevice2AImpl_CreateEffect,
1587 IDirectInputDevice2AImpl_EnumEffects,
1588 IDirectInputDevice2AImpl_GetEffectInfo,
1589 IDirectInputDevice2AImpl_GetForceFeedbackState,
1590 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
1591 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
1592 IDirectInputDevice2AImpl_Escape,
1594 IDirectInputDevice2AImpl_SendDeviceData,