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>
40 #include "sysmetrics.h"
43 extern BYTE InputKeyStateTable
[256];
44 extern int min_keycode
, max_keycode
;
45 extern WORD keyc2vkey
[256];
47 static IDirectInputA_VTable ddiavt
;
48 static IDirectInputDeviceA_VTable SysKeyboardAvt
;
49 static IDirectInputDeviceA_VTable SysMouseAvt
;
51 /* UIDs for Wine "drivers".
52 When enumerating each device supporting DInput, they have two UIDs :
55 static GUID DInput_Wine_Mouse_GUID
= { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */
59 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
61 static GUID DInput_Wine_Keyboard_GUID
= { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */
65 {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41}
68 /* This is ugly and not thread safe :/ */
69 static LPDIRECTINPUTDEVICE32A current_lock
= NULL
;
71 /******************************************************************************
72 * Various debugging tools
74 static void _dump_cooperativelevel(DWORD dwFlags
) {
80 #define FE(x) { x, #x},
84 FE(DISCL_NONEXCLUSIVE
)
86 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
87 if (flags
[i
].mask
& dwFlags
)
88 DUMP("%s ",flags
[i
].name
);
93 /******************************************************************************
94 * DirectInputCreate32A
96 HRESULT WINAPI
DirectInputCreate32A(HINSTANCE32 hinst
, DWORD dwVersion
, LPDIRECTINPUT32A
*ppDI
, LPUNKNOWN punkOuter
) {
97 TRACE(dinput
, "(0x%08lx,%04lx,%p,%p)\n",
98 (DWORD
)hinst
,dwVersion
,ppDI
,punkOuter
100 (*ppDI
) = (LPDIRECTINPUT32A
)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInput32A
));
102 (*ppDI
)->lpvtbl
= &ddiavt
;
105 /******************************************************************************
106 * IDirectInputA_EnumDevices
108 static HRESULT WINAPI
IDirectInputA_EnumDevices(
109 LPDIRECTINPUT32A
this, DWORD dwDevType
, LPDIENUMDEVICESCALLBACK32A lpCallback
,
110 LPVOID pvRef
, DWORD dwFlags
112 DIDEVICEINSTANCE32A devInstance
;
115 TRACE(dinput
, "(this=%p,0x%04lx,%p,%p,%04lx)\n", this, dwDevType
, lpCallback
, pvRef
, dwFlags
);
117 devInstance
.dwSize
= sizeof(DIDEVICEINSTANCE32A
);
119 if ((dwDevType
== 0) || (dwDevType
== DIDEVTYPE_KEYBOARD
)) {
120 /* Return keyboard */
121 devInstance
.guidInstance
= GUID_SysKeyboard
; /* DInput's GUID */
122 devInstance
.guidProduct
= DInput_Wine_Keyboard_GUID
; /* Vendor's GUID */
123 devInstance
.dwDevType
= DIDEVTYPE_KEYBOARD
| (DIDEVTYPEKEYBOARD_UNKNOWN
<< 8);
124 strcpy(devInstance
.tszInstanceName
, "Keyboard");
125 strcpy(devInstance
.tszProductName
, "Wine Keyboard");
127 ret
= lpCallback(&devInstance
, pvRef
);
128 TRACE(dinput
, "Keyboard registered\n");
130 if (ret
== DIENUM_STOP
)
134 if ((dwDevType
== 0) || (dwDevType
== DIDEVTYPE_KEYBOARD
)) {
136 devInstance
.guidInstance
= GUID_SysMouse
; /* DInput's GUID */
137 devInstance
.guidProduct
= DInput_Wine_Mouse_GUID
; /* Vendor's GUID */
138 devInstance
.dwDevType
= DIDEVTYPE_MOUSE
| (DIDEVTYPEMOUSE_UNKNOWN
<< 8);
139 strcpy(devInstance
.tszInstanceName
, "Mouse");
140 strcpy(devInstance
.tszProductName
, "Wine Mouse");
142 ret
= lpCallback(&devInstance
, pvRef
);
143 TRACE(dinput
, "Mouse registered\n");
146 /* Should also do joystick enumerations.... */
151 static ULONG WINAPI
IDirectInputA_AddRef(LPDIRECTINPUT32A
this) {
152 return ++(this->ref
);
155 static ULONG WINAPI
IDirectInputA_Release(LPDIRECTINPUT32A
this) {
156 if (!(--this->ref
)) {
157 HeapFree(GetProcessHeap(),0,this);
163 static HRESULT WINAPI
IDirectInputA_CreateDevice(
164 LPDIRECTINPUT32A
this,REFGUID rguid
,LPDIRECTINPUTDEVICE32A
* pdev
,
169 WINE_StringFromCLSID(rguid
,xbuf
);
170 FIXME(dinput
,"(this=%p,%s,%p,%p): stub\n",this,xbuf
,pdev
,punk
);
171 if ((!memcmp(&GUID_SysKeyboard
,rguid
,sizeof(GUID_SysKeyboard
))) || /* Generic Keyboard */
172 (!memcmp(&DInput_Wine_Keyboard_GUID
,rguid
,sizeof(GUID_SysKeyboard
)))) { /* Wine Keyboard */
173 *pdev
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(SysKeyboard32A
));
175 (*pdev
)->lpvtbl
= &SysKeyboardAvt
;
176 memcpy(&((*pdev
)->guid
),rguid
,sizeof(*rguid
));
177 memset(((LPSYSKEYBOARD32A
)(*pdev
))->keystate
,0,256);
180 if ((!memcmp(&GUID_SysMouse
,rguid
,sizeof(GUID_SysMouse
))) || /* Generic Mouse */
181 (!memcmp(&DInput_Wine_Mouse_GUID
,rguid
,sizeof(GUID_SysMouse
)))) { /* Wine Mouse */
182 *pdev
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(SysMouse32A
));
184 (*pdev
)->lpvtbl
= &SysMouseAvt
;
185 memcpy(&((*pdev
)->guid
),rguid
,sizeof(*rguid
));
191 static HRESULT WINAPI
IDirectInputA_QueryInterface(
192 LPDIRECTINPUT32A
this,REFIID riid
,LPVOID
*ppobj
196 WINE_StringFromCLSID(riid
,xbuf
);
197 TRACE(dinput
,"(this=%p,%s,%p)\n",this,xbuf
,ppobj
);
198 if (!memcmp(&IID_IUnknown
,riid
,sizeof(*riid
))) {
199 this->lpvtbl
->fnAddRef(this);
203 if (!memcmp(&IID_IDirectInputA
,riid
,sizeof(*riid
))) {
204 this->lpvtbl
->fnAddRef(this);
211 static HRESULT WINAPI
IDirectInputA_Initialize(
212 LPDIRECTINPUT32A
this,HINSTANCE32 hinst
,DWORD x
214 return DIERR_ALREADYINITIALIZED
;
217 static IDirectInputA_VTable ddiavt
= {
218 IDirectInputA_QueryInterface
,
219 IDirectInputA_AddRef
,
220 IDirectInputA_Release
,
221 IDirectInputA_CreateDevice
,
222 IDirectInputA_EnumDevices
,
225 IDirectInputA_Initialize
228 /******************************************************************************
229 * IDirectInputDeviceA
231 static HRESULT WINAPI
IDirectInputDeviceA_SetDataFormat(
232 LPDIRECTINPUTDEVICE32A
this,LPCDIDATAFORMAT df
236 TRACE(dinput,"(this=%p,%p)\n",this,df);
238 TRACE(dinput,"df.dwSize=%ld\n",df->dwSize);
239 TRACE(dinput,"(df.dwObjsize=%ld)\n",df->dwObjSize);
240 TRACE(dinput,"(df.dwFlags=0x%08lx)\n",df->dwFlags);
241 TRACE(dinput,"(df.dwDataSize=%ld)\n",df->dwDataSize);
242 TRACE(dinput,"(df.dwNumObjs=%ld)\n",df->dwNumObjs);
244 for (i=0;i<df->dwNumObjs;i++) {
247 if (df->rgodf[i].pguid)
248 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
250 strcpy(xbuf,"<no guid>");
251 TRACE(dinput,"df.rgodf[%d].guid %s\n",i,xbuf);
252 TRACE(dinput,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
253 TRACE(dinput,"dwType 0x%02lx,dwInstance %ld\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
254 TRACE(dinput,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
260 static HRESULT WINAPI
IDirectInputDeviceA_SetCooperativeLevel(
261 LPDIRECTINPUTDEVICE32A
this,HWND32 hwnd
,DWORD dwflags
263 FIXME(dinput
,"(this=%p,0x%08lx,0x%08lx): stub\n",this,(DWORD
)hwnd
,dwflags
);
264 if (TRACE_ON(dinput
))
265 _dump_cooperativelevel(dwflags
);
269 static HRESULT WINAPI
IDirectInputDeviceA_SetEventNotification(
270 LPDIRECTINPUTDEVICE32A
this,HANDLE32 hnd
272 FIXME(dinput
,"(this=%p,0x%08lx): stub\n",this,(DWORD
)hnd
);
276 static ULONG WINAPI
IDirectInputDeviceA_Release(LPDIRECTINPUTDEVICE32A
this) {
280 HeapFree(GetProcessHeap(),0,this);
284 static HRESULT WINAPI
SysKeyboardA_SetProperty(
285 LPDIRECTINPUTDEVICE32A
this,REFGUID rguid
,LPCDIPROPHEADER ph
290 WINE_StringFromCLSID(rguid
,xbuf
);
292 sprintf(xbuf
,"<special guid %ld>",(DWORD
)rguid
);
293 TRACE(dinput
,"(this=%p,%s,%p)\n",this,xbuf
,ph
);
294 TRACE(dinput
,"(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
295 ph
->dwSize
,ph
->dwHeaderSize
,ph
->dwObj
,ph
->dwHow
);
296 if (!HIWORD(rguid
)) {
297 switch ((DWORD
)rguid
) {
298 case DIPROP_BUFFERSIZE
: {
299 LPCDIPROPDWORD pd
= (LPCDIPROPDWORD
)ph
;
301 TRACE(dinput
,"(buffersize=%ld)\n",pd
->dwData
);
305 WARN(dinput
,"Unknown type %ld\n",(DWORD
)rguid
);
312 static HRESULT WINAPI
SysKeyboardA_GetDeviceState(
313 LPDIRECTINPUTDEVICE32A
this,DWORD len
,LPVOID ptr
319 for (keyc
=min_keycode
;keyc
<max_keycode
;keyc
++)
321 /* X keycode to virtual key */
322 vkey
= keyc2vkey
[keyc
] & 0xFF;
323 /* The windows scancode is keyc-min_keycode */
324 if (InputKeyStateTable
[vkey
]&0x80) {
325 ((LPBYTE
)ptr
)[keyc
-min_keycode
]=0x80;
326 ((LPBYTE
)ptr
)[(keyc
-min_keycode
)|0x80]=0x80;
331 WARN(dinput
,"whoops, SysKeyboardA_GetDeviceState got len %ld?\n",len
);
335 static HRESULT WINAPI
SysKeyboardA_GetDeviceData(
336 LPDIRECTINPUTDEVICE32A
this,DWORD dodsize
,LPDIDEVICEOBJECTDATA dod
,
337 LPDWORD entries
,DWORD flags
339 int keyc
,n
,vkey
,xentries
;
340 LPSYSKEYBOARD32A kthis
= (LPSYSKEYBOARD32A
)this;
342 TRACE(dinput
,"(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
343 this,dodsize
,dod
,entries
,entries
?*entries
:0,flags
);
344 EVENT_WaitNetEvent(FALSE
,TRUE
);
352 for (keyc
=min_keycode
;(keyc
<max_keycode
) && (n
<*entries
);keyc
++)
354 /* X keycode to virtual key */
355 vkey
= keyc2vkey
[keyc
] & 0xFF;
356 if (kthis
->keystate
[vkey
] == (InputKeyStateTable
[vkey
]&0x80))
360 dod
[n
].dwOfs
= keyc
-min_keycode
; /* scancode */
361 dod
[n
].dwData
= InputKeyStateTable
[vkey
]&0x80;
362 dod
[n
].dwTimeStamp
= 0; /* umm */
363 dod
[n
].dwSequence
= 0; /* umm */
366 if (!(flags
& DIGDD_PEEK
))
367 kthis
->keystate
[vkey
] = InputKeyStateTable
[vkey
]&0x80;
371 if (n
) fprintf(stderr
,"%d entries\n",n
);
376 static HRESULT WINAPI
SysKeyboardA_Acquire(LPDIRECTINPUTDEVICE32A
this) {
377 TRACE(dinput
,"(this=%p): stub\n",this);
381 static HRESULT WINAPI
SysKeyboardA_Unacquire(LPDIRECTINPUTDEVICE32A
this) {
382 TRACE(dinput
,"(this=%p): stub\n",this);
386 static HRESULT WINAPI
IDirectInputDeviceA_QueryInterface(
387 LPDIRECTINPUTDEVICE32A
this,REFIID riid
,LPVOID
*ppobj
391 WINE_StringFromCLSID(riid
,xbuf
);
392 TRACE(dinput
,"(this=%p,%s,%p)\n",this,xbuf
,ppobj
);
393 if (!memcmp(&IID_IUnknown
,riid
,sizeof(*riid
))) {
394 this->lpvtbl
->fnAddRef(this);
398 if (!memcmp(&IID_IDirectInputDeviceA
,riid
,sizeof(*riid
))) {
399 this->lpvtbl
->fnAddRef(this);
403 if (!memcmp(&IID_IDirectInputDevice2A
,riid
,sizeof(*riid
))) {
404 this->lpvtbl
->fnAddRef(this);
411 static ULONG WINAPI
IDirectInputDeviceA_AddRef(
412 LPDIRECTINPUTDEVICE32A
this)
417 static HRESULT WINAPI
IDirectInputDeviceA_GetCapabilities(
418 LPDIRECTINPUTDEVICE32A
this,
419 LPDIDEVCAPS lpDIDevCaps
)
421 FIXME(dinput
, "stub!\n");
425 static HRESULT WINAPI
IDirectInputDeviceA_EnumObjects(
426 LPDIRECTINPUTDEVICE32A
this,
427 LPDIENUMDEVICEOBJECTSCALLBACK32A lpCallback
,
431 FIXME(dinput
, "stub!\n");
434 lpCallback(NULL
, lpvRef
);
439 static HRESULT WINAPI
IDirectInputDeviceA_GetProperty(
440 LPDIRECTINPUTDEVICE32A
this,
442 LPDIPROPHEADER pdiph
)
444 FIXME(dinput
, "stub!\n");
448 static HRESULT WINAPI
IDirectInputDeviceA_GetObjectInfo(
449 LPDIRECTINPUTDEVICE32A
this,
450 LPDIDEVICEOBJECTINSTANCE32A pdidoi
,
454 FIXME(dinput
, "stub!\n");
458 static HRESULT WINAPI
IDirectInputDeviceA_GetDeviceInfo(
459 LPDIRECTINPUTDEVICE32A
this,
460 LPDIDEVICEINSTANCE32A pdidi
)
462 FIXME(dinput
, "stub!\n");
466 static HRESULT WINAPI
IDirectInputDeviceA_RunControlPanel(
467 LPDIRECTINPUTDEVICE32A
this,
471 FIXME(dinput
, "stub!\n");
475 static HRESULT WINAPI
IDirectInputDeviceA_Initialize(
476 LPDIRECTINPUTDEVICE32A
this,
481 FIXME(dinput
, "stub!\n");
485 /******************************************************************************
486 * IDirectInputDevice2A
489 static HRESULT WINAPI
IDirectInputDevice2A_CreateEffect(
490 LPDIRECTINPUTDEVICE32A
this,
493 LPDIRECTINPUTEFFECT
*ppdef
,
496 FIXME(dinput
, "stub!\n");
500 static HRESULT WINAPI
IDirectInputDevice2A_EnumEffects(
501 LPDIRECTINPUTDEVICE32A
this,
502 LPDIENUMEFFECTSCALLBACKA lpCallback
,
506 FIXME(dinput
, "stub!\n");
508 lpCallback(NULL
, lpvRef
);
512 static HRESULT WINAPI
IDirectInputDevice2A_GetEffectInfo(
513 LPDIRECTINPUTDEVICE32A
this,
514 LPDIEFFECTINFOA lpdei
,
517 FIXME(dinput
, "stub!\n");
521 static HRESULT WINAPI
IDirectInputDevice2A_GetForceFeedbackState(
522 LPDIRECTINPUTDEVICE32A
this,
525 FIXME(dinput
, "stub!\n");
529 static HRESULT WINAPI
IDirectInputDevice2A_SendForceFeedbackCommand(
530 LPDIRECTINPUTDEVICE32A
this,
533 FIXME(dinput
, "stub!\n");
537 static HRESULT WINAPI
IDirectInputDevice2A_EnumCreatedEffectObjects(
538 LPDIRECTINPUTDEVICE32A
this,
539 LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback
,
543 FIXME(dinput
, "stub!\n");
545 lpCallback(NULL
, lpvRef
);
549 static HRESULT WINAPI
IDirectInputDevice2A_Escape(
550 LPDIRECTINPUTDEVICE32A
this,
551 LPDIEFFESCAPE lpDIEEsc
)
553 FIXME(dinput
, "stub!\n");
557 static HRESULT WINAPI
IDirectInputDevice2A_Poll(
558 LPDIRECTINPUTDEVICE32A
this)
560 FIXME(dinput
, "stub!\n");
564 static HRESULT WINAPI
IDirectInputDevice2A_SendDeviceData(
565 LPDIRECTINPUTDEVICE32A
this,
567 LPDIDEVICEOBJECTDATA rgdod
,
571 FIXME(dinput
, "stub!\n");
575 /******************************************************************************
576 * SysMouseA (DInput Mouse support)
579 /******************************************************************************
580 * Release : release the mouse buffer.
582 static ULONG WINAPI
SysMouseA_Release(LPDIRECTINPUTDEVICE32A
this) {
583 LPSYSMOUSE32A mthis
= (LPSYSMOUSE32A
) this;
589 /* Free the data queue */
590 if (mthis
->data_queue
!= NULL
)
591 HeapFree(GetProcessHeap(),0,mthis
->data_queue
);
593 /* Install the previous event handler (in case of releasing an aquired
595 if (mthis
->prev_handler
!= NULL
)
596 MOUSE_Enable(mthis
->prev_handler
);
598 HeapFree(GetProcessHeap(),0,this);
603 /******************************************************************************
604 * SetCooperativeLevel : store the window in which we will do our
607 static HRESULT WINAPI
SysMouseA_SetCooperativeLevel(
608 LPDIRECTINPUTDEVICE32A
this,HWND32 hwnd
,DWORD dwflags
610 LPSYSMOUSE32A mthis
= (LPSYSMOUSE32A
) this;
612 TRACE(dinput
,"(this=%p,0x%08lx,0x%08lx): stub\n",this,(DWORD
)hwnd
,dwflags
);
614 if (TRACE_ON(dinput
))
615 _dump_cooperativelevel(dwflags
);
617 /* Store the window which asks for the mouse */
624 /******************************************************************************
625 * SetDataFormat : the application can choose the format of the data
626 * the device driver sends back with GetDeviceState.
628 * For the moment, only the "standard" configuration (c_dfDIMouse) is supported
629 * in absolute and relative mode.
631 static HRESULT WINAPI
SysMouseA_SetDataFormat(
632 LPDIRECTINPUTDEVICE32A
this,LPCDIDATAFORMAT df
635 LPSYSMOUSE32A mthis
= (LPSYSMOUSE32A
) this;
637 TRACE(dinput
,"(this=%p,%p)\n",this,df
);
639 TRACE(dinput
,"(df.dwSize=%ld)\n",df
->dwSize
);
640 TRACE(dinput
,"(df.dwObjsize=%ld)\n",df
->dwObjSize
);
641 TRACE(dinput
,"(df.dwFlags=0x%08lx)\n",df
->dwFlags
);
642 TRACE(dinput
,"(df.dwDataSize=%ld)\n",df
->dwDataSize
);
643 TRACE(dinput
,"(df.dwNumObjs=%ld)\n",df
->dwNumObjs
);
645 for (i
=0;i
<df
->dwNumObjs
;i
++) {
648 if (df
->rgodf
[i
].pguid
)
649 WINE_StringFromCLSID(df
->rgodf
[i
].pguid
,xbuf
);
651 strcpy(xbuf
,"<no guid>");
652 TRACE(dinput
,"df.rgodf[%d].guid %s (%p)\n",i
,xbuf
, df
->rgodf
[i
].pguid
);
653 TRACE(dinput
,"df.rgodf[%d].dwOfs %ld\n",i
,df
->rgodf
[i
].dwOfs
);
654 TRACE(dinput
,"dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df
->rgodf
[i
].dwType
),DIDFT_GETINSTANCE(df
->rgodf
[i
].dwType
));
655 TRACE(dinput
,"df.rgodf[%d].dwFlags 0x%08lx\n",i
,df
->rgodf
[i
].dwFlags
);
658 /* Check size of data format to prevent crashes if the applications
659 sends a smaller buffer */
660 if (df
->dwDataSize
!= sizeof(struct DIMOUSESTATE
)) {
661 FIXME(dinput
, "non-standard mouse configuration not supported yet.");
662 return DIERR_INVALIDPARAM
;
665 /* For the moment, ignore these fields and return always as if
666 c_dfDIMouse was passed as format... */
668 /* Check if the mouse is in absolute or relative mode */
669 if (df
->dwFlags
== DIDF_ABSAXIS
)
677 #define GEN_EVENT(offset,data,time,seq) \
679 if (mthis->queue_pos < mthis->queue_len) { \
680 mthis->data_queue[mthis->queue_pos].dwOfs = offset; \
681 mthis->data_queue[mthis->queue_pos].dwData = data; \
682 mthis->data_queue[mthis->queue_pos].dwTimeStamp = time; \
683 mthis->data_queue[mthis->queue_pos].dwSequence = seq; \
684 mthis->queue_pos++; \
688 /* Our private mouse event handler */
689 static void WINAPI
dinput_mouse_event( DWORD dwFlags
, DWORD dx
, DWORD dy
,
690 DWORD cButtons
, DWORD dwExtraInfo
)
692 DWORD posX
, posY
, keyState
, time
, extra
;
693 LPSYSMOUSE32A mthis
= (LPSYSMOUSE32A
) current_lock
;
695 if ( !IsBadReadPtr32( (LPVOID
)dwExtraInfo
, sizeof(WINE_MOUSEEVENT
) )
696 && ((WINE_MOUSEEVENT
*)dwExtraInfo
)->magic
== WINE_MOUSEEVENT_MAGIC
) {
697 WINE_MOUSEEVENT
*wme
= (WINE_MOUSEEVENT
*)dwExtraInfo
;
698 keyState
= wme
->keyState
;
700 extra
= (DWORD
)wme
->hWnd
;
702 assert( dwFlags
& MOUSEEVENTF_ABSOLUTE
);
703 posX
= (dx
* SYSMETRICS_CXSCREEN
) >> 16;
704 posY
= (dy
* SYSMETRICS_CYSCREEN
) >> 16;
706 ERR(dinput
, "Mouse event not supported...\n");
710 TRACE(dinput
, " %ld %ld ", posX
, posY
);
712 if ( dwFlags
& MOUSEEVENTF_MOVE
) {
713 if (mthis
->absolute
) {
714 if (posX
!= mthis
->prevX
)
715 GEN_EVENT(DIMOFS_X
, posX
, time
, 0);
716 if (posY
!= mthis
->prevY
)
717 GEN_EVENT(DIMOFS_Y
, posY
, time
, 0);
719 /* Relative mouse input : the real fun starts here... */
720 if (mthis
->need_warp
) {
721 if (posX
!= mthis
->prevX
)
722 GEN_EVENT(DIMOFS_X
, posX
- mthis
->prevX
, time
, 0);
723 if (posY
!= mthis
->prevY
)
724 GEN_EVENT(DIMOFS_Y
, posY
- mthis
->prevY
, time
, 0);
726 /* This is the first time the event handler has been called after a
727 GetData of GetState. */
728 if (posX
!= mthis
->win_centerX
) {
729 GEN_EVENT(DIMOFS_X
, posX
- mthis
->win_centerX
, time
, 0);
730 mthis
->need_warp
= 1;
733 if (posY
!= mthis
->win_centerY
) {
734 GEN_EVENT(DIMOFS_Y
, posY
- mthis
->win_centerY
, time
, 0);
735 mthis
->need_warp
= 1;
740 if ( dwFlags
& MOUSEEVENTF_LEFTDOWN
) {
741 if (TRACE_ON(dinput
))
744 GEN_EVENT(DIMOFS_BUTTON0
, 0xFF, time
, 0);
746 if ( dwFlags
& MOUSEEVENTF_LEFTUP
) {
747 if (TRACE_ON(dinput
))
750 GEN_EVENT(DIMOFS_BUTTON0
, 0x00, time
, 0);
752 if ( dwFlags
& MOUSEEVENTF_RIGHTDOWN
) {
753 if (TRACE_ON(dinput
))
756 GEN_EVENT(DIMOFS_BUTTON1
, 0xFF, time
, 0);
758 if ( dwFlags
& MOUSEEVENTF_RIGHTUP
) {
759 if (TRACE_ON(dinput
))
762 GEN_EVENT(DIMOFS_BUTTON1
, 0x00, time
, 0);
764 if ( dwFlags
& MOUSEEVENTF_MIDDLEDOWN
) {
765 if (TRACE_ON(dinput
))
768 GEN_EVENT(DIMOFS_BUTTON2
, 0xFF, time
, 0);
770 if ( dwFlags
& MOUSEEVENTF_MIDDLEUP
) {
771 if (TRACE_ON(dinput
))
774 GEN_EVENT(DIMOFS_BUTTON2
, 0x00, time
, 0);
776 if (TRACE_ON(dinput
))
784 /******************************************************************************
785 * Acquire : gets exclusive control of the mouse
787 static HRESULT WINAPI
SysMouseA_Acquire(LPDIRECTINPUTDEVICE32A
this) {
788 LPSYSMOUSE32A mthis
= (LPSYSMOUSE32A
) this;
791 TRACE(dinput
,"(this=%p)\n",this);
793 if (mthis
->acquired
== 0) {
794 /* This stores the current mouse handler.
795 FIXME : need to be fixed for native USER use */
796 mthis
->prev_handler
= mouse_event
;
798 /* Store (in a global variable) the current lock */
801 /* Install our own mouse event handler */
802 MOUSE_Enable(dinput_mouse_event
);
804 /* Get the window dimension and find the center */
805 GetWindowRect32(mthis
->win
, &rect
);
806 mthis
->xwin
= ((X11DRV_WND_DATA
*) WIN_FindWndPtr(mthis
->win
)->pDriverData
)->window
;
807 mthis
->win_centerX
= (rect
.right
- rect
.left
) / 2;
808 mthis
->win_centerY
= (rect
.bottom
- rect
.top
) / 2;
809 /* Warp the mouse to the center of the window */
810 TRACE(dinput
, "Warping mouse to %ld - %ld\n", mthis
->win_centerX
, mthis
->win_centerY
);
811 TSXWarpPointer(display
, DefaultRootWindow(display
),
812 mthis
->xwin
, 0, 0, 0, 0,
813 mthis
->win_centerX
, mthis
->win_centerY
);
820 /******************************************************************************
821 * Unacquire : frees the mouse
823 static HRESULT WINAPI
SysMouseA_Unacquire(LPDIRECTINPUTDEVICE32A
this) {
824 LPSYSMOUSE32A mthis
= (LPSYSMOUSE32A
) this;
826 TRACE(dinput
,"(this=%p)\n",this);
828 /* Reinstall previous mouse event handler */
829 MOUSE_Enable(mthis
->prev_handler
);
830 mthis
->prev_handler
= NULL
;
835 /* Unacquire device */
841 /******************************************************************************
842 * GetDeviceState : returns the "state" of the mouse.
844 * For the moment, only the "standard" return structure (DIMOUSESTATE) is
847 static HRESULT WINAPI
SysMouseA_GetDeviceState(
848 LPDIRECTINPUTDEVICE32A
this,DWORD len
,LPVOID ptr
851 struct DIMOUSESTATE
*mstate
= (struct DIMOUSESTATE
*) ptr
;
852 LPSYSMOUSE32A mthis
= (LPSYSMOUSE32A
) this;
854 TRACE(dinput
,"(this=%p,0x%08lx,%p): \n",this,len
,ptr
);
856 /* Check if the buffer is big enough */
857 if (len
< sizeof(struct DIMOUSESTATE
)) {
858 FIXME(dinput
, "unsupported state structure.");
859 return DIERR_INVALIDPARAM
;
862 /* Get the mouse position */
863 EVENT_QueryPointer(&rx
, &ry
, &state
);
864 TRACE(dinput
,"(X:%ld - Y:%ld)\n", rx
, ry
);
866 /* Fill the mouse state structure */
867 if (mthis
->absolute
) {
871 mstate
->lX
= rx
- mthis
->win_centerX
;
872 mstate
->lY
= ry
- mthis
->win_centerY
;
874 if ((mstate
->lX
!= 0) || (mstate
->lY
!= 0))
875 mthis
->need_warp
= 1;
878 mstate
->rgbButtons
[0] = (state
& MK_LBUTTON
? 0xFF : 0x00);
879 mstate
->rgbButtons
[1] = (state
& MK_RBUTTON
? 0xFF : 0x00);
880 mstate
->rgbButtons
[2] = (state
& MK_MBUTTON
? 0xFF : 0x00);
881 mstate
->rgbButtons
[3] = 0x00;
883 /* Check if we need to do a mouse warping */
884 if (mthis
->need_warp
) {
885 TRACE(dinput
, "Warping mouse to %ld - %ld\n", mthis
->win_centerX
, mthis
->win_centerY
);
886 TSXWarpPointer(display
, DefaultRootWindow(display
),
887 mthis
->xwin
, 0, 0, 0, 0,
888 mthis
->win_centerX
, mthis
->win_centerY
);
889 mthis
->need_warp
= 0;
892 TRACE(dinput
, "(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n",
893 mstate
->lX
, mstate
->lY
,
894 mstate
->rgbButtons
[0], mstate
->rgbButtons
[2], mstate
->rgbButtons
[1]);
899 /******************************************************************************
900 * GetDeviceState : gets buffered input data.
902 static HRESULT WINAPI
SysMouseA_GetDeviceData(LPDIRECTINPUTDEVICE32A
this,
904 LPDIDEVICEOBJECTDATA dod
,
908 LPSYSMOUSE32A mthis
= (LPSYSMOUSE32A
) this;
910 TRACE(dinput
,"(%p)->(%ld,%p,%p(0x%08lx),0x%08lx)\n",
911 this,dodsize
,dod
,entries
,*entries
,flags
);
913 if (flags
& DIGDD_PEEK
)
914 TRACE(dinput
, "DIGDD_PEEK\n");
917 *entries
= mthis
->queue_pos
;
918 mthis
->queue_pos
= 0;
920 /* Check for buffer overflow */
921 if (mthis
->queue_pos
> *entries
) {
922 WARN(dinput
, "Buffer overflow not handled properly yet...\n");
923 mthis
->queue_pos
= *entries
;
925 if (dodsize
!= sizeof(DIDEVICEOBJECTDATA
)) {
926 ERR(dinput
, "Wrong structure size !\n");
927 return DIERR_INVALIDPARAM
;
930 /* Copy the buffered data into the application queue */
931 memcpy(dod
, mthis
->data_queue
, mthis
->queue_pos
* dodsize
);
933 /* Reset the event queue */
934 mthis
->queue_pos
= 0;
937 /* Check if we need to do a mouse warping */
938 if (mthis
->need_warp
) {
939 TRACE(dinput
, "Warping mouse to %ld - %ld\n", mthis
->win_centerX
, mthis
->win_centerY
);
940 TSXWarpPointer(display
, DefaultRootWindow(display
),
941 mthis
->xwin
, 0, 0, 0, 0,
942 mthis
->win_centerX
, mthis
->win_centerY
);
943 mthis
->need_warp
= 0;
949 /******************************************************************************
950 * SetProperty : change input device properties
952 static HRESULT WINAPI
SysMouseA_SetProperty(LPDIRECTINPUTDEVICE32A
this,
954 LPCDIPROPHEADER ph
) {
956 LPSYSMOUSE32A mthis
= (LPSYSMOUSE32A
) this;
959 WINE_StringFromCLSID(rguid
,xbuf
);
961 sprintf(xbuf
,"<special guid %ld>",(DWORD
)rguid
);
963 TRACE(dinput
,"(this=%p,%s,%p)\n",this,xbuf
,ph
);
965 if (!HIWORD(rguid
)) {
966 switch ((DWORD
)rguid
) {
967 case DIPROP_BUFFERSIZE
: {
968 LPCDIPROPDWORD pd
= (LPCDIPROPDWORD
)ph
;
970 TRACE(dinput
,"buffersize = %ld\n",pd
->dwData
);
972 mthis
->data_queue
= (LPDIDEVICEOBJECTDATA
)HeapAlloc(GetProcessHeap(),0,
973 pd
->dwData
* sizeof(DIDEVICEOBJECTDATA
));
974 mthis
->queue_pos
= 0;
975 mthis
->queue_len
= pd
->dwData
;
979 WARN(dinput
,"Unknown type %ld\n",(DWORD
)rguid
);
988 static IDirectInputDeviceA_VTable SysKeyboardAvt
={
989 IDirectInputDeviceA_QueryInterface
,
990 IDirectInputDeviceA_AddRef
,
991 IDirectInputDeviceA_Release
,
992 IDirectInputDeviceA_GetCapabilities
,
993 IDirectInputDeviceA_EnumObjects
,
994 IDirectInputDeviceA_GetProperty
,
995 SysKeyboardA_SetProperty
,
996 SysKeyboardA_Acquire
,
997 SysKeyboardA_Unacquire
,
998 SysKeyboardA_GetDeviceState
,
999 SysKeyboardA_GetDeviceData
,
1000 IDirectInputDeviceA_SetDataFormat
,
1001 IDirectInputDeviceA_SetEventNotification
,
1002 IDirectInputDeviceA_SetCooperativeLevel
,
1003 IDirectInputDeviceA_GetObjectInfo
,
1004 IDirectInputDeviceA_GetDeviceInfo
,
1005 IDirectInputDeviceA_RunControlPanel
,
1006 IDirectInputDeviceA_Initialize
,
1007 IDirectInputDevice2A_CreateEffect
,
1008 IDirectInputDevice2A_EnumEffects
,
1009 IDirectInputDevice2A_GetEffectInfo
,
1010 IDirectInputDevice2A_GetForceFeedbackState
,
1011 IDirectInputDevice2A_SendForceFeedbackCommand
,
1012 IDirectInputDevice2A_EnumCreatedEffectObjects
,
1013 IDirectInputDevice2A_Escape
,
1014 IDirectInputDevice2A_Poll
,
1015 IDirectInputDevice2A_SendDeviceData
,
1018 static IDirectInputDeviceA_VTable SysMouseAvt
={
1019 IDirectInputDeviceA_QueryInterface
,
1020 IDirectInputDeviceA_AddRef
,
1022 IDirectInputDeviceA_GetCapabilities
,
1023 IDirectInputDeviceA_EnumObjects
,
1024 IDirectInputDeviceA_GetProperty
,
1025 SysMouseA_SetProperty
,
1027 SysMouseA_Unacquire
,
1028 SysMouseA_GetDeviceState
,
1029 SysMouseA_GetDeviceData
,
1030 SysMouseA_SetDataFormat
,
1031 IDirectInputDeviceA_SetEventNotification
,
1032 SysMouseA_SetCooperativeLevel
,
1033 IDirectInputDeviceA_GetObjectInfo
,
1034 IDirectInputDeviceA_GetDeviceInfo
,
1035 IDirectInputDeviceA_RunControlPanel
,
1036 IDirectInputDeviceA_Initialize
,
1037 IDirectInputDevice2A_CreateEffect
,
1038 IDirectInputDevice2A_EnumEffects
,
1039 IDirectInputDevice2A_GetEffectInfo
,
1040 IDirectInputDevice2A_GetForceFeedbackState
,
1041 IDirectInputDevice2A_SendForceFeedbackCommand
,
1042 IDirectInputDevice2A_EnumCreatedEffectObjects
,
1043 IDirectInputDevice2A_Escape
,
1044 IDirectInputDevice2A_Poll
,
1045 IDirectInputDevice2A_SendDeviceData
,