1 /* DirectInput Mouse device
3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998,1999 Lionel Ulmer
5 * Copyright 2000-2001 TransGaming Technologies Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/port.h"
35 #include "dinput_private.h"
36 #include "device_private.h"
37 #include "wine/debug.h"
38 #include "wine/unicode.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(dinput);
42 /* Wine mouse driver object instances */
43 #define WINE_MOUSE_X_AXIS_INSTANCE 0
44 #define WINE_MOUSE_Y_AXIS_INSTANCE 1
45 #define WINE_MOUSE_Z_AXIS_INSTANCE 2
46 #define WINE_MOUSE_BUTTONS_INSTANCE 3
48 static const IDirectInputDevice8AVtbl SysMouseAvt;
49 static const IDirectInputDevice8WVtbl SysMouseWvt;
51 typedef struct SysMouseImpl SysMouseImpl;
55 struct IDirectInputDevice2AImpl base;
58 /* These are used in case of relative -> absolute transitions */
61 DWORD win_centerX, win_centerY;
62 /* warping: whether we need to move mouse back to middle once we
63 * reach window borders (for e.g. shooters, "surface movement" games) */
67 /* This is for mouse reporting. */
68 DIMOUSESTATE2 m_state;
71 static void dinput_mouse_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam );
73 const GUID DInput_Wine_Mouse_GUID = { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */
74 0x9e573ed8, 0x7734, 0x11d2, {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
77 void _dump_mouse_state(DIMOUSESTATE2 *m_state)
81 if (!TRACE_ON(dinput)) return;
83 TRACE("(X: %d Y: %d Z: %d", m_state->lX, m_state->lY, m_state->lZ);
84 for (i = 0; i < 5; i++) TRACE(" B%d: %02x", i, m_state->rgbButtons[i]);
88 static void fill_mouse_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD version) {
90 DIDEVICEINSTANCEA ddi;
92 dwSize = lpddi->dwSize;
94 TRACE("%d %p\n", dwSize, lpddi);
96 memset(lpddi, 0, dwSize);
97 memset(&ddi, 0, sizeof(ddi));
100 ddi.guidInstance = GUID_SysMouse;/* DInput's GUID */
101 ddi.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */
102 if (version >= 0x0800)
103 ddi.dwDevType = DI8DEVTYPE_MOUSE | (DI8DEVTYPEMOUSE_TRADITIONAL << 8);
105 ddi.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_TRADITIONAL << 8);
106 strcpy(ddi.tszInstanceName, "Mouse");
107 strcpy(ddi.tszProductName, "Wine Mouse");
109 memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi)));
112 static void fill_mouse_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD version) {
114 DIDEVICEINSTANCEW ddi;
116 dwSize = lpddi->dwSize;
118 TRACE("%d %p\n", dwSize, lpddi);
120 memset(lpddi, 0, dwSize);
121 memset(&ddi, 0, sizeof(ddi));
124 ddi.guidInstance = GUID_SysMouse;/* DInput's GUID */
125 ddi.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */
126 if (version >= 0x0800)
127 ddi.dwDevType = DI8DEVTYPE_MOUSE | (DI8DEVTYPEMOUSE_TRADITIONAL << 8);
129 ddi.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_TRADITIONAL << 8);
130 MultiByteToWideChar(CP_ACP, 0, "Mouse", -1, ddi.tszInstanceName, MAX_PATH);
131 MultiByteToWideChar(CP_ACP, 0, "Wine Mouse", -1, ddi.tszProductName, MAX_PATH);
133 memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi)));
136 static BOOL mousedev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
141 if ((dwDevType == 0) ||
142 ((dwDevType == DIDEVTYPE_MOUSE) && (version < 0x0800)) ||
143 (((dwDevType == DI8DEVCLASS_POINTER) || (dwDevType == DI8DEVTYPE_MOUSE)) && (version >= 0x0800))) {
144 TRACE("Enumerating the mouse device\n");
146 fill_mouse_dideviceinstanceA(lpddi, version);
154 static BOOL mousedev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
159 if ((dwDevType == 0) ||
160 ((dwDevType == DIDEVTYPE_MOUSE) && (version < 0x0800)) ||
161 (((dwDevType == DI8DEVCLASS_POINTER) || (dwDevType == DI8DEVTYPE_MOUSE)) && (version >= 0x0800))) {
162 TRACE("Enumerating the mouse device\n");
164 fill_mouse_dideviceinstanceW(lpddi, version);
172 static SysMouseImpl *alloc_device(REFGUID rguid, const void *mvt, IDirectInputImpl *dinput)
174 SysMouseImpl* newDevice;
175 LPDIDATAFORMAT df = NULL;
178 newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysMouseImpl));
179 if (!newDevice) return NULL;
180 newDevice->base.lpVtbl = mvt;
181 newDevice->base.ref = 1;
182 newDevice->base.dwCoopLevel = DISCL_NONEXCLUSIVE | DISCL_BACKGROUND;
183 memcpy(&newDevice->base.guid, rguid, sizeof(*rguid));
184 InitializeCriticalSection(&newDevice->base.crit);
185 newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SysMouseImpl*->base.crit");
186 newDevice->base.dinput = dinput;
187 newDevice->base.event_proc = dinput_mouse_hook;
189 /* Create copy of default data format */
190 if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIMouse2.dwSize))) goto failed;
191 memcpy(df, &c_dfDIMouse2, c_dfDIMouse2.dwSize);
192 if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto failed;
193 memcpy(df->rgodf, c_dfDIMouse2.rgodf, df->dwNumObjs * df->dwObjSize);
195 /* Because we don't do any detection yet just modify instance and type */
196 for (i = 0; i < df->dwNumObjs; i++)
197 if (DIDFT_GETTYPE(df->rgodf[i].dwType) & DIDFT_AXIS)
198 df->rgodf[i].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_RELAXIS;
200 df->rgodf[i].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_PSHBUTTON;
202 newDevice->base.data_format.wine_df = df;
203 IDirectInput_AddRef((LPDIRECTINPUTDEVICE8A)newDevice->base.dinput);
207 if (df) HeapFree(GetProcessHeap(), 0, df->rgodf);
208 HeapFree(GetProcessHeap(), 0, df);
209 HeapFree(GetProcessHeap(), 0, newDevice);
213 static HRESULT mousedev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev)
215 if ((IsEqualGUID(&GUID_SysMouse,rguid)) || /* Generic Mouse */
216 (IsEqualGUID(&DInput_Wine_Mouse_GUID,rguid))) { /* Wine Mouse */
217 if ((riid == NULL) ||
218 IsEqualGUID(&IID_IDirectInputDeviceA,riid) ||
219 IsEqualGUID(&IID_IDirectInputDevice2A,riid) ||
220 IsEqualGUID(&IID_IDirectInputDevice7A,riid) ||
221 IsEqualGUID(&IID_IDirectInputDevice8A,riid)) {
222 *pdev = (IDirectInputDeviceA*) alloc_device(rguid, &SysMouseAvt, dinput);
223 TRACE("Creating a Mouse device (%p)\n", *pdev);
224 if (!*pdev) return DIERR_OUTOFMEMORY;
227 return DIERR_NOINTERFACE;
230 return DIERR_DEVICENOTREG;
233 static HRESULT mousedev_create_deviceW(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev)
235 if ((IsEqualGUID(&GUID_SysMouse,rguid)) || /* Generic Mouse */
236 (IsEqualGUID(&DInput_Wine_Mouse_GUID,rguid))) { /* Wine Mouse */
237 if ((riid == NULL) ||
238 IsEqualGUID(&IID_IDirectInputDeviceW,riid) ||
239 IsEqualGUID(&IID_IDirectInputDevice2W,riid) ||
240 IsEqualGUID(&IID_IDirectInputDevice7W,riid) ||
241 IsEqualGUID(&IID_IDirectInputDevice8W,riid)) {
242 *pdev = (IDirectInputDeviceW*) alloc_device(rguid, &SysMouseWvt, dinput);
243 TRACE("Creating a Mouse device (%p)\n", *pdev);
244 if (!*pdev) return DIERR_OUTOFMEMORY;
247 return DIERR_NOINTERFACE;
250 return DIERR_DEVICENOTREG;
253 const struct dinput_device mouse_device = {
255 mousedev_enum_deviceA,
256 mousedev_enum_deviceW,
257 mousedev_create_deviceA,
258 mousedev_create_deviceW
261 /******************************************************************************
262 * SysMouseA (DInput Mouse support)
265 /* low-level mouse hook */
266 static void dinput_mouse_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam )
268 MSLLHOOKSTRUCT *hook = (MSLLHOOKSTRUCT *)lparam;
269 SysMouseImpl* This = (SysMouseImpl*) iface;
271 int wdata = 0, inst_id = -1;
273 TRACE("msg %lx @ (%d %d)\n", wparam, hook->pt.x, hook->pt.y);
275 EnterCriticalSection(&This->base.crit);
276 dwCoop = This->base.dwCoopLevel;
284 This->m_state.lX += pt.x = hook->pt.x - pt.x;
285 This->m_state.lY += pt.y = hook->pt.y - pt.y;
287 if (This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS)
289 pt1.x = This->m_state.lX;
290 pt1.y = This->m_state.lY;
296 inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS;
301 /* Already have X, need to queue it */
303 queue_event((LPDIRECTINPUTDEVICE8A)This, id_to_offset(&This->base.data_format, inst_id),
304 wdata, hook->time, This->base.dinput->evsequence);
305 inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS;
309 This->need_warp = (pt.x || pt.y) && dwCoop & DISCL_EXCLUSIVE;
313 inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_Z_AXIS_INSTANCE) | DIDFT_RELAXIS;
314 This->m_state.lZ += wdata = (short)HIWORD(hook->mouseData);
317 inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 0) | DIDFT_PSHBUTTON;
318 This->m_state.rgbButtons[0] = wdata = 0x80;
321 inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 0) | DIDFT_PSHBUTTON;
322 This->m_state.rgbButtons[0] = wdata = 0x00;
325 inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 1) | DIDFT_PSHBUTTON;
326 This->m_state.rgbButtons[1] = wdata = 0x80;
329 inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 1) | DIDFT_PSHBUTTON;
330 This->m_state.rgbButtons[1] = wdata = 0x00;
333 inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2) | DIDFT_PSHBUTTON;
334 This->m_state.rgbButtons[2] = wdata = 0x80;
337 inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2) | DIDFT_PSHBUTTON;
338 This->m_state.rgbButtons[2] = wdata = 0x00;
341 inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2 + HIWORD(hook->mouseData)) | DIDFT_PSHBUTTON;
342 This->m_state.rgbButtons[2 + HIWORD(hook->mouseData)] = wdata = 0x80;
345 inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2 + HIWORD(hook->mouseData)) | DIDFT_PSHBUTTON;
346 This->m_state.rgbButtons[2 + HIWORD(hook->mouseData)] = wdata = 0x00;
353 _dump_mouse_state(&This->m_state);
354 queue_event((LPDIRECTINPUTDEVICE8A)This, id_to_offset(&This->base.data_format, inst_id),
355 wdata, hook->time, This->base.dinput->evsequence++);
358 LeaveCriticalSection(&This->base.crit);
361 static BOOL dinput_window_check(SysMouseImpl* This) {
363 DWORD centerX, centerY;
365 /* make sure the window hasn't moved */
366 if(!GetWindowRect(This->base.win, &rect))
368 centerX = (rect.right - rect.left) / 2;
369 centerY = (rect.bottom - rect.top ) / 2;
370 if (This->win_centerX != centerX || This->win_centerY != centerY) {
371 This->win_centerX = centerX;
372 This->win_centerY = centerY;
374 This->mapped_center.x = This->win_centerX;
375 This->mapped_center.y = This->win_centerY;
376 MapWindowPoints(This->base.win, HWND_DESKTOP, &This->mapped_center, 1);
381 /******************************************************************************
382 * Acquire : gets exclusive control of the mouse
384 static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
386 SysMouseImpl *This = (SysMouseImpl *)iface;
391 TRACE("(this=%p)\n",This);
393 if ((res = IDirectInputDevice2AImpl_Acquire(iface)) != DI_OK) return res;
395 /* Init the mouse state */
396 GetCursorPos( &point );
397 if (This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS)
399 This->m_state.lX = point.x;
400 This->m_state.lY = point.y;
402 This->m_state.lX = 0;
403 This->m_state.lY = 0;
404 This->org_coords = point;
406 This->m_state.lZ = 0;
407 This->m_state.rgbButtons[0] = GetKeyState(VK_LBUTTON) & 0x80;
408 This->m_state.rgbButtons[1] = GetKeyState(VK_RBUTTON) & 0x80;
409 This->m_state.rgbButtons[2] = GetKeyState(VK_MBUTTON) & 0x80;
411 /* Install our mouse hook */
412 if (This->base.dwCoopLevel & DISCL_EXCLUSIVE)
413 ShowCursor(FALSE); /* hide cursor */
415 /* Get the window dimension and find the center */
416 GetWindowRect(This->base.win, &rect);
417 This->win_centerX = (rect.right - rect.left) / 2;
418 This->win_centerY = (rect.bottom - rect.top ) / 2;
420 /* Warp the mouse to the center of the window */
421 if (This->base.dwCoopLevel & DISCL_EXCLUSIVE)
423 This->mapped_center.x = This->win_centerX;
424 This->mapped_center.y = This->win_centerY;
425 MapWindowPoints(This->base.win, HWND_DESKTOP, &This->mapped_center, 1);
426 TRACE("Warping mouse to %d - %d\n", This->mapped_center.x, This->mapped_center.y);
427 SetCursorPos( This->mapped_center.x, This->mapped_center.y );
428 This->last_warped = GetCurrentTime();
430 This->need_warp = FALSE;
436 /******************************************************************************
437 * Unacquire : frees the mouse
439 static HRESULT WINAPI SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
441 SysMouseImpl *This = (SysMouseImpl *)iface;
444 TRACE("(this=%p)\n",This);
446 if ((res = IDirectInputDevice2AImpl_Unacquire(iface)) != DI_OK) return res;
448 if (This->base.dwCoopLevel & DISCL_EXCLUSIVE)
449 ShowCursor(TRUE); /* show cursor */
451 /* And put the mouse cursor back where it was at acquire time */
452 if (This->base.dwCoopLevel & DISCL_EXCLUSIVE)
454 TRACE(" warping mouse back to (%d , %d)\n", This->org_coords.x, This->org_coords.y);
455 SetCursorPos(This->org_coords.x, This->org_coords.y);
461 /******************************************************************************
462 * GetDeviceState : returns the "state" of the mouse.
464 * For the moment, only the "standard" return structure (DIMOUSESTATE) is
467 static HRESULT WINAPI SysMouseAImpl_GetDeviceState(
468 LPDIRECTINPUTDEVICE8A iface,DWORD len,LPVOID ptr
470 SysMouseImpl *This = (SysMouseImpl *)iface;
472 if(This->base.acquired == 0) return DIERR_NOTACQUIRED;
474 TRACE("(this=%p,0x%08x,%p):\n", This, len, ptr);
475 _dump_mouse_state(&This->m_state);
477 EnterCriticalSection(&This->base.crit);
478 /* Copy the current mouse state */
479 fill_DataFormat(ptr, &(This->m_state), &This->base.data_format);
481 /* Initialize the buffer when in relative mode */
482 if (!(This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS))
484 This->m_state.lX = 0;
485 This->m_state.lY = 0;
486 This->m_state.lZ = 0;
488 LeaveCriticalSection(&This->base.crit);
490 /* Check if we need to do a mouse warping */
491 if (This->need_warp && (GetCurrentTime() - This->last_warped > 10))
493 if(!dinput_window_check(This))
494 return DIERR_GENERIC;
495 TRACE("Warping mouse to %d - %d\n", This->mapped_center.x, This->mapped_center.y);
496 SetCursorPos( This->mapped_center.x, This->mapped_center.y );
497 This->last_warped = GetCurrentTime();
499 This->need_warp = FALSE;
505 /******************************************************************************
506 * GetDeviceData : gets buffered input data.
508 static HRESULT WINAPI SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE8A iface,
509 DWORD dodsize, LPDIDEVICEOBJECTDATA dod, LPDWORD entries, DWORD flags)
511 SysMouseImpl *This = (SysMouseImpl *)iface;
514 res = IDirectInputDevice2AImpl_GetDeviceData(iface, dodsize, dod, entries, flags);
515 if (FAILED(res)) return res;
517 /* Check if we need to do a mouse warping */
518 if (This->need_warp && (GetCurrentTime() - This->last_warped > 10))
520 if(!dinput_window_check(This))
521 return DIERR_GENERIC;
522 TRACE("Warping mouse to %d - %d\n", This->mapped_center.x, This->mapped_center.y);
523 SetCursorPos( This->mapped_center.x, This->mapped_center.y );
524 This->last_warped = GetCurrentTime();
526 This->need_warp = FALSE;
531 /******************************************************************************
532 * GetProperty : get input device properties
534 static HRESULT WINAPI SysMouseAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface,
536 LPDIPROPHEADER pdiph)
538 SysMouseImpl *This = (SysMouseImpl *)iface;
540 TRACE("(%p) %s,%p\n", This, debugstr_guid(rguid), pdiph);
541 _dump_DIPROPHEADER(pdiph);
543 if (!HIWORD(rguid)) {
544 switch (LOWORD(rguid)) {
545 case (DWORD) DIPROP_GRANULARITY: {
546 LPDIPROPDWORD pr = (LPDIPROPDWORD) pdiph;
548 /* We'll just assume that the app asks about the Z axis */
549 pr->dwData = WHEEL_DELTA;
554 case (DWORD) DIPROP_RANGE: {
555 LPDIPROPRANGE pr = (LPDIPROPRANGE) pdiph;
557 if ((pdiph->dwHow == DIPH_BYID) &&
558 ((pdiph->dwObj == (DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS)) ||
559 (pdiph->dwObj == (DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS)))) {
560 /* Querying the range of either the X or the Y axis. As I do
561 not know the range, do as if the range were
563 pr->lMin = DIPROPRANGE_NOMIN;
564 pr->lMax = DIPROPRANGE_NOMAX;
571 return IDirectInputDevice2AImpl_GetProperty(iface, rguid, pdiph);
578 /******************************************************************************
579 * GetCapabilities : get the device capablitites
581 static HRESULT WINAPI SysMouseAImpl_GetCapabilities(
582 LPDIRECTINPUTDEVICE8A iface,
583 LPDIDEVCAPS lpDIDevCaps)
585 SysMouseImpl *This = (SysMouseImpl *)iface;
588 TRACE("(this=%p,%p)\n",This,lpDIDevCaps);
590 if ((lpDIDevCaps->dwSize != sizeof(DIDEVCAPS)) && (lpDIDevCaps->dwSize != sizeof(DIDEVCAPS_DX3))) {
591 WARN("invalid parameter\n");
592 return DIERR_INVALIDPARAM;
595 devcaps.dwSize = lpDIDevCaps->dwSize;
596 devcaps.dwFlags = DIDC_ATTACHED;
597 if (This->base.dinput->dwVersion >= 0x0800)
598 devcaps.dwDevType = DI8DEVTYPE_MOUSE | (DI8DEVTYPEMOUSE_TRADITIONAL << 8);
600 devcaps.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_TRADITIONAL << 8);
602 devcaps.dwButtons = 8;
604 devcaps.dwFFSamplePeriod = 0;
605 devcaps.dwFFMinTimeResolution = 0;
606 devcaps.dwFirmwareRevision = 100;
607 devcaps.dwHardwareRevision = 100;
608 devcaps.dwFFDriverVersion = 0;
610 memcpy(lpDIDevCaps, &devcaps, lpDIDevCaps->dwSize);
615 /******************************************************************************
616 * GetObjectInfo : get information about a device object such as a button
619 static HRESULT WINAPI SysMouseWImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface,
620 LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow)
622 static const WCHAR x_axisW[] = {'X','-','A','x','i','s',0};
623 static const WCHAR y_axisW[] = {'Y','-','A','x','i','s',0};
624 static const WCHAR wheelW[] = {'W','h','e','e','l',0};
625 static const WCHAR buttonW[] = {'B','u','t','t','o','n',' ','%','d',0};
628 res = IDirectInputDevice2WImpl_GetObjectInfo(iface, pdidoi, dwObj, dwHow);
629 if (res != DI_OK) return res;
631 if (IsEqualGUID(&pdidoi->guidType, &GUID_XAxis)) strcpyW(pdidoi->tszName, x_axisW);
632 else if (IsEqualGUID(&pdidoi->guidType, &GUID_YAxis)) strcpyW(pdidoi->tszName, y_axisW);
633 else if (IsEqualGUID(&pdidoi->guidType, &GUID_ZAxis)) strcpyW(pdidoi->tszName, wheelW);
634 else if (pdidoi->dwType & DIDFT_BUTTON)
635 wsprintfW(pdidoi->tszName, buttonW, DIDFT_GETINSTANCE(pdidoi->dwType) - 3);
637 _dump_OBJECTINSTANCEW(pdidoi);
641 static HRESULT WINAPI SysMouseAImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8A iface,
642 LPDIDEVICEOBJECTINSTANCEA pdidoi, DWORD dwObj, DWORD dwHow)
645 DIDEVICEOBJECTINSTANCEW didoiW;
646 DWORD dwSize = pdidoi->dwSize;
648 didoiW.dwSize = sizeof(didoiW);
649 res = SysMouseWImpl_GetObjectInfo((LPDIRECTINPUTDEVICE8W)iface, &didoiW, dwObj, dwHow);
650 if (res != DI_OK) return res;
652 memset(pdidoi, 0, pdidoi->dwSize);
653 memcpy(pdidoi, &didoiW, FIELD_OFFSET(DIDEVICEOBJECTINSTANCEW, tszName));
654 pdidoi->dwSize = dwSize;
655 WideCharToMultiByte(CP_ACP, 0, didoiW.tszName, -1, pdidoi->tszName,
656 sizeof(pdidoi->tszName), NULL, NULL);
661 /******************************************************************************
662 * GetDeviceInfo : get information about a device's identity
664 static HRESULT WINAPI SysMouseAImpl_GetDeviceInfo(
665 LPDIRECTINPUTDEVICE8A iface,
666 LPDIDEVICEINSTANCEA pdidi)
668 SysMouseImpl *This = (SysMouseImpl *)iface;
669 TRACE("(this=%p,%p)\n", This, pdidi);
671 if (pdidi->dwSize != sizeof(DIDEVICEINSTANCEA)) {
672 WARN(" dinput3 not supporte yet...\n");
676 fill_mouse_dideviceinstanceA(pdidi, This->base.dinput->dwVersion);
681 static HRESULT WINAPI SysMouseWImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8W iface, LPDIDEVICEINSTANCEW pdidi)
683 SysMouseImpl *This = (SysMouseImpl *)iface;
684 TRACE("(this=%p,%p)\n", This, pdidi);
686 if (pdidi->dwSize != sizeof(DIDEVICEINSTANCEW)) {
687 WARN(" dinput3 not supporte yet...\n");
691 fill_mouse_dideviceinstanceW(pdidi, This->base.dinput->dwVersion);
697 static const IDirectInputDevice8AVtbl SysMouseAvt =
699 IDirectInputDevice2AImpl_QueryInterface,
700 IDirectInputDevice2AImpl_AddRef,
701 IDirectInputDevice2AImpl_Release,
702 SysMouseAImpl_GetCapabilities,
703 IDirectInputDevice2AImpl_EnumObjects,
704 SysMouseAImpl_GetProperty,
705 IDirectInputDevice2AImpl_SetProperty,
706 SysMouseAImpl_Acquire,
707 SysMouseAImpl_Unacquire,
708 SysMouseAImpl_GetDeviceState,
709 SysMouseAImpl_GetDeviceData,
710 IDirectInputDevice2AImpl_SetDataFormat,
711 IDirectInputDevice2AImpl_SetEventNotification,
712 IDirectInputDevice2AImpl_SetCooperativeLevel,
713 SysMouseAImpl_GetObjectInfo,
714 SysMouseAImpl_GetDeviceInfo,
715 IDirectInputDevice2AImpl_RunControlPanel,
716 IDirectInputDevice2AImpl_Initialize,
717 IDirectInputDevice2AImpl_CreateEffect,
718 IDirectInputDevice2AImpl_EnumEffects,
719 IDirectInputDevice2AImpl_GetEffectInfo,
720 IDirectInputDevice2AImpl_GetForceFeedbackState,
721 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
722 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
723 IDirectInputDevice2AImpl_Escape,
724 IDirectInputDevice2AImpl_Poll,
725 IDirectInputDevice2AImpl_SendDeviceData,
726 IDirectInputDevice7AImpl_EnumEffectsInFile,
727 IDirectInputDevice7AImpl_WriteEffectToFile,
728 IDirectInputDevice8AImpl_BuildActionMap,
729 IDirectInputDevice8AImpl_SetActionMap,
730 IDirectInputDevice8AImpl_GetImageInfo
733 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
734 # define XCAST(fun) (typeof(SysMouseWvt.fun))
736 # define XCAST(fun) (void*)
739 static const IDirectInputDevice8WVtbl SysMouseWvt =
741 IDirectInputDevice2WImpl_QueryInterface,
742 XCAST(AddRef)IDirectInputDevice2AImpl_AddRef,
743 XCAST(Release)IDirectInputDevice2AImpl_Release,
744 XCAST(GetCapabilities)SysMouseAImpl_GetCapabilities,
745 IDirectInputDevice2WImpl_EnumObjects,
746 XCAST(GetProperty)SysMouseAImpl_GetProperty,
747 XCAST(SetProperty)IDirectInputDevice2AImpl_SetProperty,
748 XCAST(Acquire)SysMouseAImpl_Acquire,
749 XCAST(Unacquire)SysMouseAImpl_Unacquire,
750 XCAST(GetDeviceState)SysMouseAImpl_GetDeviceState,
751 XCAST(GetDeviceData)SysMouseAImpl_GetDeviceData,
752 XCAST(SetDataFormat)IDirectInputDevice2AImpl_SetDataFormat,
753 XCAST(SetEventNotification)IDirectInputDevice2AImpl_SetEventNotification,
754 XCAST(SetCooperativeLevel)IDirectInputDevice2AImpl_SetCooperativeLevel,
755 SysMouseWImpl_GetObjectInfo,
756 SysMouseWImpl_GetDeviceInfo,
757 XCAST(RunControlPanel)IDirectInputDevice2AImpl_RunControlPanel,
758 XCAST(Initialize)IDirectInputDevice2AImpl_Initialize,
759 XCAST(CreateEffect)IDirectInputDevice2AImpl_CreateEffect,
760 IDirectInputDevice2WImpl_EnumEffects,
761 IDirectInputDevice2WImpl_GetEffectInfo,
762 XCAST(GetForceFeedbackState)IDirectInputDevice2AImpl_GetForceFeedbackState,
763 XCAST(SendForceFeedbackCommand)IDirectInputDevice2AImpl_SendForceFeedbackCommand,
764 XCAST(EnumCreatedEffectObjects)IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
765 XCAST(Escape)IDirectInputDevice2AImpl_Escape,
766 XCAST(Poll)IDirectInputDevice2AImpl_Poll,
767 XCAST(SendDeviceData)IDirectInputDevice2AImpl_SendDeviceData,
768 IDirectInputDevice7WImpl_EnumEffectsInFile,
769 IDirectInputDevice7WImpl_WriteEffectToFile,
770 IDirectInputDevice8WImpl_BuildActionMap,
771 IDirectInputDevice8WImpl_SetActionMap,
772 IDirectInputDevice8WImpl_GetImageInfo