bool JoystickImpl::open(unsigned int index)
{
m_index = index;
Location deviceLoc = m_locationIDs[index]; // The device we need to load
// Get all devices
CFSetRef devices = HIDJoystickManager::getInstance().copyJoysticks();
if (devices == NULL)
return false;
// Get a usable copy of the joysticks devices.
CFIndex joysticksCount = CFSetGetCount(devices);
CFTypeRef devicesArray[joysticksCount];
CFSetGetValues(devices, devicesArray);
// Get the desired joystick.
IOHIDDeviceRef self = 0;
for (CFIndex i(0); i < joysticksCount; ++i)
{
IOHIDDeviceRef d = (IOHIDDeviceRef)devicesArray[i];
if (deviceLoc == HIDInputManager::getLocationID(d))
{
self = d;
break; // We found it so we stop looping.
}
}
if (self == 0)
{
// This shouldn't happen!
CFRelease(devices);
return false;
}
m_identification.name = getDeviceString(self, CFSTR(kIOHIDProductKey), m_index);
m_identification.vendorId = getDeviceUint(self, CFSTR(kIOHIDVendorIDKey), m_index);
m_identification.productId = getDeviceUint(self, CFSTR(kIOHIDProductIDKey), m_index);
// Get a list of all elements attached to the device.
CFArrayRef elements = IOHIDDeviceCopyMatchingElements(self, NULL, kIOHIDOptionsTypeNone);
if (elements == NULL)
{
CFRelease(devices);
return false;
}
// How many elements are there?
CFIndex elementsCount = CFArrayGetCount(elements);
if (elementsCount == 0)
{
// What is a joystick with no element?
CFRelease(elements);
CFRelease(devices);
return false;
}
// Go through all connected elements.
for (int i = 0; i < elementsCount; ++i)
{
IOHIDElementRef element = (IOHIDElementRef) CFArrayGetValueAtIndex(elements, i);
switch (IOHIDElementGetType(element))
{
case kIOHIDElementTypeInput_Misc:
switch (IOHIDElementGetUsage(element))
{
case kHIDUsage_GD_X: m_axis[Joystick::X] = element; break;
case kHIDUsage_GD_Y: m_axis[Joystick::Y] = element; break;
case kHIDUsage_GD_Z: m_axis[Joystick::Z] = element; break;
case kHIDUsage_GD_Rx: m_axis[Joystick::U] = element; break;
case kHIDUsage_GD_Ry: m_axis[Joystick::V] = element; break;
case kHIDUsage_GD_Rz: m_axis[Joystick::R] = element; break;
// kHIDUsage_GD_Vx, kHIDUsage_GD_Vy, kHIDUsage_GD_Vz are ignored.
}
break;
case kIOHIDElementTypeInput_Button:
if (m_buttons.size() < Joystick::ButtonCount) // If we have free slot...
m_buttons.push_back(element); // ...we add this element to the list
// Else: too many buttons. We ignore this one.
break;
default: // Make compiler happy
break;
}
}
// Ensure that the buttons will be indexed in the same order as their
// HID Usage (assigned by manufacturer and/or a driver).
std::sort(m_buttons.begin(), m_buttons.end(), JoystickButtonSortPredicate);
// Note: Joy::AxisPovX/Y are not supported (yet).
// Maybe kIOHIDElementTypeInput_Axis is the corresponding type but I can't test.
// Retain all these objects for personal use
for (ButtonsVector::iterator it(m_buttons.begin()); it != m_buttons.end(); ++it)
CFRetain(*it);
for (AxisMap::iterator it(m_axis.begin()); it != m_axis.end(); ++it)
CFRetain(it->second);
//.........这里部分代码省略.........
struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{
struct hid_device_info *root = NULL; /* return object */
struct hid_device_info *cur_dev = NULL;
CFIndex num_devices;
int i;
/* Set up the HID Manager if it hasn't been done */
if (hid_init() < 0)
return NULL;
/* give the IOHIDManager a chance to update itself */
process_pending_events();
/* Get a list of the Devices */
IOHIDManagerSetDeviceMatching(hid_mgr, NULL);
CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr);
/* Convert the list into a C array so we can iterate easily. */
num_devices = CFSetGetCount(device_set);
IOHIDDeviceRef *device_array = calloc(num_devices, sizeof(IOHIDDeviceRef));
CFSetGetValues(device_set, (const void **) device_array);
/* Iterate over each device, making an entry for it. */
for (i = 0; i < num_devices; i++) {
unsigned short dev_vid;
unsigned short dev_pid;
#define BUF_LEN 256
wchar_t buf[BUF_LEN];
IOHIDDeviceRef dev = device_array[i];
if (!dev) {
continue;
}
dev_vid = get_vendor_id(dev);
dev_pid = get_product_id(dev);
/* Check the VID/PID against the arguments */
if ((vendor_id == 0x0 || vendor_id == dev_vid) &&
(product_id == 0x0 || product_id == dev_pid)) {
struct hid_device_info *tmp;
io_object_t iokit_dev;
kern_return_t res;
io_string_t path;
/* VID/PID match. Create the record. */
tmp = malloc(sizeof(struct hid_device_info));
if (cur_dev) {
cur_dev->next = tmp;
}
else {
root = tmp;
}
cur_dev = tmp;
/* Get the Usage Page and Usage for this device. */
cur_dev->usage_page = get_int_property(dev, CFSTR(kIOHIDPrimaryUsagePageKey));
cur_dev->usage = get_int_property(dev, CFSTR(kIOHIDPrimaryUsageKey));
/* Fill out the record */
cur_dev->next = NULL;
/* Fill in the path (IOService plane) */
iokit_dev = hidapi_IOHIDDeviceGetService(dev);
res = IORegistryEntryGetPath(iokit_dev, kIOServicePlane, path);
if (res == KERN_SUCCESS)
cur_dev->path = strdup(path);
else
cur_dev->path = strdup("");
/* Serial Number */
get_serial_number(dev, buf, BUF_LEN);
cur_dev->serial_number = dup_wcs(buf);
/* Manufacturer and Product strings */
get_manufacturer_string(dev, buf, BUF_LEN);
cur_dev->manufacturer_string = dup_wcs(buf);
get_product_string(dev, buf, BUF_LEN);
cur_dev->product_string = dup_wcs(buf);
/* VID/PID */
cur_dev->vendor_id = dev_vid;
cur_dev->product_id = dev_pid;
/* Release Number */
cur_dev->release_number = get_int_property(dev, CFSTR(kIOHIDVersionNumberKey));
/* Interface Number (Unsupported on Mac)*/
cur_dev->interface_number = -1;
}
}
free(device_array);
CFRelease(device_set);
return root;
}
开发者ID:billsq,项目名称:hidapi,代码行数:98,代码来源:hid.c
示例16: yUSBGetInterfaces
int yUSBGetInterfaces(yInterfaceSt **ifaces,int *nbifaceDetect,char *errmsg)
{
int nbifaceAlloc;
int deviceIndex;
CFSetRef deviceCFSetRef;
CFIndex deviceCount;
IOHIDDeviceRef *dev_refs;
// allocate buffer for detected interfaces
*nbifaceDetect = 0;
nbifaceAlloc = 8;
*ifaces =yMalloc(nbifaceAlloc * sizeof(yInterfaceSt));
memset(*ifaces, 0 ,nbifaceAlloc * sizeof(yInterfaceSt));
yEnterCriticalSection(&yContext->hidMCS);
deviceCFSetRef = IOHIDManagerCopyDevices( yContext->hidM );
yLeaveCriticalSection(&yContext->hidMCS);
if(deviceCFSetRef== NULL){
//no device found
return 0;
}
// how many devices in the set?
deviceCount = CFSetGetCount( deviceCFSetRef );
HALLOG("%ld usb interfaces detected\n",deviceCount);
dev_refs = yMalloc( sizeof(IOHIDDeviceRef) * (u32)deviceCount );
// now extract the device ref's from the set
CFSetGetValues( deviceCFSetRef, (const void **) dev_refs );
for(deviceIndex=0 ; deviceIndex < deviceCount ;deviceIndex++){
u16 vendorid;
u16 deviceid;
IOHIDDeviceRef dev = dev_refs[deviceIndex];
yInterfaceSt *iface;
vendorid = get_int_property(dev,CFSTR(kIOHIDVendorIDKey));
deviceid = get_int_property(dev,CFSTR(kIOHIDProductIDKey));
//ensure the buffer of detected interface is big enought
if(*nbifaceDetect == nbifaceAlloc){
yInterfaceSt *tmp;
tmp = (yInterfaceSt*) yMalloc(nbifaceAlloc*2 * sizeof(yInterfaceSt));
memset(tmp,0,nbifaceAlloc*2 * sizeof(yInterfaceSt));
yMemcpy(tmp,*ifaces, nbifaceAlloc * sizeof(yInterfaceSt) );
yFree(*ifaces);
*ifaces = tmp;
nbifaceAlloc *=2;
}
iface = *ifaces + *nbifaceDetect;
iface->devref = dev;
iface->vendorid = vendorid;
iface->deviceid = deviceid;
get_txt_property(dev,iface->serial,YOCTO_SERIAL_LEN*2, CFSTR(kIOHIDSerialNumberKey));
HALLOG("work on interface %d (%x:%x:%s)\n",deviceIndex,vendorid,deviceid,iface->serial);
(*nbifaceDetect)++;
}
CFRelease(deviceCFSetRef);
yFree(dev_refs);
return YAPI_SUCCESS;
}
bool JoystickImpl::open(unsigned int index)
{
m_index = index;
m_hat = NULL;
Location deviceLoc = m_locationIDs[index]; // The device we need to load
// Get all devices
CFSetRef devices = HIDJoystickManager::getInstance().copyJoysticks();
if (devices == NULL)
return false;
// Get a usable copy of the joysticks devices.
CFIndex joysticksCount = CFSetGetCount(devices);
CFTypeRef devicesArray[joysticksCount];
CFSetGetValues(devices, devicesArray);
// Get the desired joystick.
IOHIDDeviceRef self = 0;
for (CFIndex i(0); self == 0 && i < joysticksCount; ++i)
{
IOHIDDeviceRef d = (IOHIDDeviceRef)devicesArray[i];
if (deviceLoc == HIDInputManager::getLocationID(d))
self = d;
}
if (self == 0)
{
CFRelease(devices);
return false;
}
m_identification.name = getDeviceString(self, CFSTR(kIOHIDProductKey), m_index);
m_identification.vendorId = getDeviceUint(self, CFSTR(kIOHIDVendorIDKey), m_index);
m_identification.productId = getDeviceUint(self, CFSTR(kIOHIDProductIDKey), m_index);
// Get a list of all elements attached to the device.
CFArrayRef elements = IOHIDDeviceCopyMatchingElements(self, NULL, kIOHIDOptionsTypeNone);
if (elements == NULL)
{
CFRelease(devices);
return false;
}
// Go through all connected elements.
CFIndex elementsCount = CFArrayGetCount(elements);
for (int i = 0; i < elementsCount; ++i)
{
IOHIDElementRef element = (IOHIDElementRef) CFArrayGetValueAtIndex(elements, i);
switch (IOHIDElementGetUsagePage(element))
{
case kHIDPage_GenericDesktop:
switch (IOHIDElementGetUsage(element))
{
case kHIDUsage_GD_X: m_axis[Joystick::X] = element; break;
case kHIDUsage_GD_Y: m_axis[Joystick::Y] = element; break;
case kHIDUsage_GD_Z: m_axis[Joystick::Z] = element; break;
case kHIDUsage_GD_Rx: m_axis[Joystick::U] = element; break;
case kHIDUsage_GD_Ry: m_axis[Joystick::V] = element; break;
case kHIDUsage_GD_Rz: m_axis[Joystick::R] = element; break;
case kHIDUsage_GD_Hatswitch:
// From §4.3 MiscellaneousControls of HUT v1.12:
//
// > Hat Switch:
// > A typical example is four switches that are capable of generating
// > information about four possible directions in which the knob can be
// > tilted. Intermediate positions can also be decoded if the hardware
// > allows two switches to be reported simultaneously.
//
// We assume this model here as well. Hence, with 4 switches and intermediate
// positions we have 8 values (0-7) plus the "null" state (8).
{
CFIndex min = IOHIDElementGetLogicalMin(element);
CFIndex max = IOHIDElementGetLogicalMax(element);
if (min != 0 || max != 7)
{
sf::err() << std::hex
<< "Joystick (vendor/product id: 0x" << m_identification.vendorId
<< "/0x" << m_identification.productId << std::dec
<< ") range is an unexpected one: [" << min << ", " << max << "]"
<< std::endl;
}
else
{
m_hat = element;
}
}
break;
case kHIDUsage_GD_GamePad:
// We assume a game pad is an application collection, meaning it doesn't hold
// any values per say. They kind of "emit" the joystick's usages.
// See §3.4.3 Usage Types (Collection) of HUT v1.12
if (IOHIDElementGetCollectionType(element) != kIOHIDElementCollectionTypeApplication)
{
sf::err() << std::hex << "Gamepage (vendor/product id: 0x" << m_identification.vendorId
<< "/0x" << m_identification.productId << ") is not an CA but a 0x"
<< IOHIDElementGetCollectionType(element) << std::dec << std::endl;
//.........这里部分代码省略.........
请发表评论