blob: 7daccd471ec2f7ed54ef795dca797fb11a4cf896 [file] [log] [blame]
Aric Stewart225a4942009-03-10 14:59:20 -05001/* DirectInput Joystick device for Mac OS/X
2 *
3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998,1999 Lionel Ulmer
5 * Copyright 2000-2001 TransGaming Technologies Inc.
6 * Copyright 2009 CodeWeavers, Aric Stewart
7 *
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.
12 *
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.
17 *
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
21 */
22
23#include "config.h"
24#include "wine/port.h"
25
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>
65#undef LoadResource
66#undef CompareString
67#undef GetCurrentThread
68#undef _CDECL
69#undef DPRINTF
70#undef GetCurrentProcess
71#undef AnimatePalette
72#undef EqualRgn
73#undef FillRgn
74#undef FrameRgn
75#undef GetPixel
76#undef InvertRgn
77#undef LineTo
78#undef OffsetRgn
79#undef PaintRgn
80#undef Polygon
81#undef ResizePalette
82#undef SetRectRgn
83#undef ULONG
84#undef E_INVALIDARG
85#undef E_OUTOFMEMORY
86#undef E_HANDLE
87#undef E_ACCESSDENIED
88#undef E_UNEXPECTED
89#undef E_FAIL
90#undef E_ABORT
91#undef E_POINTER
92#undef E_NOINTERFACE
93#undef E_NOTIMPL
94#undef S_FALSE
95#undef S_OK
96#undef HRESULT_FACILITY
97#undef IS_ERROR
98#undef FAILED
99#undef SUCCEEDED
100#undef MAKE_HRESULT
101#undef HRESULT
102#undef STDMETHODCALLTYPE
103#endif /* HAVE_CARBON_CARBON_H */
104
105#include "wine/debug.h"
106#include "wine/unicode.h"
107#include "windef.h"
108#include "winbase.h"
109#include "winerror.h"
110#include "winreg.h"
111#include "dinput.h"
112
113#include "dinput_private.h"
114#include "device_private.h"
115#include "joystick_private.h"
116
117WINE_DEFAULT_DEBUG_CHANNEL(dinput);
118
Alexandre Julliard81f8c032009-03-11 16:49:55 +0100119#ifdef HAVE_IOHIDMANAGERCREATE
Aric Stewart225a4942009-03-10 14:59:20 -0500120
121static IOHIDManagerRef gIOHIDManagerRef = NULL;
Zach Smithfa5f61f2010-09-20 22:25:27 -0400122static CFArrayRef gCollections = NULL;
Aric Stewart225a4942009-03-10 14:59:20 -0500123
124typedef struct JoystickImpl JoystickImpl;
125static const IDirectInputDevice8AVtbl JoystickAvt;
126static const IDirectInputDevice8WVtbl JoystickWvt;
127
128struct JoystickImpl
129{
130 struct JoystickGenericImpl generic;
131
132 /* osx private */
133 int id;
134 CFMutableArrayRef elementCFArrayRef;
135 ObjProps **propmap;
136};
137
138static const GUID DInput_Wine_OsX_Joystick_GUID = { /* 59CAD8F6-E617-41E2-8EB7-47B23EEEDC5A */
139 0x59CAD8F6, 0xE617, 0x41E2, {0x8E, 0xB7, 0x47, 0xB2, 0x3E, 0xEE, 0xDC, 0x5A}
140};
141
142static void CFSetApplierFunctionCopyToCFArray(const void *value, void *context)
143{
144 CFArrayAppendValue( ( CFMutableArrayRef ) context, value );
145}
146
147static CFMutableDictionaryRef creates_osx_device_match(int usage)
148{
149 CFMutableDictionaryRef result;
150
151 result = CFDictionaryCreateMutable( kCFAllocatorDefault, 0,
152 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks );
153
154 if ( result )
155 {
156 int number = kHIDPage_GenericDesktop;
157 CFNumberRef pageCFNumberRef = CFNumberCreate( kCFAllocatorDefault,
158 kCFNumberIntType, &number);
159
160 if ( pageCFNumberRef )
161 {
162 CFNumberRef usageCFNumberRef;
163
164 CFDictionarySetValue( result, CFSTR( kIOHIDDeviceUsagePageKey ),
165 pageCFNumberRef );
166 CFRelease( pageCFNumberRef );
167
168 usageCFNumberRef = CFNumberCreate( kCFAllocatorDefault,
169 kCFNumberIntType, &usage);
170 if ( usageCFNumberRef )
171 {
172 CFDictionarySetValue( result, CFSTR( kIOHIDDeviceUsageKey ),
173 usageCFNumberRef );
174 CFRelease( usageCFNumberRef );
175 }
176 else
177 {
Francois Gouget40363a22009-03-12 10:10:44 +0100178 ERR("CFNumberCreate() failed.\n");
Aric Stewart225a4942009-03-10 14:59:20 -0500179 return NULL;
180 }
181 }
182 else
183 {
Francois Gouget40363a22009-03-12 10:10:44 +0100184 ERR("CFNumberCreate failed.\n");
Aric Stewart225a4942009-03-10 14:59:20 -0500185 return NULL;
186 }
187 }
188 else
189 {
Francois Gouget40363a22009-03-12 10:10:44 +0100190 ERR("CFDictionaryCreateMutable failed.\n");
Aric Stewart225a4942009-03-10 14:59:20 -0500191 return NULL;
192 }
193
194 return result;
195}
196
Zach Smithfa5f61f2010-09-20 22:25:27 -0400197static CFIndex find_top_level(IOHIDDeviceRef tIOHIDDeviceRef, CFArrayRef topLevels)
198{
199 CFArrayRef gElementCFArrayRef;
200 CFIndex numTops = 0;
201
202 if (!tIOHIDDeviceRef)
203 return 0;
204
205 gElementCFArrayRef = IOHIDDeviceCopyMatchingElements(tIOHIDDeviceRef, NULL, 0);
206
207 if (gElementCFArrayRef)
208 {
209 CFIndex idx, cnt = CFArrayGetCount(gElementCFArrayRef);
210 for (idx=0; idx<cnt; idx++)
211 {
212 IOHIDElementRef tIOHIDElementRef = (IOHIDElementRef)CFArrayGetValueAtIndex(gElementCFArrayRef, idx);
213 int eleType = IOHIDElementGetType(tIOHIDElementRef);
214
215 /* Check for top-level gaming device collections */
216 if (eleType == kIOHIDElementTypeCollection && IOHIDElementGetParent(tIOHIDElementRef) == 0)
217 {
218 int tUsagePage = IOHIDElementGetUsagePage(tIOHIDElementRef);
219 int tUsage = IOHIDElementGetUsage(tIOHIDElementRef);
220
221 if (tUsagePage == kHIDPage_GenericDesktop &&
222 (tUsage == kHIDUsage_GD_Joystick || tUsage == kHIDUsage_GD_GamePad))
223 {
224 CFArrayAppendValue((CFMutableArrayRef)topLevels, tIOHIDElementRef);
225 numTops++;
226 }
227 }
228 }
229 }
230 return numTops;
231}
232
233static void get_element_children(IOHIDElementRef tElement, CFArrayRef childElements)
234{
235 CFIndex idx, cnt;
236 CFArrayRef tElementChildrenArray = IOHIDElementGetChildren(tElement);
237
238 cnt = CFArrayGetCount(tElementChildrenArray);
239 if (cnt < 1)
240 return;
241
242 /* Either add the element to the array or grab its children */
243 for (idx=0; idx<cnt; idx++)
244 {
245 IOHIDElementRef tChildElementRef;
246
247 tChildElementRef = (IOHIDElementRef)CFArrayGetValueAtIndex(tElementChildrenArray, idx);
248 if (IOHIDElementGetType(tChildElementRef) == kIOHIDElementTypeCollection)
249 get_element_children(tChildElementRef, childElements);
250 else
251 CFArrayAppendValue((CFMutableArrayRef)childElements, tChildElementRef);
252 }
253}
254
Aric Stewart225a4942009-03-10 14:59:20 -0500255static int find_osx_devices(void)
256{
257 IOReturn tIOReturn;
258 CFMutableDictionaryRef result;
259 CFSetRef devset;
260 CFArrayRef matching;
261
262 gIOHIDManagerRef = IOHIDManagerCreate( kCFAllocatorDefault, 0L );
263 tIOReturn = IOHIDManagerOpen( gIOHIDManagerRef, 0L);
264 if ( kIOReturnSuccess != tIOReturn )
265 {
Francois Gouget14e03d72009-04-20 15:10:22 +0200266 ERR("Couldn't open IOHIDManager.\n");
Aric Stewart225a4942009-03-10 14:59:20 -0500267 return 0;
268 }
269
270 matching = CFArrayCreateMutable( kCFAllocatorDefault, 0,
271 &kCFTypeArrayCallBacks );
272
273 /* build matching dictionary */
Zach Smithfa5f61f2010-09-20 22:25:27 -0400274 result = creates_osx_device_match(kHIDUsage_GD_Joystick);
Aric Stewart225a4942009-03-10 14:59:20 -0500275 if (!result)
276 {
277 CFRelease(matching);
278 return 0;
279 }
280 CFArrayAppendValue( ( CFMutableArrayRef )matching, result );
Zach Smithfa5f61f2010-09-20 22:25:27 -0400281 result = creates_osx_device_match(kHIDUsage_GD_GamePad);
Aric Stewart225a4942009-03-10 14:59:20 -0500282 if (!result)
283 {
284 CFRelease(matching);
285 return 0;
286 }
287 CFArrayAppendValue( ( CFMutableArrayRef )matching, result );
288
289 IOHIDManagerSetDeviceMatchingMultiple( gIOHIDManagerRef, matching);
290 devset = IOHIDManagerCopyDevices( gIOHIDManagerRef );
291 if (devset)
292 {
Zach Smithfa5f61f2010-09-20 22:25:27 -0400293 CFIndex countDevices, countCollections, idx;
294 CFArrayRef gDevices = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
Aric Stewart225a4942009-03-10 14:59:20 -0500295 CFSetApplyFunction(devset, CFSetApplierFunctionCopyToCFArray, (void*)gDevices);
Aric Stewart225a4942009-03-10 14:59:20 -0500296 CFRelease( devset);
Zach Smithfa5f61f2010-09-20 22:25:27 -0400297 countDevices = CFArrayGetCount(gDevices);
Aric Stewart225a4942009-03-10 14:59:20 -0500298
Zach Smithfa5f61f2010-09-20 22:25:27 -0400299 gCollections = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
300 if (!gCollections)
301 return 0;
Aric Stewart225a4942009-03-10 14:59:20 -0500302
Zach Smithfa5f61f2010-09-20 22:25:27 -0400303 countCollections = 0;
304 for (idx = 0; idx < countDevices; idx++)
305 {
306 CFIndex tTop;
307 IOHIDDeviceRef tDevice;
308
309 tDevice = (IOHIDDeviceRef) CFArrayGetValueAtIndex(gDevices, idx);
310 tTop = find_top_level(tDevice, gCollections);
311 countCollections += tTop;
312 }
313
314 CFRelease(gDevices);
315
316 TRACE("found %i device(s), %i collection(s)\n",(int)countDevices,(int)countCollections);
317 return (int)countCollections;
Aric Stewart225a4942009-03-10 14:59:20 -0500318 }
319 return 0;
320}
321
322static int get_osx_device_name(int id, char *name, int length)
323{
324 CFStringRef str;
Zach Smithfa5f61f2010-09-20 22:25:27 -0400325 IOHIDElementRef tIOHIDElementRef;
Aric Stewart225a4942009-03-10 14:59:20 -0500326 IOHIDDeviceRef tIOHIDDeviceRef;
327
Zach Smithfa5f61f2010-09-20 22:25:27 -0400328 if (!gCollections)
Aric Stewart225a4942009-03-10 14:59:20 -0500329 return 0;
330
Zach Smithfa5f61f2010-09-20 22:25:27 -0400331 tIOHIDElementRef = (IOHIDElementRef)CFArrayGetValueAtIndex(gCollections, id);
332
333 if (!tIOHIDElementRef)
334 {
335 ERR("Invalid Element requested %i\n",id);
336 return 0;
337 }
338
339 tIOHIDDeviceRef = IOHIDElementGetDevice(tIOHIDElementRef);
Aric Stewart225a4942009-03-10 14:59:20 -0500340
Aric Stewart225a4942009-03-10 14:59:20 -0500341 if (name)
342 name[0] = 0;
343
344 if (!tIOHIDDeviceRef)
345 {
346 ERR("Invalid Device requested %i\n",id);
347 return 0;
348 }
349
350 str = IOHIDDeviceGetProperty(tIOHIDDeviceRef, CFSTR( kIOHIDProductKey ));
351 if (str)
352 {
353 CFIndex len = CFStringGetLength(str);
354 if (length >= len)
355 {
356 CFStringGetCString(str,name,length,kCFStringEncodingASCII);
357 return len;
358 }
359 else
360 return (len+1);
361 }
362 return 0;
363}
364
Aric Stewart79859cb2009-03-12 08:03:04 -0500365static void insert_sort_button(int header, IOHIDElementRef tIOHIDElementRef,
366 CFMutableArrayRef elementCFArrayRef, int index,
367 int target)
368{
369 IOHIDElementRef targetElement;
370 int usage;
371
372 CFArraySetValueAtIndex(elementCFArrayRef, header+index, NULL);
373 targetElement = ( IOHIDElementRef ) CFArrayGetValueAtIndex( elementCFArrayRef, header+target);
374 if (targetElement == NULL)
375 {
376 CFArraySetValueAtIndex(elementCFArrayRef, header+target,tIOHIDElementRef);
377 return;
378 }
379 usage = IOHIDElementGetUsage( targetElement );
380 usage --; /* usage 1 based index */
381
382 insert_sort_button(header, targetElement, elementCFArrayRef, target, usage);
383 CFArraySetValueAtIndex(elementCFArrayRef, header+target,tIOHIDElementRef);
384}
385
Aric Stewart08388a32009-03-10 14:59:56 -0500386static void get_osx_device_elements(JoystickImpl *device, int axis_map[8])
Aric Stewart225a4942009-03-10 14:59:20 -0500387{
Zach Smithfa5f61f2010-09-20 22:25:27 -0400388 IOHIDElementRef tIOHIDElementRef;
Aric Stewart225a4942009-03-10 14:59:20 -0500389 CFArrayRef gElementCFArrayRef;
390 DWORD axes = 0;
Aric Stewartae16df62009-03-10 15:00:03 -0500391 DWORD sliders = 0;
Aric Stewart225a4942009-03-10 14:59:20 -0500392 DWORD buttons = 0;
393 DWORD povs = 0;
394
395 device->elementCFArrayRef = NULL;
396
Zach Smithfa5f61f2010-09-20 22:25:27 -0400397 if (!gCollections)
Aric Stewart225a4942009-03-10 14:59:20 -0500398 return;
399
Zach Smithfa5f61f2010-09-20 22:25:27 -0400400 tIOHIDElementRef = (IOHIDElementRef)CFArrayGetValueAtIndex(gCollections, device->id);
Aric Stewart225a4942009-03-10 14:59:20 -0500401
Zach Smithfa5f61f2010-09-20 22:25:27 -0400402 if (!tIOHIDElementRef)
Aric Stewart225a4942009-03-10 14:59:20 -0500403 return;
404
Zach Smithfa5f61f2010-09-20 22:25:27 -0400405 gElementCFArrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
406 get_element_children(tIOHIDElementRef, gElementCFArrayRef);
Aric Stewart225a4942009-03-10 14:59:20 -0500407
408 if (gElementCFArrayRef)
409 {
410 CFIndex idx, cnt = CFArrayGetCount( gElementCFArrayRef );
411 /* build our element array in the order that dinput expects */
412 device->elementCFArrayRef = CFArrayCreateMutable(NULL,0,NULL);
413
414 for ( idx = 0; idx < cnt; idx++ )
415 {
416 IOHIDElementRef tIOHIDElementRef = ( IOHIDElementRef ) CFArrayGetValueAtIndex( gElementCFArrayRef, idx );
417 int eleType = IOHIDElementGetType( tIOHIDElementRef );
418 switch(eleType)
419 {
420 case kIOHIDElementTypeInput_Button:
421 {
Aric Stewart6bbec8e2009-03-11 15:06:31 -0500422 int usagePage = IOHIDElementGetUsagePage( tIOHIDElementRef );
423 if (usagePage != kHIDPage_Button)
424 {
425 /* avoid strange elements found on the 360 controler */
426 continue;
427 }
428
Aric Stewart225a4942009-03-10 14:59:20 -0500429 if (buttons < 128)
430 {
431 CFArrayInsertValueAtIndex(device->elementCFArrayRef, (axes+povs+buttons), tIOHIDElementRef);
432 buttons++;
433 }
434 break;
435 }
Aric Stewart0e7eba12009-03-10 14:59:28 -0500436 case kIOHIDElementTypeInput_Axis:
437 {
438 CFArrayInsertValueAtIndex(device->elementCFArrayRef, axes, tIOHIDElementRef);
439 axes++;
440 break;
441 }
Aric Stewart87d61ab2009-03-10 14:59:35 -0500442 case kIOHIDElementTypeInput_Misc:
443 {
444 uint32_t usage = IOHIDElementGetUsage( tIOHIDElementRef );
445 switch(usage)
446 {
447 case kHIDUsage_GD_Hatswitch:
448 {
449 CFArrayInsertValueAtIndex(device->elementCFArrayRef, (axes+povs), tIOHIDElementRef);
450 povs++;
451 break;
452 }
Aric Stewartae16df62009-03-10 15:00:03 -0500453 case kHIDUsage_GD_Slider:
454 sliders ++;
455 if (sliders > 2)
456 break;
457 /* fallthrough, sliders are axis */
Aric Stewartffbd6a72009-03-10 14:59:41 -0500458 case kHIDUsage_GD_X:
459 case kHIDUsage_GD_Y:
460 case kHIDUsage_GD_Z:
Aric Stewart17daca72009-03-10 14:59:49 -0500461 case kHIDUsage_GD_Rx:
462 case kHIDUsage_GD_Ry:
463 case kHIDUsage_GD_Rz:
Aric Stewartffbd6a72009-03-10 14:59:41 -0500464 {
465 CFArrayInsertValueAtIndex(device->elementCFArrayRef, axes, tIOHIDElementRef);
Aric Stewart08388a32009-03-10 14:59:56 -0500466 axis_map[axes]=usage;
Aric Stewartffbd6a72009-03-10 14:59:41 -0500467 axes++;
468 break;
469 }
Aric Stewart87d61ab2009-03-10 14:59:35 -0500470 default:
471 FIXME("Unhandled usage %i\n",usage);
472 }
473 break;
474 }
Aric Stewart225a4942009-03-10 14:59:20 -0500475 default:
476 FIXME("Unhandled type %i\n",eleType);
477 }
478 }
479 }
480
481 device->generic.devcaps.dwAxes = axes;
482 device->generic.devcaps.dwButtons = buttons;
483 device->generic.devcaps.dwPOVs = povs;
Aric Stewart79859cb2009-03-12 08:03:04 -0500484
485 /* Sort buttons into correct order */
486 for (buttons = 0; buttons < device->generic.devcaps.dwButtons; buttons++)
487 {
488 IOHIDElementRef tIOHIDElementRef = ( IOHIDElementRef ) CFArrayGetValueAtIndex( device->elementCFArrayRef, axes+povs+buttons);
489 uint32_t usage = IOHIDElementGetUsage( tIOHIDElementRef );
490 usage --; /* usage is 1 indexed we need 0 indexed */
491 if (usage == buttons)
492 continue;
493
494 insert_sort_button(axes+povs, tIOHIDElementRef, device->elementCFArrayRef,buttons,usage);
495 }
Aric Stewart225a4942009-03-10 14:59:20 -0500496}
497
498static void get_osx_device_elements_props(JoystickImpl *device)
499{
500 CFArrayRef gElementCFArrayRef = device->elementCFArrayRef;
501
502 if (gElementCFArrayRef)
503 {
504 CFIndex idx, cnt = CFArrayGetCount( gElementCFArrayRef );
505
506 for ( idx = 0; idx < cnt; idx++ )
507 {
508 IOHIDElementRef tIOHIDElementRef = ( IOHIDElementRef ) CFArrayGetValueAtIndex( gElementCFArrayRef, idx );
509
510 device->generic.props[idx].lDevMin = IOHIDElementGetLogicalMin(tIOHIDElementRef);
511 device->generic.props[idx].lDevMax = IOHIDElementGetLogicalMax(tIOHIDElementRef);
512 device->generic.props[idx].lMin = 0;
513 device->generic.props[idx].lMax = 0xffff;
514 device->generic.props[idx].lDeadZone = 0;
515 device->generic.props[idx].lSaturation = 0;
516 }
517 }
518}
519
Vitaliy Margolen7d650d02011-01-03 07:25:11 -0700520static void poll_osx_device_state(LPDIRECTINPUTDEVICE8A iface)
Aric Stewart225a4942009-03-10 14:59:20 -0500521{
Vitaliy Margolen7d650d02011-01-03 07:25:11 -0700522 JoystickImpl *device = (JoystickImpl*)iface;
Zach Smithfa5f61f2010-09-20 22:25:27 -0400523 IOHIDElementRef tIOHIDTopElementRef;
Aric Stewart225a4942009-03-10 14:59:20 -0500524 IOHIDDeviceRef tIOHIDDeviceRef;
525 CFArrayRef gElementCFArrayRef = device->elementCFArrayRef;
526
527 TRACE("polling device %i\n",device->id);
528
Zach Smithfa5f61f2010-09-20 22:25:27 -0400529 if (!gCollections)
Aric Stewart225a4942009-03-10 14:59:20 -0500530 return;
531
Zach Smithfa5f61f2010-09-20 22:25:27 -0400532 tIOHIDTopElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(gCollections, device->id);
533 tIOHIDDeviceRef = IOHIDElementGetDevice(tIOHIDTopElementRef);
Aric Stewart225a4942009-03-10 14:59:20 -0500534
535 if (!tIOHIDDeviceRef)
536 return;
537
538 if (gElementCFArrayRef)
539 {
540 int button_idx = 0;
Aric Stewart87d61ab2009-03-10 14:59:35 -0500541 int pov_idx = 0;
Aric Stewartae16df62009-03-10 15:00:03 -0500542 int slider_idx = 0;
Aric Stewart225a4942009-03-10 14:59:20 -0500543 CFIndex idx, cnt = CFArrayGetCount( gElementCFArrayRef );
544
545 for ( idx = 0; idx < cnt; idx++ )
546 {
547 IOHIDValueRef valueRef;
548 int val;
549 IOHIDElementRef tIOHIDElementRef = ( IOHIDElementRef ) CFArrayGetValueAtIndex( gElementCFArrayRef, idx );
550 int eleType = IOHIDElementGetType( tIOHIDElementRef );
551
552 switch(eleType)
553 {
554 case kIOHIDElementTypeInput_Button:
555 if(button_idx < 128)
556 {
557 IOHIDDeviceGetValue(tIOHIDDeviceRef, tIOHIDElementRef, &valueRef);
558 val = IOHIDValueGetIntegerValue(valueRef);
559 device->generic.js.rgbButtons[button_idx] = val ? 0x80 : 0x00;
560 button_idx ++;
561 }
562 break;
Aric Stewart87d61ab2009-03-10 14:59:35 -0500563 case kIOHIDElementTypeInput_Misc:
564 {
565 uint32_t usage = IOHIDElementGetUsage( tIOHIDElementRef );
566 switch(usage)
567 {
568 case kHIDUsage_GD_Hatswitch:
569 {
570 IOHIDDeviceGetValue(tIOHIDDeviceRef, tIOHIDElementRef, &valueRef);
571 val = IOHIDValueGetIntegerValue(valueRef);
572 if (val >= 8)
573 device->generic.js.rgdwPOV[pov_idx] = -1;
574 else
575 device->generic.js.rgdwPOV[pov_idx] = val * 4500;
576 pov_idx ++;
577 break;
578 }
Aric Stewartffbd6a72009-03-10 14:59:41 -0500579 case kHIDUsage_GD_X:
580 case kHIDUsage_GD_Y:
581 case kHIDUsage_GD_Z:
Aric Stewart17daca72009-03-10 14:59:49 -0500582 case kHIDUsage_GD_Rx:
583 case kHIDUsage_GD_Ry:
584 case kHIDUsage_GD_Rz:
Aric Stewartae16df62009-03-10 15:00:03 -0500585 case kHIDUsage_GD_Slider:
Aric Stewartffbd6a72009-03-10 14:59:41 -0500586 {
587 IOHIDDeviceGetValue(tIOHIDDeviceRef, tIOHIDElementRef, &valueRef);
588 val = IOHIDValueGetIntegerValue(valueRef);
589 switch (usage)
590 {
591 case kHIDUsage_GD_X:
592 device->generic.js.lX = joystick_map_axis(&device->generic.props[idx], val);
593 break;
594 case kHIDUsage_GD_Y:
595 device->generic.js.lY = joystick_map_axis(&device->generic.props[idx], val);
596 break;
597 case kHIDUsage_GD_Z:
598 device->generic.js.lZ = joystick_map_axis(&device->generic.props[idx], val);
599 break;
Aric Stewart17daca72009-03-10 14:59:49 -0500600 case kHIDUsage_GD_Rx:
601 device->generic.js.lRx = joystick_map_axis(&device->generic.props[idx], val);
602 break;
603 case kHIDUsage_GD_Ry:
604 device->generic.js.lRy = joystick_map_axis(&device->generic.props[idx], val);
605 break;
606 case kHIDUsage_GD_Rz:
607 device->generic.js.lRz = joystick_map_axis(&device->generic.props[idx], val);
608 break;
Aric Stewartae16df62009-03-10 15:00:03 -0500609 case kHIDUsage_GD_Slider:
610 device->generic.js.rglSlider[slider_idx] = joystick_map_axis(&device->generic.props[idx], val);
611 slider_idx ++;
612 break;
Aric Stewartffbd6a72009-03-10 14:59:41 -0500613 }
614 break;
615 }
Aric Stewart87d61ab2009-03-10 14:59:35 -0500616 default:
617 FIXME("unhandled usage %i\n",usage);
618 }
619 break;
620 }
Aric Stewart225a4942009-03-10 14:59:20 -0500621 default:
622 FIXME("Unhandled type %i\n",eleType);
623 }
624 }
625 }
626}
627
628static INT find_joystick_devices(void)
629{
630 static INT joystick_devices_count = -1;
631
632 if (joystick_devices_count != -1) return joystick_devices_count;
633
634 joystick_devices_count = find_osx_devices();
635
636 return joystick_devices_count;
637}
638
639static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
640{
641 if (id >= find_joystick_devices()) return FALSE;
642
643 if (dwFlags & DIEDFL_FORCEFEEDBACK) {
644 WARN("force feedback not supported\n");
645 return FALSE;
646 }
647
648 if ((dwDevType == 0) ||
649 ((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) ||
650 (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800)))
651 {
652 /* Return joystick */
653 lpddi->guidInstance = DInput_Wine_OsX_Joystick_GUID;
654 lpddi->guidInstance.Data3 = id;
655 lpddi->guidProduct = DInput_Wine_OsX_Joystick_GUID;
656 /* we only support traditional joysticks for now */
657 if (version >= 0x0800)
658 lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
659 else
660 lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
661 sprintf(lpddi->tszInstanceName, "Joystick %d", id);
662
663 /* get the device name */
664 get_osx_device_name(id, lpddi->tszProductName, MAX_PATH);
665
666 lpddi->guidFFDriver = GUID_NULL;
667 return TRUE;
668 }
669
670 return FALSE;
671}
672
673static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
674{
675 char name[MAX_PATH];
676 char friendly[32];
677
678 if (id >= find_joystick_devices()) return FALSE;
679
680 if (dwFlags & DIEDFL_FORCEFEEDBACK) {
681 WARN("force feedback not supported\n");
682 return FALSE;
683 }
684
685 if ((dwDevType == 0) ||
686 ((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) ||
687 (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))) {
688 /* Return joystick */
689 lpddi->guidInstance = DInput_Wine_OsX_Joystick_GUID;
690 lpddi->guidInstance.Data3 = id;
691 lpddi->guidProduct = DInput_Wine_OsX_Joystick_GUID;
692 /* we only support traditional joysticks for now */
693 if (version >= 0x0800)
694 lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
695 else
696 lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
697 sprintf(friendly, "Joystick %d", id);
698 MultiByteToWideChar(CP_ACP, 0, friendly, -1, lpddi->tszInstanceName, MAX_PATH);
699 /* get the device name */
700 get_osx_device_name(id, name, MAX_PATH);
701
702 MultiByteToWideChar(CP_ACP, 0, name, -1, lpddi->tszProductName, MAX_PATH);
703 lpddi->guidFFDriver = GUID_NULL;
704 return TRUE;
705 }
706
707 return FALSE;
708}
709
710static HRESULT alloc_device(REFGUID rguid, const void *jvt, IDirectInputImpl *dinput,
711 LPDIRECTINPUTDEVICEA* pdev, unsigned short index)
712{
713 DWORD i;
714 JoystickImpl* newDevice;
715 char name[MAX_PATH];
716 HRESULT hr;
717 LPDIDATAFORMAT df = NULL;
718 int idx = 0;
Aric Stewart08388a32009-03-10 14:59:56 -0500719 int axis_map[8]; /* max axes */
Aric Stewartae16df62009-03-10 15:00:03 -0500720 int slider_count = 0;
Aric Stewart225a4942009-03-10 14:59:20 -0500721
722 TRACE("%s %p %p %p %hu\n", debugstr_guid(rguid), jvt, dinput, pdev, index);
723
724 newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickImpl));
725 if (newDevice == 0) {
726 WARN("out of memory\n");
727 *pdev = 0;
728 return DIERR_OUTOFMEMORY;
729 }
730
731 newDevice->id = index;
732
Vitaliy Margolenfc4f1602009-04-19 20:33:22 -0600733 newDevice->generic.guidInstance = DInput_Wine_OsX_Joystick_GUID;
734 newDevice->generic.guidInstance.Data3 = index;
Aric Stewart225a4942009-03-10 14:59:20 -0500735 newDevice->generic.guidProduct = DInput_Wine_OsX_Joystick_GUID;
736 newDevice->generic.joy_polldev = poll_osx_device_state;
737
738 /* get the device name */
739 get_osx_device_name(index, name, MAX_PATH);
740 TRACE("Name %s\n",name);
741
742 /* copy the device name */
743 newDevice->generic.name = HeapAlloc(GetProcessHeap(),0,strlen(name) + 1);
744 strcpy(newDevice->generic.name, name);
745
Aric Stewart08388a32009-03-10 14:59:56 -0500746 memset(axis_map, 0, sizeof(axis_map));
747 get_osx_device_elements(newDevice, axis_map);
Aric Stewart225a4942009-03-10 14:59:20 -0500748
749 TRACE("%i axes %i buttons %i povs\n",newDevice->generic.devcaps.dwAxes,newDevice->generic.devcaps.dwButtons,newDevice->generic.devcaps.dwPOVs);
750
751 if (newDevice->generic.devcaps.dwButtons > 128)
752 {
753 WARN("Can't support %d buttons. Clamping down to 128\n", newDevice->generic.devcaps.dwButtons);
754 newDevice->generic.devcaps.dwButtons = 128;
755 }
756
757 newDevice->generic.base.lpVtbl = jvt;
758 newDevice->generic.base.ref = 1;
759 newDevice->generic.base.dinput = dinput;
760 newDevice->generic.base.guid = *rguid;
761 InitializeCriticalSection(&newDevice->generic.base.crit);
762 newDevice->generic.base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JoystickImpl*->generic.base.crit");
763
764 /* Create copy of default data format */
765 if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIJoystick2.dwSize))) goto FAILED;
766 memcpy(df, &c_dfDIJoystick2, c_dfDIJoystick2.dwSize);
767
768 df->dwNumObjs = newDevice->generic.devcaps.dwAxes + newDevice->generic.devcaps.dwPOVs + newDevice->generic.devcaps.dwButtons;
769 if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto FAILED;
770
771 for (i = 0; i < newDevice->generic.devcaps.dwAxes; i++)
772 {
Aric Stewart08388a32009-03-10 14:59:56 -0500773 int wine_obj = -1;
774 switch (axis_map[i])
775 {
776 case kHIDUsage_GD_X: wine_obj = 0; break;
777 case kHIDUsage_GD_Y: wine_obj = 1; break;
778 case kHIDUsage_GD_Z: wine_obj = 2; break;
779 case kHIDUsage_GD_Rx: wine_obj = 3; break;
780 case kHIDUsage_GD_Ry: wine_obj = 4; break;
781 case kHIDUsage_GD_Rz: wine_obj = 5; break;
Aric Stewartae16df62009-03-10 15:00:03 -0500782 case kHIDUsage_GD_Slider:
783 wine_obj = 6 + slider_count;
784 slider_count++;
785 break;
Aric Stewart08388a32009-03-10 14:59:56 -0500786 }
787 if (wine_obj < 0 ) continue;
788
789 memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[wine_obj], df->dwObjSize);
790 df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(wine_obj) | DIDFT_ABSAXIS;
Aric Stewart225a4942009-03-10 14:59:20 -0500791 }
792
793 for (i = 0; i < newDevice->generic.devcaps.dwPOVs; i++)
794 {
795 memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i + 8], df->dwObjSize);
796 df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_POV;
797 }
798
799 for (i = 0; i < newDevice->generic.devcaps.dwButtons; i++)
800 {
801 memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i + 12], df->dwObjSize);
802 df->rgodf[idx ].pguid = &GUID_Button;
803 df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_PSHBUTTON;
804 }
805 newDevice->generic.base.data_format.wine_df = df;
806
Aric Stewart225a4942009-03-10 14:59:20 -0500807 /* initialize default properties */
808 get_osx_device_elements_props(newDevice);
809
Vitaliy Margolen15216092011-01-09 15:43:09 -0700810 IDirectInput_AddRef(&newDevice->generic.base.dinput->IDirectInput7A_iface);
Aric Stewart225a4942009-03-10 14:59:20 -0500811
812 newDevice->generic.devcaps.dwSize = sizeof(newDevice->generic.devcaps);
813 newDevice->generic.devcaps.dwFlags = DIDC_ATTACHED;
814 if (newDevice->generic.base.dinput->dwVersion >= 0x0800)
815 newDevice->generic.devcaps.dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
816 else
817 newDevice->generic.devcaps.dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
818 newDevice->generic.devcaps.dwFFSamplePeriod = 0;
819 newDevice->generic.devcaps.dwFFMinTimeResolution = 0;
820 newDevice->generic.devcaps.dwFirmwareRevision = 0;
821 newDevice->generic.devcaps.dwHardwareRevision = 0;
822 newDevice->generic.devcaps.dwFFDriverVersion = 0;
823
824 if (TRACE_ON(dinput)) {
825 _dump_DIDATAFORMAT(newDevice->generic.base.data_format.wine_df);
826 _dump_DIDEVCAPS(&newDevice->generic.devcaps);
827 }
828
829 *pdev = (LPDIRECTINPUTDEVICEA)newDevice;
830
831 return DI_OK;
832
833FAILED:
834 hr = DIERR_OUTOFMEMORY;
835 if (df) HeapFree(GetProcessHeap(), 0, df->rgodf);
836 HeapFree(GetProcessHeap(), 0, df);
837 release_DataFormat(&newDevice->generic.base.data_format);
838 HeapFree(GetProcessHeap(),0,newDevice->generic.name);
Aric Stewart225a4942009-03-10 14:59:20 -0500839 HeapFree(GetProcessHeap(),0,newDevice);
840 *pdev = 0;
841
842 return hr;
843}
844
845/******************************************************************************
846 * get_joystick_index : Get the joystick index from a given GUID
847 */
848static unsigned short get_joystick_index(REFGUID guid)
849{
850 GUID wine_joystick = DInput_Wine_OsX_Joystick_GUID;
851 GUID dev_guid = *guid;
852
853 wine_joystick.Data3 = 0;
854 dev_guid.Data3 = 0;
855
856 /* for the standard joystick GUID use index 0 */
857 if(IsEqualGUID(&GUID_Joystick,guid)) return 0;
858
859 /* for the wine joystick GUIDs use the index stored in Data3 */
860 if(IsEqualGUID(&wine_joystick, &dev_guid)) return guid->Data3;
861
862 return 0xffff;
863}
864
865static HRESULT joydev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev)
866{
867 unsigned short index;
868 int joystick_devices_count;
869
870 TRACE("%p %s %p %p\n",dinput, debugstr_guid(rguid), riid, pdev);
871 *pdev = NULL;
872
873 if ((joystick_devices_count = find_joystick_devices()) == 0)
874 return DIERR_DEVICENOTREG;
875
876 if ((index = get_joystick_index(rguid)) < 0xffff &&
877 joystick_devices_count && index < joystick_devices_count)
878 {
879 if ((riid == NULL) ||
880 IsEqualGUID(&IID_IDirectInputDeviceA, riid) ||
881 IsEqualGUID(&IID_IDirectInputDevice2A, riid) ||
882 IsEqualGUID(&IID_IDirectInputDevice7A, riid) ||
883 IsEqualGUID(&IID_IDirectInputDevice8A, riid))
884 {
885 return alloc_device(rguid, &JoystickAvt, dinput, pdev, index);
886 }
887
888 WARN("no interface\n");
889 return DIERR_NOINTERFACE;
890 }
891
892 return DIERR_DEVICENOTREG;
893}
894
895static HRESULT joydev_create_deviceW(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev)
896{
897 unsigned short index;
898 int joystick_devices_count;
899
900 TRACE("%p %s %p %p\n",dinput, debugstr_guid(rguid), riid, pdev);
901 *pdev = NULL;
902
903 if ((joystick_devices_count = find_joystick_devices()) == 0)
904 return DIERR_DEVICENOTREG;
905
906 if ((index = get_joystick_index(rguid)) < 0xffff &&
907 joystick_devices_count && index < joystick_devices_count)
908 {
909 if ((riid == NULL) ||
910 IsEqualGUID(&IID_IDirectInputDeviceW, riid) ||
911 IsEqualGUID(&IID_IDirectInputDevice2W, riid) ||
912 IsEqualGUID(&IID_IDirectInputDevice7W, riid) ||
913 IsEqualGUID(&IID_IDirectInputDevice8W, riid))
914 {
915 return alloc_device(rguid, &JoystickWvt, dinput, (LPDIRECTINPUTDEVICEA *)pdev, index);
916 }
917 WARN("no interface\n");
918 return DIERR_NOINTERFACE;
919 }
920
921 WARN("invalid device GUID %s\n",debugstr_guid(rguid));
922 return DIERR_DEVICENOTREG;
923}
924
925const struct dinput_device joystick_osx_device = {
926 "Wine OS X joystick driver",
927 joydev_enum_deviceA,
928 joydev_enum_deviceW,
929 joydev_create_deviceA,
930 joydev_create_deviceW
931};
932
933static const IDirectInputDevice8AVtbl JoystickAvt =
934{
935 IDirectInputDevice2AImpl_QueryInterface,
936 IDirectInputDevice2AImpl_AddRef,
937 IDirectInputDevice2AImpl_Release,
938 JoystickAGenericImpl_GetCapabilities,
939 IDirectInputDevice2AImpl_EnumObjects,
940 JoystickAGenericImpl_GetProperty,
941 JoystickAGenericImpl_SetProperty,
Vitaliy Margolenaee42372009-04-19 20:33:25 -0600942 IDirectInputDevice2AImpl_Acquire,
943 IDirectInputDevice2AImpl_Unacquire,
Aric Stewart225a4942009-03-10 14:59:20 -0500944 JoystickAGenericImpl_GetDeviceState,
945 IDirectInputDevice2AImpl_GetDeviceData,
946 IDirectInputDevice2AImpl_SetDataFormat,
947 IDirectInputDevice2AImpl_SetEventNotification,
948 IDirectInputDevice2AImpl_SetCooperativeLevel,
949 JoystickAGenericImpl_GetObjectInfo,
950 JoystickAGenericImpl_GetDeviceInfo,
951 IDirectInputDevice2AImpl_RunControlPanel,
952 IDirectInputDevice2AImpl_Initialize,
953 IDirectInputDevice2AImpl_CreateEffect,
954 IDirectInputDevice2AImpl_EnumEffects,
955 IDirectInputDevice2AImpl_GetEffectInfo,
956 IDirectInputDevice2AImpl_GetForceFeedbackState,
957 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
958 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
959 IDirectInputDevice2AImpl_Escape,
960 JoystickAGenericImpl_Poll,
961 IDirectInputDevice2AImpl_SendDeviceData,
962 IDirectInputDevice7AImpl_EnumEffectsInFile,
963 IDirectInputDevice7AImpl_WriteEffectToFile,
964 IDirectInputDevice8AImpl_BuildActionMap,
965 IDirectInputDevice8AImpl_SetActionMap,
966 IDirectInputDevice8AImpl_GetImageInfo
967};
968
969#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
970# define XCAST(fun) (typeof(JoystickWvt.fun))
971#else
972# define XCAST(fun) (void*)
973#endif
974
975static const IDirectInputDevice8WVtbl JoystickWvt =
976{
977 IDirectInputDevice2WImpl_QueryInterface,
978 XCAST(AddRef)IDirectInputDevice2AImpl_AddRef,
979 XCAST(Release)IDirectInputDevice2AImpl_Release,
980 XCAST(GetCapabilities)JoystickAGenericImpl_GetCapabilities,
981 IDirectInputDevice2WImpl_EnumObjects,
982 XCAST(GetProperty)JoystickAGenericImpl_GetProperty,
983 XCAST(SetProperty)JoystickAGenericImpl_SetProperty,
Vitaliy Margolenaee42372009-04-19 20:33:25 -0600984 XCAST(Acquire)IDirectInputDevice2AImpl_Acquire,
985 XCAST(Unacquire)IDirectInputDevice2AImpl_Unacquire,
Aric Stewart225a4942009-03-10 14:59:20 -0500986 XCAST(GetDeviceState)JoystickAGenericImpl_GetDeviceState,
987 XCAST(GetDeviceData)IDirectInputDevice2AImpl_GetDeviceData,
988 XCAST(SetDataFormat)IDirectInputDevice2AImpl_SetDataFormat,
989 XCAST(SetEventNotification)IDirectInputDevice2AImpl_SetEventNotification,
990 XCAST(SetCooperativeLevel)IDirectInputDevice2AImpl_SetCooperativeLevel,
991 JoystickWGenericImpl_GetObjectInfo,
992 JoystickWGenericImpl_GetDeviceInfo,
993 XCAST(RunControlPanel)IDirectInputDevice2AImpl_RunControlPanel,
994 XCAST(Initialize)IDirectInputDevice2AImpl_Initialize,
995 XCAST(CreateEffect)IDirectInputDevice2AImpl_CreateEffect,
996 IDirectInputDevice2WImpl_EnumEffects,
997 IDirectInputDevice2WImpl_GetEffectInfo,
998 XCAST(GetForceFeedbackState)IDirectInputDevice2AImpl_GetForceFeedbackState,
999 XCAST(SendForceFeedbackCommand)IDirectInputDevice2AImpl_SendForceFeedbackCommand,
1000 XCAST(EnumCreatedEffectObjects)IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
1001 XCAST(Escape)IDirectInputDevice2AImpl_Escape,
1002 XCAST(Poll)JoystickAGenericImpl_Poll,
1003 XCAST(SendDeviceData)IDirectInputDevice2AImpl_SendDeviceData,
1004 IDirectInputDevice7WImpl_EnumEffectsInFile,
1005 IDirectInputDevice7WImpl_WriteEffectToFile,
1006 IDirectInputDevice8WImpl_BuildActionMap,
1007 IDirectInputDevice8WImpl_SetActionMap,
1008 IDirectInputDevice8WImpl_GetImageInfo
1009};
1010#undef XCAST
1011
Alexandre Julliard81f8c032009-03-11 16:49:55 +01001012#else /* HAVE_IOHIDMANAGERCREATE */
Aric Stewart225a4942009-03-10 14:59:20 -05001013
1014const struct dinput_device joystick_osx_device = {
1015 "Wine OS X joystick driver",
1016 NULL,
1017 NULL,
1018 NULL,
1019 NULL
1020};
1021
Alexandre Julliard81f8c032009-03-11 16:49:55 +01001022#endif /* HAVE_IOHIDMANAGERCREATE */