src/joystick/darwin/SDL_sysjoystick.c
changeset 1487 dc6b59e925a2
parent 1409 ebc8b5855040
child 1496 405e20dc004c
equal deleted inserted replaced
1486:9d77fc9d0ace 1487:dc6b59e925a2
    46 #include "../SDL_sysjoystick.h"
    46 #include "../SDL_sysjoystick.h"
    47 #include "../SDL_joystick_c.h"
    47 #include "../SDL_joystick_c.h"
    48 
    48 
    49 struct recElement
    49 struct recElement
    50 {
    50 {
    51 	IOHIDElementCookie cookie;				// unique value which identifies element, will NOT change
    51 	IOHIDElementCookie cookie;				/* unique value which identifies element, will NOT change */
    52 	long min;								// reported min value possible
    52 	long min;								/* reported min value possible */
    53 	long max;								// reported max value possible
    53 	long max;								/* reported max value possible */
    54 /*
    54 #if 0
    55 	TODO: maybe should handle the following stuff somehow?
    55 	/* TODO: maybe should handle the following stuff somehow? */
    56 
    56 
    57 	long scaledMin;							// reported scaled min value possible
    57 	long scaledMin;							/* reported scaled min value possible */
    58 	long scaledMax;							// reported scaled max value possible
    58 	long scaledMax;							/* reported scaled max value possible */
    59 	long size;								// size in bits of data return from element
    59 	long size;								/* size in bits of data return from element */
    60 	Boolean relative;						// are reports relative to last report (deltas)
    60 	Boolean relative;						/* are reports relative to last report (deltas) */
    61 	Boolean wrapping;						// does element wrap around (one value higher than max is min)
    61 	Boolean wrapping;						/* does element wrap around (one value higher than max is min) */
    62 	Boolean nonLinear;						// are the values reported non-linear relative to element movement
    62 	Boolean nonLinear;						/* are the values reported non-linear relative to element movement */
    63 	Boolean preferredState;					// does element have a preferred state (such as a button)
    63 	Boolean preferredState;					/* does element have a preferred state (such as a button) */
    64 	Boolean nullState;						// does element have null state
    64 	Boolean nullState;						/* does element have null state */
    65 */
    65 #endif /* 0 */
    66 
    66 
    67 	/* runtime variables used for auto-calibration */
    67 	/* runtime variables used for auto-calibration */
    68 	long minReport;							// min returned value
    68 	long minReport;							/* min returned value */
    69 	long maxReport;							// max returned value
    69 	long maxReport;							/* max returned value */
    70 	
    70 	
    71 	struct recElement * pNext;				// next element in list
    71 	struct recElement * pNext;				/* next element in list */
    72 };
    72 };
    73 typedef struct recElement recElement;
    73 typedef struct recElement recElement;
    74 
    74 
    75 struct joystick_hwdata
    75 struct joystick_hwdata
    76 {
    76 {
    77 	IOHIDDeviceInterface ** interface;		// interface to device, NULL = no interface
    77 	IOHIDDeviceInterface ** interface;		/* interface to device, NULL = no interface */
    78 
    78 
    79 	char product[256];							// name of product
    79 	char product[256];							/* name of product */
    80 	long usage;								// usage page from IOUSBHID Parser.h which defines general usage
    80 	long usage;								/* usage page from IOUSBHID Parser.h which defines general usage */
    81 	long usagePage;							// usage within above page from IOUSBHID Parser.h which defines specific usage
    81 	long usagePage;							/* usage within above page from IOUSBHID Parser.h which defines specific usage */
    82 
    82 
    83 	long axes;								// number of axis (calculated, not reported by device)
    83 	long axes;								/* number of axis (calculated, not reported by device) */
    84 	long buttons;							// number of buttons (calculated, not reported by device)
    84 	long buttons;							/* number of buttons (calculated, not reported by device) */
    85 	long hats;								// number of hat switches (calculated, not reported by device)
    85 	long hats;								/* number of hat switches (calculated, not reported by device) */
    86 	long elements;							// number of total elements (shouldbe total of above) (calculated, not reported by device)
    86 	long elements;							/* number of total elements (shouldbe total of above) (calculated, not reported by device) */
    87 
    87 
    88 	recElement* firstAxis;
    88 	recElement* firstAxis;
    89 	recElement* firstButton;
    89 	recElement* firstButton;
    90 	recElement* firstHat;
    90 	recElement* firstHat;
    91 
    91 
    92 	int removed;
    92 	int removed;
    93 	int uncentered;
    93 	int uncentered;
    94 
    94 
    95 	struct joystick_hwdata* pNext;			// next device
    95 	struct joystick_hwdata* pNext;			/* next device */
    96 };
    96 };
    97 typedef struct joystick_hwdata recDevice;
    97 typedef struct joystick_hwdata recDevice;
    98 
    98 
    99 
    99 
   100 /* Linked list of all available devices */
   100 /* Linked list of all available devices */
   129 			if (hidEvent.value > pElement->maxReport)
   129 			if (hidEvent.value > pElement->maxReport)
   130 				pElement->maxReport = hidEvent.value;
   130 				pElement->maxReport = hidEvent.value;
   131 		}
   131 		}
   132 	}
   132 	}
   133 
   133 
   134 	// auto user scale
   134 	/* auto user scale */
   135 	return hidEvent.value;
   135 	return hidEvent.value;
   136 }
   136 }
   137 
       
   138 /* similiar to HIDGetElementValue, but auto-calibrates the value before returning it */
       
   139 
       
   140 static SInt32 HIDCalibratedValue (recDevice *pDevice, recElement *pElement)
       
   141 {
       
   142 	float deviceScale = pElement->max - pElement->min;
       
   143 	float readScale = pElement->maxReport - pElement->minReport;
       
   144 	SInt32 value = HIDGetElementValue(pDevice, pElement);
       
   145 	if (readScale == 0)
       
   146 		return value; // no scaling at all
       
   147 	else
       
   148 		return ((value - pElement->minReport) * deviceScale / readScale) + pElement->min;
       
   149 }
       
   150 
       
   151 /* similiar to HIDCalibratedValue but calibrates to an arbitrary scale instead of the elements default scale */
       
   152 
   137 
   153 static SInt32 HIDScaledCalibratedValue (recDevice *pDevice, recElement *pElement, long min, long max)
   138 static SInt32 HIDScaledCalibratedValue (recDevice *pDevice, recElement *pElement, long min, long max)
   154 {
   139 {
   155 	float deviceScale = max - min;
   140 	float deviceScale = max - min;
   156 	float readScale = pElement->maxReport - pElement->minReport;
   141 	float readScale = pElement->maxReport - pElement->minReport;
   157 	SInt32 value = HIDGetElementValue(pDevice, pElement);
   142 	SInt32 value = HIDGetElementValue(pDevice, pElement);
   158 	if (readScale == 0)
   143 	if (readScale == 0)
   159 		return value; // no scaling at all
   144 		return value; /* no scaling at all */
   160 	else
   145 	else
   161 		return ((value - pElement->minReport) * deviceScale / readScale) + min;
   146 		return ((value - pElement->minReport) * deviceScale / readScale) + min;
   162 }
   147 }
   163 
   148 
   164 
   149 
   189 	{
   174 	{
   190 		result = IOCreatePlugInInterfaceForService (hidDevice, kIOHIDDeviceUserClientTypeID,
   175 		result = IOCreatePlugInInterfaceForService (hidDevice, kIOHIDDeviceUserClientTypeID,
   191 													kIOCFPlugInInterfaceID, &ppPlugInInterface, &score);
   176 													kIOCFPlugInInterfaceID, &ppPlugInInterface, &score);
   192 		if (kIOReturnSuccess == result)
   177 		if (kIOReturnSuccess == result)
   193 		{
   178 		{
   194 			// Call a method of the intermediate plug-in to create the device interface
   179 			/* Call a method of the intermediate plug-in to create the device interface */
   195 			plugInResult = (*ppPlugInInterface)->QueryInterface (ppPlugInInterface,
   180 			plugInResult = (*ppPlugInInterface)->QueryInterface (ppPlugInInterface,
   196 								CFUUIDGetUUIDBytes (kIOHIDDeviceInterfaceID), (void *) &(pDevice->interface));
   181 								CFUUIDGetUUIDBytes (kIOHIDDeviceInterfaceID), (void *) &(pDevice->interface));
   197 			if (S_OK != plugInResult)
   182 			if (S_OK != plugInResult)
   198 				HIDReportErrorNum ("CouldnŐt query HID class device interface from plugInInterface", plugInResult);
   183 				HIDReportErrorNum ("CouldnŐt query HID class device interface from plugInInterface", plugInResult);
   199 			(*ppPlugInInterface)->Release (ppPlugInInterface);
   184 			(*ppPlugInInterface)->Release (ppPlugInInterface);
   223 {
   208 {
   224 	IOReturn result = kIOReturnSuccess;
   209 	IOReturn result = kIOReturnSuccess;
   225 	
   210 	
   226 	if ((NULL != pDevice) && (NULL != pDevice->interface))
   211 	if ((NULL != pDevice) && (NULL != pDevice->interface))
   227 	{
   212 	{
   228 		// close the interface
   213 		/* close the interface */
   229 		result = (*(pDevice->interface))->close (pDevice->interface);
   214 		result = (*(pDevice->interface))->close (pDevice->interface);
   230 		if (kIOReturnNotOpen == result)
   215 		if (kIOReturnNotOpen == result)
   231 		{
   216 		{
   232 			//  do nothing as device was not opened, thus can't be closed
   217 			/* do nothing as device was not opened, thus can't be closed */
   233 		}
   218 		}
   234 		else if (kIOReturnSuccess != result)
   219 		else if (kIOReturnSuccess != result)
   235 			HIDReportErrorNum ("Failed to close IOHIDDeviceInterface.", result);
   220 			HIDReportErrorNum ("Failed to close IOHIDDeviceInterface.", result);
   236 		//release the interface
   221 		/* release the interface */
   237 		result = (*(pDevice->interface))->Release (pDevice->interface);
   222 		result = (*(pDevice->interface))->Release (pDevice->interface);
   238 		if (kIOReturnSuccess != result)
   223 		if (kIOReturnSuccess != result)
   239 			HIDReportErrorNum ("Failed to release IOHIDDeviceInterface.", result);
   224 			HIDReportErrorNum ("Failed to release IOHIDDeviceInterface.", result);
   240 		pDevice->interface = NULL;
   225 		pDevice->interface = NULL;
   241 	}	
   226 	}	
   557 {
   542 {
   558 	kern_return_t result = KERN_SUCCESS;
   543 	kern_return_t result = KERN_SUCCESS;
   559 	recDevice *pDeviceNext = NULL;
   544 	recDevice *pDeviceNext = NULL;
   560 	if (*ppDevice)
   545 	if (*ppDevice)
   561 	{
   546 	{
   562 		// save next device prior to disposing of this device
   547 		/* save next device prior to disposing of this device */
   563 		pDeviceNext = (*ppDevice)->pNext;
   548 		pDeviceNext = (*ppDevice)->pNext;
   564 		
   549 		
   565 		/* free element lists */
   550 		/* free element lists */
   566 		HIDDisposeElementList (&(*ppDevice)->firstAxis);
   551 		HIDDisposeElementList (&(*ppDevice)->firstAxis);
   567 		HIDDisposeElementList (&(*ppDevice)->firstButton);
   552 		HIDDisposeElementList (&(*ppDevice)->firstButton);
   656 		if (!device)
   641 		if (!device)
   657 			continue;
   642 			continue;
   658 
   643 
   659 		/* dump device object, it is no longer needed */
   644 		/* dump device object, it is no longer needed */
   660 		result = IOObjectRelease (ioHIDDeviceObject);
   645 		result = IOObjectRelease (ioHIDDeviceObject);
   661 //		if (KERN_SUCCESS != result)
   646 /*		if (KERN_SUCCESS != result)
   662 //			HIDReportErrorNum ("IOObjectRelease error with ioHIDDeviceObject.", result);
   647 			HIDReportErrorNum ("IOObjectRelease error with ioHIDDeviceObject.", result);
       
   648 */
   663 
   649 
   664 		/* Filter device list to non-keyboard/mouse stuff */ 
   650 		/* Filter device list to non-keyboard/mouse stuff */ 
   665 		if ( (device->usagePage != kHIDPage_GenericDesktop) ||
   651 		if ( (device->usagePage != kHIDPage_GenericDesktop) ||
   666 		     ((device->usage != kHIDUsage_GD_Joystick &&
   652 		     ((device->usage != kHIDUsage_GD_Joystick &&
   667 		      device->usage != kHIDUsage_GD_GamePad)) ) {
   653 		      device->usage != kHIDUsage_GD_GamePad)) ) {