pcsxr-1.9.92
[pcsx_rearmed.git] / macosx / plugins / DFInput / SDL / src / joystick / darwin / SDL_sysjoystick.c
CommitLineData
ef79bbde
P
1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2010 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21*/
22#include "SDL_config.h"
23
24#ifdef SDL_JOYSTICK_IOKIT
25
26/* SDL joystick driver for Darwin / Mac OS X, based on the IOKit HID API */
27/* Written 2001 by Max Horn */
28
29#include <unistd.h>
30#include <ctype.h>
31#include <sysexits.h>
32#include <mach/mach.h>
33#include <mach/mach_error.h>
34#include <IOKit/IOKitLib.h>
35#include <IOKit/IOCFPlugIn.h>
36#ifdef MACOS_10_0_4
37#include <IOKit/hidsystem/IOHIDUsageTables.h>
38#else
39/* The header was moved here in Mac OS X 10.1 */
40#include <Kernel/IOKit/hidsystem/IOHIDUsageTables.h>
41#endif
42#include <IOKit/hid/IOHIDLib.h>
43#include <IOKit/hid/IOHIDKeys.h>
44#include <CoreFoundation/CoreFoundation.h>
45#include <Carbon/Carbon.h> /* for NewPtrClear, DisposePtr */
46
47/* For force feedback testing. */
48#include <ForceFeedback/ForceFeedback.h>
49#include <ForceFeedback/ForceFeedbackConstants.h>
50
51#include "SDL_joystick.h"
52#include "../SDL_sysjoystick.h"
53#include "../SDL_joystick_c.h"
54#include "SDL_sysjoystick_c.h"
55
56
57/* Linked list of all available devices */
58static recDevice *gpDeviceList = NULL;
59
60
61static void
62HIDReportErrorNum(char *strError, long numError)
63{
64 SDL_SetError(strError);
65}
66
67static void HIDGetCollectionElements(CFMutableDictionaryRef deviceProperties,
68 recDevice * pDevice);
69
70/* returns current value for element, polling element
71 * will return 0 on error conditions which should be accounted for by application
72 */
73
74static SInt32
75HIDGetElementValue(recDevice * pDevice, recElement * pElement)
76{
77 IOReturn result = kIOReturnSuccess;
78 IOHIDEventStruct hidEvent;
79 hidEvent.value = 0;
80
81 if (NULL != pDevice && NULL != pElement && NULL != pDevice->interface) {
82 result =
83 (*(pDevice->interface))->getElementValue(pDevice->interface,
84 pElement->cookie,
85 &hidEvent);
86 if (kIOReturnSuccess == result) {
87 /* record min and max for auto calibration */
88 if (hidEvent.value < pElement->minReport)
89 pElement->minReport = hidEvent.value;
90 if (hidEvent.value > pElement->maxReport)
91 pElement->maxReport = hidEvent.value;
92 }
93 }
94
95 /* auto user scale */
96 return hidEvent.value;
97}
98
99static SInt32
100HIDScaledCalibratedValue(recDevice * pDevice, recElement * pElement,
101 long min, long max)
102{
103 float deviceScale = max - min;
104 float readScale = pElement->maxReport - pElement->minReport;
105 SInt32 value = HIDGetElementValue(pDevice, pElement);
106 if (readScale == 0)
107 return value; /* no scaling at all */
108 else
109 return ((value - pElement->minReport) * deviceScale / readScale) +
110 min;
111}
112
113
114static void
115HIDRemovalCallback(void *target, IOReturn result, void *refcon, void *sender)
116{
117 recDevice *device = (recDevice *) refcon;
118 device->removed = 1;
119 device->uncentered = 1;
120}
121
122
123
124/* Create and open an interface to device, required prior to extracting values or building queues.
125 * Note: appliction now owns the device and must close and release it prior to exiting
126 */
127
128static IOReturn
129HIDCreateOpenDeviceInterface(io_object_t hidDevice, recDevice * pDevice)
130{
131 IOReturn result = kIOReturnSuccess;
132 HRESULT plugInResult = S_OK;
133 SInt32 score = 0;
134 IOCFPlugInInterface **ppPlugInInterface = NULL;
135
136 if (NULL == pDevice->interface) {
137 result =
138 IOCreatePlugInInterfaceForService(hidDevice,
139 kIOHIDDeviceUserClientTypeID,
140 kIOCFPlugInInterfaceID,
141 &ppPlugInInterface, &score);
142 if (kIOReturnSuccess == result) {
143 /* Call a method of the intermediate plug-in to create the device interface */
144 plugInResult =
145 (*ppPlugInInterface)->QueryInterface(ppPlugInInterface,
146 CFUUIDGetUUIDBytes
147 (kIOHIDDeviceInterfaceID),
148 (void *)
149 &(pDevice->interface));
150 if (S_OK != plugInResult)
151 HIDReportErrorNum
152