/* extern */ void _CFTypeInvalidate(CFTypeRef obj) { CFTypeID t = CFGetTypeID(obj); /* Invalidate according to type of object. */ if (t == CFRunLoopSourceGetTypeID()) { CFRunLoopSourceInvalidate((CFRunLoopSourceRef)obj); } else if (t == CFMachPortGetTypeID()) { CFMachPortInvalidate((CFMachPortRef)obj); } else if (t == CFSocketGetTypeID()) { CFSocketInvalidate((CFSocketRef)obj); } /* For scheduled types of objects, it is invalidated by setting the client to NULL. */ else if (t == CFReadStreamGetTypeID()) { CFReadStreamSetClient((CFReadStreamRef)obj, kCFStreamEventNone, NULL, NULL); } else if (t == CFWriteStreamGetTypeID()) { CFWriteStreamSetClient((CFWriteStreamRef)obj, kCFStreamEventNone, NULL, NULL); } else if (t == CFHostGetTypeID()) { CFHostSetClient((CFHostRef)obj, NULL, NULL); } else if (t == SCNetworkReachabilityGetTypeID()) { SCNetworkReachabilitySetCallback((SCNetworkReachabilityRef)obj, NULL, NULL); } else if (t == CFRunLoopTimerGetTypeID()) { CFRunLoopTimerInvalidate((CFRunLoopTimerRef)obj); } else if (t == CFNetServiceGetTypeID()) { CFNetServiceSetClient((CFNetServiceRef)obj, NULL, NULL); } else if (t == CFNetServiceBrowserGetTypeID()) { CFNetServiceBrowserInvalidate((CFNetServiceBrowserRef)obj); } else if (t == CFNetServiceMonitorGetTypeID()) { CFNetServiceMonitorInvalidate((CFNetServiceMonitorRef)obj); } else if (t == SCNetworkReachabilityGetTypeID()) { SCNetworkConnectionStop((SCNetworkConnectionRef)obj, FALSE); } }
void* os_inputmain(void* context){ usbdevice* kb = context; int index = INDEX_OF(kb, keyboard); // Schedule async events for the device on this thread CFRunLoopRef runloop = CFRunLoopGetCurrent(); int count = (IS_RGB(kb->vendor, kb->product)) ? 4 : 3; for(int i = 0; i < count; i++){ CFTypeRef eventsource; kern_return_t res = (*kb->handles[i])->getAsyncEventSource(kb->handles[i], &eventsource); if(res != kIOReturnSuccess){ ckb_err("Failed to start input thread for %s%d: %x\n", devpath, index, res); return 0; } if(CFGetTypeID(eventsource) == CFRunLoopSourceGetTypeID()) CFRunLoopAddSource(runloop, (CFRunLoopSourceRef)eventsource, kCFRunLoopDefaultMode); else if(CFGetTypeID(eventsource) == CFRunLoopTimerGetTypeID()) CFRunLoopAddTimer(runloop, (CFRunLoopTimerRef)eventsource, kCFRunLoopDefaultMode); } ckb_info("Starting input thread for %s%d\n", devpath, index); // Start getting reports uint8_t* urbinput[] = { malloc(8), malloc(32), malloc(MSG_SIZE) }; (*kb->handles[0])->setInputReportCallback(kb->handles[0], urbinput[0], 8, intreport, kb, 0); if(IS_RGB(kb->vendor, kb->product)){ (*kb->handles[1])->setInputReportCallback(kb->handles[1], urbinput[1], 21, intreport, kb, 0); (*kb->handles[2])->setInputReportCallback(kb->handles[2], urbinput[2], MSG_SIZE, intreport, kb, 0); } else { (*kb->handles[1])->setInputReportCallback(kb->handles[1], urbinput[1], 4, intreport, kb, 0); (*kb->handles[2])->setInputReportCallback(kb->handles[2], urbinput[2], 15, intreport, kb, 0); } // Run the run loop for up to 2ms at a time, then check for key repeats while(1){ CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.002, false); pthread_mutex_lock(imutex(kb)); if(!IS_CONNECTED(kb)){ // Make sure the device hasn't disconnected pthread_mutex_unlock(imutex(kb)); break; } keyretrigger(kb); pthread_mutex_unlock(imutex(kb)); } // Clean up ckb_info("Stopping input thread for %s%d\n", devpath, index); free(urbinput[0]); free(urbinput[1]); free(urbinput[2]); return 0; }
void UPSDeviceAdded(void *refCon, io_iterator_t iterator) { io_object_t upsDevice = MACH_PORT_NULL; UPSDataRef upsDataRef = NULL; CFDictionaryRef upsProperties = NULL; CFDictionaryRef upsEvent = NULL; CFSetRef upsCapabilites = NULL; CFRunLoopSourceRef upsEventSource = NULL; CFRunLoopTimerRef upsEventTimer = NULL; CFTypeRef typeRef = NULL; IOCFPlugInInterface ** plugInInterface = NULL; IOUPSPlugInInterface_v140 ** upsPlugInInterface = NULL; HRESULT result = S_FALSE; IOReturn kr; SInt32 score; while ( (upsDevice = IOIteratorNext(iterator)) ) { // Create the CF plugin for this device kr = IOCreatePlugInInterfaceForService(upsDevice, kIOUPSPlugInTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); if ( kr != kIOReturnSuccess ) goto UPSDEVICEADDED_NONPLUGIN_CLEANUP; // Grab the new v140 interface result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUPSPlugInInterfaceID_v140), (LPVOID)&upsPlugInInterface); if ( ( result == S_OK ) && upsPlugInInterface ) { kr = (*upsPlugInInterface)->createAsyncEventSource(upsPlugInInterface, &typeRef); if ((kr != kIOReturnSuccess) || !typeRef) goto UPSDEVICEADDED_FAIL; if ( CFGetTypeID(typeRef) == CFRunLoopTimerGetTypeID() ) { upsEventTimer = (CFRunLoopTimerRef)typeRef; CFRunLoopAddTimer(CFRunLoopGetCurrent(), upsEventTimer, kCFRunLoopDefaultMode); } else if ( CFGetTypeID(typeRef) == CFRunLoopSourceGetTypeID() ) { upsEventSource = (CFRunLoopSourceRef)typeRef; CFRunLoopAddSource(CFRunLoopGetCurrent(), upsEventSource, kCFRunLoopDefaultMode); } } // Couldn't grab the new interface. Fallback on the old. else { result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUPSPlugInInterfaceID), (LPVOID)&upsPlugInInterface); } // Got the interface if ( ( result == S_OK ) && upsPlugInInterface ) { kr = (*upsPlugInInterface)->getProperties(upsPlugInInterface, &upsProperties); if (kr != kIOReturnSuccess) goto UPSDEVICEADDED_FAIL; upsDataRef = GetPrivateData(upsProperties); if ( !upsDataRef ) goto UPSDEVICEADDED_FAIL; upsDataRef->upsPlugInInterface = (IOUPSPlugInInterface **)upsPlugInInterface; upsDataRef->upsEventSource = upsEventSource; upsDataRef->upsEventTimer = upsEventTimer; upsDataRef->isPresent = true; kr = (*upsPlugInInterface)->getCapabilities(upsPlugInInterface, &upsCapabilites); if (kr != kIOReturnSuccess) goto UPSDEVICEADDED_FAIL; kr = CreatePowerManagerUPSEntry(upsDataRef, upsProperties, upsCapabilites); if (kr != kIOReturnSuccess) goto UPSDEVICEADDED_FAIL; kr = (*upsPlugInInterface)->getEvent(upsPlugInInterface, &upsEvent); if (kr != kIOReturnSuccess) goto UPSDEVICEADDED_FAIL; ProcessUPSEvent(upsDataRef, upsEvent); (*upsPlugInInterface)->setEventCallback(upsPlugInInterface, UPSEventCallback, NULL, upsDataRef); IOServiceAddInterestNotification( gNotifyPort, // notifyPort upsDevice, // service kIOGeneralInterest, // interestType DeviceNotification, // callback upsDataRef, // refCon &(upsDataRef->notification) // notification ); goto UPSDEVICEADDED_CLEANUP; } UPSDEVICEADDED_FAIL: // Failed to allocated a UPS interface. Do some cleanup if ( upsPlugInInterface ) { (*upsPlugInInterface)->Release(upsPlugInInterface); upsPlugInInterface = NULL; } if ( upsEventSource ) { CFRunLoopRemoveSource(CFRunLoopGetCurrent(), upsEventSource, kCFRunLoopDefaultMode); upsEventSource = NULL; } if ( upsEventTimer ) { CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), upsEventTimer, kCFRunLoopDefaultMode); upsEventSource = NULL; } UPSDEVICEADDED_CLEANUP: // Clean up (*plugInInterface)->Release(plugInInterface); UPSDEVICEADDED_NONPLUGIN_CLEANUP: IOObjectRelease(upsDevice); } }
/* extern */ void _CFTypeScheduleOnRunLoop(CFTypeRef obj, CFRunLoopRef runLoop, CFStringRef runLoopMode) { CFTypeID t = CFGetTypeID(obj); CFTypeRef src = NULL; void(*fn)(CFTypeRef, CFRunLoopRef, CFStringRef); void(*fn2)(CFRunLoopRef, CFTypeRef, CFStringRef); fn = NULL; fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopAddSource; /* Get the correct source or function used for adding the object to the run loop. */ if (t == CFRunLoopSourceGetTypeID()) { src = CFRetain(obj); } else if (t == CFMachPortGetTypeID()) { src = CFMachPortCreateRunLoopSource(CFGetAllocator(obj), (CFMachPortRef)obj, 0); } else if (t == CFSocketGetTypeID()) { src = CFSocketCreateRunLoopSource(CFGetAllocator(obj), (CFSocketRef)obj, 0); } else if (t == CFReadStreamGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFReadStreamScheduleWithRunLoop; } else if (t == CFWriteStreamGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFWriteStreamScheduleWithRunLoop; } else if (t == CFHostGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFHostScheduleWithRunLoop; } else if (t == SCNetworkReachabilityGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkReachabilityScheduleWithRunLoop; } else if (t == CFRunLoopTimerGetTypeID()) { src = CFRetain(obj); fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopAddTimer; } else if (t == CFNetServiceGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceScheduleWithRunLoop; } else if (t == CFNetServiceBrowserGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceBrowserScheduleWithRunLoop; } else if (t == CFNetServiceMonitorGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceMonitorScheduleWithRunLoop; } else if (t == SCNetworkConnectionGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkConnectionScheduleWithRunLoop; } /* If a source was retrieved, need to add the source */ if (src) { fn2(runLoop, src, runLoopMode); CFRelease(src); } /* If a schedule function was retrieved, call it. */ else if (fn) { fn(obj, runLoop, runLoopMode); } }
/* extern */ void _CFTypeUnscheduleFromMultipleRunLoops(CFTypeRef obj, CFArrayRef schedules) { CFTypeID t = CFGetTypeID(obj); CFTypeRef src = NULL; void(*fn)(CFTypeRef, CFRunLoopRef, CFStringRef); void(*fn2)(CFRunLoopRef, CFTypeRef, CFStringRef); fn = NULL; fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopRemoveSource; /* Get the proper source or function for removing the object from the run loop. */ if (t == CFRunLoopSourceGetTypeID()) { src = CFRetain(obj); } else if (t == CFMachPortGetTypeID()) { src = CFMachPortCreateRunLoopSource(CFGetAllocator(obj), (CFMachPortRef)obj, 0); } else if (t == CFSocketGetTypeID()) { src = CFSocketCreateRunLoopSource(CFGetAllocator(obj), (CFSocketRef)obj, 0); } else if (t == CFReadStreamGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFReadStreamUnscheduleFromRunLoop; } else if (t == CFWriteStreamGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFWriteStreamUnscheduleFromRunLoop; } else if (t == CFHostGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFHostUnscheduleFromRunLoop; } else if (t == SCNetworkReachabilityGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkReachabilityUnscheduleFromRunLoop; } else if (t == CFRunLoopTimerGetTypeID()) { src = CFRetain(obj); fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopRemoveTimer; } else if (t == CFNetServiceGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceUnscheduleFromRunLoop; } else if (t == CFNetServiceBrowserGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceBrowserUnscheduleFromRunLoop; } else if (t == CFNetServiceMonitorGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceMonitorUnscheduleFromRunLoop; } else if (t == SCNetworkConnectionGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkConnectionUnscheduleFromRunLoop; } /* If a source was retrieved, need to remove it from the list of run loops*/ if (src) { CFIndex i, length = CFArrayGetCount(schedules); for (i = 0; i < length; i += 2) { fn2((CFRunLoopRef)CFArrayGetValueAtIndex(schedules, i), src, (CFStringRef)CFArrayGetValueAtIndex(schedules, i + 1)); } CFRelease(src); } /* If an unschedule function was retrieved, need to call it for each schedule in the list. */ else if (fn) { CFIndex i, length = CFArrayGetCount(schedules); for (i = 0; i < length; i += 2) { fn(obj, (CFRunLoopRef)CFArrayGetValueAtIndex(schedules, i), (CFStringRef)CFArrayGetValueAtIndex(schedules, i + 1)); } } }
/* extern */ void _CFTypeUnscheduleFromRunLoop(CFTypeRef obj, CFRunLoopRef runLoop, CFStringRef runLoopMode) { CFTypeID t = CFGetTypeID(obj); CFTypeRef src = NULL; void(*fn)(CFTypeRef, CFRunLoopRef, CFStringRef); void(*fn2)(CFRunLoopRef, CFTypeRef, CFStringRef); fn = NULL; fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopRemoveSource; /* Get the proper source or function for removing the object from the run loop. */ if (t == CFRunLoopSourceGetTypeID()) { src = CFRetain(obj); } else if (t == CFMachPortGetTypeID()) { src = CFMachPortCreateRunLoopSource(CFGetAllocator(obj), (CFMachPortRef)obj, 0); } else if (t == CFSocketGetTypeID()) { src = CFSocketCreateRunLoopSource(CFGetAllocator(obj), (CFSocketRef)obj, 0); } else if (t == CFReadStreamGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFReadStreamUnscheduleFromRunLoop; } else if (t == CFWriteStreamGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFWriteStreamUnscheduleFromRunLoop; } else if (t == CFHostGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFHostUnscheduleFromRunLoop; } else if (t == SCNetworkReachabilityGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkReachabilityUnscheduleFromRunLoop; } else if (t == CFRunLoopTimerGetTypeID()) { src = CFRetain(obj); fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopRemoveTimer; } else if (t == CFNetServiceGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceUnscheduleFromRunLoop; } else if (t == CFNetServiceBrowserGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceBrowserUnscheduleFromRunLoop; } else if (t == CFNetServiceMonitorGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceMonitorUnscheduleFromRunLoop; } else if (t == SCNetworkConnectionGetTypeID()) { fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkConnectionUnscheduleFromRunLoop; } /* If a source was retrieved, need to remove it */ if (src) { fn2(runLoop, src, runLoopMode); CFRelease(src); } /* If an unschedule function was retrieved, need to call it. */ else if (fn) { fn(obj, runLoop, runLoopMode); } }