1 /* DirectInput Joystick device for Mac OS/X
3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998,1999 Lionel Ulmer
5 * Copyright 2000-2001 TransGaming Technologies Inc.
6 * Copyright 2009 CodeWeavers, Aric Stewart
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/port.h"
26 #if defined(HAVE_CARBON_CARBON_H) && defined(HAVE_IOKIT_HID_IOHIDLIB_H)
27 #define LoadResource __carbon_LoadResource
28 #define CompareString __carbon_CompareString
29 #define GetCurrentThread __carbon_GetCurrentThread
30 #define GetCurrentProcess __carbon_GetCurrentProcess
31 #define AnimatePalette __carbon_AnimatePalette
32 #define EqualRgn __carbon_EqualRgn
33 #define FillRgn __carbon_FillRgn
34 #define FrameRgn __carbon_FrameRgn
35 #define GetPixel __carbon_GetPixel
36 #define InvertRgn __carbon_InvertRgn
37 #define LineTo __carbon_LineTo
38 #define OffsetRgn __carbon_OffsetRgn
39 #define PaintRgn __carbon_PaintRgn
40 #define Polygon __carbon_Polygon
41 #define ResizePalette __carbon_ResizePalette
42 #define SetRectRgn __carbon_SetRectRgn
43 #define ULONG __carbon_ULONG
44 #define E_INVALIDARG __carbon_E_INVALIDARG
45 #define E_OUTOFMEMORY __carbon_E_OUTOFMEMORY
46 #define E_HANDLE __carbon_E_HANDLE
47 #define E_ACCESSDENIED __carbon_E_ACCESSDENIED
48 #define E_UNEXPECTED __carbon_E_UNEXPECTED
49 #define E_FAIL __carbon_E_FAIL
50 #define E_ABORT __carbon_E_ABORT
51 #define E_POINTER __carbon_E_POINTER
52 #define E_NOINTERFACE __carbon_E_NOINTERFACE
53 #define E_NOTIMPL __carbon_E_NOTIMPL
54 #define S_FALSE __carbon_S_FALSE
55 #define S_OK __carbon_S_OK
56 #define HRESULT_FACILITY __carbon_HRESULT_FACILITY
57 #define IS_ERROR __carbon_IS_ERROR
58 #define FAILED __carbon_FAILED
59 #define SUCCEEDED __carbon_SUCCEEDED
60 #define MAKE_HRESULT __carbon_MAKE_HRESULT
61 #define HRESULT __carbon_HRESULT
62 #define STDMETHODCALLTYPE __carbon_STDMETHODCALLTYPE
63 #include <Carbon/Carbon.h>
64 #include <IOKit/hid/IOHIDLib.h>
67 #undef GetCurrentThread
70 #undef GetCurrentProcess
96 #undef HRESULT_FACILITY
102 #undef STDMETHODCALLTYPE
103 #endif /* HAVE_CARBON_CARBON_H */
105 #include "wine/debug.h"
106 #include "wine/unicode.h"
109 #include "winerror.h"
113 #include "dinput_private.h"
114 #include "device_private.h"
115 #include "joystick_private.h"
117 WINE_DEFAULT_DEBUG_CHANNEL(dinput);
119 #ifdef HAVE_IOKIT_HID_IOHIDLIB_H
121 static IOHIDManagerRef gIOHIDManagerRef = NULL;
122 static CFArrayRef gDevices = NULL;
124 typedef struct JoystickImpl JoystickImpl;
125 static const IDirectInputDevice8AVtbl JoystickAvt;
126 static const IDirectInputDevice8WVtbl JoystickWvt;
130 struct JoystickGenericImpl generic;
134 CFMutableArrayRef elementCFArrayRef;
138 static const GUID DInput_Wine_OsX_Joystick_GUID = { /* 59CAD8F6-E617-41E2-8EB7-47B23EEEDC5A */
139 0x59CAD8F6, 0xE617, 0x41E2, {0x8E, 0xB7, 0x47, 0xB2, 0x3E, 0xEE, 0xDC, 0x5A}
142 static void CFSetApplierFunctionCopyToCFArray(const void *value, void *context)
144 CFArrayAppendValue( ( CFMutableArrayRef ) context, value );
147 static CFMutableDictionaryRef creates_osx_device_match(int usage)
149 CFMutableDictionaryRef result;
151 result = CFDictionaryCreateMutable( kCFAllocatorDefault, 0,
152 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks );
156 int number = kHIDPage_GenericDesktop;
157 CFNumberRef pageCFNumberRef = CFNumberCreate( kCFAllocatorDefault,
158 kCFNumberIntType, &number);
160 if ( pageCFNumberRef )
162 CFNumberRef usageCFNumberRef;
164 CFDictionarySetValue( result, CFSTR( kIOHIDDeviceUsagePageKey ),
166 CFRelease( pageCFNumberRef );
168 usageCFNumberRef = CFNumberCreate( kCFAllocatorDefault,
169 kCFNumberIntType, &usage);
170 if ( usageCFNumberRef )
172 CFDictionarySetValue( result, CFSTR( kIOHIDDeviceUsageKey ),
174 CFRelease( usageCFNumberRef );
178 ERR("CFNumberCreate() failed.");
184 ERR("CFNumberCreate failed.");
190 ERR("CFDictionaryCreateMutable failed.");
197 static int find_osx_devices(void)
200 CFMutableDictionaryRef result;
204 gIOHIDManagerRef = IOHIDManagerCreate( kCFAllocatorDefault, 0L );
205 tIOReturn = IOHIDManagerOpen( gIOHIDManagerRef, 0L);
206 if ( kIOReturnSuccess != tIOReturn )
208 ERR("Couldn’t open IOHIDManager.");
212 matching = CFArrayCreateMutable( kCFAllocatorDefault, 0,
213 &kCFTypeArrayCallBacks );
215 /* build matching dictionary */
216 result = creates_osx_device_match(kHIDPage_Sport);
222 CFArrayAppendValue( ( CFMutableArrayRef )matching, result );
223 result = creates_osx_device_match(kHIDPage_Game);
229 CFArrayAppendValue( ( CFMutableArrayRef )matching, result );
231 IOHIDManagerSetDeviceMatchingMultiple( gIOHIDManagerRef, matching);
232 devset = IOHIDManagerCopyDevices( gIOHIDManagerRef );
236 gDevices = CFArrayCreateMutable( kCFAllocatorDefault, 0,
237 &kCFTypeArrayCallBacks );
238 CFSetApplyFunction(devset, CFSetApplierFunctionCopyToCFArray, (void*)gDevices);
239 count = CFArrayGetCount( gDevices);
241 count = CFArrayGetCount( gDevices);
243 TRACE("found %i device(s)\n",(int)count);
250 static int get_osx_device_name(int id, char *name, int length)
253 IOHIDDeviceRef tIOHIDDeviceRef;
258 tIOHIDDeviceRef = ( IOHIDDeviceRef ) CFArrayGetValueAtIndex( gDevices, id );
260 if (!tIOHIDDeviceRef)
266 if (!tIOHIDDeviceRef)
268 ERR("Invalid Device requested %i\n",id);
272 str = IOHIDDeviceGetProperty(tIOHIDDeviceRef, CFSTR( kIOHIDProductKey ));
275 CFIndex len = CFStringGetLength(str);
278 CFStringGetCString(str,name,length,kCFStringEncodingASCII);
287 static void get_osx_device_elements(JoystickImpl *device)
289 IOHIDDeviceRef tIOHIDDeviceRef;
290 CFArrayRef gElementCFArrayRef;
295 device->elementCFArrayRef = NULL;
300 tIOHIDDeviceRef = ( IOHIDDeviceRef ) CFArrayGetValueAtIndex( gDevices, device->id );
302 if (!tIOHIDDeviceRef)
305 gElementCFArrayRef = IOHIDDeviceCopyMatchingElements( tIOHIDDeviceRef,
308 if (gElementCFArrayRef)
310 CFIndex idx, cnt = CFArrayGetCount( gElementCFArrayRef );
311 /* build our element array in the order that dinput expects */
312 device->elementCFArrayRef = CFArrayCreateMutable(NULL,0,NULL);
314 for ( idx = 0; idx < cnt; idx++ )
316 IOHIDElementRef tIOHIDElementRef = ( IOHIDElementRef ) CFArrayGetValueAtIndex( gElementCFArrayRef, idx );
317 int eleType = IOHIDElementGetType( tIOHIDElementRef );
320 case kIOHIDElementTypeInput_Button:
324 CFArrayInsertValueAtIndex(device->elementCFArrayRef, (axes+povs+buttons), tIOHIDElementRef);
329 case kIOHIDElementTypeInput_Axis:
331 CFArrayInsertValueAtIndex(device->elementCFArrayRef, axes, tIOHIDElementRef);
336 FIXME("Unhandled type %i\n",eleType);
341 device->generic.devcaps.dwAxes = axes;
342 device->generic.devcaps.dwButtons = buttons;
343 device->generic.devcaps.dwPOVs = povs;
346 static void get_osx_device_elements_props(JoystickImpl *device)
348 CFArrayRef gElementCFArrayRef = device->elementCFArrayRef;
350 if (gElementCFArrayRef)
352 CFIndex idx, cnt = CFArrayGetCount( gElementCFArrayRef );
354 for ( idx = 0; idx < cnt; idx++ )
356 IOHIDElementRef tIOHIDElementRef = ( IOHIDElementRef ) CFArrayGetValueAtIndex( gElementCFArrayRef, idx );
358 device->generic.props[idx].lDevMin = IOHIDElementGetLogicalMin(tIOHIDElementRef);
359 device->generic.props[idx].lDevMax = IOHIDElementGetLogicalMax(tIOHIDElementRef);
360 device->generic.props[idx].lMin = 0;
361 device->generic.props[idx].lMax = 0xffff;
362 device->generic.props[idx].lDeadZone = 0;
363 device->generic.props[idx].lSaturation = 0;
368 static void poll_osx_device_state(JoystickGenericImpl *device_in)
370 JoystickImpl *device = (JoystickImpl*)device_in;
371 IOHIDDeviceRef tIOHIDDeviceRef;
372 CFArrayRef gElementCFArrayRef = device->elementCFArrayRef;
374 TRACE("polling device %i\n",device->id);
379 tIOHIDDeviceRef = ( IOHIDDeviceRef ) CFArrayGetValueAtIndex( gDevices, device->id );
381 if (!tIOHIDDeviceRef)
384 if (gElementCFArrayRef)
387 CFIndex idx, cnt = CFArrayGetCount( gElementCFArrayRef );
389 for ( idx = 0; idx < cnt; idx++ )
391 IOHIDValueRef valueRef;
393 IOHIDElementRef tIOHIDElementRef = ( IOHIDElementRef ) CFArrayGetValueAtIndex( gElementCFArrayRef, idx );
394 int eleType = IOHIDElementGetType( tIOHIDElementRef );
398 case kIOHIDElementTypeInput_Button:
401 IOHIDDeviceGetValue(tIOHIDDeviceRef, tIOHIDElementRef, &valueRef);
402 val = IOHIDValueGetIntegerValue(valueRef);
403 device->generic.js.rgbButtons[button_idx] = val ? 0x80 : 0x00;
408 FIXME("Unhandled type %i\n",eleType);
414 static INT find_joystick_devices(void)
416 static INT joystick_devices_count = -1;
418 if (joystick_devices_count != -1) return joystick_devices_count;
420 joystick_devices_count = find_osx_devices();
422 return joystick_devices_count;
425 static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
427 if (id >= find_joystick_devices()) return FALSE;
429 if (dwFlags & DIEDFL_FORCEFEEDBACK) {
430 WARN("force feedback not supported\n");
434 if ((dwDevType == 0) ||
435 ((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) ||
436 (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800)))
438 /* Return joystick */
439 lpddi->guidInstance = DInput_Wine_OsX_Joystick_GUID;
440 lpddi->guidInstance.Data3 = id;
441 lpddi->guidProduct = DInput_Wine_OsX_Joystick_GUID;
442 /* we only support traditional joysticks for now */
443 if (version >= 0x0800)
444 lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
446 lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
447 sprintf(lpddi->tszInstanceName, "Joystick %d", id);
449 /* get the device name */
450 get_osx_device_name(id, lpddi->tszProductName, MAX_PATH);
452 lpddi->guidFFDriver = GUID_NULL;
459 static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
464 if (id >= find_joystick_devices()) return FALSE;
466 if (dwFlags & DIEDFL_FORCEFEEDBACK) {
467 WARN("force feedback not supported\n");
471 if ((dwDevType == 0) ||
472 ((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) ||
473 (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))) {
474 /* Return joystick */
475 lpddi->guidInstance = DInput_Wine_OsX_Joystick_GUID;
476 lpddi->guidInstance.Data3 = id;
477 lpddi->guidProduct = DInput_Wine_OsX_Joystick_GUID;
478 /* we only support traditional joysticks for now */
479 if (version >= 0x0800)
480 lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
482 lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
483 sprintf(friendly, "Joystick %d", id);
484 MultiByteToWideChar(CP_ACP, 0, friendly, -1, lpddi->tszInstanceName, MAX_PATH);
485 /* get the device name */
486 get_osx_device_name(id, name, MAX_PATH);
488 MultiByteToWideChar(CP_ACP, 0, name, -1, lpddi->tszProductName, MAX_PATH);
489 lpddi->guidFFDriver = GUID_NULL;
496 static HRESULT alloc_device(REFGUID rguid, const void *jvt, IDirectInputImpl *dinput,
497 LPDIRECTINPUTDEVICEA* pdev, unsigned short index)
500 JoystickImpl* newDevice;
503 LPDIDATAFORMAT df = NULL;
506 TRACE("%s %p %p %p %hu\n", debugstr_guid(rguid), jvt, dinput, pdev, index);
508 newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickImpl));
509 if (newDevice == 0) {
510 WARN("out of memory\n");
512 return DIERR_OUTOFMEMORY;
515 newDevice->id = index;
517 newDevice->generic.guidProduct = DInput_Wine_OsX_Joystick_GUID;
518 newDevice->generic.joy_polldev = poll_osx_device_state;
520 /* get the device name */
521 get_osx_device_name(index, name, MAX_PATH);
522 TRACE("Name %s\n",name);
524 /* copy the device name */
525 newDevice->generic.name = HeapAlloc(GetProcessHeap(),0,strlen(name) + 1);
526 strcpy(newDevice->generic.name, name);
528 get_osx_device_elements(newDevice);
530 TRACE("%i axes %i buttons %i povs\n",newDevice->generic.devcaps.dwAxes,newDevice->generic.devcaps.dwButtons,newDevice->generic.devcaps.dwPOVs);
532 if (newDevice->generic.devcaps.dwButtons > 128)
534 WARN("Can't support %d buttons. Clamping down to 128\n", newDevice->generic.devcaps.dwButtons);
535 newDevice->generic.devcaps.dwButtons = 128;
538 newDevice->generic.base.lpVtbl = jvt;
539 newDevice->generic.base.ref = 1;
540 newDevice->generic.base.dinput = dinput;
541 newDevice->generic.base.guid = *rguid;
542 InitializeCriticalSection(&newDevice->generic.base.crit);
543 newDevice->generic.base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JoystickImpl*->generic.base.crit");
545 /* Create copy of default data format */
546 if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIJoystick2.dwSize))) goto FAILED;
547 memcpy(df, &c_dfDIJoystick2, c_dfDIJoystick2.dwSize);
549 df->dwNumObjs = newDevice->generic.devcaps.dwAxes + newDevice->generic.devcaps.dwPOVs + newDevice->generic.devcaps.dwButtons;
550 if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto FAILED;
552 for (i = 0; i < newDevice->generic.devcaps.dwAxes; i++)
554 memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i], df->dwObjSize);
555 df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_ABSAXIS;
558 for (i = 0; i < newDevice->generic.devcaps.dwPOVs; i++)
560 memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i + 8], df->dwObjSize);
561 df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_POV;
564 for (i = 0; i < newDevice->generic.devcaps.dwButtons; i++)
566 memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i + 12], df->dwObjSize);
567 df->rgodf[idx ].pguid = &GUID_Button;
568 df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_PSHBUTTON;
570 newDevice->generic.base.data_format.wine_df = df;
572 /* create default properties */
573 newDevice->generic.props = HeapAlloc(GetProcessHeap(),0,c_dfDIJoystick2.dwNumObjs*sizeof(ObjProps));
574 if (newDevice->generic.props == 0)
577 /* initialize default properties */
578 get_osx_device_elements_props(newDevice);
580 IDirectInput_AddRef((LPDIRECTINPUTDEVICE8A)newDevice->generic.base.dinput);
582 newDevice->generic.devcaps.dwSize = sizeof(newDevice->generic.devcaps);
583 newDevice->generic.devcaps.dwFlags = DIDC_ATTACHED;
584 if (newDevice->generic.base.dinput->dwVersion >= 0x0800)
585 newDevice->generic.devcaps.dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
587 newDevice->generic.devcaps.dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
588 newDevice->generic.devcaps.dwFFSamplePeriod = 0;
589 newDevice->generic.devcaps.dwFFMinTimeResolution = 0;
590 newDevice->generic.devcaps.dwFirmwareRevision = 0;
591 newDevice->generic.devcaps.dwHardwareRevision = 0;
592 newDevice->generic.devcaps.dwFFDriverVersion = 0;
594 if (TRACE_ON(dinput)) {
595 _dump_DIDATAFORMAT(newDevice->generic.base.data_format.wine_df);
596 _dump_DIDEVCAPS(&newDevice->generic.devcaps);
599 *pdev = (LPDIRECTINPUTDEVICEA)newDevice;
604 hr = DIERR_OUTOFMEMORY;
605 if (df) HeapFree(GetProcessHeap(), 0, df->rgodf);
606 HeapFree(GetProcessHeap(), 0, df);
607 release_DataFormat(&newDevice->generic.base.data_format);
608 HeapFree(GetProcessHeap(),0,newDevice->generic.name);
609 HeapFree(GetProcessHeap(),0,newDevice->generic.props);
610 HeapFree(GetProcessHeap(),0,newDevice);
616 /******************************************************************************
617 * get_joystick_index : Get the joystick index from a given GUID
619 static unsigned short get_joystick_index(REFGUID guid)
621 GUID wine_joystick = DInput_Wine_OsX_Joystick_GUID;
622 GUID dev_guid = *guid;
624 wine_joystick.Data3 = 0;
627 /* for the standard joystick GUID use index 0 */
628 if(IsEqualGUID(&GUID_Joystick,guid)) return 0;
630 /* for the wine joystick GUIDs use the index stored in Data3 */
631 if(IsEqualGUID(&wine_joystick, &dev_guid)) return guid->Data3;
636 static HRESULT joydev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev)
638 unsigned short index;
639 int joystick_devices_count;
641 TRACE("%p %s %p %p\n",dinput, debugstr_guid(rguid), riid, pdev);
644 if ((joystick_devices_count = find_joystick_devices()) == 0)
645 return DIERR_DEVICENOTREG;
647 if ((index = get_joystick_index(rguid)) < 0xffff &&
648 joystick_devices_count && index < joystick_devices_count)
650 if ((riid == NULL) ||
651 IsEqualGUID(&IID_IDirectInputDeviceA, riid) ||
652 IsEqualGUID(&IID_IDirectInputDevice2A, riid) ||
653 IsEqualGUID(&IID_IDirectInputDevice7A, riid) ||
654 IsEqualGUID(&IID_IDirectInputDevice8A, riid))
656 return alloc_device(rguid, &JoystickAvt, dinput, pdev, index);
659 WARN("no interface\n");
660 return DIERR_NOINTERFACE;
663 return DIERR_DEVICENOTREG;
666 static HRESULT joydev_create_deviceW(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev)
668 unsigned short index;
669 int joystick_devices_count;
671 TRACE("%p %s %p %p\n",dinput, debugstr_guid(rguid), riid, pdev);
674 if ((joystick_devices_count = find_joystick_devices()) == 0)
675 return DIERR_DEVICENOTREG;
677 if ((index = get_joystick_index(rguid)) < 0xffff &&
678 joystick_devices_count && index < joystick_devices_count)
680 if ((riid == NULL) ||
681 IsEqualGUID(&IID_IDirectInputDeviceW, riid) ||
682 IsEqualGUID(&IID_IDirectInputDevice2W, riid) ||
683 IsEqualGUID(&IID_IDirectInputDevice7W, riid) ||
684 IsEqualGUID(&IID_IDirectInputDevice8W, riid))
686 return alloc_device(rguid, &JoystickWvt, dinput, (LPDIRECTINPUTDEVICEA *)pdev, index);
688 WARN("no interface\n");
689 return DIERR_NOINTERFACE;
692 WARN("invalid device GUID %s\n",debugstr_guid(rguid));
693 return DIERR_DEVICENOTREG;
696 const struct dinput_device joystick_osx_device = {
697 "Wine OS X joystick driver",
700 joydev_create_deviceA,
701 joydev_create_deviceW
704 static const IDirectInputDevice8AVtbl JoystickAvt =
706 IDirectInputDevice2AImpl_QueryInterface,
707 IDirectInputDevice2AImpl_AddRef,
708 IDirectInputDevice2AImpl_Release,
709 JoystickAGenericImpl_GetCapabilities,
710 IDirectInputDevice2AImpl_EnumObjects,
711 JoystickAGenericImpl_GetProperty,
712 JoystickAGenericImpl_SetProperty,
713 JoystickAGenericImpl_Acquire,
714 JoystickAGenericImpl_Unacquire,
715 JoystickAGenericImpl_GetDeviceState,
716 IDirectInputDevice2AImpl_GetDeviceData,
717 IDirectInputDevice2AImpl_SetDataFormat,
718 IDirectInputDevice2AImpl_SetEventNotification,
719 IDirectInputDevice2AImpl_SetCooperativeLevel,
720 JoystickAGenericImpl_GetObjectInfo,
721 JoystickAGenericImpl_GetDeviceInfo,
722 IDirectInputDevice2AImpl_RunControlPanel,
723 IDirectInputDevice2AImpl_Initialize,
724 IDirectInputDevice2AImpl_CreateEffect,
725 IDirectInputDevice2AImpl_EnumEffects,
726 IDirectInputDevice2AImpl_GetEffectInfo,
727 IDirectInputDevice2AImpl_GetForceFeedbackState,
728 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
729 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
730 IDirectInputDevice2AImpl_Escape,
731 JoystickAGenericImpl_Poll,
732 IDirectInputDevice2AImpl_SendDeviceData,
733 IDirectInputDevice7AImpl_EnumEffectsInFile,
734 IDirectInputDevice7AImpl_WriteEffectToFile,
735 IDirectInputDevice8AImpl_BuildActionMap,
736 IDirectInputDevice8AImpl_SetActionMap,
737 IDirectInputDevice8AImpl_GetImageInfo
740 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
741 # define XCAST(fun) (typeof(JoystickWvt.fun))
743 # define XCAST(fun) (void*)
746 static const IDirectInputDevice8WVtbl JoystickWvt =
748 IDirectInputDevice2WImpl_QueryInterface,
749 XCAST(AddRef)IDirectInputDevice2AImpl_AddRef,
750 XCAST(Release)IDirectInputDevice2AImpl_Release,
751 XCAST(GetCapabilities)JoystickAGenericImpl_GetCapabilities,
752 IDirectInputDevice2WImpl_EnumObjects,
753 XCAST(GetProperty)JoystickAGenericImpl_GetProperty,
754 XCAST(SetProperty)JoystickAGenericImpl_SetProperty,
755 XCAST(Acquire)JoystickAGenericImpl_Acquire,
756 XCAST(Unacquire)JoystickAGenericImpl_Unacquire,
757 XCAST(GetDeviceState)JoystickAGenericImpl_GetDeviceState,
758 XCAST(GetDeviceData)IDirectInputDevice2AImpl_GetDeviceData,
759 XCAST(SetDataFormat)IDirectInputDevice2AImpl_SetDataFormat,
760 XCAST(SetEventNotification)IDirectInputDevice2AImpl_SetEventNotification,
761 XCAST(SetCooperativeLevel)IDirectInputDevice2AImpl_SetCooperativeLevel,
762 JoystickWGenericImpl_GetObjectInfo,
763 JoystickWGenericImpl_GetDeviceInfo,
764 XCAST(RunControlPanel)IDirectInputDevice2AImpl_RunControlPanel,
765 XCAST(Initialize)IDirectInputDevice2AImpl_Initialize,
766 XCAST(CreateEffect)IDirectInputDevice2AImpl_CreateEffect,
767 IDirectInputDevice2WImpl_EnumEffects,
768 IDirectInputDevice2WImpl_GetEffectInfo,
769 XCAST(GetForceFeedbackState)IDirectInputDevice2AImpl_GetForceFeedbackState,
770 XCAST(SendForceFeedbackCommand)IDirectInputDevice2AImpl_SendForceFeedbackCommand,
771 XCAST(EnumCreatedEffectObjects)IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
772 XCAST(Escape)IDirectInputDevice2AImpl_Escape,
773 XCAST(Poll)JoystickAGenericImpl_Poll,
774 XCAST(SendDeviceData)IDirectInputDevice2AImpl_SendDeviceData,
775 IDirectInputDevice7WImpl_EnumEffectsInFile,
776 IDirectInputDevice7WImpl_WriteEffectToFile,
777 IDirectInputDevice8WImpl_BuildActionMap,
778 IDirectInputDevice8WImpl_SetActionMap,
779 IDirectInputDevice8WImpl_GetImageInfo
783 #else /* HAVE_IOKIT_HID_IOHIDLIB_H */
785 const struct dinput_device joystick_osx_device = {
786 "Wine OS X joystick driver",
793 #endif /* HAVE_IOKIT_HID_IOHIDLIB_H */