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
,