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"
37 #include "sysmetrics.h"
40 extern BYTE InputKeyStateTable
[256];
41 extern int min_keycode
, max_keycode
;
42 extern WORD keyc2vkey
[256];
44 static ICOM_VTABLE(IDirectInputA
) ddiavt
;
45 static ICOM_VTABLE(IDirectInputDevice2A
) SysKeyboardAvt
;
46 static ICOM_VTABLE(IDirectInputDevice2A
) SysMouseAvt
;
48 typedef struct IDirectInputAImpl IDirectInputAImpl
;
49 typedef struct IDirectInputDevice2AImpl IDirectInputDevice2AImpl
;
50 typedef struct SysKeyboardAImpl SysKeyboardAImpl
;
51 typedef struct SysMouseAImpl SysMouseAImpl
;
53 struct IDirectInputDevice2AImpl
55 ICOM_VTABLE(IDirectInputDevice2A
)* lpvtbl
;
60 struct SysKeyboardAImpl
62 /* IDirectInputDevice2AImpl */
63 ICOM_VTABLE(IDirectInputDevice2A
)* lpvtbl
;
66 /* SysKeyboardAImpl */
72 /* IDirectInputDevice2AImpl */
73 ICOM_VTABLE(IDirectInputDevice2A
)* lpvtbl
;
78 /* Previous position for relative moves */
80 LPMOUSE_EVENT_PROC prev_handler
;
83 DWORD win_centerX
, win_centerY
;
84 LPDIDEVICEOBJECTDATA data_queue
;
85 int queue_pos
, queue_len
;
91 /* UIDs for Wine "drivers".
92 When enumerating each device supporting DInput, they have two UIDs :
95 static GUID DInput_Wine_Mouse_GUID
= { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */
99 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
101 static GUID DInput_Wine_Keyboard_GUID
= { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */
105 {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41}
108 /* FIXME: This is ugly and not thread safe :/ */
109 static IDirectInputDevice2A
* current_lock
= NULL
;
111 /******************************************************************************
112 * Various debugging tools
114 static void _dump_cooperativelevel(DWORD dwFlags
) {
120 #define FE(x) { x, #x},
124 FE(DISCL_NONEXCLUSIVE
)
126 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
127 if (flags
[i
].mask
& dwFlags
)
128 DUMP("%s ",flags
[i
].name
);
132 struct IDirectInputAImpl
134 ICOM_VTABLE(IDirectInputA
)* lpvtbl
;
138 /******************************************************************************
139 * DirectInputCreate32A
141 HRESULT WINAPI
DirectInputCreate32A(HINSTANCE32 hinst
, DWORD dwVersion
, LPDIRECTINPUTA
*ppDI
, LPUNKNOWN punkOuter
)
143 IDirectInputAImpl
* This
;
144 TRACE(dinput
, "(0x%08lx,%04lx,%p,%p)\n",
145 (DWORD
)hinst
,dwVersion
,ppDI
,punkOuter
147 This
= (IDirectInputAImpl
*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl
));
149 This
->lpvtbl
= &ddiavt
;
150 *ppDI
=(IDirectInputA
*)This
;
153 /******************************************************************************
154 * IDirectInputA_EnumDevices
156 static HRESULT WINAPI
IDirectInputAImpl_EnumDevices(
157 LPDIRECTINPUTA iface
, DWORD dwDevType
, LPDIENUMDEVICESCALLBACK32A lpCallback
,
158 LPVOID pvRef
, DWORD dwFlags
161 ICOM_THIS(IDirectInputAImpl
,iface
);
162 DIDEVICEINSTANCE32A devInstance
;
165 TRACE(dinput
, "(this=%p,0x%04lx,%p,%p,%04lx)\n", This
, dwDevType
, lpCallback
, pvRef
, dwFlags
);
167 devInstance
.dwSize
= sizeof(DIDEVICEINSTANCE32A
);
169 if ((dwDevType
== 0) || (dwDevType
== DIDEVTYPE_KEYBOARD
)) {
170 /* Return keyboard */
171 devInstance
.guidInstance
= GUID_SysKeyboard
; /* DInput's GUID */
172 devInstance
.guidProduct
= DInput_Wine_Keyboard_GUID
; /* Vendor's GUID */
173 devInstance
.dwDevType
= DIDEVTYPE_KEYBOARD
| (DIDEVTYPEKEYBOARD_UNKNOWN
<< 8);
174 strcpy(devInstance
.tszInstanceName
, "Keyboard");
175 strcpy(devInstance
.tszProductName
, "Wine Keyboard");
177 ret
= lpCallback(&devInstance
, pvRef
);
178 TRACE(dinput
, "Keyboard registered\n");
180 if (ret
== DIENUM_STOP
)
184 if ((dwDevType
== 0) || (dwDevType
== DIDEVTYPE_KEYBOARD
)) {
186 devInstance
.guidInstance
= GUID_SysMouse
; /* DInput's GUID */
187 devInstance
.guidProduct
= DInput_Wine_Mouse_GUID
; /* Vendor's GUID */
188 devInstance
.dwDevType
= DIDEVTYPE_MOUSE
| (DIDEVTYPEMOUSE_UNKNOWN
<< 8);
189 strcpy(devInstance
.tszInstanceName
, "Mouse");
190 strcpy(devInstance
.tszProductName
, "Wine Mouse");
192 ret
= lpCallback(&devInstance
, pvRef
);
193 TRACE(dinput
, "Mouse registered\n");
196 /* Should also do joystick enumerations.... */
201 static ULONG WINAPI
IDirectInputAImpl_AddRef(LPDIRECTINPUTA iface
)
203 ICOM_THIS(IDirectInputAImpl
,iface
);
204 return ++(This
->ref
);
207 static ULONG WINAPI
IDirectInputAImpl_Release(LPDIRECTINPUTA iface
)
209 ICOM_THIS(IDirectInputAImpl
,iface
);
210 if (!(--This
->ref
)) {
211 HeapFree(GetProcessHeap(),0,This
);
217 static HRESULT WINAPI
IDirectInputAImpl_CreateDevice(
218 LPDIRECTINPUTA iface
,REFGUID rguid
,LPDIRECTINPUTDEVICEA
* pdev
,
221 ICOM_THIS(IDirectInputAImpl
,iface
);
224 WINE_StringFromCLSID(rguid
,xbuf
);
225 FIXME(dinput
,"(this=%p,%s,%p,%p): stub\n",This
,xbuf
,pdev
,punk
);
226 if ((!memcmp(&GUID_SysKeyboard
,rguid
,sizeof(GUID_SysKeyboard
))) || /* Generic Keyboard */
227 (!memcmp(&DInput_Wine_Keyboard_GUID
,rguid
,sizeof(GUID_SysKeyboard
)))) { /* Wine Keyboard */
228 SysKeyboardAImpl
* newDevice
;
229 newDevice
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(SysKeyboardAImpl
));
231 newDevice
->lpvtbl
= &SysKeyboardAvt
;
232 memcpy(&(newDevice
->guid
),rguid
,sizeof(*rguid
));
233 memset(newDevice
->keystate
,0,256);
234 *pdev
=(IDirectInputDeviceA
*)newDevice
;
237 if ((!memcmp(&GUID_SysMouse
,rguid
,sizeof(GUID_SysMouse
))) || /* Generic Mouse */
238 (!memcmp(&DInput_Wine_Mouse_GUID
,rguid
,sizeof(GUID_SysMouse
)))) { /* Wine Mouse */
239 SysKeyboardAImpl
* newDevice
;
240 newDevice
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(SysMouseAImpl
));
242 newDevice
->lpvtbl
= &SysMouseAvt
;
243 memcpy(&(newDevice
->guid
),rguid
,sizeof(*rguid
));
244 *pdev
=(IDirectInputDeviceA
*)newDevice
;
250 static HRESULT WINAPI
IDirectInputAImpl_QueryInterface(
251 LPDIRECTINPUTA iface
,REFIID riid
,LPVOID
*ppobj
253 ICOM_THIS(IDirectInputAImpl
,iface
);
256 WINE_StringFromCLSID(riid
,xbuf
);
257 TRACE(dinput
,"(this=%p,%s,%p)\n",This
,xbuf
,ppobj
);
258 if (!memcmp(&IID_IUnknown
,riid
,sizeof(*riid
))) {
259 IDirectInputA_AddRef(iface
);
263 if (!memcmp(&IID_IDirectInputA
,riid
,sizeof(*riid
))) {
264 IDirectInputA_AddRef(iface
);
271 static HRESULT WINAPI
IDirectInputAImpl_Initialize(
272 LPDIRECTINPUTA iface
,HINSTANCE32 hinst
,DWORD x
274 return DIERR_ALREADYINITIALIZED
;
277 static ICOM_VTABLE(IDirectInputA
) ddiavt
= {
278 IDirectInputAImpl_QueryInterface
,
279 IDirectInputAImpl_AddRef
,
280 IDirectInputAImpl_Release
,
281 IDirectInputAImpl_CreateDevice
,
282 IDirectInputAImpl_EnumDevices
,
285 IDirectInputAImpl_Initialize
288 /******************************************************************************
289 * IDirectInputDeviceA
292 static HRESULT WINAPI
IDirectInputDevice2AImpl_SetDataFormat(
293 LPDIRECTINPUTDEVICE2A iface
,LPCDIDATAFORMAT df
297 TRACE(dinput,"(this=%p,%p)\n",This,df);
299 TRACE(dinput,"df.dwSize=%ld\n",df->dwSize);
300 TRACE(dinput,"(df.dwObjsize=%ld)\n",df->dwObjSize);
301 TRACE(dinput,"(df.dwFlags=0x%08lx)\n",df->dwFlags);
302 TRACE(dinput,"(df.dwDataSize=%ld)\n",df->dwDataSize);
303 TRACE(dinput,"(df.dwNumObjs=%ld)\n",df->dwNumObjs);
305 for (i=0;i<df->dwNumObjs;i++) {
308 if (df->rgodf[i].pguid)
309 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
311 strcpy(xbuf,"<no guid>");
312 TRACE(dinput,"df.rgodf[%d].guid %s\n",i,xbuf);
313 TRACE(dinput,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
314 TRACE(dinput,"dwType 0x%02lx,dwInstance %ld\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
315 TRACE(dinput,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
321 static HRESULT WINAPI
IDirectInputDevice2AImpl_SetCooperativeLevel(
322 LPDIRECTINPUTDEVICE2A iface
,HWND32 hwnd
,DWORD dwflags
324 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
325 FIXME(dinput
,"(this=%p,0x%08lx,0x%08lx): stub\n",This
,(DWORD
)hwnd
,dwflags
);
326 if (TRACE_ON(dinput
))
327 _dump_cooperativelevel(dwflags
);
331 static HRESULT WINAPI
IDirectInputDevice2AImpl_SetEventNotification(
332 LPDIRECTINPUTDEVICE2A iface
,HANDLE32 hnd
334 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
335 FIXME(dinput
,"(this=%p,0x%08lx): stub\n",This
,(DWORD
)hnd
);
339 static ULONG WINAPI
IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE2A iface
)
341 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
345 HeapFree(GetProcessHeap(),0,This
);
349 static HRESULT WINAPI
SysKeyboardAImpl_SetProperty(
350 LPDIRECTINPUTDEVICE2A iface
,REFGUID rguid
,LPCDIPROPHEADER ph
353 ICOM_THIS(SysKeyboardAImpl
,iface
);
357 WINE_StringFromCLSID(rguid
,xbuf
);
359 sprintf(xbuf
,"<special guid %ld>",(DWORD
)rguid
);
360 TRACE(dinput
,"(this=%p,%s,%p)\n",This
,xbuf
,ph
);
361 TRACE(dinput
,"(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
362 ph
->dwSize
,ph
->dwHeaderSize
,ph
->dwObj
,ph
->dwHow
);
363 if (!HIWORD(rguid
)) {
364 switch ((DWORD
)rguid
) {
365 case DIPROP_BUFFERSIZE
: {
366 LPCDIPROPDWORD pd
= (LPCDIPROPDWORD
)ph
;
368 TRACE(dinput
,"(buffersize=%ld)\n",pd
->dwData
);
372 WARN(dinput
,"Unknown type %ld\n",(DWORD
)rguid
);
379 static HRESULT WINAPI
SysKeyboardAImpl_GetDeviceState(
380 LPDIRECTINPUTDEVICE2A iface
,DWORD len
,LPVOID ptr
387 for (keyc
=min_keycode
;keyc
<max_keycode
;keyc
++)
389 /* X keycode to virtual key */
390 vkey
= keyc2vkey
[keyc
] & 0xFF;
391 /* The windows scancode is keyc-min_keycode */
392 if (InputKeyStateTable
[vkey
]&0x80) {
393 ((LPBYTE
)ptr
)[keyc
-min_keycode
]=0x80;
394 ((LPBYTE
)ptr
)[(keyc
-min_keycode
)|0x80]=0x80;
399 WARN(dinput
,"whoops, SysKeyboardAImpl_GetDeviceState got len %ld?\n",len
);
403 static HRESULT WINAPI
SysKeyboardAImpl_GetDeviceData(
404 LPDIRECTINPUTDEVICE2A iface
,DWORD dodsize
,LPDIDEVICEOBJECTDATA dod
,
405 LPDWORD entries
,DWORD flags
408 ICOM_THIS(SysKeyboardAImpl
,iface
);
409 int keyc
,n
,vkey
,xentries
;
411 TRACE(dinput
,"(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
412 This
,dodsize
,dod
,entries
,entries
?*entries
:0,flags
);
413 EVENT_WaitNetEvent(FALSE
,TRUE
);
421 for (keyc
=min_keycode
;(keyc
<max_keycode
) && (n
<*entries
);keyc
++)
423 /* X keycode to virtual key */
424 vkey
= keyc2vkey
[keyc
] & 0xFF;
425 if (This
->keystate
[vkey
] == (InputKeyStateTable
[vkey
]&0x80))
429 dod
[n
].dwOfs
= keyc
-min_keycode
; /* scancode */
430 dod
[n
].dwData
= InputKeyStateTable
[vkey
]&0x80;
431 dod
[n
].dwTimeStamp
= 0; /* umm */
432 dod
[n
].dwSequence
= 0; /* umm */
435 if (!(flags
& DIGDD_PEEK
))
436 This
->keystate
[vkey
] = InputKeyStateTable
[vkey
]&0x80;
440 if (n
) fprintf(stderr
,"%d entries\n",n
);
445 static HRESULT WINAPI
SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface
)
447 ICOM_THIS(SysKeyboardAImpl
,iface
);
448 TRACE(dinput
,"(this=%p): stub\n",This
);
452 static HRESULT WINAPI
SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface
)
454 ICOM_THIS(SysKeyboardAImpl
,iface
);
455 TRACE(dinput
,"(this=%p): stub\n",This
);
459 static HRESULT WINAPI
IDirectInputDevice2AImpl_QueryInterface(
460 LPDIRECTINPUTDEVICE2A iface
,REFIID riid
,LPVOID
*ppobj
463 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
466 WINE_StringFromCLSID(riid
,xbuf
);
467 TRACE(dinput
,"(this=%p,%s,%p)\n",This
,xbuf
,ppobj
);
468 if (!memcmp(&IID_IUnknown
,riid
,sizeof(*riid
))) {
469 IDirectInputDevice2_AddRef(iface
);
473 if (!memcmp(&IID_IDirectInputDeviceA
,riid
,sizeof(*riid
))) {
474 IDirectInputDevice2_AddRef(iface
);
478 if (!memcmp(&IID_IDirectInputDevice2A
,riid
,sizeof(*riid
))) {
479 IDirectInputDevice2_AddRef(iface
);
486 static ULONG WINAPI
IDirectInputDevice2AImpl_AddRef(
487 LPDIRECTINPUTDEVICE2A iface
)
489 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
493 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetCapabilities(
494 LPDIRECTINPUTDEVICE2A iface
,
495 LPDIDEVCAPS lpDIDevCaps
)
497 FIXME(dinput
, "stub!\n");
501 static HRESULT WINAPI
IDirectInputDevice2AImpl_EnumObjects(
502 LPDIRECTINPUTDEVICE2A iface
,
503 LPDIENUMDEVICEOBJECTSCALLBACK32A lpCallback
,
507 FIXME(dinput
, "stub!\n");
510 lpCallback(NULL
, lpvRef
);
515 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetProperty(
516 LPDIRECTINPUTDEVICE2A iface
,
518 LPDIPROPHEADER pdiph
)
520 FIXME(dinput
, "stub!\n");
524 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetObjectInfo(
525 LPDIRECTINPUTDEVICE2A iface
,
526 LPDIDEVICEOBJECTINSTANCE32A pdidoi
,
530 FIXME(dinput
, "stub!\n");
534 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetDeviceInfo(
535 LPDIRECTINPUTDEVICE2A iface
,
536 LPDIDEVICEINSTANCE32A pdidi
)
538 FIXME(dinput
, "stub!\n");
542 static HRESULT WINAPI
IDirectInputDevice2AImpl_RunControlPanel(
543 LPDIRECTINPUTDEVICE2A iface
,
547 FIXME(dinput
, "stub!\n");
551 static HRESULT WINAPI
IDirectInputDevice2AImpl_Initialize(
552 LPDIRECTINPUTDEVICE2A iface
,
557 FIXME(dinput
, "stub!\n");
561 /******************************************************************************
562 * IDirectInputDevice2A
565 static HRESULT WINAPI
IDirectInputDevice2AImpl_CreateEffect(
566 LPDIRECTINPUTDEVICE2A iface
,
569 LPDIRECTINPUTEFFECT
*ppdef
,
572 FIXME(dinput
, "stub!\n");
576 static HRESULT WINAPI
IDirectInputDevice2AImpl_EnumEffects(
577 LPDIRECTINPUTDEVICE2A iface
,
578 LPDIENUMEFFECTSCALLBACKA lpCallback
,
582 FIXME(dinput
, "stub!\n");
584 lpCallback(NULL
, lpvRef
);
588 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetEffectInfo(
589 LPDIRECTINPUTDEVICE2A iface
,
590 LPDIEFFECTINFOA lpdei
,
593 FIXME(dinput
, "stub!\n");
597 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetForceFeedbackState(
598 LPDIRECTINPUTDEVICE2A iface
,
601 FIXME(dinput
, "stub!\n");
605 static HRESULT WINAPI
IDirectInputDevice2AImpl_SendForceFeedbackCommand(
606 LPDIRECTINPUTDEVICE2A iface
,
609 FIXME(dinput
, "stub!\n");
613 static HRESULT WINAPI
IDirectInputDevice2AImpl_EnumCreatedEffectObjects(
614 LPDIRECTINPUTDEVICE2A iface
,
615 LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback
,
619 FIXME(dinput
, "stub!\n");
621 lpCallback(NULL
, lpvRef
);
625 static HRESULT WINAPI
IDirectInputDevice2AImpl_Escape(
626 LPDIRECTINPUTDEVICE2A iface
,
627 LPDIEFFESCAPE lpDIEEsc
)
629 FIXME(dinput
, "stub!\n");
633 static HRESULT WINAPI
IDirectInputDevice2AImpl_Poll(
634 LPDIRECTINPUTDEVICE2A iface
)
636 FIXME(dinput
, "stub!\n");
640 static HRESULT WINAPI
IDirectInputDevice2AImpl_SendDeviceData(
641 LPDIRECTINPUTDEVICE2A iface
,
643 LPDIDEVICEOBJECTDATA rgdod
,
647 FIXME(dinput
, "stub!\n");
651 /******************************************************************************
652 * SysMouseA (DInput Mouse support)
655 /******************************************************************************
656 * Release : release the mouse buffer.
658 static ULONG WINAPI
SysMouseAImpl_Release(LPDIRECTINPUTDEVICE2A iface
)
660 ICOM_THIS(SysMouseAImpl
,iface
);
666 /* Free the data queue */
667 if (This
->data_queue
!= NULL
)
668 HeapFree(GetProcessHeap(),0,This
->data_queue
);
670 /* Install the previous event handler (in case of releasing an aquired
672 if (This
->prev_handler
!= NULL
)
673 MOUSE_Enable(This
->prev_handler
);
675 HeapFree(GetProcessHeap(),0,This
);
680 /******************************************************************************
681 * SetCooperativeLevel : store the window in which we will do our
684 static HRESULT WINAPI
SysMouseAImpl_SetCooperativeLevel(
685 LPDIRECTINPUTDEVICE2A iface
,HWND32 hwnd
,DWORD dwflags
688 ICOM_THIS(SysMouseAImpl
,iface
);
690 TRACE(dinput
,"(this=%p,0x%08lx,0x%08lx): stub\n",This
,(DWORD
)hwnd
,dwflags
);
692 if (TRACE_ON(dinput
))
693 _dump_cooperativelevel(dwflags
);
695 /* Store the window which asks for the mouse */
702 /******************************************************************************
703 * SetDataFormat : the application can choose the format of the data
704 * the device driver sends back with GetDeviceState.
706 * For the moment, only the "standard" configuration (c_dfDIMouse) is supported
707 * in absolute and relative mode.
709 static HRESULT WINAPI
SysMouseAImpl_SetDataFormat(
710 LPDIRECTINPUTDEVICE2A iface
,LPCDIDATAFORMAT df
713 ICOM_THIS(SysMouseAImpl
,iface
);
716 TRACE(dinput
,"(this=%p,%p)\n",This
,df
);
718 TRACE(dinput
,"(df.dwSize=%ld)\n",df
->dwSize
);
719 TRACE(dinput
,"(df.dwObjsize=%ld)\n",df
->dwObjSize
);
720 TRACE(dinput
,"(df.dwFlags=0x%08lx)\n",df
->dwFlags
);
721 TRACE(dinput
,"(df.dwDataSize=%ld)\n",df
->dwDataSize
);
722 TRACE(dinput
,"(df.dwNumObjs=%ld)\n",df
->dwNumObjs
);
724 for (i
=0;i
<df
->dwNumObjs
;i
++) {
727 if (df
->rgodf
[i
].pguid
)
728 WINE_StringFromCLSID(df
->rgodf
[i
].pguid
,xbuf
);
730 strcpy(xbuf
,"<no guid>");
731 TRACE(dinput
,"df.rgodf[%d].guid %s (%p)\n",i
,xbuf
, df
->rgodf
[i
].pguid
);
732 TRACE(dinput
,"df.rgodf[%d].dwOfs %ld\n",i
,df
->rgodf
[i
].dwOfs
);
733 TRACE(dinput
,"dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df
->rgodf
[i
].dwType
),DIDFT_GETINSTANCE(df
->rgodf
[i
].dwType
));
734 TRACE(dinput
,"df.rgodf[%d].dwFlags 0x%08lx\n",i
,df
->rgodf
[i
].dwFlags
);
737 /* Check size of data format to prevent crashes if the applications
738 sends a smaller buffer */
739 if (df
->dwDataSize
!= sizeof(struct DIMOUSESTATE
)) {
740 FIXME(dinput
, "non-standard mouse configuration not supported yet.");
741 return DIERR_INVALIDPARAM
;
744 /* For the moment, ignore these fields and return always as if
745 c_dfDIMouse was passed as format... */
747 /* Check if the mouse is in absolute or relative mode */
748 if (df
->dwFlags
== DIDF_ABSAXIS
)
756 #define GEN_EVENT(offset,data,time,seq) \
758 if (This->queue_pos < This->queue_len) { \
759 This->data_queue[This->queue_pos].dwOfs = offset; \
760 This->data_queue[This->queue_pos].dwData = data; \
761 This->data_queue[This->queue_pos].dwTimeStamp = time; \
762 This->data_queue[This->queue_pos].dwSequence = seq; \
767 /* Our private mouse event handler */
768 static void WINAPI
dinput_mouse_event( DWORD dwFlags
, DWORD dx
, DWORD dy
,
769 DWORD cButtons
, DWORD dwExtraInfo
)
771 DWORD posX
, posY
, keyState
, time
, extra
;
772 SysMouseAImpl
* This
= (SysMouseAImpl
*) current_lock
;
774 if ( !IsBadReadPtr32( (LPVOID
)dwExtraInfo
, sizeof(WINE_MOUSEEVENT
) )
775 && ((WINE_MOUSEEVENT
*)dwExtraInfo
)->magic
== WINE_MOUSEEVENT_MAGIC
) {
776 WINE_MOUSEEVENT
*wme
= (WINE_MOUSEEVENT
*)dwExtraInfo
;
777 keyState
= wme
->keyState
;
779 extra
= (DWORD
)wme
->hWnd
;
781 assert( dwFlags
& MOUSEEVENTF_ABSOLUTE
);
782 posX
= (dx
* SYSMETRICS_CXSCREEN
) >> 16;
783 posY
= (dy
* SYSMETRICS_CYSCREEN
) >> 16;
785 ERR(dinput
, "Mouse event not supported...\n");
789 TRACE(dinput
, " %ld %ld ", posX
, posY
);
791 if ( dwFlags
& MOUSEEVENTF_MOVE
) {
792 if (This
->absolute
) {
793 if (posX
!= This
->prevX
)
794 GEN_EVENT(DIMOFS_X
, posX
, time
, 0);
795 if (posY
!= This
->prevY
)
796 GEN_EVENT(DIMOFS_Y
, posY
, time
, 0);
798 /* Relative mouse input : the real fun starts here... */
799 if (This
->need_warp
) {
800 if (posX
!= This
->prevX
)
801 GEN_EVENT(DIMOFS_X
, posX
- This
->prevX
, time
, 0);
802 if (posY
!= This
->prevY
)
803 GEN_EVENT(DIMOFS_Y
, posY
- This
->prevY
, time
, 0);
805 /* This is the first time the event handler has been called after a
806 GetData of GetState. */
807 if (posX
!= This
->win_centerX
) {
808 GEN_EVENT(DIMOFS_X
, posX
- This
->win_centerX
, time
, 0);
812 if (posY
!= This
->win_centerY
) {
813 GEN_EVENT(DIMOFS_Y
, posY
- This
->win_centerY
, time
, 0);
819 if ( dwFlags
& MOUSEEVENTF_LEFTDOWN
) {
820 if (TRACE_ON(dinput
))
823 GEN_EVENT(DIMOFS_BUTTON0
, 0xFF, time
, 0);
825 if ( dwFlags
& MOUSEEVENTF_LEFTUP
) {
826 if (TRACE_ON(dinput
))
829 GEN_EVENT(DIMOFS_BUTTON0
, 0x00, time
, 0);
831 if ( dwFlags
& MOUSEEVENTF_RIGHTDOWN
) {
832 if (TRACE_ON(dinput
))
835 GEN_EVENT(DIMOFS_BUTTON1
, 0xFF, time
, 0);
837 if ( dwFlags
& MOUSEEVENTF_RIGHTUP
) {
838 if (TRACE_ON(dinput
))
841 GEN_EVENT(DIMOFS_BUTTON1
, 0x00, time
, 0);
843 if ( dwFlags
& MOUSEEVENTF_MIDDLEDOWN
) {
844 if (TRACE_ON(dinput
))
847 GEN_EVENT(DIMOFS_BUTTON2
, 0xFF, time
, 0);
849 if ( dwFlags
& MOUSEEVENTF_MIDDLEUP
) {
850 if (TRACE_ON(dinput
))
853 GEN_EVENT(DIMOFS_BUTTON2
, 0x00, time
, 0);
855 if (TRACE_ON(dinput
))
863 /******************************************************************************
864 * Acquire : gets exclusive control of the mouse
866 static HRESULT WINAPI
SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface
)
868 ICOM_THIS(SysMouseAImpl
,iface
);
871 TRACE(dinput
,"(this=%p)\n",This
);
873 if (This
->acquired
== 0) {
874 /* This stores the current mouse handler.
875 FIXME : need to be fixed for native USER use */
876 This
->prev_handler
= mouse_event
;
878 /* Store (in a global variable) the current lock */
879 current_lock
= (IDirectInputDevice2A
*)This
;
881 /* Install our own mouse event handler */
882 MOUSE_Enable(dinput_mouse_event
);
884 /* Get the window dimension and find the center */
885 GetWindowRect32(This
->win
, &rect
);
886 This
->xwin
= ((X11DRV_WND_DATA
*) WIN_FindWndPtr(This
->win
)->pDriverData
)->window
;
887 This
->win_centerX
= (rect
.right
- rect
.left
) / 2;
888 This
->win_centerY
= (rect
.bottom
- rect
.top
) / 2;
889 /* Warp the mouse to the center of the window */
890 TRACE(dinput
, "Warping mouse to %ld - %ld\n", This
->win_centerX
, This
->win_centerY
);
891 TSXWarpPointer(display
, DefaultRootWindow(display
),
892 This
->xwin
, 0, 0, 0, 0,
893 This
->win_centerX
, This
->win_centerY
);
900 /******************************************************************************
901 * Unacquire : frees the mouse
903 static HRESULT WINAPI
SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface
)
905 ICOM_THIS(SysMouseAImpl
,iface
);
907 TRACE(dinput
,"(this=%p)\n",This
);
909 /* Reinstall previous mouse event handler */
910 MOUSE_Enable(This
->prev_handler
);
911 This
->prev_handler
= NULL
;
916 /* Unacquire device */
922 /******************************************************************************
923 * GetDeviceState : returns the "state" of the mouse.
925 * For the moment, only the "standard" return structure (DIMOUSESTATE) is
928 static HRESULT WINAPI
SysMouseAImpl_GetDeviceState(
929 LPDIRECTINPUTDEVICE2A iface
,DWORD len
,LPVOID ptr
931 ICOM_THIS(SysMouseAImpl
,iface
);
933 struct DIMOUSESTATE
*mstate
= (struct DIMOUSESTATE
*) ptr
;
935 TRACE(dinput
,"(this=%p,0x%08lx,%p): \n",This
,len
,ptr
);
937 /* Check if the buffer is big enough */
938 if (len
< sizeof(struct DIMOUSESTATE
)) {
939 FIXME(dinput
, "unsupported state structure.");
940 return DIERR_INVALIDPARAM
;
943 /* Get the mouse position */
944 EVENT_QueryPointer(&rx
, &ry
, &state
);
945 TRACE(dinput
,"(X:%ld - Y:%ld)\n", rx
, ry
);
947 /* Fill the mouse state structure */
948 if (This
->absolute
) {
952 mstate
->lX
= rx
- This
->win_centerX
;
953 mstate
->lY
= ry
- This
->win_centerY
;
955 if ((mstate
->lX
!= 0) || (mstate
->lY
!= 0))
959 mstate
->rgbButtons
[0] = (state
& MK_LBUTTON
? 0xFF : 0x00);
960 mstate
->rgbButtons
[1] = (state
& MK_RBUTTON
? 0xFF : 0x00);
961 mstate
->rgbButtons
[2] = (state
& MK_MBUTTON
? 0xFF : 0x00);
962 mstate
->rgbButtons
[3] = 0x00;
964 /* Check if we need to do a mouse warping */
965 if (This
->need_warp
) {
966 TRACE(dinput
, "Warping mouse to %ld - %ld\n", This
->win_centerX
, This
->win_centerY
);
967 TSXWarpPointer(display
, DefaultRootWindow(display
),
968 This
->xwin
, 0, 0, 0, 0,
969 This
->win_centerX
, This
->win_centerY
);
973 TRACE(dinput
, "(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n",
974 mstate
->lX
, mstate
->lY
,
975 mstate
->rgbButtons
[0], mstate
->rgbButtons
[2], mstate
->rgbButtons
[1]);
980 /******************************************************************************
981 * GetDeviceState : gets buffered input data.
983 static HRESULT WINAPI
SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface
,
985 LPDIDEVICEOBJECTDATA dod
,
989 ICOM_THIS(SysMouseAImpl
,iface
);
991 TRACE(dinput
,"(%p)->(%ld,%p,%p(0x%08lx),0x%08lx)\n",
992 This
,dodsize
,dod
,entries
,*entries
,flags
);
994 if (flags
& DIGDD_PEEK
)
995 TRACE(dinput
, "DIGDD_PEEK\n");
998 *entries
= This
->queue_pos
;
1001 /* Check for buffer overflow */
1002 if (This
->queue_pos
> *entries
) {
1003 WARN(dinput
, "Buffer overflow not handled properly yet...\n");
1004 This
->queue_pos
= *entries
;
1006 if (dodsize
!= sizeof(DIDEVICEOBJECTDATA
)) {
1007 ERR(dinput
, "Wrong structure size !\n");
1008 return DIERR_INVALIDPARAM
;
1011 /* Copy the buffered data into the application queue */
1012 memcpy(dod
, This
->data_queue
, This
->queue_pos
* dodsize
);
1014 /* Reset the event queue */
1015 This
->queue_pos
= 0;
1018 /* Check if we need to do a mouse warping */
1019 if (This
->need_warp
) {
1020 TRACE(dinput
, "Warping mouse to %ld - %ld\n", This
->win_centerX
, This
->win_centerY
);
1021 TSXWarpPointer(display
, DefaultRootWindow(display
),
1022 This
->xwin
, 0, 0, 0, 0,
1023 This
->win_centerX
, This
->win_centerY
);
1024 This
->need_warp
= 0;
1030 /******************************************************************************
1031 * SetProperty : change input device properties
1033 static HRESULT WINAPI
SysMouseAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface
,
1037 ICOM_THIS(SysMouseAImpl
,iface
);
1041 WINE_StringFromCLSID(rguid
,xbuf
);
1043 sprintf(xbuf
,"<special guid %ld>",(DWORD
)rguid
);
1045 TRACE(dinput
,"(this=%p,%s,%p)\n",This
,xbuf
,ph
);
1047 if (!HIWORD(rguid
)) {
1048 switch ((DWORD
)rguid
) {
1049 case DIPROP_BUFFERSIZE
: {
1050 LPCDIPROPDWORD pd
= (LPCDIPROPDWORD
)ph
;
1052 TRACE(dinput
,"buffersize = %ld\n",pd
->dwData
);
1054 This
->data_queue
= (LPDIDEVICEOBJECTDATA
)HeapAlloc(GetProcessHeap(),0,
1055 pd
->dwData
* sizeof(DIDEVICEOBJECTDATA
));
1056 This
->queue_pos
= 0;
1057 This
->queue_len
= pd
->dwData
;
1061 WARN(dinput
,"Unknown type %ld\n",(DWORD
)rguid
);
1070 static ICOM_VTABLE(IDirectInputDevice2A
) SysKeyboardAvt
={
1071 IDirectInputDevice2AImpl_QueryInterface
,
1072 IDirectInputDevice2AImpl_AddRef
,
1073 IDirectInputDevice2AImpl_Release
,
1074 IDirectInputDevice2AImpl_GetCapabilities
,
1075 IDirectInputDevice2AImpl_EnumObjects
,
1076 IDirectInputDevice2AImpl_GetProperty
,
1077 SysKeyboardAImpl_SetProperty
,
1078 SysKeyboardAImpl_Acquire
,
1079 SysKeyboardAImpl_Unacquire
,
1080 SysKeyboardAImpl_GetDeviceState
,
1081 SysKeyboardAImpl_GetDeviceData
,
1082 IDirectInputDevice2AImpl_SetDataFormat
,
1083 IDirectInputDevice2AImpl_SetEventNotification
,
1084 IDirectInputDevice2AImpl_SetCooperativeLevel
,
1085 IDirectInputDevice2AImpl_GetObjectInfo
,
1086 IDirectInputDevice2AImpl_GetDeviceInfo
,
1087 IDirectInputDevice2AImpl_RunControlPanel
,
1088 IDirectInputDevice2AImpl_Initialize
,
1089 IDirectInputDevice2AImpl_CreateEffect
,
1090 IDirectInputDevice2AImpl_EnumEffects
,
1091 IDirectInputDevice2AImpl_GetEffectInfo
,
1092 IDirectInputDevice2AImpl_GetForceFeedbackState
,
1093 IDirectInputDevice2AImpl_SendForceFeedbackCommand
,
1094 IDirectInputDevice2AImpl_EnumCreatedEffectObjects
,
1095 IDirectInputDevice2AImpl_Escape
,
1096 IDirectInputDevice2AImpl_Poll
,
1097 IDirectInputDevice2AImpl_SendDeviceData
,
1100 static ICOM_VTABLE(IDirectInputDevice2A
) SysMouseAvt
={
1101 IDirectInputDevice2AImpl_QueryInterface
,
1102 IDirectInputDevice2AImpl_AddRef
,
1103 SysMouseAImpl_Release
,
1104 IDirectInputDevice2AImpl_GetCapabilities
,
1105 IDirectInputDevice2AImpl_EnumObjects
,
1106 IDirectInputDevice2AImpl_GetProperty
,
1107 SysMouseAImpl_SetProperty
,
1108 SysMouseAImpl_Acquire
,
1109 SysMouseAImpl_Unacquire
,
1110 SysMouseAImpl_GetDeviceState
,
1111 SysMouseAImpl_GetDeviceData
,
1112 SysMouseAImpl_SetDataFormat
,
1113 IDirectInputDevice2AImpl_SetEventNotification
,
1114 SysMouseAImpl_SetCooperativeLevel
,
1115 IDirectInputDevice2AImpl_GetObjectInfo
,
1116 IDirectInputDevice2AImpl_GetDeviceInfo
,
1117 IDirectInputDevice2AImpl_RunControlPanel
,
1118 IDirectInputDevice2AImpl_Initialize
,
1119 IDirectInputDevice2AImpl_CreateEffect
,
1120 IDirectInputDevice2AImpl_EnumEffects
,
1121 IDirectInputDevice2AImpl_GetEffectInfo
,
1122 IDirectInputDevice2AImpl_GetForceFeedbackState
,
1123 IDirectInputDevice2AImpl_SendForceFeedbackCommand
,
1124 IDirectInputDevice2AImpl_EnumCreatedEffectObjects
,
1125 IDirectInputDevice2AImpl_Escape
,
1126 IDirectInputDevice2AImpl_Poll
,
1127 IDirectInputDevice2AImpl_SendDeviceData
,