⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 osx.c

📁 linux下的任天堂模拟器代码。供大家参考。
💻 C
📖 第 1 页 / 共 5 页
字号:
        {      pRecElement pCurrentElement = NULL;      // create device interface      result = HIDCreateOpenDeviceInterface (hidDevice, pDevice);      if (kIOReturnSuccess != result)        HIDReportErrorNum ("HIDCreateOpenDeviceInterface failed.", result);            hid_GetDeviceInfo (hidDevice, hidProperties, pDevice); // hidDevice used to find parents in registry tree                                   // set current device for use in getting elements      gCurrentGetDevice = pDevice;      // Add all elements            hid_GetCollectionElements (hidProperties, &pCurrentElement);      gCurrentGetDevice = NULL;            CFRelease (hidProperties);        }        else            HIDReportErrorNum ("IORegistryEntryCreateCFProperties error when creating deviceProperties.", result);    }    else        HIDReportError ("malloc error when allocating pRecDevice.");    return pDevice;}#if USE_NOTIFICATIONS//================================================================================================////  hid_DeviceNotification////  This routine will get called whenever any kIOGeneralInterest notification happens.  We are//  interested in the kIOMessageServiceIsTerminated message so that's what we look for.  Other//  messages are defined in IOMessage.h.////================================================================================================//static void hid_DeviceNotification( void *refCon,                  io_service_t service,                  natural_t messageType,                  void *messageArgument ){    pRecDevice pDevice = (pRecDevice) refCon;    if (messageType == kIOMessageServiceIsTerminated)    {        //printf("Device 0x%08x \"%s\"removed.\n", service, pDevice->product);        // ryan added this.        if (pDevice->disconnect == DISCONNECT_CONNECTED)          pDevice->disconnect = DISCONNECT_TELLUSER;        // Free the data we're no longer using now that the device is going away        // ryan commented this out.    //hid_DisposeDevice (pDevice);    }}#elsestatic void hid_RemovalCallbackFunction(void * target, IOReturn result, void * refcon, void * sender){    // ryan commented this out.  //hid_DisposeDevice ((pRecDevice) target);    // ryan added this.    pRecDevice = (pRecDevice) target;    if (pDevice->disconnect == DISCONNECT_CONNECTED)        pDevice->disconnect = DISCONNECT_TELLUSER;}#endif USE_NOTIFICATIONSstatic void hid_AddDevices (void *refCon, io_iterator_t iterator){  // NOTE: refcon passed in is used to point to the device list head    pRecDevice* pListDeviceHead = (pRecDevice*) refCon;    IOReturn result = kIOReturnSuccess;    io_object_t ioHIDDeviceObject = 0;    while ((ioHIDDeviceObject = IOIteratorNext (iterator)) != 0)    {    pRecDevice* pNewDeviceAt = NULL;    pRecDevice pNewDevice = hid_BuildDevice (ioHIDDeviceObject);    if (pNewDevice)    {#if 0 // set true for verbose output      printf("\nhid_AddDevices: pNewDevice = {t: \"%s\", v: %ld, p: %ld, v: %ld, m: \"%s\", " \      "p: \"%s\", l: %ld, u: %4.4lX:%4.4lX, #e: %ld, #f: %ld, #i: %ld, #o: %ld, " \      "#c: %ld, #a: %ld, #b: %ld, #h: %ld, #s: %ld, #d: %ld, #w: %ld}.",      pNewDevice->transport,      pNewDevice->vendorID,      pNewDevice->productID,      pNewDevice->version,      pNewDevice->manufacturer,      pNewDevice->product,      pNewDevice->locID,      pNewDevice->usagePage,      pNewDevice->usage,      pNewDevice->totalElements,      pNewDevice->features,      pNewDevice->inputs,      pNewDevice->outputs,      pNewDevice->collections,      pNewDevice->axis,      pNewDevice->buttons,      pNewDevice->hats,      pNewDevice->sliders,      pNewDevice->dials,      pNewDevice->wheels      );      fflush(stdout);#elif 0 // otherwise output brief description      printf("\nhid_AddDevices: pNewDevice = {m: \"%s\" p: \"%s\", vid: %ld, pid: %ld, loc: %8.8lX, usage: %4.4lX:%4.4lX}.",      pNewDevice->manufacturer,      pNewDevice->product,      pNewDevice->vendorID,      pNewDevice->productID,      pNewDevice->locID,      pNewDevice->usagePage,      pNewDevice->usage      );      fflush(stdout);#endif      pNewDeviceAt = hid_AddDevice (pListDeviceHead, pNewDevice);    }#if USE_NOTIFICATIONS        // Register for an interest notification of this device being removed. Use a reference to our        // private data as the refCon which will be passed to the notification callback.        result = IOServiceAddInterestNotification( gNotifyPort,         // notifyPort                           ioHIDDeviceObject,     // service                           kIOGeneralInterest,      // interestType                           hid_DeviceNotification,    // callback                           pNewDevice,          // refCon                           (io_object_t*) &pNewDevice->notification); // notification    if (KERN_SUCCESS != result)      HIDReportErrorNum ("hid_AddDevices: IOServiceAddInterestNotification error: x0%8.8lX.", result);#else    result = (*(IOHIDDeviceInterface**)pNewDevice->interface)->setRemovalCallback (pNewDevice->interface, hid_RemovalCallbackFunction,pNewDeviceAt,0);#endif USE_NOTIFICATIONS    // release the device object, it is no longer needed    result = IOObjectRelease (ioHIDDeviceObject);    if (KERN_SUCCESS != result)      HIDReportErrorNum ("hid_AddDevices: IOObjectRelease error with ioHIDDeviceObject.", result);    }}static Boolean HIDBuildDeviceList (UInt32 usagePage, UInt32 usage){    IOReturn result = kIOReturnSuccess;    mach_port_t masterPort = 0;    if (NULL != gpDeviceList)        HIDReleaseDeviceList ();    result = IOMasterPort (bootstrap_port, &masterPort);    if (kIOReturnSuccess != result)        HIDReportErrorNum ("IOMasterPort error with bootstrap_port.", result);    else    {    CFMutableDictionaryRef hidMatchDictionary = NULL;    // Set up matching dictionary to search the I/O Registry for HID devices we are interested in. Dictionary reference is NULL if error.    {      CFNumberRef refUsage = NULL, refUsagePage = NULL;      // Set up a matching dictionary to search I/O Registry by class name for all HID class devices.      hidMatchDictionary = IOServiceMatching (kIOHIDDeviceKey);      if (NULL != hidMatchDictionary)      {        if (usagePage)        {          // Add key for device type (joystick, in this case) to refine the matching dictionary.          refUsagePage = CFNumberCreate (kCFAllocatorDefault, kCFNumberLongType, &usagePage);          CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsagePageKey), refUsagePage);          CFRelease (refUsagePage);          if (usage)          {            refUsage = CFNumberCreate (kCFAllocatorDefault, kCFNumberLongType, &usage);            CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsageKey), refUsage);            CFRelease (refUsage);          }        }        CFRetain(hidMatchDictionary);      }      else        HIDReportError ("Failed to get HID CFMutableDictionaryRef via IOServiceMatching.");    }#if USE_NOTIFICATIONS    // Create a notification port and add its run loop event source to our run loop    // This is how async notifications get set up.    {      CFRunLoopSourceRef    runLoopSource;      gNotifyPort = IONotificationPortCreate(masterPort);      runLoopSource = IONotificationPortGetRunLoopSource(gNotifyPort);      gRunLoop = CFRunLoopGetCurrent();      CFRunLoopAddSource(gRunLoop, runLoopSource, kCFRunLoopDefaultMode);      // Now set up a notification to be called when a device is first matched by I/O Kit.      result = IOServiceAddMatchingNotification(gNotifyPort,      // notifyPort                       kIOFirstMatchNotification,   // notificationType                       hidMatchDictionary,      // matching                       hid_AddDevices,        // callback                       &gpDeviceList,         // refCon                       &gAddedIter          // notification                       );      // call it now to add all existing devices      hid_AddDevices(&gpDeviceList,gAddedIter);            return true;    }#else    {      io_iterator_t hidObjectIterator = NULL;      // Now search I/O Registry for matching devices.      result = IOServiceGetMatchingServices (masterPort, hidMatchDictionary, &hidObjectIterator);      if (kIOReturnSuccess != result)        HIDReportErrorNum ("Failed to create IO object iterator, error:", result);      else if (NULL == hidObjectIterator) // likely no HID devices which matched selection criteria are connected        HIDReportError ("Warning: Could not find any matching devices, thus iterator creation failed.");      if (NULL != hidObjectIterator)      {        hid_AddDevices(&gpDeviceList,hidObjectIterator);        result = IOObjectRelease (hidObjectIterator); // release the iterator        if (kIOReturnSuccess != result)          HIDReportErrorNum ("IOObjectRelease error with hidObjectIterator.", result);        gNumDevices = hid_CountCurrentDevices ();        return true;      }    }#endif USE_NOTIFICATIONS    // IOServiceGetMatchingServices consumes a reference to the dictionary, so we don't need to release the dictionary ref.    hidMatchDictionary = NULL;    }  return false;}// ---------------------------------// release list built by above function// MUST be called prior to application exit to properly release devices// if not called (or app crashes) devices can be recovered by pluging into different location in USB chainstatic void HIDReleaseDeviceList (void){    while (NULL != gpDeviceList)    gpDeviceList = hid_DisposeDevice (gpDeviceList); // dispose current device return next device will set gpDeviceList to NULL    gNumDevices = 0;}// ---------------------------------// get the first device in the device list// returns NULL if no list existsstatic pRecDevice HIDGetFirstDevice (void){    return gpDeviceList;}// ---------------------------------// get next device in list given current device as parameter// returns NULL if end of liststatic pRecDevice HIDGetNextDevice (pRecDevice pDevice){    if (NULL != pDevice)        return pDevice->pNext;    else        return NULL;}// ---------------------------------// get the first element of device passed in as parameter// returns NULL if no list exists or device does not exists or is NULLstatic pRecElement HIDGetFirstDeviceElement (pRecDevice pDevice, HIDElementTypeMask typeMask){    if (HIDIsValidDevice(pDevice))  {        if (hid_MatchElementTypeMask (pDevice->pListElements->type, typeMask)) // ensure first type matches      return pDevice->pListElements;    else      return HIDGetNextDeviceElement (pDevice->pListElements, typeMask);  }    else        return NULL;}// ---------------------------------// get next element of given device in list given current element as parameter// will walk down each collection then to next element or collection (depthwise traverse)// returns NULL if end of list// uses mask of HIDElementTypeMask to restrict element found// use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionalitystatic pRecElement HIDGetNextDeviceElement (pRecElement pElement, HIDElementTypeMask typeMask){  // should only have elements passed in (though someone could mix calls and pass us a collection)  // collection means return the next child or sibling (in that order)  // element means returnt he next sibling (as elements can't have children    if (NULL != pElement)  {    if (pElement->pChild)    {      if (pElement->type != kIOHIDElementTypeCollection)        HIDReportError ("Malformed element list: found child of element.");      else        return hid_GetDeviceElement (pElement->pChild, typeMask); // return the child of this element    }    else if (pElement->pSibling)    {      return hid_GetDeviceElement (pElement->pSibling, typeMask); //return the sibling of this element    }    else // at end back up correctly    {      pRecElement pPreviousElement = NULL;      // malformed device ending in collection      if (pElement->type == kIOHIDElementTypeCollection)        HIDReportError ("Malformed device: found collection at end of element chain.");      // walk back up tree to element prior to first collection ecountered and take next element      while (NULL != pElement->pPrevious)      {        pPreviousElement = pElement;        pElement = pElement->pPrevious; // look at previous element                  // if we have a collection and the previous element is the branch element (should have both a colection and next element attached to it)     // if we found a collection, which we are not at the sibling level that actually does have siblings        if (((pElement->type == kIOHIDElementTypeCollection) && (pPreviousElement != pElement->pSibling) && pElement->pSibling) ||    // or if we are at the top    (NULL == pElement->pPrevious)) // at top of tree          break;      }      if (NULL == pElement->pPrevious)        return NULL; // got to top of list with only a collection as the first element         // now we must have been down the child route so go down the sibling route

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -