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
25 #include <sys/signal.h>
29 #include "wine/obj_base.h"
36 DEFAULT_DEBUG_CHANNEL(dinput
)
38 extern BYTE InputKeyStateTable
[256];
39 extern int min_keycode
, max_keycode
;
40 extern WORD keyc2vkey
[256];
42 static ICOM_VTABLE(IDirectInputA
) ddiavt
;
43 static ICOM_VTABLE(IDirectInputDevice2A
) SysKeyboardAvt
;
44 static ICOM_VTABLE(IDirectInputDevice2A
) SysMouseAvt
;
46 typedef struct IDirectInputAImpl IDirectInputAImpl
;
47 typedef struct IDirectInputDevice2AImpl IDirectInputDevice2AImpl
;
48 typedef struct SysKeyboardAImpl SysKeyboardAImpl
;
49 typedef struct SysMouseAImpl SysMouseAImpl
;
51 struct IDirectInputDevice2AImpl
53 ICOM_VTABLE(IDirectInputDevice2A
)* lpvtbl
;
58 struct SysKeyboardAImpl
60 /* IDirectInputDevice2AImpl */
61 ICOM_VTABLE(IDirectInputDevice2A
)* lpvtbl
;
64 /* SysKeyboardAImpl */
70 /* IDirectInputDevice2AImpl */
71 ICOM_VTABLE(IDirectInputDevice2A
)* lpvtbl
;
76 /* Previous position for relative moves */
78 LPMOUSE_EVENT_PROC prev_handler
;
80 DWORD win_centerX
, win_centerY
;
81 LPDIDEVICEOBJECTDATA data_queue
;
82 int queue_pos
, queue_len
;
88 /* UIDs for Wine "drivers".
89 When enumerating each device supporting DInput, they have two UIDs :
92 static GUID DInput_Wine_Mouse_GUID
= { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */
96 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
98 static GUID DInput_Wine_Keyboard_GUID
= { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */
102 {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41}
105 /* FIXME: This is ugly and not thread safe :/ */
106 static IDirectInputDevice2A
* current_lock
= NULL
;
108 /******************************************************************************
109 * Various debugging tools
111 static void _dump_cooperativelevel(DWORD dwFlags
) {
117 #define FE(x) { x, #x},
121 FE(DISCL_NONEXCLUSIVE
)
123 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
124 if (flags
[i
].mask
& dwFlags
)
125 DUMP("%s ",flags
[i
].name
);
129 struct IDirectInputAImpl
131 ICOM_VTABLE(IDirectInputA
)* lpvtbl
;
135 /******************************************************************************
136 * DirectInputCreate32A
138 HRESULT WINAPI
DirectInputCreateA(HINSTANCE hinst
, DWORD dwVersion
, LPDIRECTINPUTA
*ppDI
, LPUNKNOWN punkOuter
)
140 IDirectInputAImpl
* This
;
141 TRACE(dinput
, "(0x%08lx,%04lx,%p,%p)\n",
142 (DWORD
)hinst
,dwVersion
,ppDI
,punkOuter
144 This
= (IDirectInputAImpl
*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl
));
146 This
->lpvtbl
= &ddiavt
;
147 *ppDI
=(IDirectInputA
*)This
;
150 /******************************************************************************
151 * IDirectInputA_EnumDevices
153 static HRESULT WINAPI
IDirectInputAImpl_EnumDevices(
154 LPDIRECTINPUTA iface
, DWORD dwDevType
, LPDIENUMDEVICESCALLBACKA lpCallback
,
155 LPVOID pvRef
, DWORD dwFlags
158 ICOM_THIS(IDirectInputAImpl
,iface
);
159 DIDEVICEINSTANCEA devInstance
;
162 TRACE(dinput
, "(this=%p,0x%04lx,%p,%p,%04lx)\n", This
, dwDevType
, lpCallback
, pvRef
, dwFlags
);
164 devInstance
.dwSize
= sizeof(DIDEVICEINSTANCEA
);
166 if ((dwDevType
== 0) || (dwDevType
== DIDEVTYPE_KEYBOARD
)) {
167 /* Return keyboard */
168 devInstance
.guidInstance
= GUID_SysKeyboard
; /* DInput's GUID */
169 devInstance
.guidProduct
= DInput_Wine_Keyboard_GUID
; /* Vendor's GUID */
170 devInstance
.dwDevType
= DIDEVTYPE_KEYBOARD
| (DIDEVTYPEKEYBOARD_UNKNOWN
<< 8);
171 strcpy(devInstance
.tszInstanceName
, "Keyboard");
172 strcpy(devInstance
.tszProductName
, "Wine Keyboard");
174 ret
= lpCallback(&devInstance
, pvRef
);
175 TRACE(dinput
, "Keyboard registered\n");
177 if (ret
== DIENUM_STOP
)
181 if ((dwDevType
== 0) || (dwDevType
== DIDEVTYPE_KEYBOARD
)) {
183 devInstance
.guidInstance
= GUID_SysMouse
; /* DInput's GUID */
184 devInstance
.guidProduct
= DInput_Wine_Mouse_GUID
; /* Vendor's GUID */
185 devInstance
.dwDevType
= DIDEVTYPE_MOUSE
| (DIDEVTYPEMOUSE_UNKNOWN
<< 8);
186 strcpy(devInstance
.tszInstanceName
, "Mouse");
187 strcpy(devInstance
.tszProductName
, "Wine Mouse");
189 ret
= lpCallback(&devInstance
, pvRef
);
190 TRACE(dinput
, "Mouse registered\n");
193 /* Should also do joystick enumerations.... */
198 static ULONG WINAPI
IDirectInputAImpl_AddRef(LPDIRECTINPUTA iface
)
200 ICOM_THIS(IDirectInputAImpl
,iface
);
201 return ++(This
->ref
);
204 static ULONG WINAPI
IDirectInputAImpl_Release(LPDIRECTINPUTA iface
)
206 ICOM_THIS(IDirectInputAImpl
,iface
);
207 if (!(--This
->ref
)) {
208 HeapFree(GetProcessHeap(),0,This
);
214 static HRESULT WINAPI
IDirectInputAImpl_CreateDevice(
215 LPDIRECTINPUTA iface
,REFGUID rguid
,LPDIRECTINPUTDEVICEA
* pdev
,
218 ICOM_THIS(IDirectInputAImpl
,iface
);
221 WINE_StringFromCLSID(rguid
,xbuf
);
222 FIXME(dinput
,"(this=%p,%s,%p,%p): stub\n",This
,xbuf
,pdev
,punk
);
223 if ((!memcmp(&GUID_SysKeyboard
,rguid
,sizeof(GUID_SysKeyboard
))) || /* Generic Keyboard */
224 (!memcmp(&DInput_Wine_Keyboard_GUID
,rguid
,sizeof(GUID_SysKeyboard
)))) { /* Wine Keyboard */
225 SysKeyboardAImpl
* newDevice
;
226 newDevice
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(SysKeyboardAImpl
));
228 newDevice
->lpvtbl
= &SysKeyboardAvt
;
229 memcpy(&(newDevice
->guid
),rguid
,sizeof(*rguid
));
230 memset(newDevice
->keystate
,0,256);
231 *pdev
=(IDirectInputDeviceA
*)newDevice
;
234 if ((!memcmp(&GUID_SysMouse
,rguid
,sizeof(GUID_SysMouse
))) || /* Generic Mouse */
235 (!memcmp(&DInput_Wine_Mouse_GUID
,rguid
,sizeof(GUID_SysMouse
)))) { /* Wine Mouse */
236 SysKeyboardAImpl
* newDevice
;
237 newDevice
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(SysMouseAImpl
));
239 newDevice
->lpvtbl
= &SysMouseAvt
;
240 memcpy(&(newDevice
->guid
),rguid
,sizeof(*rguid
));
241 *pdev
=(IDirectInputDeviceA
*)newDevice
;
247 static HRESULT WINAPI
IDirectInputAImpl_QueryInterface(
248 LPDIRECTINPUTA iface
,REFIID riid
,LPVOID
*ppobj
250 ICOM_THIS(IDirectInputAImpl
,iface
);
253 WINE_StringFromCLSID(riid
,xbuf
);
254 TRACE(dinput
,"(this=%p,%s,%p)\n",This
,xbuf
,ppobj
);
255 if (!memcmp(&IID_IUnknown
,riid
,sizeof(*riid
))) {
256 IDirectInputA_AddRef(iface
);
260 if (!memcmp(&IID_IDirectInputA
,riid
,sizeof(*riid
))) {
261 IDirectInputA_AddRef(iface
);
268 static HRESULT WINAPI
IDirectInputAImpl_Initialize(
269 LPDIRECTINPUTA iface
,HINSTANCE hinst
,DWORD x
271 return DIERR_ALREADYINITIALIZED
;
274 static HRESULT WINAPI
IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUTA iface
,
276 ICOM_THIS(IDirectInputAImpl
,iface
);
279 WINE_StringFromCLSID(rguid
,xbuf
);
280 FIXME(dinput
,"(%p)->(%s): stub\n",This
,xbuf
);
285 static HRESULT WINAPI
IDirectInputAImpl_RunControlPanel(LPDIRECTINPUTA iface
,
288 ICOM_THIS(IDirectInputAImpl
,iface
);
289 FIXME(dinput
,"(%p)->(%08lx,%08lx): stub\n",This
, (DWORD
) hwndOwner
, dwFlags
);
294 static ICOM_VTABLE(IDirectInputA
) ddiavt
=
296 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
297 IDirectInputAImpl_QueryInterface
,
298 IDirectInputAImpl_AddRef
,
299 IDirectInputAImpl_Release
,
300 IDirectInputAImpl_CreateDevice
,
301 IDirectInputAImpl_EnumDevices
,
302 IDirectInputAImpl_GetDeviceStatus
,
303 IDirectInputAImpl_RunControlPanel
,
304 IDirectInputAImpl_Initialize
307 /******************************************************************************
308 * IDirectInputDeviceA
311 static HRESULT WINAPI
IDirectInputDevice2AImpl_SetDataFormat(
312 LPDIRECTINPUTDEVICE2A iface
,LPCDIDATAFORMAT df
316 TRACE(dinput,"(this=%p,%p)\n",This,df);
318 TRACE(dinput,"df.dwSize=%ld\n",df->dwSize);
319 TRACE(dinput,"(df.dwObjsize=%ld)\n",df->dwObjSize);
320 TRACE(dinput,"(df.dwFlags=0x%08lx)\n",df->dwFlags);
321 TRACE(dinput,"(df.dwDataSize=%ld)\n",df->dwDataSize);
322 TRACE(dinput,"(df.dwNumObjs=%ld)\n",df->dwNumObjs);
324 for (i=0;i<df->dwNumObjs;i++) {
327 if (df->rgodf[i].pguid)
328 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
330 strcpy(xbuf,"<no guid>");
331 TRACE(dinput,"df.rgodf[%d].guid %s\n",i,xbuf);
332 TRACE(dinput,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
333 TRACE(dinput,"dwType 0x%02lx,dwInstance %ld\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
334 TRACE(dinput,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
340 static HRESULT WINAPI
IDirectInputDevice2AImpl_SetCooperativeLevel(
341 LPDIRECTINPUTDEVICE2A iface
,HWND hwnd
,DWORD dwflags
343 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
344 FIXME(dinput
,"(this=%p,0x%08lx,0x%08lx): stub\n",This
,(DWORD
)hwnd
,dwflags
);
345 if (TRACE_ON(dinput
))
346 _dump_cooperativelevel(dwflags
);
350 static HRESULT WINAPI
IDirectInputDevice2AImpl_SetEventNotification(
351 LPDIRECTINPUTDEVICE2A iface
,HANDLE hnd
353 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
354 FIXME(dinput
,"(this=%p,0x%08lx): stub\n",This
,(DWORD
)hnd
);
358 static ULONG WINAPI
IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE2A iface
)
360 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
364 HeapFree(GetProcessHeap(),0,This
);
368 static HRESULT WINAPI
SysKeyboardAImpl_SetProperty(
369 LPDIRECTINPUTDEVICE2A iface
,REFGUID rguid
,LPCDIPROPHEADER ph
372 ICOM_THIS(SysKeyboardAImpl
,iface
);
376 WINE_StringFromCLSID(rguid
,xbuf
);
378 sprintf(xbuf
,"<special guid %ld>",(DWORD
)rguid
);
379 TRACE(dinput
,"(this=%p,%s,%p)\n",This
,xbuf
,ph
);
380 TRACE(dinput
,"(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
381 ph
->dwSize
,ph
->dwHeaderSize
,ph
->dwObj
,ph
->dwHow
);
382 if (!HIWORD(rguid
)) {
383 switch ((DWORD
)rguid
) {
384 case (DWORD
) DIPROP_BUFFERSIZE
: {
385 LPCDIPROPDWORD pd
= (LPCDIPROPDWORD
)ph
;
387 TRACE(dinput
,"(buffersize=%ld)\n",pd
->dwData
);
391 WARN(dinput
,"Unknown type %ld\n",(DWORD
)rguid
);
398 static HRESULT WINAPI
SysKeyboardAImpl_GetDeviceState(
399 LPDIRECTINPUTDEVICE2A iface
,DWORD len
,LPVOID ptr
406 for (keyc
=min_keycode
;keyc
<max_keycode
;keyc
++)
408 /* X keycode to virtual key */
409 vkey
= keyc2vkey
[keyc
] & 0xFF;
410 /* The windows scancode is keyc-min_keycode */
411 if (InputKeyStateTable
[vkey
]&0x80) {
412 ((LPBYTE
)ptr
)[keyc
-min_keycode
]=0x80;
413 ((LPBYTE
)ptr
)[(keyc
-min_keycode
)|0x80]=0x80;
418 WARN(dinput
,"whoops, SysKeyboardAImpl_GetDeviceState got len %ld?\n",len
);
422 static HRESULT WINAPI
SysKeyboardAImpl_GetDeviceData(
423 LPDIRECTINPUTDEVICE2A iface
,DWORD dodsize
,LPDIDEVICEOBJECTDATA dod
,
424 LPDWORD entries
,DWORD flags
427 ICOM_THIS(SysKeyboardAImpl
,iface
);
428 int keyc
,n
,vkey
,xentries
;
430 TRACE(dinput
,"(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
431 This
,dodsize
,dod
,entries
,entries
?*entries
:0,flags
);
435 EVENT_Synchronize( FALSE
);
444 for (keyc
=min_keycode
;(keyc
<max_keycode
) && (n
<*entries
);keyc
++)
446 /* X keycode to virtual key */
447 vkey
= keyc2vkey
[keyc
] & 0xFF;
448 if (This
->keystate
[vkey
] == (InputKeyStateTable
[vkey
]&0x80))
452 dod
[n
].dwOfs
= keyc
-min_keycode
; /* scancode */
453 dod
[n
].dwData
= InputKeyStateTable
[vkey
]&0x80;
454 dod
[n
].dwTimeStamp
= 0; /* umm */
455 dod
[n
].dwSequence
= 0; /* umm */
458 if (!(flags
& DIGDD_PEEK
))
459 This
->keystate
[vkey
] = InputKeyStateTable
[vkey
]&0x80;
463 if (n
) fprintf(stderr
,"%d entries\n",n
);
468 static HRESULT WINAPI
SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface
)
470 ICOM_THIS(SysKeyboardAImpl
,iface
);
471 TRACE(dinput
,"(this=%p): stub\n",This
);
475 static HRESULT WINAPI
SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface
)
477 ICOM_THIS(SysKeyboardAImpl
,iface
);
478 TRACE(dinput
,"(this=%p): stub\n",This
);
482 static HRESULT WINAPI
IDirectInputDevice2AImpl_QueryInterface(
483 LPDIRECTINPUTDEVICE2A iface
,REFIID riid
,LPVOID
*ppobj
486 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
489 WINE_StringFromCLSID(riid
,xbuf
);
490 TRACE(dinput
,"(this=%p,%s,%p)\n",This
,xbuf
,ppobj
);
491 if (!memcmp(&IID_IUnknown
,riid
,sizeof(*riid
))) {
492 IDirectInputDevice2_AddRef(iface
);
496 if (!memcmp(&IID_IDirectInputDeviceA
,riid
,sizeof(*riid
))) {
497 IDirectInputDevice2_AddRef(iface
);
501 if (!memcmp(&IID_IDirectInputDevice2A
,riid
,sizeof(*riid
))) {
502 IDirectInputDevice2_AddRef(iface
);
509 static ULONG WINAPI
IDirectInputDevice2AImpl_AddRef(
510 LPDIRECTINPUTDEVICE2A iface
)
512 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
516 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetCapabilities(
517 LPDIRECTINPUTDEVICE2A iface
,
518 LPDIDEVCAPS lpDIDevCaps
)
520 FIXME(dinput
, "stub!\n");
524 static HRESULT WINAPI
IDirectInputDevice2AImpl_EnumObjects(
525 LPDIRECTINPUTDEVICE2A iface
,
526 LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback
,
530 FIXME(dinput
, "stub!\n");
533 lpCallback(NULL
, lpvRef
);
538 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetProperty(
539 LPDIRECTINPUTDEVICE2A iface
,
541 LPDIPROPHEADER pdiph
)
543 FIXME(dinput
, "stub!\n");
547 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetObjectInfo(
548 LPDIRECTINPUTDEVICE2A iface
,
549 LPDIDEVICEOBJECTINSTANCEA pdidoi
,
553 FIXME(dinput
, "stub!\n");
557 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetDeviceInfo(
558 LPDIRECTINPUTDEVICE2A iface
,
559 LPDIDEVICEINSTANCEA pdidi
)
561 FIXME(dinput
, "stub!\n");
565 static HRESULT WINAPI
IDirectInputDevice2AImpl_RunControlPanel(
566 LPDIRECTINPUTDEVICE2A iface
,
570 FIXME(dinput
, "stub!\n");
574 static HRESULT WINAPI
IDirectInputDevice2AImpl_Initialize(
575 LPDIRECTINPUTDEVICE2A iface
,
580 FIXME(dinput
, "stub!\n");
584 /******************************************************************************
585 * IDirectInputDevice2A
588 static HRESULT WINAPI
IDirectInputDevice2AImpl_CreateEffect(
589 LPDIRECTINPUTDEVICE2A iface
,
592 LPDIRECTINPUTEFFECT
*ppdef
,
595 FIXME(dinput
, "stub!\n");
599 static HRESULT WINAPI
IDirectInputDevice2AImpl_EnumEffects(
600 LPDIRECTINPUTDEVICE2A iface
,
601 LPDIENUMEFFECTSCALLBACKA lpCallback
,
605 FIXME(dinput
, "stub!\n");
607 lpCallback(NULL
, lpvRef
);
611 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetEffectInfo(
612 LPDIRECTINPUTDEVICE2A iface
,
613 LPDIEFFECTINFOA lpdei
,
616 FIXME(dinput
, "stub!\n");
620 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetForceFeedbackState(
621 LPDIRECTINPUTDEVICE2A iface
,
624 FIXME(dinput
, "stub!\n");
628 static HRESULT WINAPI
IDirectInputDevice2AImpl_SendForceFeedbackCommand(
629 LPDIRECTINPUTDEVICE2A iface
,
632 FIXME(dinput
, "stub!\n");
636 static HRESULT WINAPI
IDirectInputDevice2AImpl_EnumCreatedEffectObjects(
637 LPDIRECTINPUTDEVICE2A iface
,
638 LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback
,
642 FIXME(dinput
, "stub!\n");
644 lpCallback(NULL
, lpvRef
);
648 static HRESULT WINAPI
IDirectInputDevice2AImpl_Escape(
649 LPDIRECTINPUTDEVICE2A iface
,
650 LPDIEFFESCAPE lpDIEEsc
)
652 FIXME(dinput
, "stub!\n");
656 static HRESULT WINAPI
IDirectInputDevice2AImpl_Poll(
657 LPDIRECTINPUTDEVICE2A iface
)
659 FIXME(dinput
, "stub!\n");
663 static HRESULT WINAPI
IDirectInputDevice2AImpl_SendDeviceData(
664 LPDIRECTINPUTDEVICE2A iface
,
666 LPDIDEVICEOBJECTDATA rgdod
,
670 FIXME(dinput
, "stub!\n");
674 /******************************************************************************
675 * SysMouseA (DInput Mouse support)
678 /******************************************************************************
679 * Release : release the mouse buffer.
681 static ULONG WINAPI
SysMouseAImpl_Release(LPDIRECTINPUTDEVICE2A iface
)
683 ICOM_THIS(SysMouseAImpl
,iface
);
689 /* Free the data queue */
690 if (This
->data_queue
!= NULL
)
691 HeapFree(GetProcessHeap(),0,This
->data_queue
);
693 /* Install the previous event handler (in case of releasing an aquired
695 if (This
->prev_handler
!= NULL
)
696 MOUSE_Enable(This
->prev_handler
);
698 HeapFree(GetProcessHeap(),0,This
);
703 /******************************************************************************
704 * SetCooperativeLevel : store the window in which we will do our
707 static HRESULT WINAPI
SysMouseAImpl_SetCooperativeLevel(
708 LPDIRECTINPUTDEVICE2A iface
,HWND hwnd
,DWORD dwflags
711 ICOM_THIS(SysMouseAImpl
,iface
);
713 TRACE(dinput
,"(this=%p,0x%08lx,0x%08lx): stub\n",This
,(DWORD
)hwnd
,dwflags
);
715 if (TRACE_ON(dinput
))
716 _dump_cooperativelevel(dwflags
);
718 /* Store the window which asks for the mouse */
725 /******************************************************************************
726 * SetDataFormat : the application can choose the format of the data
727 * the device driver sends back with GetDeviceState.
729 * For the moment, only the "standard" configuration (c_dfDIMouse) is supported
730 * in absolute and relative mode.
732 static HRESULT WINAPI
SysMouseAImpl_SetDataFormat(
733 LPDIRECTINPUTDEVICE2A iface
,LPCDIDATAFORMAT df
736 ICOM_THIS(SysMouseAImpl
,iface
);
739 TRACE(dinput
,"(this=%p,%p)\n",This
,df
);
741 TRACE(dinput
,"(df.dwSize=%ld)\n",df
->dwSize
);
742 TRACE(dinput
,"(df.dwObjsize=%ld)\n",df
->dwObjSize
);
743 TRACE(dinput
,"(df.dwFlags=0x%08lx)\n",df
->dwFlags
);
744 TRACE(dinput
,"(df.dwDataSize=%ld)\n",df
->dwDataSize
);
745 TRACE(dinput
,"(df.dwNumObjs=%ld)\n",df
->dwNumObjs
);
747 for (i
=0;i
<df
->dwNumObjs
;i
++) {
750 if (df
->rgodf
[i
].pguid
)
751 WINE_StringFromCLSID(df
->rgodf
[i
].pguid
,xbuf
);
753 strcpy(xbuf
,"<no guid>");
754 TRACE(dinput
,"df.rgodf[%d].guid %s (%p)\n",i
,xbuf
, df
->rgodf
[i
].pguid
);
755 TRACE(dinput
,"df.rgodf[%d].dwOfs %ld\n",i
,df
->rgodf
[i
].dwOfs
);
756 TRACE(dinput
,"dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df
->rgodf
[i
].dwType
),DIDFT_GETINSTANCE(df
->rgodf
[i
].dwType
));
757 TRACE(dinput
,"df.rgodf[%d].dwFlags 0x%08lx\n",i
,df
->rgodf
[i
].dwFlags
);
760 /* Check size of data format to prevent crashes if the applications
761 sends a smaller buffer */
762 if (df
->dwDataSize
!= sizeof(struct DIMOUSESTATE
)) {
763 FIXME(dinput
, "non-standard mouse configuration not supported yet.");
764 return DIERR_INVALIDPARAM
;
767 /* For the moment, ignore these fields and return always as if
768 c_dfDIMouse was passed as format... */
770 /* Check if the mouse is in absolute or relative mode */
771 if (df
->dwFlags
== DIDF_ABSAXIS
)
779 #define GEN_EVENT(offset,data,time,seq) \
781 if (This->queue_pos < This->queue_len) { \
782 This->data_queue[This->queue_pos].dwOfs = offset; \
783 This->data_queue[This->queue_pos].dwData = data; \
784 This->data_queue[This->queue_pos].dwTimeStamp = time; \
785 This->data_queue[This->queue_pos].dwSequence = seq; \
790 /* Our private mouse event handler */
791 static void WINAPI
dinput_mouse_event( DWORD dwFlags
, DWORD dx
, DWORD dy
,
792 DWORD cButtons
, DWORD dwExtraInfo
)
794 DWORD posX
, posY
, keyState
, time
, extra
;
795 SysMouseAImpl
* This
= (SysMouseAImpl
*) current_lock
;
797 if ( !IsBadReadPtr( (LPVOID
)dwExtraInfo
, sizeof(WINE_MOUSEEVENT
) )
798 && ((WINE_MOUSEEVENT
*)dwExtraInfo
)->magic
== WINE_MOUSEEVENT_MAGIC
) {
799 WINE_MOUSEEVENT
*wme
= (WINE_MOUSEEVENT
*)dwExtraInfo
;
800 keyState
= wme
->keyState
;
802 extra
= (DWORD
)wme
->hWnd
;
804 assert( dwFlags
& MOUSEEVENTF_ABSOLUTE
);
805 posX
= (dx
* GetSystemMetrics(SM_CXSCREEN
)) >> 16;
806 posY
= (dy
* GetSystemMetrics(SM_CYSCREEN
)) >> 16;
808 ERR(dinput
, "Mouse event not supported...\n");
812 TRACE(dinput
, " %ld %ld ", posX
, posY
);
814 if ( dwFlags
& MOUSEEVENTF_MOVE
) {
815 if (This
->absolute
) {
816 if (posX
!= This
->prevX
)
817 GEN_EVENT(DIMOFS_X
, posX
, time
, 0);
818 if (posY
!= This
->prevY
)
819 GEN_EVENT(DIMOFS_Y
, posY
, time
, 0);
821 /* Relative mouse input : the real fun starts here... */
822 if (This
->need_warp
) {
823 if (posX
!= This
->prevX
)
824 GEN_EVENT(DIMOFS_X
, posX
- This
->prevX
, time
, 0);
825 if (posY
!= This
->prevY
)
826 GEN_EVENT(DIMOFS_Y
, posY
- This
->prevY
, time
, 0);
828 /* This is the first time the event handler has been called after a
829 GetData of GetState. */
830 if (posX
!= This
->win_centerX
) {
831 GEN_EVENT(DIMOFS_X
, posX
- This
->win_centerX
, time
, 0);
835 if (posY
!= This
->win_centerY
) {
836 GEN_EVENT(DIMOFS_Y
, posY
- This
->win_centerY
, time
, 0);
842 if ( dwFlags
& MOUSEEVENTF_LEFTDOWN
) {
843 if (TRACE_ON(dinput
))
846 GEN_EVENT(DIMOFS_BUTTON0
, 0xFF, time
, 0);
848 if ( dwFlags
& MOUSEEVENTF_LEFTUP
) {
849 if (TRACE_ON(dinput
))
852 GEN_EVENT(DIMOFS_BUTTON0
, 0x00, time
, 0);
854 if ( dwFlags
& MOUSEEVENTF_RIGHTDOWN
) {
855 if (TRACE_ON(dinput
))
858 GEN_EVENT(DIMOFS_BUTTON1
, 0xFF, time
, 0);
860 if ( dwFlags
& MOUSEEVENTF_RIGHTUP
) {
861 if (TRACE_ON(dinput
))
864 GEN_EVENT(DIMOFS_BUTTON1
, 0x00, time
, 0);
866 if ( dwFlags
& MOUSEEVENTF_MIDDLEDOWN
) {
867 if (TRACE_ON(dinput
))
870 GEN_EVENT(DIMOFS_BUTTON2
, 0xFF, time
, 0);
872 if ( dwFlags
& MOUSEEVENTF_MIDDLEUP
) {
873 if (TRACE_ON(dinput
))
876 GEN_EVENT(DIMOFS_BUTTON2
, 0x00, time
, 0);
878 if (TRACE_ON(dinput
))
886 /******************************************************************************
887 * Acquire : gets exclusive control of the mouse
889 static HRESULT WINAPI
SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface
)
891 ICOM_THIS(SysMouseAImpl
,iface
);
894 TRACE(dinput
,"(this=%p)\n",This
);
896 if (This
->acquired
== 0) {
899 /* This stores the current mouse handler. */
900 This
->prev_handler
= mouse_event
;
902 /* Store (in a global variable) the current lock */
903 current_lock
= (IDirectInputDevice2A
*)This
;
905 /* Install our own mouse event handler */
906 MOUSE_Enable(dinput_mouse_event
);
908 /* Get the window dimension and find the center */
909 GetWindowRect(This
->win
, &rect
);
910 This
->win_centerX
= (rect
.right
- rect
.left
) / 2;
911 This
->win_centerY
= (rect
.bottom
- rect
.top
) / 2;
913 /* Warp the mouse to the center of the window */
914 TRACE(dinput
, "Warping mouse to %ld - %ld\n", This
->win_centerX
, This
->win_centerY
);
915 point
.x
= This
->win_centerX
;
916 point
.y
= This
->win_centerY
;
917 MapWindowPoints(This
->win
, HWND_DESKTOP
, &point
, 1);
918 DISPLAY_MoveCursor(point
.x
, point
.y
);
925 /******************************************************************************
926 * Unacquire : frees the mouse
928 static HRESULT WINAPI
SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface
)
930 ICOM_THIS(SysMouseAImpl
,iface
);
932 TRACE(dinput
,"(this=%p)\n",This
);
934 /* Reinstall previous mouse event handler */
935 MOUSE_Enable(This
->prev_handler
);
936 This
->prev_handler
= NULL
;
941 /* Unacquire device */
947 /******************************************************************************
948 * GetDeviceState : returns the "state" of the mouse.
950 * For the moment, only the "standard" return structure (DIMOUSESTATE) is
953 static HRESULT WINAPI
SysMouseAImpl_GetDeviceState(
954 LPDIRECTINPUTDEVICE2A iface
,DWORD len
,LPVOID ptr
956 ICOM_THIS(SysMouseAImpl
,iface
);
958 struct DIMOUSESTATE
*mstate
= (struct DIMOUSESTATE
*) ptr
;
960 TRACE(dinput
,"(this=%p,0x%08lx,%p): \n",This
,len
,ptr
);
962 /* Check if the buffer is big enough */
963 if (len
< sizeof(struct DIMOUSESTATE
)) {
964 FIXME(dinput
, "unsupported state structure.");
965 return DIERR_INVALIDPARAM
;
968 /* Get the mouse position */
969 EVENT_QueryPointer(&rx
, &ry
, &state
);
970 TRACE(dinput
,"(X:%ld - Y:%ld)\n", rx
, ry
);
972 /* Fill the mouse state structure */
973 if (This
->absolute
) {
977 mstate
->lX
= rx
- This
->win_centerX
;
978 mstate
->lY
= ry
- This
->win_centerY
;
980 if ((mstate
->lX
!= 0) || (mstate
->lY
!= 0))
984 mstate
->rgbButtons
[0] = (state
& MK_LBUTTON
? 0xFF : 0x00);
985 mstate
->rgbButtons
[1] = (state
& MK_RBUTTON
? 0xFF : 0x00);
986 mstate
->rgbButtons
[2] = (state
& MK_MBUTTON
? 0xFF : 0x00);
987 mstate
->rgbButtons
[3] = 0x00;
989 /* Check if we need to do a mouse warping */
990 if (This
->need_warp
) {
993 TRACE(dinput
, "Warping mouse to %ld - %ld\n", This
->win_centerX
, This
->win_centerY
);
994 point
.x
= This
->win_centerX
;
995 point
.y
= This
->win_centerY
;
996 MapWindowPoints(This
->win
, HWND_DESKTOP
, &point
, 1);
997 DISPLAY_MoveCursor(point
.x
, point
.y
);
1002 TRACE(dinput
, "(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n",
1003 mstate
->lX
, mstate
->lY
,
1004 mstate
->rgbButtons
[0], mstate
->rgbButtons
[2], mstate
->rgbButtons
[1]);
1009 /******************************************************************************
1010 * GetDeviceState : gets buffered input data.
1012 static HRESULT WINAPI
SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface
,
1014 LPDIDEVICEOBJECTDATA dod
,
1018 ICOM_THIS(SysMouseAImpl
,iface
);
1020 TRACE(dinput
,"(%p)->(%ld,%p,%p(0x%08lx),0x%08lx)\n",
1021 This
,dodsize
,dod
,entries
,*entries
,flags
);
1023 if (flags
& DIGDD_PEEK
)
1024 TRACE(dinput
, "DIGDD_PEEK\n");
1027 *entries
= This
->queue_pos
;
1028 This
->queue_pos
= 0;
1030 /* Check for buffer overflow */
1031 if (This
->queue_pos
> *entries
) {
1032 WARN(dinput
, "Buffer overflow not handled properly yet...\n");
1033 This
->queue_pos
= *entries
;
1035 if (dodsize
!= sizeof(DIDEVICEOBJECTDATA
)) {
1036 ERR(dinput
, "Wrong structure size !\n");
1037 return DIERR_INVALIDPARAM
;
1040 TRACE(dinput
, "Application retrieving %d event(s).\n", This
->queue_pos
);
1042 /* Copy the buffered data into the application queue */
1043 memcpy(dod
, This
->data_queue
, This
->queue_pos
* dodsize
);
1045 /* Reset the event queue */
1046 This
->queue_pos
= 0;
1049 /* Check if we need to do a mouse warping */
1050 if (This
->need_warp
) {
1053 TRACE(dinput
, "Warping mouse to %ld - %ld\n", This
->win_centerX
, This
->win_centerY
);
1054 point
.x
= This
->win_centerX
;
1055 point
.y
= This
->win_centerY
;
1056 MapWindowPoints(This
->win
, HWND_DESKTOP
, &point
, 1);
1057 DISPLAY_MoveCursor(point
.x
, point
.y
);
1059 This
->need_warp
= 0;
1065 /******************************************************************************
1066 * SetProperty : change input device properties
1068 static HRESULT WINAPI
SysMouseAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface
,
1072 ICOM_THIS(SysMouseAImpl
,iface
);
1076 WINE_StringFromCLSID(rguid
,xbuf
);
1078 sprintf(xbuf
,"<special guid %ld>",(DWORD
)rguid
);
1080 TRACE(dinput
,"(this=%p,%s,%p)\n",This
,xbuf
,ph
);
1082 if (!HIWORD(rguid
)) {
1083 switch ((DWORD
)rguid
) {
1084 case (DWORD
) DIPROP_BUFFERSIZE
: {
1085 LPCDIPROPDWORD pd
= (LPCDIPROPDWORD
)ph
;
1087 TRACE(dinput
,"buffersize = %ld\n",pd
->dwData
);
1089 This
->data_queue
= (LPDIDEVICEOBJECTDATA
)HeapAlloc(GetProcessHeap(),0,
1090 pd
->dwData
* sizeof(DIDEVICEOBJECTDATA
));
1091 This
->queue_pos
= 0;
1092 This
->queue_len
= pd
->dwData
;
1096 WARN(dinput
,"Unknown type %ld\n",(DWORD
)rguid
);
1105 static ICOM_VTABLE(IDirectInputDevice2A
) SysKeyboardAvt
=
1107 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1108 IDirectInputDevice2AImpl_QueryInterface
,
1109 IDirectInputDevice2AImpl_AddRef
,
1110 IDirectInputDevice2AImpl_Release
,
1111 IDirectInputDevice2AImpl_GetCapabilities
,
1112 IDirectInputDevice2AImpl_EnumObjects
,
1113 IDirectInputDevice2AImpl_GetProperty
,
1114 SysKeyboardAImpl_SetProperty
,
1115 SysKeyboardAImpl_Acquire
,
1116 SysKeyboardAImpl_Unacquire
,
1117 SysKeyboardAImpl_GetDeviceState
,
1118 SysKeyboardAImpl_GetDeviceData
,
1119 IDirectInputDevice2AImpl_SetDataFormat
,
1120 IDirectInputDevice2AImpl_SetEventNotification
,
1121 IDirectInputDevice2AImpl_SetCooperativeLevel
,
1122 IDirectInputDevice2AImpl_GetObjectInfo
,
1123 IDirectInputDevice2AImpl_GetDeviceInfo
,
1124 IDirectInputDevice2AImpl_RunControlPanel
,
1125 IDirectInputDevice2AImpl_Initialize
,
1126 IDirectInputDevice2AImpl_CreateEffect
,
1127 IDirectInputDevice2AImpl_EnumEffects
,
1128 IDirectInputDevice2AImpl_GetEffectInfo
,
1129 IDirectInputDevice2AImpl_GetForceFeedbackState
,
1130 IDirectInputDevice2AImpl_SendForceFeedbackCommand
,
1131 IDirectInputDevice2AImpl_EnumCreatedEffectObjects
,
1132 IDirectInputDevice2AImpl_Escape
,
1133 IDirectInputDevice2AImpl_Poll
,
1134 IDirectInputDevice2AImpl_SendDeviceData
,
1137 static ICOM_VTABLE(IDirectInputDevice2A
) SysMouseAvt
=
1139 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1140 IDirectInputDevice2AImpl_QueryInterface
,
1141 IDirectInputDevice2AImpl_AddRef
,
1142 SysMouseAImpl_Release
,
1143 IDirectInputDevice2AImpl_GetCapabilities
,
1144 IDirectInputDevice2AImpl_EnumObjects
,
1145 IDirectInputDevice2AImpl_GetProperty
,
1146 SysMouseAImpl_SetProperty
,
1147 SysMouseAImpl_Acquire
,
1148 SysMouseAImpl_Unacquire
,
1149 SysMouseAImpl_GetDeviceState
,
1150 SysMouseAImpl_GetDeviceData
,
1151 SysMouseAImpl_SetDataFormat
,
1152 IDirectInputDevice2AImpl_SetEventNotification
,
1153 SysMouseAImpl_SetCooperativeLevel
,
1154 IDirectInputDevice2AImpl_GetObjectInfo
,
1155 IDirectInputDevice2AImpl_GetDeviceInfo
,
1156 IDirectInputDevice2AImpl_RunControlPanel
,
1157 IDirectInputDevice2AImpl_Initialize
,
1158 IDirectInputDevice2AImpl_CreateEffect
,
1159 IDirectInputDevice2AImpl_EnumEffects
,
1160 IDirectInputDevice2AImpl_GetEffectInfo
,
1161 IDirectInputDevice2AImpl_GetForceFeedbackState
,
1162 IDirectInputDevice2AImpl_SendForceFeedbackCommand
,
1163 IDirectInputDevice2AImpl_EnumCreatedEffectObjects
,
1164 IDirectInputDevice2AImpl_Escape
,
1165 IDirectInputDevice2AImpl_Poll
,
1166 IDirectInputDevice2AImpl_SendDeviceData
,