Ejemplo n.º 1
1
//  open - open 1 or more devices
//
//    Inputs:
//	max = maximum number of devices to open
//	vid = Vendor ID, or -1 if any
//	pid = Product ID, or -1 if any
//	usage_page = top level usage page, or -1 if any
//	usage = top level usage number, or -1 if any
//    Output:
//	actual number of devices opened
//
int pjrc_rawhid::open(int max, int vid, int pid, int usage_page, int usage)
{
    static IOHIDManagerRef hid_manager=NULL;
    CFMutableDictionaryRef dict;
    CFNumberRef num;
    IOReturn ret;
    hid_t *p;
    int count=0;

    if (first_hid) free_all_hid();
    //printf("pjrc_rawhid_open, max=%d\n", max);
    if (max < 1) return 0;
    // Start the HID Manager
    // http://developer.apple.com/technotes/tn2007/tn2187.html
    if (!hid_manager) {
        hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
        if (hid_manager == NULL || CFGetTypeID(hid_manager) != IOHIDManagerGetTypeID()) {
            if (hid_manager) CFRelease(hid_manager);
            return 0;
        }
    }
    if (vid > 0 || pid > 0 || usage_page > 0 || usage > 0) {
        // Tell the HID Manager what type of devices we want
        dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                         &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        if (!dict) return 0;
        if (vid > 0) {
            num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vid);
            CFDictionarySetValue(dict, CFSTR(kIOHIDVendorIDKey), num);
            CFRelease(num);
        }
        if (pid > 0) {
            num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &pid);
            CFDictionarySetValue(dict, CFSTR(kIOHIDProductIDKey), num);
            CFRelease(num);
        }
        if (usage_page > 0) {
            num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage_page);
            CFDictionarySetValue(dict, CFSTR(kIOHIDPrimaryUsagePageKey), num);
            CFRelease(num);
        }
        if (usage > 0) {
            num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage);
            CFDictionarySetValue(dict, CFSTR(kIOHIDPrimaryUsageKey), num);
            CFRelease(num);
        }
        IOHIDManagerSetDeviceMatching(hid_manager, dict);
        CFRelease(dict);
    } else {
        IOHIDManagerSetDeviceMatching(hid_manager, NULL);
    }
    // set up a callbacks for device attach & detach
    IOHIDManagerScheduleWithRunLoop(hid_manager, CFRunLoopGetCurrent(),
                                    kCFRunLoopDefaultMode);
    IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, attach_callback, NULL);
    IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, detach_callback, NULL);
    ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone);
    if (ret != kIOReturnSuccess) {
        printf("Could not start IOHIDManager");
        IOHIDManagerUnscheduleFromRunLoop(hid_manager,
                                          CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
        CFRelease(hid_manager);
        return 0;
    }
    printf("run loop\n");
    // let it do the callback for all devices
    while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource) ;
    // count up how many were added by the callback
    for (p = first_hid; p; p = p->next) count++;
    return count;
}
Ejemplo n.º 2
0
static SDL_bool
ConfigHIDManager(CFArrayRef matchingArray)
{
    CFRunLoopRef runloop = CFRunLoopGetCurrent();

    /* Run in a custom RunLoop mode just while initializing,
       so we can detect sticks without messing with everything else. */
    CFStringRef tempRunLoopMode = CFSTR("SDLJoystickInit");

    if (IOHIDManagerOpen(hidman, kIOHIDOptionsTypeNone) != kIOReturnSuccess) {
        return SDL_FALSE;
    }

    IOHIDManagerRegisterDeviceMatchingCallback(hidman, JoystickDeviceWasAddedCallback, NULL);
    IOHIDManagerScheduleWithRunLoop(hidman, runloop, tempRunLoopMode);
    IOHIDManagerSetDeviceMatchingMultiple(hidman, matchingArray);

    while (CFRunLoopRunInMode(tempRunLoopMode,0,TRUE)==kCFRunLoopRunHandledSource) {
        /* no-op. Callback fires once per existing device. */
    }

    /* Put this in the normal RunLoop mode now, for future hotplug events. */
    IOHIDManagerUnscheduleFromRunLoop(hidman, runloop, tempRunLoopMode);
    IOHIDManagerScheduleWithRunLoop(hidman, runloop, kCFRunLoopDefaultMode);

    return SDL_TRUE;  /* good to go. */
}
Ejemplo n.º 3
0
 void ShutDown()
 {
     IOHIDManagerClose(g_hid_manager, kIOHIDOptionsTypeNone);
     IOHIDManagerUnscheduleFromRunLoop(g_hid_manager, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
   
     CFRelease(g_hid_manager);
 }
Ejemplo n.º 4
0
static void init_hid_manager(void)
{
	CFMutableDictionaryRef dict;
	IOReturn ret;

	if (hid_manager) return;
	hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
	if (hid_manager == NULL || CFGetTypeID(hid_manager) != IOHIDManagerGetTypeID()) {
		if (hid_manager) CFRelease(hid_manager);
		printf_verbose("no HID Manager - maybe this is a pre-Leopard (10.5) system?\n");
		return;
	}
	dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
		&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
	if (!dict) return;
	IOHIDManagerSetDeviceMatching(hid_manager, dict);
	CFRelease(dict);
	IOHIDManagerScheduleWithRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
	IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, attach_callback, NULL);
	IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, detach_callback, NULL);
	ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone);
	if (ret != kIOReturnSuccess) {
		IOHIDManagerUnscheduleFromRunLoop(hid_manager,
			CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
		CFRelease(hid_manager);
		printf_verbose("Error opening HID Manager");
	}
}
Ejemplo n.º 5
0
int TeensyControls_usb_init(void)
{
	CFMutableArrayRef array = NULL;
	IOReturn ret;

	hmgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
	if (!hmgr) goto fail;
	if (CFGetTypeID(hmgr) != IOHIDManagerGetTypeID()) goto fail;
	array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
	if (!array) goto fail;
	add_to_array(array, 0x16C0, 0x0488, 0xFF1C, 0xA739); // Teensyduino Flight Sim
	IOHIDManagerSetDeviceMatchingMultiple(hmgr, array);
	CFRelease(array);
	array = NULL;
	IOHIDManagerScheduleWithRunLoop(hmgr, CFRunLoopGetCurrent(), dev_run_mode);
	IOHIDManagerRegisterDeviceMatchingCallback(hmgr, attach_callback, NULL);
	IOHIDManagerRegisterDeviceRemovalCallback(hmgr, detach_callback, NULL);
	ret = IOHIDManagerOpen(hmgr, kIOHIDOptionsTypeNone);
	if (ret != kIOReturnSuccess) {
		IOHIDManagerUnscheduleFromRunLoop(hmgr,
			CFRunLoopGetCurrent(), dev_run_mode);
		goto fail;
	}
	CFRunLoopAddCommonMode(CFRunLoopGetCurrent(), dev_run_mode);
	return 1;
fail:
	if (array) CFRelease(array);
	if (hmgr) CFRelease(hmgr);
	return 0;
}
Ejemplo n.º 6
0
Burger::Mouse::Mouse(GameApp *pGameApp) :
	m_pGameApp(pGameApp),
	m_MouseLock(),
	m_pHIDManager(NULL),
	m_uMiceCount(0),
	m_uX(0),
	m_uY(0),
	m_uBoundsX(640),
	m_uBoundsY(480),
	m_iDeltaX(0),
	m_iDeltaY(0),
	m_iMouseWheelX(0),
	m_iMouseWheelY(0),
	m_uButtons(0),
	m_uPressedButtons(0),
	m_bButtonSwap(FALSE),
	m_uArrayStart(0),
	m_uArrayEnd(0)
{
	// Back link to the game app
	CFMutableDictionaryRef pDictionary = Globals::CreateHIDDictionary(kHIDPage_GenericDesktop,kHIDUsage_GD_Mouse);
	if (pDictionary != NULL) {
		m_pHIDManager = IOHIDManagerCreate(kCFAllocatorDefault,kIOHIDOptionsTypeNone);
		if (m_pHIDManager != NULL) {
			CFRunLoopRef pRunLoop = CFRunLoopGetCurrent();
			IOHIDManagerRegisterDeviceMatchingCallback(m_pHIDManager,EnumerationCallback,this);
			IOHIDManagerScheduleWithRunLoop(m_pHIDManager,pRunLoop,g_BurgerMouse);
			IOHIDManagerSetDeviceMatching(m_pHIDManager,pDictionary);
			IOHIDManagerOpen(m_pHIDManager,kIOHIDOptionsTypeNone);
			// Handle the run loops
			Poll(this);
			// All scanned!
			IOHIDManagerUnscheduleFromRunLoop(m_pHIDManager,pRunLoop,g_BurgerMouse);
			IOHIDManagerRegisterDeviceMatchingCallback(m_pHIDManager,NULL, NULL);
			
			// Open all the located devices
			Word i;
			DeviceStruct *pRat = m_Mice;
			for (i = 0; i < m_uMiceCount; i++) {
				IOHIDDeviceRef pDevice = pRat->m_pDevice;
				if (IOHIDDeviceOpen(pDevice,kIOHIDOptionsTypeNone) != kIOReturnSuccess) {
					pRat->m_pDevice = NULL;		// Hmm. Toast it
					pRat->m_bUnplugged = FALSE;	// Don't attempt to reconnect
				} else {
					IOHIDDeviceRegisterRemovalCallback(pDevice,DisconnectionCallback,this);
					IOHIDDeviceRegisterInputValueCallback(pDevice,InputCallback,this);
					IOHIDDeviceScheduleWithRunLoop(pDevice,pRunLoop,g_BurgerMouse);
				}
				++pRat;
			}
			pGameApp->AddRoutine(Poll,NULL,this,RunQueue::PRIORITY_MOUSE);
        }
        CFRelease(pDictionary);
    }
}
Ejemplo n.º 7
0
HIDJoystickManager::~HIDJoystickManager()
{
    IOHIDManagerUnscheduleFromRunLoop(m_manager,
                                      CFRunLoopGetCurrent(),
                                      RunLoopMode);

    IOHIDManagerRegisterDeviceMatchingCallback(m_manager, NULL, 0);
    IOHIDManagerRegisterDeviceRemovalCallback(m_manager, NULL, 0);

    IOHIDManagerClose(m_manager, kIOHIDOptionsTypeNone);
}
Ejemplo n.º 8
0
JoypadOSX::~JoypadOSX() {

	for (int i = 0; i < device_list.size(); i++) {
		device_list[i].free();
	}

	IOHIDManagerUnscheduleFromRunLoop(hid_manager, CFRunLoopGetCurrent(), GODOT_JOY_LOOP_RUN_MODE);
	IOHIDManagerClose(hid_manager, kIOHIDOptionsTypeNone);
	CFRelease(hid_manager);
	hid_manager = NULL;
}
Ejemplo n.º 9
0
static int OSX_Mouse_Thread(void *ctx)
{
	if (!ctx)
		return 0;
	struct osx_mouse_data *mdata = static_cast<struct osx_mouse_data *>(ctx);
	
	IOHIDManagerRef hid_manager = IOHIDManagerCreate(kCFAllocatorSystemDefault, kIOHIDOptionsTypeNone);
	if (!hid_manager) {
		SDL_DestroyMutex(mdata->mouse_mutex);
		delete mdata;
		return 0;
	}
	
	if (IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone) != kIOReturnSuccess) {
		CFRelease(hid_manager);
		SDL_DestroyMutex(mdata->mouse_mutex);
		delete mdata;
		return 0;
	}
	
	IOHIDManagerRegisterInputValueCallback(hid_manager, input_callback, mdata);
	IOHIDManagerScheduleWithRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
		
	uint32_t page = kHIDPage_GenericDesktop;
	uint32_t usage = kHIDUsage_GD_Mouse;
	CFDictionaryRef dict = NULL;
	CFNumberRef pageNumRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page);
	CFNumberRef usageNumRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage);
	const void *keys[2] = { CFSTR(kIOHIDDeviceUsagePageKey), CFSTR(kIOHIDDeviceUsageKey) };
	const void *vals[2] = { pageNumRef, usageNumRef };

	if (pageNumRef && usageNumRef)
		dict = CFDictionaryCreate(kCFAllocatorDefault, keys, vals, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
	if (pageNumRef)
		CFRelease(pageNumRef);
	if (usageNumRef)
		CFRelease(usageNumRef);
	IOHIDManagerSetDeviceMatching(hid_manager, dict);
	if (dict)
		CFRelease(dict);

	while (!mdata->should_exit) {
		CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, false);
	}

	IOHIDManagerUnscheduleFromRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
	IOHIDManagerClose(hid_manager, kIOHIDOptionsTypeNone);
	
	CFRelease(hid_manager);
	SDL_DestroyMutex(mdata->mouse_mutex);
	delete mdata;
	return 0;
}
Ejemplo n.º 10
0
void osx_pad_quit(void)
{
   if (g_hid_manager)
   {
      IOHIDManagerClose(g_hid_manager, kIOHIDOptionsTypeNone);
      IOHIDManagerUnscheduleFromRunLoop(g_hid_manager, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
      
      CFRelease(g_hid_manager);
   }

   g_hid_manager = 0;
}
Ejemplo n.º 11
0
void HIDGamepadProvider::closeAndUnscheduleManager()
{
    LOG(Gamepad, "HIDGamepadProvider closing/unscheduling HID manager");

    IOHIDManagerUnscheduleFromRunLoop(m_manager.get(), CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
    IOHIDManagerClose(m_manager.get(), kIOHIDOptionsTypeNone);

    m_gamepadVector.clear();
    m_gamepadMap.clear();

    m_connectionDelayTimer.stop();
}
Ejemplo n.º 12
0
static int apple_hid_manager_free(apple_hid_t *hid)
{
   if (!hid || !hid->ptr)
      return -1;

   IOHIDManagerUnscheduleFromRunLoop(hid->ptr,
         CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
   IOHIDManagerClose(hid->ptr, kIOHIDOptionsTypeNone);
   CFRelease(hid->ptr);
   hid->ptr = NULL;

   return 0;
}
Ejemplo n.º 13
0
static void apple_hid_free(void)
{
    if (!g_hid_manager)
        return;
    
    IOHIDManagerClose(g_hid_manager, kIOHIDOptionsTypeNone);
    IOHIDManagerUnscheduleFromRunLoop(g_hid_manager,
                                      CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
    
    CFRelease(g_hid_manager);
    
    g_hid_manager = NULL;
}
Ejemplo n.º 14
0
/* Function to perform any system-specific joystick related cleanup */
void
SDL_SYS_JoystickQuit(void)
{
    while (FreeDevice(gpDeviceList)) {
        /* spin */
    }

    if (hidman) {
        IOHIDManagerUnscheduleFromRunLoop(hidman, CFRunLoopGetCurrent(), SDL_JOYSTICK_RUNLOOP_MODE);
        IOHIDManagerClose(hidman, kIOHIDOptionsTypeNone);
        CFRelease(hidman);
        hidman = NULL;
    }
}
Ejemplo n.º 15
0
void IOKitHIDEventPublisher::stop() {
  // Stop the manager.
  if (manager_ != nullptr) {
    IOHIDManagerUnscheduleFromRunLoop(
        manager_, run_loop_, kCFRunLoopDefaultMode);
    IOHIDManagerClose(manager_, kIOHIDOptionsTypeNone);
    manager_started_ = false;
    manager_ = nullptr;
  }

  // Stop the run loop.
  if (run_loop_ != nullptr) {
    CFRunLoopStop(run_loop_);
  }
}
Ejemplo n.º 16
0
void Gamepad_shutdown() {
	if (hidManager != NULL) {
		unsigned int deviceIndex;
		
		IOHIDManagerUnscheduleFromRunLoop(hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
		IOHIDManagerClose(hidManager, 0);
		CFRelease(hidManager);
		hidManager = NULL;
		
		for (deviceIndex = 0; deviceIndex < numDevices; deviceIndex++) {
			disposeDevice(devices[deviceIndex]);
		}
		free(devices);
		devices = NULL;
		numDevices = 0;
	}
}
Ejemplo n.º 17
0
int yUSB_stop(yContextSt *ctx,char *errmsg)
{

    if ( ctx->hidM ) {
        IOHIDManagerUnscheduleFromRunLoop(ctx->hidM, ctx->usb_run_loop, kCFRunLoopDefaultMode);
        CFRelease( ctx->hidM );
        ctx->hidM=NULL;
    }
    
    
    if(ctx->usb_thread_state == USB_THREAD_RUNNING){
        ctx->usb_thread_state = USB_THREAD_MUST_STOP;
        CFRunLoopStop(ctx->usb_run_loop);       
    }
    pthread_join(ctx->usb_thread,NULL); 
    YASSERT(ctx->usb_thread_state == USB_THREAD_STOPED);

    yDeleteCriticalSection(&ctx->hidMCS);
    yReleaseGlobalAccess(ctx);

    return 0;
}
Ejemplo n.º 18
0
static void *Sys_Input_Thread(void *inarg)
{
	struct input_data *input;
	IOReturn tIOReturn;

	input = inarg;

	pthread_mutex_lock(&input->thread_mutex);
	input->threadrunloop = CFRunLoopGetCurrent();
	pthread_cond_signal(&input->thread_has_spawned);
	pthread_mutex_unlock(&input->thread_mutex);

	input->hid_manager = IOHIDManagerCreate(kCFAllocatorSystemDefault, kIOHIDOptionsTypeNone);
	if (input->hid_manager)
	{
		IOHIDManagerSetDeviceMatching(input->hid_manager, NULL);
		IOHIDManagerRegisterInputValueCallback(input->hid_manager, input_callback, input);
		IOHIDManagerScheduleWithRunLoop(input->hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);

		tIOReturn = IOHIDManagerOpen(input->hid_manager, kIOHIDOptionsTypeNone);
		if (tIOReturn == kIOReturnSuccess)
		{
			do
			{
				CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, true);
			}
			while (!input->thread_shutdown);
		}

		IOHIDManagerUnscheduleFromRunLoop(input->hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);

	}

	CFRelease(input->hid_manager);

	return 0;
}
Ejemplo n.º 19
0
static void apple_joypad_destroy(void)
{
   unsigned i;

   for (i = 0; i < MAX_PLAYERS; i ++)
   {
      if (slots[i].used && slots[i].iface && slots[i].iface->set_rumble)
      {
         slots[i].iface->set_rumble(slots[i].data, RETRO_RUMBLE_STRONG, 0);
         slots[i].iface->set_rumble(slots[i].data, RETRO_RUMBLE_WEAK, 0);
      }
   }

#ifdef OSX
    if (g_hid_manager)
    {
        IOHIDManagerClose(g_hid_manager, kIOHIDOptionsTypeNone);
        IOHIDManagerUnscheduleFromRunLoop(g_hid_manager, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
        
        CFRelease(g_hid_manager);
    }
    g_hid_manager = NULL;
#endif
}
Ejemplo n.º 20
0
void *_ykusb_open_device(int vendor_id, int *product_ids, size_t pids_len)
{
	void *yk = NULL;

	int rc = YK_ENOKEY;

	size_t i;

	IOHIDManagerSetDeviceMatchingMultiple( ykosxManager, NULL );

	CFSetRef devSet = IOHIDManagerCopyDevices( ykosxManager );

	if ( devSet ) {
		CFMutableArrayRef array = CFArrayCreateMutable( kCFAllocatorDefault, 0, NULL );

		CFSetApplyFunction( devSet, _ykosx_CopyToCFArray, array );

		CFIndex cnt = CFArrayGetCount( array );

		CFIndex i;

		for(i = 0; i < cnt; i++) {
			IOHIDDeviceRef dev = (IOHIDDeviceRef)CFArrayGetValueAtIndex( array, i );
			long devVendorId = _ykosx_getIntProperty( dev, CFSTR( kIOHIDVendorIDKey ));
			if(devVendorId == vendor_id) {
				long devProductId = _ykosx_getIntProperty( dev, CFSTR( kIOHIDProductIDKey ));
				size_t j;
				for(j = 0; j < pids_len; j++) {
					if(product_ids[j] == devProductId) {
						if(yk == NULL) {
							yk = dev;
							break;
						} else {
							rc = YK_EMORETHANONE;
							break;
						}
					}
				}
			}
			if(rc == YK_EMORETHANONE) {
				yk = NULL;
				break;
			}
		}

		if(rc != YK_EMORETHANONE) {
			rc = YK_ENOKEY;
		}

		/* this is a workaround for a memory leak in IOHIDManagerCopyDevices() in 10.8 */
		IOHIDManagerScheduleWithRunLoop( ykosxManager, CFRunLoopGetCurrent( ), kCFRunLoopDefaultMode );
		IOHIDManagerUnscheduleFromRunLoop( ykosxManager, CFRunLoopGetCurrent( ), kCFRunLoopDefaultMode );

		CFRelease( array );
		CFRelease( devSet );
	}

	if (yk) {
		CFRetain(yk);
		_ykusb_IOReturn = IOHIDDeviceOpen( yk, 0L );

		if ( _ykusb_IOReturn != kIOReturnSuccess ) {
			CFRelease(yk);
			rc = YK_EUSBERR;
			goto error;
		}

		return yk;
	}

error:
	yk_errno = rc;
	return 0;
}
Ejemplo n.º 21
0
/**
  * @brief open - open 1 or more devices
  * @param[in] max maximum number of devices to open
  * @param[in] vid Vendor ID, or -1 if any
  * @param[in] pid Product ID, or -1 if any
  * @param[in] usage_page top level usage page, or -1 if any
  * @param[in] usage top level usage number, or -1 if any
  * @returns actual number of devices opened
  */
int pjrc_rawhid::open(int max, int vid, int pid, int usage_page, int usage)
{
    CFMutableDictionaryRef dict;
    CFNumberRef num;
    IOReturn ret;

    Q_ASSERT(hid_manager == NULL);
    Q_ASSERT(device_open == false);

    attach_count = 0;

    // Start the HID Manager
    hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
    if (hid_manager == NULL || CFGetTypeID(hid_manager) != IOHIDManagerGetTypeID()) {
        if (hid_manager) CFRelease(hid_manager);
        return 0;
    }

    if (vid > 0 || pid > 0 || usage_page > 0 || usage > 0) {
        // Tell the HID Manager what type of devices we want
        dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                         &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        if (!dict) return 0;
        if (vid > 0) {
            num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vid);
            CFDictionarySetValue(dict, CFSTR(kIOHIDVendorIDKey), num);
            CFRelease(num);
        }
        if (pid > 0) {
            num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &pid);
            CFDictionarySetValue(dict, CFSTR(kIOHIDProductIDKey), num);
            CFRelease(num);
        }
        if (usage_page > 0) {
            num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage_page);
            CFDictionarySetValue(dict, CFSTR(kIOHIDPrimaryUsagePageKey), num);
            CFRelease(num);
        }
        if (usage > 0) {
            num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage);
            CFDictionarySetValue(dict, CFSTR(kIOHIDPrimaryUsageKey), num);
            CFRelease(num);
        }
        IOHIDManagerSetDeviceMatching(hid_manager, dict);
        CFRelease(dict);
    } else {
        IOHIDManagerSetDeviceMatching(hid_manager, NULL);
    }

    // Set the run loop reference before configuring the attach callback
    the_correct_runloop = CFRunLoopGetCurrent();

    // set up a callbacks for device attach & detach
    IOHIDManagerScheduleWithRunLoop(hid_manager, CFRunLoopGetCurrent(),
                                    kCFRunLoopDefaultMode);
    IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, pjrc_rawhid::attach_callback, this);
    IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, pjrc_rawhid::dettach_callback, this);
    ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone);
    if (ret != kIOReturnSuccess) {
        IOHIDManagerUnscheduleFromRunLoop(hid_manager,
                                          CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
        CFRelease(hid_manager);
        return 0;
    }

    // let it do the callback for all devices
    while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource) ;

    // count up how many were added by the callback
    return attach_count;
}
Ejemplo n.º 22
0
//  rawhid_open - open 1 or more devices
//
//    Inputs:
//	max = maximum number of devices to open
//	vid = Vendor ID, or -1 if any
//	pid = Product ID, or -1 if any
//	usage_page = top level usage page, or -1 if any
//	usage = top level usage number, or -1 if any
//    Output:
//	actual number of devices opened
//
int rawhid_open(int max, int vid, int pid, int usage_page, int usage)
{
   //***
   kern_return_t           result;
   mach_port_t             masterPort;
   CFMutableDictionaryRef  matchingDict;
   CFRunLoopSourceRef      runLoopSource;
   
   
   //Create a master port for communication with the I/O Kit
   result = IOMasterPort(MACH_PORT_NULL, &masterPort);
   if (result || !masterPort)
   {
      return -1;
   }
   
   //To set up asynchronous notifications, create a notification port and
   //add its run loop event source to the programs run loop
   gNotifyPort = IONotificationPortCreate(masterPort);
   runLoopSource = IONotificationPortGetRunLoopSource(gNotifyPort);
   CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource,
                      kCFRunLoopDefaultMode);
   // ***
   /*
   IOServiceAddMatchingNotification(
                                    gNotifyPort,
                                    kIOFirstMatchNotification,
                                    matchingDict,
                                    attach_callback, 
                                    NULL,
                                    &gAddedIter);
   */
   // ***
   
   static IOHIDManagerRef hid_manager=NULL;
   CFMutableDictionaryRef dict;
   CFNumberRef num;
   IOReturn ret;
	hid_t *p;
	int count=0;
   //fprintf(stderr,"fprintf rawhid_open\n");
	if (first_hid) free_all_hid();
	//printf("rawhid_open, max=%d\n", max);
   //fflush (stdout); 
	if (max < 1) return 0;
   // Start the HID Manager
   // http://developer.apple.com/technotes/tn2007/tn2187.html
	if (!hid_manager) {
      hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
      if (hid_manager == NULL || CFGetTypeID(hid_manager) != IOHIDManagerGetTypeID()) {
         if (hid_manager) CFRelease(hid_manager);
         return 0;
      }
	}
	if (vid > 0 || pid > 0 || usage_page > 0 || usage > 0) {
		// Tell the HID Manager what type of devices we want
      dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                       &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
      if (!dict) return 0;
		if (vid > 0) 
      {
			num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vid);
			CFDictionarySetValue(dict, CFSTR(kIOHIDVendorIDKey), num);
			CFRelease(num);
		}
		if (pid > 0) 
      {
			num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &pid);
			CFDictionarySetValue(dict, CFSTR(kIOHIDProductIDKey), num);
			CFRelease(num);
		}
		if (usage_page > 0) 
      {
			num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage_page);
			CFDictionarySetValue(dict, CFSTR(kIOHIDPrimaryUsagePageKey), num);
			CFRelease(num);
		}
		if (usage > 0) 
      {
			num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage);
			CFDictionarySetValue(dict, CFSTR(kIOHIDPrimaryUsageKey), num);
			CFRelease(num);
		}
      IOHIDManagerSetDeviceMatching(hid_manager, dict);
      CFRelease(dict);
	} 
   else 
   {
      IOHIDManagerSetDeviceMatching(hid_manager, NULL);
	}
	// set up a callbacks for device attach & detach
   IOHIDManagerScheduleWithRunLoop(hid_manager, CFRunLoopGetCurrent(),
                                   kCFRunLoopDefaultMode);
   IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, attach_callback, NULL);
	IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, detach_callback, NULL);
   ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone);
   if (ret != kIOReturnSuccess) 
   {
      IOHIDManagerUnscheduleFromRunLoop(hid_manager,
                                        CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
      CFRelease(hid_manager);
      return 0;
   }
	printf("run loop\n");
	// let it do the callback for all devices
	while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource) ;
	// count up how many were added by the callback
	for (p = first_hid; p; p = p->next) count++;
   
   usbstatus=count;
	return count;
}