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 #ifdef HAVE_SYS_SIGNAL_H
26 #include <sys/signal.h>
29 #include "wine/obj_base.h"
30 #include "debugtools.h"
36 #include "sysmetrics.h"
40 DEFAULT_DEBUG_CHANNEL(dinput)
42 extern BYTE InputKeyStateTable[256];
43 extern int min_keycode, max_keycode;
44 extern WORD keyc2vkey[256];
46 static ICOM_VTABLE(IDirectInputA) ddiavt;
47 static ICOM_VTABLE(IDirectInputDevice2A) SysKeyboardAvt;
48 static ICOM_VTABLE(IDirectInputDevice2A) SysMouseAvt;
50 typedef struct IDirectInputAImpl IDirectInputAImpl;
51 typedef struct IDirectInputDevice2AImpl IDirectInputDevice2AImpl;
52 typedef struct SysKeyboardAImpl SysKeyboardAImpl;
53 typedef struct SysMouseAImpl SysMouseAImpl;
55 struct IDirectInputDevice2AImpl
57 ICOM_VTABLE(IDirectInputDevice2A)* lpvtbl;
62 struct SysKeyboardAImpl
64 /* IDirectInputDevice2AImpl */
65 ICOM_VTABLE(IDirectInputDevice2A)* lpvtbl;
68 /* SysKeyboardAImpl */
74 /* IDirectInputDevice2AImpl */
75 ICOM_VTABLE(IDirectInputDevice2A)* lpvtbl;
80 /* Previous position for relative moves */
82 LPMOUSE_EVENT_PROC prev_handler;
84 DWORD win_centerX, win_centerY;
85 LPDIDEVICEOBJECTDATA data_queue;
86 int queue_pos, queue_len;
92 /* UIDs for Wine "drivers".
93 When enumerating each device supporting DInput, they have two UIDs :
96 static GUID DInput_Wine_Mouse_GUID = { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */
100 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
102 static GUID DInput_Wine_Keyboard_GUID = { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */
106 {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41}
109 /* FIXME: This is ugly and not thread safe :/ */
110 static IDirectInputDevice2A* current_lock = NULL;
112 /******************************************************************************
113 * Various debugging tools
115 static void _dump_cooperativelevel(DWORD dwFlags) {
121 #define FE(x) { x, #x},
125 FE(DISCL_NONEXCLUSIVE)
127 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
128 if (flags[i].mask & dwFlags)
129 DPRINTF("%s ",flags[i].name);
133 struct IDirectInputAImpl
135 ICOM_VTABLE(IDirectInputA)* lpvtbl;
139 /******************************************************************************
140 * DirectInputCreate32A
142 HRESULT WINAPI DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA *ppDI, LPUNKNOWN punkOuter)
144 IDirectInputAImpl* This;
145 TRACE("(0x%08lx,%04lx,%p,%p)\n",
146 (DWORD)hinst,dwVersion,ppDI,punkOuter
148 This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl));
150 This->lpvtbl = &ddiavt;
151 *ppDI=(IDirectInputA*)This;
154 /******************************************************************************
155 * IDirectInputA_EnumDevices
157 static HRESULT WINAPI IDirectInputAImpl_EnumDevices(
158 LPDIRECTINPUTA iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback,
159 LPVOID pvRef, DWORD dwFlags
162 ICOM_THIS(IDirectInputAImpl,iface);
163 DIDEVICEINSTANCEA devInstance;
166 TRACE("(this=%p,0x%04lx,%p,%p,%04lx)\n", This, dwDevType, lpCallback, pvRef, dwFlags);
168 devInstance.dwSize = sizeof(DIDEVICEINSTANCEA);
170 if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_KEYBOARD)) {
171 /* Return keyboard */
172 devInstance.guidInstance = GUID_SysKeyboard; /* DInput's GUID */
173 devInstance.guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */
174 devInstance.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8);
175 strcpy(devInstance.tszInstanceName, "Keyboard");
176 strcpy(devInstance.tszProductName, "Wine Keyboard");
178 ret = lpCallback(&devInstance, pvRef);
179 TRACE("Keyboard registered\n");
181 if (ret == DIENUM_STOP)
185 if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_KEYBOARD)) {
187 devInstance.guidInstance = GUID_SysMouse; /* DInput's GUID */
188 devInstance.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */
189 devInstance.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_UNKNOWN << 8);
190 strcpy(devInstance.tszInstanceName, "Mouse");
191 strcpy(devInstance.tszProductName, "Wine Mouse");
193 ret = lpCallback(&devInstance, pvRef);
194 TRACE("Mouse registered\n");
197 /* Should also do joystick enumerations.... */
202 static ULONG WINAPI IDirectInputAImpl_AddRef(LPDIRECTINPUTA iface)
204 ICOM_THIS(IDirectInputAImpl,iface);
205 return ++(This->ref);
208 static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUTA iface)
210 ICOM_THIS(IDirectInputAImpl,iface);
211 if (!(--This->ref)) {
212 HeapFree(GetProcessHeap(),0,This);
218 static HRESULT WINAPI IDirectInputAImpl_CreateDevice(
219 LPDIRECTINPUTA iface,REFGUID rguid,LPDIRECTINPUTDEVICEA* pdev,
222 ICOM_THIS(IDirectInputAImpl,iface);
225 WINE_StringFromCLSID(rguid,xbuf);
226 FIXME("(this=%p,%s,%p,%p): stub\n",This,xbuf,pdev,punk);
227 if ((!memcmp(&GUID_SysKeyboard,rguid,sizeof(GUID_SysKeyboard))) || /* Generic Keyboard */
228 (!memcmp(&DInput_Wine_Keyboard_GUID,rguid,sizeof(GUID_SysKeyboard)))) { /* Wine Keyboard */
229 SysKeyboardAImpl* newDevice;
230 newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysKeyboardAImpl));
232 newDevice->lpvtbl = &SysKeyboardAvt;
233 memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
234 memset(newDevice->keystate,0,256);
235 *pdev=(IDirectInputDeviceA*)newDevice;
238 if ((!memcmp(&GUID_SysMouse,rguid,sizeof(GUID_SysMouse))) || /* Generic Mouse */
239 (!memcmp(&DInput_Wine_Mouse_GUID,rguid,sizeof(GUID_SysMouse)))) { /* Wine Mouse */
240 SysKeyboardAImpl* newDevice;
241 newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysMouseAImpl));
243 newDevice->lpvtbl = &SysMouseAvt;
244 memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
245 *pdev=(IDirectInputDeviceA*)newDevice;
251 static HRESULT WINAPI IDirectInputAImpl_QueryInterface(
252 LPDIRECTINPUTA iface,REFIID riid,LPVOID *ppobj
254 ICOM_THIS(IDirectInputAImpl,iface);
257 WINE_StringFromCLSID(riid,xbuf);
258 TRACE("(this=%p,%s,%p)\n",This,xbuf,ppobj);
259 if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
260 IDirectInputA_AddRef(iface);
264 if (!memcmp(&IID_IDirectInputA,riid,sizeof(*riid))) {
265 IDirectInputA_AddRef(iface);
272 static HRESULT WINAPI IDirectInputAImpl_Initialize(
273 LPDIRECTINPUTA iface,HINSTANCE hinst,DWORD x
275 return DIERR_ALREADYINITIALIZED;
278 static HRESULT WINAPI IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUTA iface,
280 ICOM_THIS(IDirectInputAImpl,iface);
283 WINE_StringFromCLSID(rguid,xbuf);
284 FIXME("(%p)->(%s): stub\n",This,xbuf);
289 static HRESULT WINAPI IDirectInputAImpl_RunControlPanel(LPDIRECTINPUTA iface,
292 ICOM_THIS(IDirectInputAImpl,iface);
293 FIXME("(%p)->(%08lx,%08lx): stub\n",This, (DWORD) hwndOwner, dwFlags);
298 static ICOM_VTABLE(IDirectInputA) ddiavt =
300 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
301 IDirectInputAImpl_QueryInterface,
302 IDirectInputAImpl_AddRef,
303 IDirectInputAImpl_Release,
304 IDirectInputAImpl_CreateDevice,
305 IDirectInputAImpl_EnumDevices,
306 IDirectInputAImpl_GetDeviceStatus,
307 IDirectInputAImpl_RunControlPanel,
308 IDirectInputAImpl_Initialize
311 /******************************************************************************
312 * IDirectInputDeviceA
315 static HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat(
316 LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df
320 TRACE(dinput,"(this=%p,%p)\n",This,df);
322 TRACE(dinput,"df.dwSize=%ld\n",df->dwSize);
323 TRACE(dinput,"(df.dwObjsize=%ld)\n",df->dwObjSize);
324 TRACE(dinput,"(df.dwFlags=0x%08lx)\n",df->dwFlags);
325 TRACE(dinput,"(df.dwDataSize=%ld)\n",df->dwDataSize);
326 TRACE(dinput,"(df.dwNumObjs=%ld)\n",df->dwNumObjs);
328 for (i=0;i<df->dwNumObjs;i++) {
331 if (df->rgodf[i].pguid)
332 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
334 strcpy(xbuf,"<no guid>");
335 TRACE(dinput,"df.rgodf[%d].guid %s\n",i,xbuf);
336 TRACE(dinput,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
337 TRACE(dinput,"dwType 0x%02lx,dwInstance %ld\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
338 TRACE(dinput,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
344 static HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel(
345 LPDIRECTINPUTDEVICE2A iface,HWND hwnd,DWORD dwflags
347 ICOM_THIS(IDirectInputDevice2AImpl,iface);
348 FIXME("(this=%p,0x%08lx,0x%08lx): stub\n",This,(DWORD)hwnd,dwflags);
349 if (TRACE_ON(dinput))
350 _dump_cooperativelevel(dwflags);
354 static HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification(
355 LPDIRECTINPUTDEVICE2A iface,HANDLE hnd
357 ICOM_THIS(IDirectInputDevice2AImpl,iface);
358 FIXME("(this=%p,0x%08lx): stub\n",This,(DWORD)hnd);
362 static ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE2A iface)
364 ICOM_THIS(IDirectInputDevice2AImpl,iface);
368 HeapFree(GetProcessHeap(),0,This);
372 static HRESULT WINAPI SysKeyboardAImpl_SetProperty(
373 LPDIRECTINPUTDEVICE2A iface,REFGUID rguid,LPCDIPROPHEADER ph
376 ICOM_THIS(SysKeyboardAImpl,iface);
380 WINE_StringFromCLSID(rguid,xbuf);
382 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
383 TRACE("(this=%p,%s,%p)\n",This,xbuf,ph);
384 TRACE("(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
385 ph->dwSize,ph->dwHeaderSize,ph->dwObj,ph->dwHow);
386 if (!HIWORD(rguid)) {
387 switch ((DWORD)rguid) {
388 case (DWORD) DIPROP_BUFFERSIZE: {
389 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
391 TRACE("(buffersize=%ld)\n",pd->dwData);
395 WARN("Unknown type %ld\n",(DWORD)rguid);
402 static HRESULT WINAPI SysKeyboardAImpl_GetDeviceState(
403 LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr
406 return KEYBOARD_Driver->pGetDIState(len, ptr)?DI_OK:E_FAIL;
409 static HRESULT WINAPI SysKeyboardAImpl_GetDeviceData(
410 LPDIRECTINPUTDEVICE2A iface,DWORD dodsize,LPDIDEVICEOBJECTDATA dod,
411 LPDWORD entries,DWORD flags
414 ICOM_THIS(SysKeyboardAImpl,iface);
416 TRACE("(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
417 This,dodsize,dod,entries,entries?*entries:0,flags);
419 return KEYBOARD_Driver->pGetDIData(
420 This->keystate, dodsize, dod, entries, flags)?DI_OK:E_FAIL;
423 static HRESULT WINAPI SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface)
425 ICOM_THIS(SysKeyboardAImpl,iface);
426 TRACE("(this=%p): stub\n",This);
430 static HRESULT WINAPI SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface)
432 ICOM_THIS(SysKeyboardAImpl,iface);
433 TRACE("(this=%p): stub\n",This);
437 static HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface(
438 LPDIRECTINPUTDEVICE2A iface,REFIID riid,LPVOID *ppobj
441 ICOM_THIS(IDirectInputDevice2AImpl,iface);
444 WINE_StringFromCLSID(riid,xbuf);
445 TRACE("(this=%p,%s,%p)\n",This,xbuf,ppobj);
446 if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
447 IDirectInputDevice2_AddRef(iface);
451 if (!memcmp(&IID_IDirectInputDeviceA,riid,sizeof(*riid))) {
452 IDirectInputDevice2_AddRef(iface);
456 if (!memcmp(&IID_IDirectInputDevice2A,riid,sizeof(*riid))) {
457 IDirectInputDevice2_AddRef(iface);
464 static ULONG WINAPI IDirectInputDevice2AImpl_AddRef(
465 LPDIRECTINPUTDEVICE2A iface)
467 ICOM_THIS(IDirectInputDevice2AImpl,iface);
471 static HRESULT WINAPI IDirectInputDevice2AImpl_GetCapabilities(
472 LPDIRECTINPUTDEVICE2A iface,
473 LPDIDEVCAPS lpDIDevCaps)
475 lpDIDevCaps->dwFlags = DIDC_ATTACHED;
480 static HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects(
481 LPDIRECTINPUTDEVICE2A iface,
482 LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
489 lpCallback(NULL, lpvRef);
494 static HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty(
495 LPDIRECTINPUTDEVICE2A iface,
497 LPDIPROPHEADER pdiph)
503 static HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo(
504 LPDIRECTINPUTDEVICE2A iface,
505 LPDIDEVICEOBJECTINSTANCEA pdidoi,
513 static HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo(
514 LPDIRECTINPUTDEVICE2A iface,
515 LPDIDEVICEINSTANCEA pdidi)
521 static HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel(
522 LPDIRECTINPUTDEVICE2A iface,
530 static HRESULT WINAPI IDirectInputDevice2AImpl_Initialize(
531 LPDIRECTINPUTDEVICE2A iface,
540 /******************************************************************************
541 * IDirectInputDevice2A
544 static HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect(
545 LPDIRECTINPUTDEVICE2A iface,
548 LPDIRECTINPUTEFFECT *ppdef,
555 static HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects(
556 LPDIRECTINPUTDEVICE2A iface,
557 LPDIENUMEFFECTSCALLBACKA lpCallback,
563 lpCallback(NULL, lpvRef);
567 static HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo(
568 LPDIRECTINPUTDEVICE2A iface,
569 LPDIEFFECTINFOA lpdei,
576 static HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState(
577 LPDIRECTINPUTDEVICE2A iface,
584 static HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand(
585 LPDIRECTINPUTDEVICE2A iface,
592 static HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects(
593 LPDIRECTINPUTDEVICE2A iface,
594 LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback,
600 lpCallback(NULL, lpvRef);
604 static HRESULT WINAPI IDirectInputDevice2AImpl_Escape(
605 LPDIRECTINPUTDEVICE2A iface,
606 LPDIEFFESCAPE lpDIEEsc)
612 static HRESULT WINAPI IDirectInputDevice2AImpl_Poll(
613 LPDIRECTINPUTDEVICE2A iface)
619 static HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData(
620 LPDIRECTINPUTDEVICE2A iface,
622 LPDIDEVICEOBJECTDATA rgdod,
630 /******************************************************************************
631 * SysMouseA (DInput Mouse support)
634 /******************************************************************************
635 * Release : release the mouse buffer.
637 static ULONG WINAPI SysMouseAImpl_Release(LPDIRECTINPUTDEVICE2A iface)
639 ICOM_THIS(SysMouseAImpl,iface);
645 /* Free the data queue */
646 if (This->data_queue != NULL)
647 HeapFree(GetProcessHeap(),0,This->data_queue);
649 /* Install the previous event handler (in case of releasing an aquired
651 if (This->prev_handler != NULL)
652 MOUSE_Enable(This->prev_handler);
654 HeapFree(GetProcessHeap(),0,This);
659 /******************************************************************************
660 * SetCooperativeLevel : store the window in which we will do our
663 static HRESULT WINAPI SysMouseAImpl_SetCooperativeLevel(
664 LPDIRECTINPUTDEVICE2A iface,HWND hwnd,DWORD dwflags
667 ICOM_THIS(SysMouseAImpl,iface);
669 TRACE("(this=%p,0x%08lx,0x%08lx): stub\n",This,(DWORD)hwnd,dwflags);
671 if (TRACE_ON(dinput))
672 _dump_cooperativelevel(dwflags);
674 /* Store the window which asks for the mouse */
681 /******************************************************************************
682 * SetDataFormat : the application can choose the format of the data
683 * the device driver sends back with GetDeviceState.
685 * For the moment, only the "standard" configuration (c_dfDIMouse) is supported
686 * in absolute and relative mode.
688 static HRESULT WINAPI SysMouseAImpl_SetDataFormat(
689 LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df
692 ICOM_THIS(SysMouseAImpl,iface);
695 TRACE("(this=%p,%p)\n",This,df);
697 TRACE("(df.dwSize=%ld)\n",df->dwSize);
698 TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize);
699 TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags);
700 TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize);
701 TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs);
703 for (i=0;i<df->dwNumObjs;i++) {
706 if (df->rgodf[i].pguid)
707 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
709 strcpy(xbuf,"<no guid>");
710 TRACE("df.rgodf[%d].guid %s (%p)\n",i,xbuf, df->rgodf[i].pguid);
711 TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
712 TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
713 TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
716 /* Check size of data format to prevent crashes if the applications
717 sends a smaller buffer */
718 if (df->dwDataSize != sizeof(struct DIMOUSESTATE)) {
719 FIXME("non-standard mouse configuration not supported yet.");
720 return DIERR_INVALIDPARAM;
723 /* For the moment, ignore these fields and return always as if
724 c_dfDIMouse was passed as format... */
726 /* Check if the mouse is in absolute or relative mode */
727 if (df->dwFlags == DIDF_ABSAXIS)
735 #define GEN_EVENT(offset,data,time,seq) \
737 if (This->queue_pos < This->queue_len) { \
738 This->data_queue[This->queue_pos].dwOfs = offset; \
739 This->data_queue[This->queue_pos].dwData = data; \
740 This->data_queue[This->queue_pos].dwTimeStamp = time; \
741 This->data_queue[This->queue_pos].dwSequence = seq; \
746 /* Our private mouse event handler */
747 static void WINAPI dinput_mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
748 DWORD cButtons, DWORD dwExtraInfo )
750 DWORD posX, posY, keyState, time, extra;
751 SysMouseAImpl* This = (SysMouseAImpl*) current_lock;
753 if ( !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_MOUSEEVENT) )
754 && ((WINE_MOUSEEVENT *)dwExtraInfo)->magic == WINE_MOUSEEVENT_MAGIC ) {
755 WINE_MOUSEEVENT *wme = (WINE_MOUSEEVENT *)dwExtraInfo;
756 keyState = wme->keyState;
758 extra = (DWORD)wme->hWnd;
760 assert( dwFlags & MOUSEEVENTF_ABSOLUTE );
761 posX = (dx * GetSystemMetrics(SM_CXSCREEN)) >> 16;
762 posY = (dy * GetSystemMetrics(SM_CYSCREEN)) >> 16;
764 ERR("Mouse event not supported...\n");
768 TRACE(" %ld %ld ", posX, posY);
770 if ( dwFlags & MOUSEEVENTF_MOVE ) {
771 if (This->absolute) {
772 if (posX != This->prevX)
773 GEN_EVENT(DIMOFS_X, posX, time, 0);
774 if (posY != This->prevY)
775 GEN_EVENT(DIMOFS_Y, posY, time, 0);
777 /* Relative mouse input : the real fun starts here... */
778 if (This->need_warp) {
779 if (posX != This->prevX)
780 GEN_EVENT(DIMOFS_X, posX - This->prevX, time, 0);
781 if (posY != This->prevY)
782 GEN_EVENT(DIMOFS_Y, posY - This->prevY, time, 0);
784 /* This is the first time the event handler has been called after a
785 GetData of GetState. */
786 if (posX != This->win_centerX) {
787 GEN_EVENT(DIMOFS_X, posX - This->win_centerX, time, 0);
791 if (posY != This->win_centerY) {
792 GEN_EVENT(DIMOFS_Y, posY - This->win_centerY, time, 0);
798 if ( dwFlags & MOUSEEVENTF_LEFTDOWN ) {
799 if (TRACE_ON(dinput))
802 GEN_EVENT(DIMOFS_BUTTON0, 0xFF, time, 0);
804 if ( dwFlags & MOUSEEVENTF_LEFTUP ) {
805 if (TRACE_ON(dinput))
808 GEN_EVENT(DIMOFS_BUTTON0, 0x00, time, 0);
810 if ( dwFlags & MOUSEEVENTF_RIGHTDOWN ) {
811 if (TRACE_ON(dinput))
814 GEN_EVENT(DIMOFS_BUTTON1, 0xFF, time, 0);
816 if ( dwFlags & MOUSEEVENTF_RIGHTUP ) {
817 if (TRACE_ON(dinput))
820 GEN_EVENT(DIMOFS_BUTTON1, 0x00, time, 0);
822 if ( dwFlags & MOUSEEVENTF_MIDDLEDOWN ) {
823 if (TRACE_ON(dinput))
826 GEN_EVENT(DIMOFS_BUTTON2, 0xFF, time, 0);
828 if ( dwFlags & MOUSEEVENTF_MIDDLEUP ) {
829 if (TRACE_ON(dinput))
832 GEN_EVENT(DIMOFS_BUTTON2, 0x00, time, 0);
834 if (TRACE_ON(dinput))
842 /******************************************************************************
843 * Acquire : gets exclusive control of the mouse
845 static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface)
847 ICOM_THIS(SysMouseAImpl,iface);
850 TRACE("(this=%p)\n",This);
852 if (This->acquired == 0) {
855 /* This stores the current mouse handler. */
856 This->prev_handler = mouse_event;
858 /* Store (in a global variable) the current lock */
859 current_lock = (IDirectInputDevice2A*)This;
861 /* Install our own mouse event handler */
862 MOUSE_Enable(dinput_mouse_event);
864 /* Get the window dimension and find the center */
865 GetWindowRect(This->win, &rect);
866 This->win_centerX = (rect.right - rect.left) / 2;
867 This->win_centerY = (rect.bottom - rect.top ) / 2;
869 /* Warp the mouse to the center of the window */
870 TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
871 point.x = This->win_centerX;
872 point.y = This->win_centerY;
873 MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
874 DISPLAY_MoveCursor(point.x, point.y);
881 /******************************************************************************
882 * Unacquire : frees the mouse
884 static HRESULT WINAPI SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface)
886 ICOM_THIS(SysMouseAImpl,iface);
888 TRACE("(this=%p)\n",This);
890 /* Reinstall previous mouse event handler */
891 MOUSE_Enable(This->prev_handler);
892 This->prev_handler = NULL;
897 /* Unacquire device */
903 /******************************************************************************
904 * GetDeviceState : returns the "state" of the mouse.
906 * For the moment, only the "standard" return structure (DIMOUSESTATE) is
909 static HRESULT WINAPI SysMouseAImpl_GetDeviceState(
910 LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr
912 ICOM_THIS(SysMouseAImpl,iface);
914 struct DIMOUSESTATE *mstate = (struct DIMOUSESTATE *) ptr;
916 TRACE("(this=%p,0x%08lx,%p): \n",This,len,ptr);
918 /* Check if the buffer is big enough */
919 if (len < sizeof(struct DIMOUSESTATE)) {
920 FIXME("unsupported state structure.");
921 return DIERR_INVALIDPARAM;
924 /* Get the mouse position */
925 EVENT_QueryPointer(&rx, &ry, &state);
926 TRACE("(X:%ld - Y:%ld)\n", rx, ry);
928 /* Fill the mouse state structure */
929 if (This->absolute) {
933 mstate->lX = rx - This->win_centerX;
934 mstate->lY = ry - This->win_centerY;
936 if ((mstate->lX != 0) || (mstate->lY != 0))
940 mstate->rgbButtons[0] = (state & MK_LBUTTON ? 0xFF : 0x00);
941 mstate->rgbButtons[1] = (state & MK_RBUTTON ? 0xFF : 0x00);
942 mstate->rgbButtons[2] = (state & MK_MBUTTON ? 0xFF : 0x00);
943 mstate->rgbButtons[3] = 0x00;
945 /* Check if we need to do a mouse warping */
946 if (This->need_warp) {
949 TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
950 point.x = This->win_centerX;
951 point.y = This->win_centerY;
952 MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
953 DISPLAY_MoveCursor(point.x, point.y);
958 TRACE("(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n",
959 mstate->lX, mstate->lY,
960 mstate->rgbButtons[0], mstate->rgbButtons[2], mstate->rgbButtons[1]);
965 /******************************************************************************
966 * GetDeviceState : gets buffered input data.
968 static HRESULT WINAPI SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface,
970 LPDIDEVICEOBJECTDATA dod,
974 ICOM_THIS(SysMouseAImpl,iface);
976 TRACE("(%p)->(%ld,%p,%p(0x%08lx),0x%08lx)\n",
977 This,dodsize,dod,entries,*entries,flags);
979 if (flags & DIGDD_PEEK)
980 TRACE("DIGDD_PEEK\n");
983 *entries = This->queue_pos;
986 /* Check for buffer overflow */
987 if (This->queue_pos > *entries) {
988 WARN("Buffer overflow not handled properly yet...\n");
989 This->queue_pos = *entries;
991 if (dodsize != sizeof(DIDEVICEOBJECTDATA)) {
992 ERR("Wrong structure size !\n");
993 return DIERR_INVALIDPARAM;
996 TRACE("Application retrieving %d event(s).\n", This->queue_pos);
998 /* Copy the buffered data into the application queue */
999 memcpy(dod, This->data_queue, This->queue_pos * dodsize);
1001 /* Reset the event queue */
1002 This->queue_pos = 0;
1005 /* Check if we need to do a mouse warping */
1006 if (This->need_warp) {
1009 TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
1010 point.x = This->win_centerX;
1011 point.y = This->win_centerY;
1012 MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
1013 DISPLAY_MoveCursor(point.x, point.y);
1015 This->need_warp = 0;
1021 /******************************************************************************
1022 * SetProperty : change input device properties
1024 static HRESULT WINAPI SysMouseAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface,
1028 ICOM_THIS(SysMouseAImpl,iface);
1032 WINE_StringFromCLSID(rguid,xbuf);
1034 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
1036 TRACE("(this=%p,%s,%p)\n",This,xbuf,ph);
1038 if (!HIWORD(rguid)) {
1039 switch ((DWORD)rguid) {
1040 case (DWORD) DIPROP_BUFFERSIZE: {
1041 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
1043 TRACE("buffersize = %ld\n",pd->dwData);
1045 This->data_queue = (LPDIDEVICEOBJECTDATA)HeapAlloc(GetProcessHeap(),0,
1046 pd->dwData * sizeof(DIDEVICEOBJECTDATA));
1047 This->queue_pos = 0;
1048 This->queue_len = pd->dwData;
1052 WARN("Unknown type %ld\n",(DWORD)rguid);
1061 static ICOM_VTABLE(IDirectInputDevice2A) SysKeyboardAvt =
1063 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1064 IDirectInputDevice2AImpl_QueryInterface,
1065 IDirectInputDevice2AImpl_AddRef,
1066 IDirectInputDevice2AImpl_Release,
1067 IDirectInputDevice2AImpl_GetCapabilities,
1068 IDirectInputDevice2AImpl_EnumObjects,
1069 IDirectInputDevice2AImpl_GetProperty,
1070 SysKeyboardAImpl_SetProperty,
1071 SysKeyboardAImpl_Acquire,
1072 SysKeyboardAImpl_Unacquire,
1073 SysKeyboardAImpl_GetDeviceState,
1074 SysKeyboardAImpl_GetDeviceData,
1075 IDirectInputDevice2AImpl_SetDataFormat,
1076 IDirectInputDevice2AImpl_SetEventNotification,
1077 IDirectInputDevice2AImpl_SetCooperativeLevel,
1078 IDirectInputDevice2AImpl_GetObjectInfo,
1079 IDirectInputDevice2AImpl_GetDeviceInfo,
1080 IDirectInputDevice2AImpl_RunControlPanel,
1081 IDirectInputDevice2AImpl_Initialize,
1082 IDirectInputDevice2AImpl_CreateEffect,
1083 IDirectInputDevice2AImpl_EnumEffects,
1084 IDirectInputDevice2AImpl_GetEffectInfo,
1085 IDirectInputDevice2AImpl_GetForceFeedbackState,
1086 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
1087 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
1088 IDirectInputDevice2AImpl_Escape,
1089 IDirectInputDevice2AImpl_Poll,
1090 IDirectInputDevice2AImpl_SendDeviceData,
1093 static ICOM_VTABLE(IDirectInputDevice2A) SysMouseAvt =
1095 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1096 IDirectInputDevice2AImpl_QueryInterface,
1097 IDirectInputDevice2AImpl_AddRef,
1098 SysMouseAImpl_Release,
1099 IDirectInputDevice2AImpl_GetCapabilities,
1100 IDirectInputDevice2AImpl_EnumObjects,
1101 IDirectInputDevice2AImpl_GetProperty,
1102 SysMouseAImpl_SetProperty,
1103 SysMouseAImpl_Acquire,
1104 SysMouseAImpl_Unacquire,
1105 SysMouseAImpl_GetDeviceState,
1106 SysMouseAImpl_GetDeviceData,
1107 SysMouseAImpl_SetDataFormat,
1108 IDirectInputDevice2AImpl_SetEventNotification,
1109 SysMouseAImpl_SetCooperativeLevel,
1110 IDirectInputDevice2AImpl_GetObjectInfo,
1111 IDirectInputDevice2AImpl_GetDeviceInfo,
1112 IDirectInputDevice2AImpl_RunControlPanel,
1113 IDirectInputDevice2AImpl_Initialize,
1114 IDirectInputDevice2AImpl_CreateEffect,
1115 IDirectInputDevice2AImpl_EnumEffects,
1116 IDirectInputDevice2AImpl_GetEffectInfo,
1117 IDirectInputDevice2AImpl_GetForceFeedbackState,
1118 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
1119 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
1120 IDirectInputDevice2AImpl_Escape,
1121 IDirectInputDevice2AImpl_Poll,
1122 IDirectInputDevice2AImpl_SendDeviceData,