static void MyNetworkConnectionCallBack( SCNetworkConnectionRef connection, SCNetworkConnectionStatus status, void *info ) // Our network connection callback. Called out of the runloop // when there's a change in the status of the network connection. // It can be called as part of both a connection attempt and a // disconnection attempt. // // In response to this callback we do two things: // // 1. Print the current connection status. // 2. Once the [dis]connection attempt is resolved (the status // hits either 'connected' or 'disconnected'), we stop // the runloop. This has the effect of breaking the "main" // function out of its called to CFRunLoopRun, after which // it can examine the results of the connection. // // The "info" parameter is a pointer to our per-connection data. // In this case we use this as a pointer to a CallbackParams // structure. We use this to track the previous state of the // connection so that we don't print redundant status changes. { CallbackParams * params; SCNetworkConnectionPPPStatus minorStatus; time_t now; struct tm nowLocal; char nowLocalStr[30]; Boolean printMinorStatus; assert(connection != NULL); assert(info != NULL); params = (CallbackParams *) info; assert(params->magic = kCallbackParamsMagic); // Get a string that represents the current time. (void) time(&now); (void) localtime_r(&now, &nowLocal); (void) strftime(nowLocalStr, sizeof(nowLocalStr), "%X", &nowLocal); // Due to a bug <rdar://problem/3725976>, it's best to get the major status via // SCNetworkConnectionGetStatus than rely on the value being passed into // the callback. status = SCNetworkConnectionGetStatus(connection); // Get the minor status from the extended status associated with // the connection. minorStatus = GetMinorStatus(connection); // Print any status changes. printMinorStatus = (params->lastMinorStatus != minorStatus); if ( (params->forcePrintStatus) || (params->lastMajorStatus != status) ) { fprintf( stderr, "%s %s (%ld)\n", nowLocalStr, StatusToString(status), (long) status ); printMinorStatus = true; params->forcePrintStatus = false; } if (printMinorStatus) { fprintf( stderr, "%s %s (%ld)\n", nowLocalStr, MinorStatusToString(minorStatus), (long) minorStatus ); } // If we hit either the connected or disconnected state, // we signal the runloop to stop so that the main function // can process the result of the [dis]connection attempt. if ( ( minorStatus == kSCNetworkConnectionPPPDisconnected ) || ( minorStatus == kSCNetworkConnectionPPPConnected ) ) { CFRunLoopStop(CFRunLoopGetCurrent()); } // Record the new status. params->lastMajorStatus = status; params->lastMinorStatus = minorStatus; }
int main (int argc, const char *argv[]) { CFURLRef audioFileURLRef; OSStatus ret; audioFileURLRef = CFURLCreateWithFileSystemPath ( kCFAllocatorDefault, /* CFSTR ("../misc/test.wav"), */ CFSTR ("../misc/alin.wav"), kCFURLPOSIXPathStyle, FALSE ); ret = AudioFileOpenURL( audioFileURLRef, kAudioFileReadWritePermission, 0, &myInfo.mAudioFile); if (ret != noErr) { printf("fail to open audio file %x\n", ret); return 1; } UInt32 propSize = sizeof(myInfo.mDataFormat); ret = AudioFileGetProperty( myInfo.mAudioFile, kAudioFilePropertyDataFormat, &propSize, &myInfo.mDataFormat ); if (ret != noErr) { printf("AudioFileGetProperty error code %d\n", ret); return 1; } printf("sample rate: %f\n" "mFormatID: %u\n" "mFormatFlags: %u\n" "mBytesPerPacket: %u\n" "mChannelsPerFrame: %u\n", myInfo.mDataFormat.mSampleRate, myInfo.mDataFormat.mFormatID, myInfo.mDataFormat.mFormatFlags, myInfo.mDataFormat.mBytesPerPacket, myInfo.mDataFormat.mChannelsPerFrame ); // Instantiate an audio queue object ret = AudioQueueNewOutput( &myInfo.mDataFormat, AQTestBufferCallback, &myInfo, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &myInfo.mQueue ); if (ret != noErr) { printf("AudioQueueNewOutput error code %d\n", ret); return 1; } AudioQueueAddPropertyListener(myInfo.mQueue, kAudioQueueProperty_IsRunning, AudioEnginePropertyListenerProc, &myInfo); /* FIXME allocate AudioQueue buffer */ int i; for (i = 0; i < 3; i++) { AudioQueueAllocateBuffer(myInfo.mQueue, 441 * 4, &myInfo.mBuffers[i]); } AudioQueueStart(myInfo.mQueue, NULL); printf("Run loop\n"); // create a system sound ID to represent the sound file /* OSStatus error = AudioServicesCreateSystemSoundID (myURLRef, &mySSID); */ // Register the sound completion callback. // Again, useful when you need to free memory after playing. /* AudioServicesAddSystemSoundCompletion ( */ /* mySSID, */ /* NULL, */ /* NULL, */ /* MyCompletionCallback, */ /* (void *) myURLRef */ /* ); */ // Play the sound file. /* AudioServicesPlaySystemSound (mySSID); */ // Invoke a run loop on the current thread to keep the application // running long enough for the sound to play; the sound completion // callback later stops this run loop. CFRunLoopRun (); return 0; }
IncrementalSweeper* IncrementalSweeper::create(Heap* heap) { return new IncrementalSweeper(heap, CFRunLoopGetCurrent()); }
void RunLoop::stop() { ASSERT(m_runLoop == CFRunLoopGetCurrent()); CFRunLoopStop(m_runLoop.get()); }
bool wxApp::Initialize(int& argc, wxChar **argv) { // Mac-specific #if __WXDEBUG__ InstallDebugAssertOutputHandler ( NewDebugAssertOutputHandlerUPP( wxMacAssertOutputHandler ) ); #endif UMAInitToolbox( 4, sm_isEmbedded ) ; SetEventMask( everyEvent ) ; UMAShowWatchCursor() ; #ifndef __DARWIN__ # if __option(profile) ProfilerInit( collectDetailed, bestTimeBase , 40000 , 50 ) ; # endif #endif #ifndef __DARWIN__ // now avoid exceptions thrown for new (bad_alloc) // FIXME CS for some changes outside wxMac does not compile anymore #if 0 std::__throws_bad_alloc = 0 ; #endif #endif s_macCursorRgn = ::NewRgn() ; // Mac OS X passes a process serial number command line argument when // the application is launched from the Finder. This argument must be // removed from the command line arguments before being handled by the // application (otherwise applications would need to handle it) if ( argc > 1 ) { static const wxChar *ARG_PSN = _T("-psn_"); if ( wxStrncmp(argv[1], ARG_PSN, wxStrlen(ARG_PSN)) == 0 ) { // remove this argument --argc; memmove(argv + 1, argv + 2, argc * sizeof(char *)); } } if ( !wxAppBase::Initialize(argc, argv) ) return false; #if wxUSE_INTL wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding()); #endif #if TARGET_API_MAC_OSX // these might be the startup dirs, set them to the 'usual' dir containing the app bundle wxString startupCwd = wxGetCwd() ; if ( startupCwd == wxT("/") || startupCwd.Right(15) == wxT("/Contents/MacOS") ) { CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle() ) ; CFURLRef urlParent = CFURLCreateCopyDeletingLastPathComponent( kCFAllocatorDefault , url ) ; CFRelease( url ) ; CFStringRef path = CFURLCopyFileSystemPath ( urlParent , kCFURLPOSIXPathStyle ) ; CFRelease( urlParent ) ; wxString cwd = wxMacCFStringHolder(path).AsString(wxLocale::GetSystemEncoding()); wxSetWorkingDirectory( cwd ) ; } #endif wxMacCreateNotifierTable() ; #ifdef __WXMAC_OSX__ /* connect posted events to common-mode run loop so that wxPostEvent events are handled even while we're in the menu or on a scrollbar */ CFRunLoopSourceContext event_posted_context = {0}; event_posted_context.perform = macPostedEventCallback; m_macEventPosted = CFRunLoopSourceCreate(NULL,0,&event_posted_context); CFRunLoopAddSource(CFRunLoopGetCurrent(), m_macEventPosted, kCFRunLoopCommonModes); #endif UMAShowArrowCursor() ; return true; }
void load(CFBundleRef bundle, Boolean bundleVerbose) { CFStringRef key; CFMutableArrayRef keys = NULL; CFStringRef pattern; CFMutableArrayRef patterns = NULL; CFRunLoopSourceRef rls; if (bundleVerbose) { _verbose = TRUE; } SCLog(_verbose, LOG_DEBUG, CFSTR("load() called")); SCLog(_verbose, LOG_DEBUG, CFSTR(" bundle ID = %@"), CFBundleGetIdentifier(bundle)); /* initialize a few globals */ curGlobals = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); curConfigFile = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); curDefaults = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); curStartup = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); /* open a "configd" store to allow cache updates */ store = SCDynamicStoreCreate(NULL, CFSTR("AppleTalk Configuraton plug-in"), atConfigChangedCallback, NULL); if (!store) { SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStoreCreate() failed: %s"), SCErrorString(SCError())); goto error; } /* establish notificaiton keys and patterns */ keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); /* ...watch for (global) AppleTalk configuration changes */ key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainSetup, kSCEntNetAppleTalk); CFArrayAppendValue(keys, key); CFRelease(key); /* ...watch for (per-service) AppleTalk configuration changes */ pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainSetup, kSCCompAnyRegex, kSCEntNetAppleTalk); CFArrayAppendValue(patterns, pattern); CFRelease(pattern); /* ...watch for network interface link status changes */ pattern = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetLink); CFArrayAppendValue(patterns, pattern); CFRelease(pattern); /* ...watch for (per-interface) AppleTalk configuration changes */ pattern = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetAppleTalk); CFArrayAppendValue(patterns, pattern); CFRelease(pattern); /* ...watch for computer name changes */ key = SCDynamicStoreKeyCreateComputerName(NULL); CFArrayAppendValue(keys, key); CFRelease(key); /* register the keys/patterns */ if (!SCDynamicStoreSetNotificationKeys(store, keys, patterns)) { SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s"), SCErrorString(SCError())); goto error; } rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0); if (!rls) { SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed: %s"), SCErrorString(SCError())); goto error; } CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); CFRelease(rls); CFRelease(keys); CFRelease(patterns); return; error : if (curGlobals) CFRelease(curGlobals); if (curConfigFile) CFRelease(curConfigFile); if (curDefaults) CFRelease(curDefaults); if (curStartup) CFRelease(curStartup); if (store) CFRelease(store); if (keys) CFRelease(keys); if (patterns) CFRelease(patterns); return; }
static void *hook_thread_proc(void *arg) { int *status = (int *) arg; *status = UIOHOOK_FAILURE; bool accessibilityEnabled = false; // FIXME Move to osx_input_helper.h after testing. #ifdef USE_WEAK_IMPORT // Check and make sure assistive devices is enabled. if (AXIsProcessTrustedWithOptions != NULL) { // New accessibility API 10.9 and later. const void * keys[] = { kAXTrustedCheckOptionPrompt }; const void * values[] = { kCFBooleanTrue }; CFDictionaryRef options = CFDictionaryCreate( kCFAllocatorDefault, keys, values, sizeof(keys) / sizeof(*keys), &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); accessibilityEnabled = AXIsProcessTrustedWithOptions(options); } else { // Old accessibility check 10.8 and older. accessibilityEnabled = AXAPIEnabled(); } #else // Dynamically load the application services framework for examination. const char *dlError = NULL; void *libApplicaitonServices = dlopen("/System/Library/Frameworks/ApplicationServices.framework/ApplicationServices", RTLD_LAZY); dlError = dlerror(); if (libApplicaitonServices != NULL && dlError == NULL) { // Check for the new function AXIsProcessTrustedWithOptions(). *(void **) (&AXIsProcessTrustedWithOptions_t) = dlsym(libApplicaitonServices, "AXIsProcessTrustedWithOptions"); dlError = dlerror(); if (AXIsProcessTrustedWithOptions_t != NULL && dlError == NULL) { // Check for property kAXTrustedCheckOptionPrompt CFStringRef kAXTrustedCheckOptionPrompt_t = (CFStringRef) dlsym(libApplicaitonServices, "kAXTrustedCheckOptionPrompt"); dlError = dlerror(); if (kAXTrustedCheckOptionPrompt_t != NULL && dlError == NULL) { // New accessibility API 10.9 and later. // FIXME This is causing a segfault on 10.9 probably due to an invalid pointer type. const void * keys[] = { kAXTrustedCheckOptionPrompt_t }; const void * values[] = { kCFBooleanTrue }; CFDictionaryRef options = CFDictionaryCreate( kCFAllocatorDefault, keys, values, sizeof(keys) / sizeof(*keys), &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); accessibilityEnabled = (*AXIsProcessTrustedWithOptions_t)(options); } } else { logger(LOG_LEVEL_DEBUG, "%s [%u]: Falling back to AXAPIEnabled(). (%s)\n", __FUNCTION__, __LINE__, dlError); // Check for the fallback function AXAPIEnabled(). *(void **) (&AXAPIEnabled_t) = dlsym(libApplicaitonServices, "AXAPIEnabled"); dlError = dlerror(); if (AXAPIEnabled_t != NULL && dlError == NULL) { // Old accessibility check 10.8 and older. accessibilityEnabled = (*AXAPIEnabled_t)(); } else { // Could not load the AXAPIEnabled function! logger(LOG_LEVEL_ERROR, "%s [%u]: Failed to locate AXAPIEnabled()! (%s)\n", __FUNCTION__, __LINE__, dlError); } } dlclose(libApplicaitonServices); } else { // Could not load the ApplicationServices framework! logger(LOG_LEVEL_ERROR, "%s [%u]: Failed to lazy load the ApplicationServices framework! (%s)\n", __FUNCTION__, __LINE__, dlError); } #endif if (accessibilityEnabled == true) { logger(LOG_LEVEL_DEBUG, "%s [%u]: Accessibility API is enabled.\n", __FUNCTION__, __LINE__); // Setup the event mask to listen for. CGEventMask event_mask = CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(kCGEventKeyUp) | CGEventMaskBit(kCGEventFlagsChanged) | CGEventMaskBit(kCGEventLeftMouseDown) | CGEventMaskBit(kCGEventLeftMouseUp) | CGEventMaskBit(kCGEventLeftMouseDragged) | CGEventMaskBit(kCGEventRightMouseDown) | CGEventMaskBit(kCGEventRightMouseUp) | CGEventMaskBit(kCGEventRightMouseDragged) | CGEventMaskBit(kCGEventOtherMouseDown) | CGEventMaskBit(kCGEventOtherMouseUp) | CGEventMaskBit(kCGEventOtherMouseDragged) | CGEventMaskBit(kCGEventMouseMoved) | CGEventMaskBit(kCGEventScrollWheel); #ifdef USE_DEBUG event_mask |= CGEventMaskBit(kCGEventNull); #endif CFMachPortRef event_port = CGEventTapCreate( kCGSessionEventTap, // kCGHIDEventTap kCGHeadInsertEventTap, // kCGTailAppendEventTap kCGEventTapOptionListenOnly, // kCGEventTapOptionDefault See Bug #22 event_mask, hook_event_proc, NULL ); if (event_port != NULL) { logger(LOG_LEVEL_DEBUG, "%s [%u]: CGEventTapCreate Successful.\n", __FUNCTION__, __LINE__); event_source = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, event_port, 0); if (event_source != NULL) { logger(LOG_LEVEL_DEBUG, "%s [%u]: CFMachPortCreateRunLoopSource successful.\n", __FUNCTION__, __LINE__); event_loop = CFRunLoopGetCurrent(); if (event_loop != NULL) { logger(LOG_LEVEL_DEBUG, "%s [%u]: CFRunLoopGetCurrent successful.\n", __FUNCTION__, __LINE__); // Initialize Native Input Functions. load_input_helper(); // Create run loop observers. CFRunLoopObserverRef observer = CFRunLoopObserverCreate( kCFAllocatorDefault, kCFRunLoopEntry | kCFRunLoopExit, //kCFRunLoopAllActivities, true, 0, hook_status_proc, NULL ); if (observer != NULL) { // Set the exit status. *status = UIOHOOK_SUCCESS; start_message_port_runloop(); CFRunLoopAddSource(event_loop, event_source, kCFRunLoopDefaultMode); CFRunLoopAddObserver(event_loop, observer, kCFRunLoopDefaultMode); CFRunLoopRun(); // Lock back up until we are done processing the exit. CFRunLoopRemoveObserver(event_loop, observer, kCFRunLoopDefaultMode); CFRunLoopRemoveSource(event_loop, event_source, kCFRunLoopDefaultMode); CFRunLoopObserverInvalidate(observer); stop_message_port_runloop(); } else { // We cant do a whole lot of anything if we cant // create run loop observer. logger(LOG_LEVEL_ERROR, "%s [%u]: CFRunLoopObserverCreate failure!\n", __FUNCTION__, __LINE__); // Set the exit status. *status = UIOHOOK_ERROR_OBSERVER_CREATE; } // Cleanup Native Input Functions. unload_input_helper(); } else { logger(LOG_LEVEL_ERROR, "%s [%u]: CFRunLoopGetCurrent failure!\n", __FUNCTION__, __LINE__); // Set the exit status. *status = UIOHOOK_ERROR_GET_RUNLOOP; } // Clean up the event source. CFRelease(event_source); } else { logger(LOG_LEVEL_ERROR, "%s [%u]: CFMachPortCreateRunLoopSource failure!\n", __FUNCTION__, __LINE__); // Set the exit status. *status = UIOHOOK_ERROR_CREATE_RUN_LOOP_SOURCE; } // Stop the CFMachPort from receiving any more messages. CFMachPortInvalidate(event_port); CFRelease(event_port); } else { logger(LOG_LEVEL_ERROR, "%s [%u]: Failed to create event port!\n", __FUNCTION__, __LINE__); // Set the exit status. *status = UIOHOOK_ERROR_EVENT_PORT; } } else { logger(LOG_LEVEL_ERROR, "%s [%u]: Accessibility API is disabled!\n", __FUNCTION__, __LINE__); // Set the exit status. *status = UIOHOOK_ERROR_AXAPI_DISABLED; } logger(LOG_LEVEL_DEBUG, "%s [%u]: Something, something, something, complete.\n", __FUNCTION__, __LINE__); // Make sure we signal that we have passed any exception throwing code. pthread_mutex_unlock(&hook_control_mutex); pthread_exit(status); }
void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { bd_addr_t event_addr; if (packet_type == HCI_EVENT_PACKET) { switch (packet[0]) { case BTSTACK_EVENT_STATE: { RARCH_LOG("BTstack: HCI State %d\n", packet[2]); switch (packet[2]) { case HCI_STATE_WORKING: btpad_queue_reset(); btpad_queue_hci_read_bd_addr(); bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_CONTROL, 672); // TODO: Where did I get 672 for mtu? bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_INTERRUPT, 672); btpad_queue_hci_inquiry(HCI_INQUIRY_LAP, 3, 1); btpad_queue_run(1); break; case HCI_STATE_HALTING: btpad_close_all_connections(); CFRunLoopStop(CFRunLoopGetCurrent()); break; } } break; case HCI_EVENT_COMMAND_STATUS: btpad_queue_run(packet[3]); break; case HCI_EVENT_COMMAND_COMPLETE: { btpad_queue_run(packet[2]); if (COMMAND_COMPLETE_EVENT(packet, (*hci_read_bd_addr_ptr))) { bt_flip_addr_ptr(event_addr, &packet[6]); if (!packet[5]) RARCH_LOG("BTpad: Local address is %s\n", bd_addr_to_str_ptr(event_addr)); else RARCH_LOG("BTpad: Failed to get local address (Status: %02X)\n", packet[5]); } } break; case HCI_EVENT_INQUIRY_RESULT: { if (packet[2]) { bt_flip_addr_ptr(event_addr, &packet[3]); struct apple_pad_connection* connection = (struct apple_pad_connection*)btpad_find_empty_connection(); if (connection) { RARCH_LOG("BTpad: Inquiry found device\n"); memset(connection, 0, sizeof(struct apple_pad_connection)); memcpy(connection->address, event_addr, sizeof(bd_addr_t)); connection->has_address = true; connection->state = BTPAD_CONNECTING; bt_send_cmd_ptr(l2cap_create_channel_ptr, connection->address, PSM_HID_CONTROL); bt_send_cmd_ptr(l2cap_create_channel_ptr, connection->address, PSM_HID_INTERRUPT); } } } break; case HCI_EVENT_INQUIRY_COMPLETE: { // This must be turned off during gameplay as it causes a ton of lag inquiry_running = !inquiry_off; if (inquiry_running) btpad_queue_hci_inquiry(HCI_INQUIRY_LAP, 3, 1); } break; case L2CAP_EVENT_CHANNEL_OPENED: { bt_flip_addr_ptr(event_addr, &packet[3]); const uint16_t handle = READ_BT_16(packet, 9); const uint16_t psm = READ_BT_16(packet, 11); const uint16_t channel_id = READ_BT_16(packet, 13); struct apple_pad_connection* connection = (struct apple_pad_connection*)btpad_find_connection_for(handle, event_addr); if (!packet[2]) { if (!connection) { RARCH_LOG("BTpad: Got L2CAP 'Channel Opened' event for unrecognized device\n"); break; } RARCH_LOG("BTpad: L2CAP channel opened: (PSM: %02X)\n", psm); connection->handle = handle; if (psm == PSM_HID_CONTROL) connection->channels[0] = channel_id; else if (psm == PSM_HID_INTERRUPT) connection->channels[1] = channel_id; else RARCH_LOG("BTpad: Got unknown L2CAP PSM, ignoring (PSM: %02X)\n", psm); if (connection->channels[0] && connection->channels[1]) { RARCH_LOG("BTpad: Got both L2CAP channels, requesting name\n"); btpad_queue_hci_remote_name_request(connection->address, 0, 0, 0); } } else RARCH_LOG("BTpad: Got failed L2CAP 'Channel Opened' event (PSM: %02X, Status: %02X)\n", psm, packet[2]); } break; case L2CAP_EVENT_INCOMING_CONNECTION: { bt_flip_addr_ptr(event_addr, &packet[2]); const uint16_t handle = READ_BT_16(packet, 8); const uint32_t psm = READ_BT_16(packet, 10); const uint32_t channel_id = READ_BT_16(packet, 12); struct apple_pad_connection* connection = (struct apple_pad_connection*)btpad_find_connection_for(handle, event_addr); if (!connection) { connection = btpad_find_empty_connection(); if (connection) { RARCH_LOG("BTpad: Got new incoming connection\n"); memset(connection, 0, sizeof(struct apple_pad_connection)); memcpy(connection->address, event_addr, sizeof(bd_addr_t)); connection->has_address = true; connection->handle = handle; connection->state = BTPAD_CONNECTING; } else break; } RARCH_LOG("BTpad: Incoming L2CAP connection (PSM: %02X)\n", psm); bt_send_cmd_ptr(l2cap_accept_connection_ptr, channel_id); } break; case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: { bt_flip_addr_ptr(event_addr, &packet[3]); struct apple_pad_connection* connection = (struct apple_pad_connection*)btpad_find_connection_for(0, event_addr); if (!connection) { RARCH_LOG("BTpad: Got unexpected remote name, ignoring\n"); break; } RARCH_LOG("BTpad: Got %.200s\n", (char*)&packet[9]); connection->slot = apple_joypad_connect((char*)packet + 9, connection); connection->state = BTPAD_CONNECTED; } break; case HCI_EVENT_PIN_CODE_REQUEST: RARCH_LOG("BTpad: Sending WiiMote PIN\n"); bt_flip_addr_ptr(event_addr, &packet[2]); btpad_queue_hci_pin_code_request_reply(event_addr, &packet[2]); break; case HCI_EVENT_DISCONNECTION_COMPLETE: { const uint32_t handle = READ_BT_16(packet, 3); if (!packet[2]) { struct apple_pad_connection* connection = (struct apple_pad_connection*)btpad_find_connection_for(handle, 0); if (connection) { connection->handle = 0; apple_joypad_disconnect(connection->slot); btpad_close_connection(connection); } } else RARCH_LOG("BTpad: Got failed 'Disconnection Complete' event (Status: %02X)\n", packet[2]); } break; case L2CAP_EVENT_SERVICE_REGISTERED: { if (packet[2]) RARCH_LOG("BTpad: Got failed 'Service Registered' event (PSM: %02X, Status: %02X)\n", READ_BT_16(packet, 3), packet[2]); } break; } } else if (packet_type == L2CAP_DATA_PACKET) { int i; for (i = 0; i < MAX_PLAYERS; i ++) { struct apple_pad_connection* connection = (struct apple_pad_connection*)&g_connections[i]; if (connection->state == BTPAD_CONNECTED && (connection->channels[0] == channel || connection->channels[1] == channel)) apple_joypad_packet(connection->slot, packet, size); } } }
PsychError ReceiveReports(int deviceIndex) { long error=0; pRecDevice device; IOHIDDeviceInterface122** interface=NULL; int reason; // kCFRunLoopRunFinished, kCFRunLoopRunStopped, kCFRunLoopRunTimedOut, kCFRunLoopRunHandledSource PsychHIDVerifyInit(); if(deviceIndex < 0 || deviceIndex >= MAXDEVICEINDEXS) PrintfExit("Sorry. Can't cope with deviceNumber %d (more than %d). Please tell [email protected]",deviceIndex,(int)MAXDEVICEINDEXS-1); // Allocate report buffers if needed: PsychHIDAllocateReports(deviceIndex); CountReports("ReceiveReports beginning."); if (freeReportsPtr[deviceIndex] == NULL) PrintfExit("No free reports."); device=PsychHIDGetDeviceRecordPtrFromIndex(deviceIndex); if(!HIDIsValidDevice(device))PrintfExit("PsychHID: Invalid device.\n"); interface = PsychHIDGetDeviceInterfacePtrFromIndex(deviceIndex); if(interface==NULL)PrintfExit("PsychHID: No interface for device.\n"); CheckRunLoopSource(deviceIndex,"ReceiveReports",__LINE__); if(!ready[deviceIndex]){ // setInterruptReportHandlerCallback static unsigned char buffer[MAXREPORTSIZE]; psych_uint32 bufferSize=MAXREPORTSIZE; psych_bool createSource; createSource=(source[deviceIndex]==NULL); if(createSource){ if(optionsPrintCrashers && createSource)printf("%d: createAsyncEventSource\n",deviceIndex); error=(*interface)->createAsyncEventSource(interface,&(source[deviceIndex])); if(error)PrintfExit("ReceiveReports - createAsyncEventSource error 0x%lx.",error); if(0 && optionsPrintCrashers && createSource) printf("%d: source %4.4lx validity %d, CFRunLoopContainsSource is %d.\n",deviceIndex,(unsigned long)source[deviceIndex] ,CFRunLoopSourceIsValid(source[deviceIndex]) ,CFRunLoopContainsSource(CFRunLoopGetCurrent(),source[deviceIndex],myRunLoopMode)); } if(optionsPrintCrashers && createSource)printf("%d: getAsyncEventSource\n",deviceIndex); CheckRunLoopSource(deviceIndex,"ReceiveReports",__LINE__); if(optionsPrintCrashers && createSource)printf("%d: CFRunLoopAddSource\n",deviceIndex); CFRunLoopAddSource(CFRunLoopGetCurrent(),source[deviceIndex],myRunLoopMode); if(0 && optionsPrintCrashers && createSource)printf("%d: source %4.4lx validity %d, CFRunLoopContainsSource is %d.\n",deviceIndex,(unsigned long)source[deviceIndex] ,CFRunLoopSourceIsValid(source[deviceIndex]) ,CFRunLoopContainsSource(CFRunLoopGetCurrent(),source[deviceIndex],myRunLoopMode)); ready[deviceIndex]=1; CheckRunLoopSource(deviceIndex,"ReceiveReports",__LINE__); if(optionsPrintCrashers && createSource)printf("%d: setInterruptReportHandlerCallback\n",deviceIndex); error=(*interface)->setInterruptReportHandlerCallback(interface,buffer,bufferSize,ReportCallback,buffer,(void *)(long int) deviceIndex); if(error)PrintfExit("ReceiveReports - setInterruptReportHandlerCallback error 0x%lx.",error); if(optionsPrintCrashers && createSource)printf("%d: CFRunLoopRunInMode.\n",deviceIndex); } //printf("%d: CFRunLoopRunInMode\n",deviceIndex); reason=CFRunLoopRunInMode(myRunLoopMode,optionsSecs,false); if(reason!=kCFRunLoopRunTimedOut && reason!=kCFRunLoopRunHandledSource){ char *s; switch(reason){ case kCFRunLoopRunFinished: s="kCFRunLoopRunFinished"; break; case kCFRunLoopRunStopped: s="kCFRunLoopRunStopped"; break; case kCFRunLoopRunTimedOut: s="kCFRunLoopRunTimedOut"; break; case kCFRunLoopRunHandledSource: s="kCFRunLoopRunHandledSource"; break; default: s="of unknown reason."; } printf("RunLoop ended at %.3f s because %s.\n",CFAbsoluteTimeGetCurrent()-AInScanStart,s); } CountReports("ReceiveReports end."); return error; }
int DeviceManagerThread::Run() { SetThreadName("OVR::DeviceManagerThread"); LogText("OVR::DeviceManagerThread - running (ThreadId=0x%p).\n", GetThreadId()); // Store out the run loop ref. RunLoop = CFRunLoopGetCurrent(); // Create a 'source' to enable us to signal the run loop to process the command queue. CFRunLoopSourceContext sourceContext; memset(&sourceContext, 0, sizeof(sourceContext)); sourceContext.version = 0; sourceContext.info = this; sourceContext.perform = &staticCommandQueueSourceCallback; CommandQueueSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0 , &sourceContext); CFRunLoopAddSource(RunLoop, CommandQueueSource, kCFRunLoopDefaultMode); // Signal to the parent thread that initialization has finished. StartupEvent.SetEvent(); ThreadCommand::PopBuffer command; while(!IsExiting()) { // PopCommand will reset event on empty queue. if (PopCommand(&command)) { command.Execute(); } else { SInt32 exitReason = 0; do { UInt32 waitMs = INT_MAX; // If devices have time-dependent logic registered, get the longest wait // allowed based on current ticks. if (!TicksNotifiers.IsEmpty()) { UInt64 ticksMks = Timer::GetTicks(); UInt32 waitAllowed; for (UPInt j = 0; j < TicksNotifiers.GetSize(); j++) { waitAllowed = (UInt32)(TicksNotifiers[j]->OnTicks(ticksMks) / Timer::MksPerMs); if (waitAllowed < waitMs) waitMs = waitAllowed; } } // Enter blocking run loop. We may continue until we timeout in which // case it's time to service the ticks. Or if commands arrive in the command // queue then the source callback will call 'CFRunLoopStop' causing this // to return. CFTimeInterval blockInterval = 0.001 * (double) waitMs; exitReason = CFRunLoopRunInMode(kCFRunLoopDefaultMode, blockInterval, false); if (exitReason == kCFRunLoopRunFinished) { // Maybe this will occur during shutdown? break; } else if (exitReason == kCFRunLoopRunStopped ) { // Commands need processing or we're being shutdown. break; } else if (exitReason == kCFRunLoopRunTimedOut) { // Timed out so that we can service our ticks callbacks. continue; } else if (exitReason == kCFRunLoopRunHandledSource) { // Should never occur since the last param when we call // 'CFRunLoopRunInMode' is false. OVR_ASSERT(false); break; } else { OVR_ASSERT_LOG(false, ("CFRunLoopRunInMode returned unexpected code")); break; } } while(true); } } CFRunLoopRemoveSource(RunLoop, CommandQueueSource, kCFRunLoopDefaultMode); CFRelease(CommandQueueSource); LogText("OVR::DeviceManagerThread - exiting (ThreadId=0x%p).\n", GetThreadId()); return 0; }
/* Function to scan the system for joysticks. * Joystick 0 should be the system default joystick. * This function should return the number of available joysticks, or -1 * on an unrecoverable fatal error. */ int SDL_SYS_JoystickInit(void) { IOReturn result = kIOReturnSuccess; mach_port_t masterPort = 0; io_iterator_t hidObjectIterator = 0; CFMutableDictionaryRef hidMatchDictionary = NULL; io_object_t ioHIDDeviceObject = 0; io_iterator_t portIterator = 0; if (gpDeviceList) { SDL_SetError("Joystick: Device list already inited."); return -1; } result = IOMasterPort(bootstrap_port, &masterPort); if (kIOReturnSuccess != result) { SDL_SetError("Joystick: IOMasterPort error with bootstrap_port."); return -1; } /* Set up a matching dictionary to search I/O Registry by class name for all HID class devices. */ hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey); if (hidMatchDictionary) { /* Add key for device type (joystick, in this case) to refine the matching dictionary. */ /* NOTE: we now perform this filtering later UInt32 usagePage = kHIDPage_GenericDesktop; UInt32 usage = kHIDUsage_GD_Joystick; CFNumberRef refUsage = NULL, refUsagePage = NULL; refUsage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usage); CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsageKey), refUsage); refUsagePage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usagePage); CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsagePageKey), refUsagePage); */ } else { SDL_SetError ("Joystick: Failed to get HID CFMutableDictionaryRef via IOServiceMatching."); return -1; } /*/ Now search I/O Registry for matching devices. */ result = IOServiceGetMatchingServices(masterPort, hidMatchDictionary, &hidObjectIterator); /* Check for errors */ if (kIOReturnSuccess != result) { SDL_SetError("Joystick: Couldn't create a HID object iterator."); return -1; } if (!hidObjectIterator) { /* there are no joysticks */ gpDeviceList = NULL; return 0; } /* IOServiceGetMatchingServices consumes a reference to the dictionary, so we don't need to release the dictionary ref. */ /* build flat linked list of devices from device iterator */ gpDeviceList = NULL; while ((ioHIDDeviceObject = IOIteratorNext(hidObjectIterator))) { AddDeviceHelper( ioHIDDeviceObject ); } result = IOObjectRelease(hidObjectIterator); /* release the iterator */ /* now connect notification for new devices */ notificationPort = IONotificationPortCreate(masterPort); hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey); CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(notificationPort), kCFRunLoopDefaultMode); // Register for notifications when a serial port is added to the system result = IOServiceAddMatchingNotification(notificationPort, kIOFirstMatchNotification, hidMatchDictionary, JoystickDeviceWasAddedCallback, NULL, &portIterator); while (IOIteratorNext(portIterator)) {}; // Run out the iterator or notifications won't start (you can also use it to iterate the available devices). return SDL_SYS_NumJoysticks(); }
void load(CFBundleRef bundle, Boolean bundleVerbose) { int so; int status; struct kev_request kev_req; CFSocketRef es; CFSocketContext context = { 0, NULL, NULL, NULL, NULL }; CFRunLoopSourceRef rls; if (bundleVerbose) { _verbose = TRUE; } SCLog(_verbose, LOG_DEBUG, CFSTR("load() called")); SCLog(_verbose, LOG_DEBUG, CFSTR(" bundle ID = %@"), CFBundleGetIdentifier(bundle)); /* open a "configd" session to allow cache updates */ store = SCDynamicStoreCreate(NULL, CFSTR("Kernel Event Monitor plug-in"), NULL, NULL); if (!store) { SCLog(TRUE, LOG_ERR, CFSTR("SCDnamicStoreCreate() failed: %s"), SCErrorString(SCError())); SCLog(TRUE, LOG_ERR, CFSTR("kernel event monitor disabled.")); return; } /* Open an event socket */ so = socket(PF_SYSTEM, SOCK_RAW, SYSPROTO_EVENT); if (so != -1) { /* establish filter to return all events */ kev_req.vendor_code = 0; kev_req.kev_class = 0; /* Not used if vendor_code is 0 */ kev_req.kev_subclass = 0; /* Not used if either kev_class OR vendor_code are 0 */ status = ioctl(so, SIOCSKEVFILT, &kev_req); if (status) { SCLog(TRUE, LOG_ERR, CFSTR("could not establish event filter, ioctl() failed: %s"), strerror(errno)); (void) close(so); so = -1; } } else { SCLog(TRUE, LOG_ERR, CFSTR("could not open event socket, socket() failed: %s"), strerror(errno)); } if (so != -1) { int yes = 1; status = ioctl(so, FIONBIO, &yes); if (status) { SCLog(TRUE, LOG_ERR, CFSTR("could not set non-blocking io, ioctl() failed: %s"), strerror(errno)); (void) close(so); so = -1; } } if (so == -1) { SCLog(TRUE, LOG_ERR, CFSTR("kernel event monitor disabled.")); CFRelease(store); return; } /* Create a CFSocketRef for the PF_SYSTEM kernel event socket */ es = CFSocketCreateWithNative(NULL, so, kCFSocketReadCallBack, eventCallback, &context); /* Create and add a run loop source for the event socket */ rls = CFSocketCreateRunLoopSource(NULL, es, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); CFRelease(rls); CFRelease(es); return; }
/*------------------------------------ udpPortSetPort ---*/ bool udpPortSetPort(UdpObjectData * xx, const bool bangOnError) { bool okSoFar = true; if (xx) { if (xx->fSocket) { CFSocketInvalidate(xx->fSocket); CFRelease(xx->fSocket); xx->fSocket = NULL; } int err; int sock = socket(AF_INET, SOCK_DGRAM, 0); if (0 > sock) { err = errno; okSoFar = false; } else { err = 0; } if (okSoFar) { sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_len = sizeof(addr); addr.sin_family = AF_INET; addr.sin_port = htons(xx->fSelfPort); addr.sin_addr.s_addr = INADDR_ANY; err = bind(sock, reinterpret_cast<sockaddr *>(&addr), sizeof(addr)); if (0 > err) { err = errno; okSoFar = false; } } if (okSoFar) { int flags = fcntl(sock, F_GETFL); err = fcntl(sock, F_SETFL, flags | O_NONBLOCK); if (0 > err) { err = errno; okSoFar = false; } } if (okSoFar) { const CFSocketContext context = { 0, xx, NULL, NULL, NULL }; xx->fSocket = CFSocketCreateWithNative(kCFAllocatorDefault, sock, kCFSocketReadCallBack, socketReadCallback, &context); sock = -1; CFRunLoopSourceRef rls = CFSocketCreateRunLoopSource(kCFAllocatorDefault, xx->fSocket, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); CFRelease(rls); setObjectState(xx, kUdpStateBound); } if (! okSoFar) { close(sock); LOG_ERROR_2(xx, OUTPUT_PREFIX "set port failed (%ld)", static_cast<long>(err)) if (bangOnError) { signalError(xx); } } }
void FSEventsWatcher::FSEventsThread(const std::shared_ptr<w_root_t>& root) { CFFileDescriptorRef fdref; CFFileDescriptorContext fdctx; w_set_thread_name("fsevents %s", root->root_path.c_str()); { // Block until fsevents_root_start is waiting for our initialization auto wlock = items_.wlock(); attempt_resync_on_drop = root->config.getBool("fsevents_try_resync", true); memset(&fdctx, 0, sizeof(fdctx)); fdctx.info = root.get(); fdref = CFFileDescriptorCreate( nullptr, fse_pipe.read.fd(), true, fse_pipe_callback, &fdctx); CFFileDescriptorEnableCallBacks(fdref, kCFFileDescriptorReadCallBack); { CFRunLoopSourceRef fdsrc; fdsrc = CFFileDescriptorCreateRunLoopSource(nullptr, fdref, 0); if (!fdsrc) { root->failure_reason = w_string_new_typed( "CFFileDescriptorCreateRunLoopSource failed", W_STRING_UNICODE); goto done; } CFRunLoopAddSource(CFRunLoopGetCurrent(), fdsrc, kCFRunLoopDefaultMode); CFRelease(fdsrc); } stream = fse_stream_make( root, kFSEventStreamEventIdSinceNow, root->failure_reason); if (!stream) { goto done; } if (!FSEventStreamStart(stream->stream)) { root->failure_reason = w_string::printf( "FSEventStreamStart failed, look at your log file %s for " "lines mentioning FSEvents and see %s#fsevents for more information\n", log_name, cfg_get_trouble_url()); goto done; } // Signal to fsevents_root_start that we're done initializing fse_cond.notify_one(); } // Process the events stream until we get signalled to quit CFRunLoopRun(); done: if (stream) { delete stream; } if (fdref) { CFRelease(fdref); } w_log(W_LOG_DBG, "fse_thread done\n"); }
int main(int argc, char *argv[]) { static struct option global_longopts[]= { { "quiet", no_argument, NULL, 'q' }, { "verbose", no_argument, NULL, 'v' }, { "timeout", required_argument, NULL, 't' }, { "id", required_argument, NULL, 'i' }, { "bundle", required_argument, NULL, 'b' }, { "file", required_argument, NULL, 'f' }, { "target", required_argument, NULL, 1 }, { "bundle-id", required_argument, NULL, 0 }, { "debug", no_argument, NULL, 'd' }, { "args", required_argument, NULL, 'a' }, { NULL, 0, NULL, 0 }, }; char ch; while ((ch = getopt_long(argc, argv, "qvi:b:f:da:t:", global_longopts, NULL)) != -1) { switch (ch) { case 0: bundle_id = optarg; break; case 'q': quiet = 1; break; case 'v': verbose = 1; break; case 'd': debug = 1; break; case 't': timeout = atoi(optarg); break; case 'b': app_path = optarg; break; case 'f': doc_file_path = optarg; break; case 1: target_filename = optarg; break; case 'a': args = optarg; break; case 'i': device_id = optarg; break; default: usage(argv[0]); return 1; } } if (optind >= argc) { usage(argv [0]); exit(EXIT_SUCCESS); } operation = OP_NONE; if (strcmp (argv [optind], "install") == 0) { operation = OP_INSTALL; } else if (strcmp (argv [optind], "uninstall") == 0) { operation = OP_UNINSTALL; } else if (strcmp (argv [optind], "list-devices") == 0) { operation = OP_LIST_DEVICES; } else if (strcmp (argv [optind], "upload") == 0) { operation = OP_UPLOAD_FILE; } else if (strcmp (argv [optind], "list-files") == 0) { operation = OP_LIST_FILES; } else { usage (argv [0]); exit (0); } if (!args_are_valid()) { usage(argv[0]); exit(0); } if (operation == OP_INSTALL) assert(access(app_path, F_OK) == 0); AMDSetLogLevel(1+4+2+8+16+32+64+128); // otherwise syslog gets flooded with crap if (timeout > 0) { CFRunLoopTimerRef timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent() + timeout, 0, 0, 0, timeout_callback, NULL); CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes); PRINT("[....] Waiting up to %d seconds for iOS device to be connected\n", timeout); } else { PRINT("[....] Waiting for iOS device to be connected\n"); } struct am_device_notification *notify; AMDeviceNotificationSubscribe(&device_callback, 0, 0, NULL, ¬ify); CFRunLoopRun(); }
static fse_stream* fse_stream_make( const std::shared_ptr<w_root_t>& root, FSEventStreamEventId since, w_string& failure_reason) { FSEventStreamContext ctx; CFMutableArrayRef parray = nullptr; CFStringRef cpath = nullptr; double latency; struct stat st; auto watcher = watcherFromRoot(root); struct fse_stream* fse_stream = new struct fse_stream(root, since); // Each device has an optional journal maintained by fseventsd that keeps // track of the change events. The journal may not be available if the // filesystem was mounted read-only. The journal has an associated UUID // to track the version of the data. In some cases the journal can become // invalidated and it will have a new UUID generated. This can happen // if the EventId rolls over. // We need to lookup up the UUID for the associated path and use that to // help decide whether we can use a value of `since` other than SinceNow. if (stat(root->root_path.c_str(), &st)) { failure_reason = w_string::printf( "failed to stat(%s): %s\n", root->root_path.c_str(), strerror(errno)); goto fail; } // Obtain the UUID for the device associated with the root fse_stream->uuid = FSEventsCopyUUIDForDevice(st.st_dev); if (since != kFSEventStreamEventIdSinceNow) { CFUUIDBytes a, b; if (!fse_stream->uuid) { // If there is no UUID available and we want to use an event offset, // we fail: a nullptr UUID means that the journal is not available. failure_reason = w_string::printf( "fsevents journal is not available for dev_t=%d\n", st.st_dev); goto fail; } // Compare the UUID with that of the current stream if (!watcher->stream->uuid) { failure_reason = w_string( "fsevents journal was not available for prior stream", W_STRING_UNICODE); goto fail; } a = CFUUIDGetUUIDBytes(fse_stream->uuid); b = CFUUIDGetUUIDBytes(watcher->stream->uuid); if (memcmp(&a, &b, sizeof(a)) != 0) { failure_reason = w_string("fsevents journal UUID is different", W_STRING_UNICODE); goto fail; } } memset(&ctx, 0, sizeof(ctx)); ctx.info = fse_stream; parray = CFArrayCreateMutable(nullptr, 0, &kCFTypeArrayCallBacks); if (!parray) { failure_reason = w_string("CFArrayCreateMutable failed", W_STRING_UNICODE); goto fail; } cpath = CFStringCreateWithBytes( nullptr, (const UInt8*)root->root_path.data(), root->root_path.size(), kCFStringEncodingUTF8, false); if (!cpath) { failure_reason = w_string("CFStringCreateWithBytes failed", W_STRING_UNICODE); goto fail; } CFArrayAppendValue(parray, cpath); latency = root->config.getDouble("fsevents_latency", 0.01), w_log( W_LOG_DBG, "FSEventStreamCreate for path %s with latency %f seconds\n", root->root_path.c_str(), latency); fse_stream->stream = FSEventStreamCreate( nullptr, fse_callback, &ctx, parray, since, latency, kFSEventStreamCreateFlagNoDefer | kFSEventStreamCreateFlagWatchRoot | kFSEventStreamCreateFlagFileEvents); if (!fse_stream->stream) { failure_reason = w_string("FSEventStreamCreate failed", W_STRING_UNICODE); goto fail; } FSEventStreamScheduleWithRunLoop(fse_stream->stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); #ifdef HAVE_FSEVENTSTREAMSETEXCLUSIONPATHS if (!root->ignore.dirs_vec.empty() && root->config.getBool("_use_fsevents_exclusions", true)) { CFMutableArrayRef ignarray; size_t i, nitems = std::min(root->ignore.dirs_vec.size(), MAX_EXCLUSIONS); ignarray = CFArrayCreateMutable(nullptr, 0, &kCFTypeArrayCallBacks); if (!ignarray) { failure_reason = w_string("CFArrayCreateMutable failed", W_STRING_UNICODE); goto fail; } for (i = 0; i < nitems; ++i) { const auto& path = root->ignore.dirs_vec[i]; CFStringRef ignpath; ignpath = CFStringCreateWithBytes( nullptr, (const UInt8*)path.data(), path.size(), kCFStringEncodingUTF8, false); if (!ignpath) { failure_reason = w_string("CFStringCreateWithBytes failed", W_STRING_UNICODE); CFRelease(ignarray); goto fail; } CFArrayAppendValue(ignarray, ignpath); CFRelease(ignpath); } if (!FSEventStreamSetExclusionPaths(fse_stream->stream, ignarray)) { failure_reason = w_string("FSEventStreamSetExclusionPaths failed", W_STRING_UNICODE); CFRelease(ignarray); goto fail; } CFRelease(ignarray); } #endif out: if (parray) { CFRelease(parray); } if (cpath) { CFRelease(cpath); } return fse_stream; fail: delete fse_stream; fse_stream = nullptr; goto out; }
static void fse_pipe_callback(CFFileDescriptorRef, CFOptionFlags, void*) { w_log(W_LOG_DBG, "pipe signalled\n"); CFRunLoopStop(CFRunLoopGetCurrent()); }
GCActivityCallback::GCActivityCallback(Heap* heap) : GCActivityCallback(heap->vm(), CFRunLoopGetCurrent()) { }
void DoAQOfflineRender(CFURLRef sourceURL, CFURLRef destinationURL) { // main audio queue code try { AQTestInfo myInfo; myInfo.mDone = false; myInfo.mFlushed = false; myInfo.mCurrentPacket = 0; // get the source file XThrowIfError(AudioFileOpenURL(sourceURL, 0x01/*fsRdPerm*/, 0/*inFileTypeHint*/, &myInfo.mAudioFile), "AudioFileOpen failed"); UInt32 size = sizeof(myInfo.mDataFormat); XThrowIfError(AudioFileGetProperty(myInfo.mAudioFile, kAudioFilePropertyDataFormat, &size, &myInfo.mDataFormat), "couldn't get file's data format"); printf ("File format: "); myInfo.mDataFormat.Print(); // create a new audio queue output XThrowIfError(AudioQueueNewOutput(&myInfo.mDataFormat, // The data format of the audio to play. For linear PCM, only interleaved formats are supported. AQTestBufferCallback, // A callback function to use with the playback audio queue. &myInfo, // A custom data structure for use with the callback function. CFRunLoopGetCurrent(), // The event loop on which the callback function pointed to by the inCallbackProc parameter is to be called. // If you specify NULL, the callback is invoked on one of the audio queue’s internal threads. kCFRunLoopCommonModes, // The run loop mode in which to invoke the callback function specified in the inCallbackProc parameter. 0, // Reserved for future use. Must be 0. &myInfo.mQueue), // On output, the newly created playback audio queue object. "AudioQueueNew failed"); UInt32 bufferByteSize; // we need to calculate how many packets we read at a time and how big a buffer we need // we base this on the size of the packets in the file and an approximate duration for each buffer { bool isFormatVBR = (myInfo.mDataFormat.mBytesPerPacket == 0 || myInfo.mDataFormat.mFramesPerPacket == 0); // first check to see what the max size of a packet is - if it is bigger // than our allocation default size, that needs to become larger UInt32 maxPacketSize; size = sizeof(maxPacketSize); XThrowIfError(AudioFileGetProperty(myInfo.mAudioFile, kAudioFilePropertyPacketSizeUpperBound, &size, &maxPacketSize), "couldn't get file's max packet size"); // adjust buffer size to represent about a second of audio based on this format CalculateBytesForTime(myInfo.mDataFormat, maxPacketSize, 1.0/*seconds*/, &bufferByteSize, &myInfo.mNumPacketsToRead); if (isFormatVBR) { myInfo.mPacketDescs = new AudioStreamPacketDescription [myInfo.mNumPacketsToRead]; } else { myInfo.mPacketDescs = NULL; // we don't provide packet descriptions for constant bit rate formats (like linear PCM) } printf ("Buffer Byte Size: %d, Num Packets to Read: %d\n", (int)bufferByteSize, (int)myInfo.mNumPacketsToRead); } // if the file has a magic cookie, we should get it and set it on the AQ size = sizeof(UInt32); OSStatus result = AudioFileGetPropertyInfo (myInfo.mAudioFile, kAudioFilePropertyMagicCookieData, &size, NULL); if (!result && size) { char* cookie = new char [size]; XThrowIfError (AudioFileGetProperty (myInfo.mAudioFile, kAudioFilePropertyMagicCookieData, &size, cookie), "get cookie from file"); XThrowIfError (AudioQueueSetProperty(myInfo.mQueue, kAudioQueueProperty_MagicCookie, cookie, size), "set cookie on queue"); delete [] cookie; } // channel layout? OSStatus err = AudioFileGetPropertyInfo(myInfo.mAudioFile, kAudioFilePropertyChannelLayout, &size, NULL); AudioChannelLayout *acl = NULL; if (err == noErr && size > 0) { acl = (AudioChannelLayout *)malloc(size); XThrowIfError(AudioFileGetProperty(myInfo.mAudioFile, kAudioFilePropertyChannelLayout, &size, acl), "get audio file's channel layout"); XThrowIfError(AudioQueueSetProperty(myInfo.mQueue, kAudioQueueProperty_ChannelLayout, acl, size), "set channel layout on queue"); } //allocate the input read buffer XThrowIfError(AudioQueueAllocateBuffer(myInfo.mQueue, bufferByteSize, &myInfo.mBuffer), "AudioQueueAllocateBuffer"); // prepare a canonical interleaved capture format CAStreamBasicDescription captureFormat; captureFormat.mSampleRate = myInfo.mDataFormat.mSampleRate; captureFormat.SetAUCanonical(myInfo.mDataFormat.mChannelsPerFrame, true); // interleaved XThrowIfError(AudioQueueSetOfflineRenderFormat(myInfo.mQueue, &captureFormat, acl), "set offline render format"); ExtAudioFileRef captureFile; // prepare a 16-bit int file format, sample channel count and sample rate CAStreamBasicDescription dstFormat; dstFormat.mSampleRate = myInfo.mDataFormat.mSampleRate; dstFormat.mChannelsPerFrame = myInfo.mDataFormat.mChannelsPerFrame; dstFormat.mFormatID = kAudioFormatLinearPCM; dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger; // little-endian dstFormat.mBitsPerChannel = 16; dstFormat.mBytesPerPacket = dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame; dstFormat.mFramesPerPacket = 1; // create the capture file XThrowIfError(ExtAudioFileCreateWithURL(destinationURL, kAudioFileCAFType, &dstFormat, acl, kAudioFileFlags_EraseFile, &captureFile), "ExtAudioFileCreateWithURL"); // set the capture file's client format to be the canonical format from the queue XThrowIfError(ExtAudioFileSetProperty(captureFile, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), &captureFormat), "set ExtAudioFile client format"); // allocate the capture buffer, just keep it at half the size of the enqueue buffer // we don't ever want to pull any faster than we can push data in for render // this 2:1 ratio keeps the AQ Offline Render happy const UInt32 captureBufferByteSize = bufferByteSize / 2; AudioQueueBufferRef captureBuffer; AudioBufferList captureABL; XThrowIfError(AudioQueueAllocateBuffer(myInfo.mQueue, captureBufferByteSize, &captureBuffer), "AudioQueueAllocateBuffer"); captureABL.mNumberBuffers = 1; captureABL.mBuffers[0].mData = captureBuffer->mAudioData; captureABL.mBuffers[0].mNumberChannels = captureFormat.mChannelsPerFrame; // lets start playing now - stop is called in the AQTestBufferCallback when there's // no more to read from the file XThrowIfError(AudioQueueStart(myInfo.mQueue, NULL), "AudioQueueStart failed"); AudioTimeStamp ts; ts.mFlags = kAudioTimeStampSampleTimeValid; ts.mSampleTime = 0; // we need to call this once asking for 0 frames XThrowIfError(AudioQueueOfflineRender(myInfo.mQueue, &ts, captureBuffer, 0), "AudioQueueOfflineRender"); // we need to enqueue a buffer after the queue has started AQTestBufferCallback(&myInfo, myInfo.mQueue, myInfo.mBuffer); while (true) { UInt32 reqFrames = captureBufferByteSize / captureFormat.mBytesPerFrame; XThrowIfError(AudioQueueOfflineRender(myInfo.mQueue, &ts, captureBuffer, reqFrames), "AudioQueueOfflineRender"); captureABL.mBuffers[0].mData = captureBuffer->mAudioData; captureABL.mBuffers[0].mDataByteSize = captureBuffer->mAudioDataByteSize; UInt32 writeFrames = captureABL.mBuffers[0].mDataByteSize / captureFormat.mBytesPerFrame; printf("t = %.f: AudioQueueOfflineRender: req %d fr/%d bytes, got %ld fr/%d bytes\n", ts.mSampleTime, (int)reqFrames, (int)captureBufferByteSize, writeFrames, (int)captureABL.mBuffers[0].mDataByteSize); XThrowIfError(ExtAudioFileWrite(captureFile, writeFrames, &captureABL), "ExtAudioFileWrite"); if (myInfo.mFlushed) break; ts.mSampleTime += writeFrames; } CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, false); XThrowIfError(AudioQueueDispose(myInfo.mQueue, true), "AudioQueueDispose(true) failed"); XThrowIfError(AudioFileClose(myInfo.mAudioFile), "AudioQueueDispose(false) failed"); XThrowIfError(ExtAudioFileDispose(captureFile), "ExtAudioFileDispose failed"); if (myInfo.mPacketDescs) delete [] myInfo.mPacketDescs; if (acl) free(acl); } catch (CAXException e) { char buf[256]; fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); } return; }
/** * Initialize mmc support */ void mmc_init() { da_session = DASessionCreate(kCFAllocatorDefault); DASessionScheduleWithRunLoop(da_session, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); }
DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap) { commonConstructor(heap, CFRunLoopGetCurrent()); }
OSStatus SetupQueue(BG_FileInfo *inFileInfo) { UInt32 size = 0; OSStatus result = AudioQueueNewOutput(&inFileInfo->mFileFormat, QueueCallback, this, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &mQueue); AssertNoError("Error creating queue", end); // (2) If the file has a cookie, we should get it and set it on the AQ size = sizeof(UInt32); result = AudioFileGetPropertyInfo (inFileInfo->mAFID, kAudioFilePropertyMagicCookieData, &size, NULL); if (!result && size) { char* cookie = new char [size]; result = AudioFileGetProperty (inFileInfo->mAFID, kAudioFilePropertyMagicCookieData, &size, cookie); AssertNoError("Error getting magic cookie", end); result = AudioQueueSetProperty(mQueue, kAudioQueueProperty_MagicCookie, cookie, size); delete [] cookie; AssertNoError("Error setting magic cookie", end); } // channel layout OSStatus err = AudioFileGetPropertyInfo(inFileInfo->mAFID, kAudioFilePropertyChannelLayout, &size, NULL); if (err == noErr && size > 0) { AudioChannelLayout *acl = (AudioChannelLayout *)malloc(size); result = AudioFileGetProperty(inFileInfo->mAFID, kAudioFilePropertyChannelLayout, &size, acl); AssertNoError("Error getting channel layout from file", end); result = AudioQueueSetProperty(mQueue, kAudioQueueProperty_ChannelLayout, acl, size); free(acl); AssertNoError("Error setting channel layout on queue", end); } // add a notification proc for when the queue stops result = AudioQueueAddPropertyListener(mQueue, kAudioQueueProperty_IsRunning, QueueStoppedProc, this); AssertNoError("Error adding isRunning property listener to queue", end); // we need to reset this variable so that if the queue is stopped mid buffer we don't dispose it mMakeNewQueueWhenStopped = false; // volume result = SetVolume(mVolume); //end: return result; }
static IOReturn HIDCreateOpenDeviceInterface(io_object_t hidDevice, recDevice * pDevice) { IOReturn result = kIOReturnSuccess; HRESULT plugInResult = S_OK; SInt32 score = 0; IOCFPlugInInterface **ppPlugInInterface = NULL; if (NULL == pDevice->interface) { result = IOCreatePlugInInterfaceForService(hidDevice, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &ppPlugInInterface, &score); if (kIOReturnSuccess == result) { /* Call a method of the intermediate plug-in to create the device interface */ plugInResult = (*ppPlugInInterface)->QueryInterface(ppPlugInInterface, CFUUIDGetUUIDBytes (kIOHIDDeviceInterfaceID), (void *) &(pDevice->interface)); if (S_OK != plugInResult) HIDReportErrorNum ("CouldnÕt query HID class device interface from plugInInterface", plugInResult); (*ppPlugInInterface)->Release(ppPlugInInterface); } else HIDReportErrorNum ("Failed to create **plugInInterface via IOCreatePlugInInterfaceForService.", result); } if (NULL != pDevice->interface) { result = (*(pDevice->interface))->open(pDevice->interface, 0); if (kIOReturnSuccess != result) HIDReportErrorNum ("Failed to open pDevice->interface via open.", result); else { pDevice->portIterator = 0; // It's okay if this fails, we have another detection method below (*(pDevice->interface))->setRemovalCallback(pDevice->interface, HIDRemovalCallback, pDevice, pDevice); /* now connect notification for new devices */ pDevice->notificationPort = IONotificationPortCreate(kIOMasterPortDefault); CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(pDevice->notificationPort), kCFRunLoopDefaultMode); // Register for notifications when a serial port is added to the system result = IOServiceAddInterestNotification(pDevice->notificationPort, hidDevice, kIOGeneralInterest, JoystickDeviceWasRemovedCallback, pDevice, &pDevice->portIterator); if (kIOReturnSuccess != result) { HIDReportErrorNum ("Failed to register for removal callback.", result); } } } return result; }
void Audio_Queue::init() { OSStatus err = noErr; cleanup(); // create the audio queue err = AudioQueueNewOutput(&m_streamDesc, audioQueueOutputCallback, this, CFRunLoopGetCurrent(), NULL, 0, &m_outAQ); if (err) { AQ_TRACE("%s: error in AudioQueueNewOutput\n", __PRETTY_FUNCTION__); m_lastError = err; if (m_delegate) { m_delegate->audioQueueInitializationFailed(); } return; } Stream_Configuration *configuration = Stream_Configuration::configuration(); // allocate audio queue buffers for (unsigned int i = 0; i < configuration->bufferCount; ++i) { err = AudioQueueAllocateBuffer(m_outAQ, configuration->bufferSize, &m_audioQueueBuffer[i]); if (err) { /* If allocating the buffers failed, everything else will fail, too. * Dispose the queue so that we can later on detect that this * queue in fact has not been initialized. */ AQ_TRACE("%s: error in AudioQueueAllocateBuffer\n", __PRETTY_FUNCTION__); (void)AudioQueueDispose(m_outAQ, true); m_outAQ = 0; m_lastError = err; if (m_delegate) { m_delegate->audioQueueInitializationFailed(); } return; } } // listen for kAudioQueueProperty_IsRunning err = AudioQueueAddPropertyListener(m_outAQ, kAudioQueueProperty_IsRunning, audioQueueIsRunningCallback, this); if (err) { AQ_TRACE("%s: error in AudioQueueAddPropertyListener\n", __PRETTY_FUNCTION__); m_lastError = err; return; } if (configuration->enableTimeAndPitchConversion) { UInt32 enableTimePitchConversion = 1; err = AudioQueueSetProperty (m_outAQ, kAudioQueueProperty_EnableTimePitch, &enableTimePitchConversion, sizeof(enableTimePitchConversion)); if (err != noErr) { AQ_TRACE("Failed to enable time and pitch conversion. Play rate setting will fail\n"); } } if (m_initialOutputVolume != 1.0) { setVolume(m_initialOutputVolume); } }
// 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; } // Set the run loop reference: the_correct_runloop = CFRunLoopGetCurrent(); 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; }
FskErr FskFSDirectoryChangeNotifierNew(const char *path, UInt32 flags, FskDirectoryChangeNotifierCallbackProc callback, void *refCon, FskDirectoryChangeNotifier *dirChangeNotifier) { FskErr err = kFskErrNone; FskFSDirectoryChangeNotifier directoryChangeNotifier; struct kevent eventToAdd; int errNum; CFFileDescriptorContext context = {0, NULL, NULL, NULL, NULL}; CFRunLoopSourceRef rls; err = FskMemPtrNewClear(sizeof(FskFSDirectoryChangeNotifierRecord), (FskMemPtr *)(&directoryChangeNotifier)); BAIL_IF_ERR(err); directoryChangeNotifier->base.dispatch.dispatch = &gFSDispatch; directoryChangeNotifier->callback = callback; directoryChangeNotifier->refCon = refCon; directoryChangeNotifier->path = FskStrDoCopy(path); directoryChangeNotifier->dirFD = -1; directoryChangeNotifier->kq = -1; directoryChangeNotifier->dirKQRef = NULL; directoryChangeNotifier->dirFD = open(path, O_EVTONLY); if (directoryChangeNotifier->dirFD < 0) { BAIL(kFskErrFileNotFound); } directoryChangeNotifier->kq = kqueue(); if (directoryChangeNotifier->kq < 0) { BAIL(kFskErrOperationFailed); } eventToAdd.ident = directoryChangeNotifier->dirFD; eventToAdd.filter = EVFILT_VNODE; eventToAdd.flags = EV_ADD | EV_CLEAR; eventToAdd.fflags = NOTE_WRITE; eventToAdd.data = 0; eventToAdd.udata = NULL; errNum = kevent(directoryChangeNotifier->kq, &eventToAdd, 1, NULL, 0, NULL); if (errNum != 0) { BAIL(kFskErrOperationFailed); } context.info = directoryChangeNotifier; directoryChangeNotifier->dirKQRef = CFFileDescriptorCreate(NULL, directoryChangeNotifier->kq, true, KQCallback, &context); if (directoryChangeNotifier->dirKQRef == NULL) { BAIL(kFskErrOperationFailed); } rls = CFFileDescriptorCreateRunLoopSource(NULL, directoryChangeNotifier->dirKQRef, 0); if (rls == NULL) { BAIL(kFskErrOperationFailed); } CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); CFRelease(rls); CFFileDescriptorEnableCallBacks(directoryChangeNotifier->dirKQRef, kCFFileDescriptorReadCallBack); bail: if (err) { FskFSDirectoryChangeNotifierDispose((FskDirectoryChangeNotifier)directoryChangeNotifier); directoryChangeNotifier = NULL; } *dirChangeNotifier = (FskDirectoryChangeNotifier)directoryChangeNotifier; return err; }
static int ListenUsingCoreFoundation(size_t noteCount, const char **noteNames) // Implements the "listenCF" command. Register for the noteCount // notifications whose names are in the noteNames array. Then wrap the // notification Mach port in a CFMachPort and use CF to read the notification // messages, printing the information about any notifications that arrive // from our CFMachPort callback. { int retVal; uint32_t noteErr; size_t noteIndex; int noteTokens[noteCount]; mach_port_t port = MACH_PORT_NULL; // Register. The first time around this loop fd == -1 and so we don't // specify NOTIFY_REUSE. notify_register_mach_port then allocates // a Mach port and returns it in port. For subsequent iterations // we /do/ specify NOTIFY_REUSE and notify_register_mach_port just // reuses the existing port. noteErr = NOTIFY_STATUS_OK; for (noteIndex = 0; noteIndex < noteCount; noteIndex++) { noteErr = notify_register_mach_port( noteNames[noteIndex], &port, (port == MACH_PORT_NULL) ? 0 : NOTIFY_REUSE, ¬eTokens[noteIndex] ); if (noteErr != NOTIFY_STATUS_OK) { break; } } if (noteErr != NOTIFY_STATUS_OK) { PrintNotifyError("registration failed", noteNames[noteIndex], noteErr); retVal = EXIT_FAILURE; } else { MyCFMachPortCallBackInfo myInfo; CFMachPortContext context = { 0 , NULL, NULL, NULL, NULL }; CFMachPortRef cfPort; Boolean shouldFreeInfo; CFRunLoopSourceRef rls; // Set up the context structure for MyCFMachPortCallBack. myInfo.magic = 'CFpI'; myInfo.noteCount = noteCount; myInfo.noteTokens = noteTokens; myInfo.noteNames = noteNames; // Create the CFMachPort. context.info = &myInfo; cfPort = CFMachPortCreateWithPort( NULL, port, MyCFMachPortCallBack, &context, &shouldFreeInfo ); assert(cfPort != NULL); // There can only be one CFMachPort for a given Mach port name. Thus, // if someone had already created a CFMachPort for "port", CFMachPort // would not create a new CFMachPort but, rather, return the existing // CFMachPort with the retain count bumped. In that case it hasn't // taken any 'reference' on the data in context; the context.info // on the /previous/ CFMachPort is still in use, but the context.info // that we supply is now superfluous. In that case it returns // shouldFreeInfo, telling us that we don't need to hold on to this // information. // // In this specific case no one should have already created a CFMachPort // for "port", so shouldFreeInfo should never be true. If it is, it's // time to worry! assert( ! shouldFreeInfo ); // Add it to the run loop. rls = CFMachPortCreateRunLoopSource(NULL, cfPort, 0); assert(rls != NULL); CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); CFRelease(rls); // Run the run loop. fprintf(stdout, "Listening using Core Foundation:\n"); fflush(stdout); CFRunLoopRun(); fprintf(stderr, "CFRunLoopRun returned\n"); retVal = EXIT_FAILURE; } return retVal; }
static void *read_thread(void *param) { hid_device *dev = param; /* Move the device's run loop to this thread. */ IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetCurrent(), dev->run_loop_mode); /* Create the RunLoopSource which is used to signal the event loop to stop when hid_close() is called. */ CFRunLoopSourceContext ctx; memset(&ctx, 0, sizeof(ctx)); ctx.version = 0; ctx.info = dev; ctx.perform = &perform_signal_callback; dev->source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0/*order*/, &ctx); CFRunLoopAddSource(CFRunLoopGetCurrent(), dev->source, dev->run_loop_mode); /* Store off the Run Loop so it can be stopped from hid_close() and on device disconnection. */ dev->run_loop = CFRunLoopGetCurrent(); /* Notify the main thread that the read thread is up and running. */ pthread_barrier_wait(&dev->barrier); /* Run the Event Loop. CFRunLoopRunInMode() will dispatch HID input reports into the hid_report_callback(). */ SInt32 code; while (!dev->shutdown_thread && !dev->disconnected) { code = CFRunLoopRunInMode(dev->run_loop_mode, 1000/*sec*/, FALSE); /* Return if the device has been disconnected */ if (code == kCFRunLoopRunFinished) { dev->disconnected = 1; break; } /* Break if The Run Loop returns Finished or Stopped. */ if (code != kCFRunLoopRunTimedOut && code != kCFRunLoopRunHandledSource) { /* There was some kind of error. Setting shutdown seems to make sense, but there may be something else more appropriate */ dev->shutdown_thread = 1; break; } } /* Now that the read thread is stopping, Wake any threads which are waiting on data (in hid_read_timeout()). Do this under a mutex to make sure that a thread which is about to go to sleep waiting on the condition acutally will go to sleep before the condition is signaled. */ pthread_mutex_lock(&dev->mutex); pthread_cond_broadcast(&dev->condition); pthread_mutex_unlock(&dev->mutex); /* Wait here until hid_close() is called and makes it past the call to CFRunLoopWakeUp(). This thread still needs to be valid when that function is called on the other thread. */ pthread_barrier_wait(&dev->shutdown_barrier); return NULL; }
DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap) : GCActivityCallback(heap->vm(), CFRunLoopGetCurrent()) , m_delay(s_decade) { }
int main (int argc, const char * argv[]) // This program finds the first PPP connection service in the // current network configuration and then connects and // disconnects that service. { int err; Boolean ok; CFStringRef serviceToDial; CFDictionaryRef optionsForDial; SCNetworkConnectionRef connection; CallbackParams params; serviceToDial = NULL; optionsForDial = NULL; connection = NULL; // If we're run without an argument, just print the usage. err = 0; if (argc != 1) { const char *programName; programName = strrchr(argv[0], '/'); if (programName == NULL) { programName = argv[0]; } else { programName += 1; } fprintf(stderr, "Usage: %s\n", programName); err = ECANCELED; } // Find the serviceID of the PPP service to dial and the user's // preferred dialling options. This routine picks up the last // service dialled using Internet Connect (and the associated // options) or, if Internet Connect has not been used, returns // the first PPP service listed in the Network preferences pane. if (err == 0) { ok = SCNetworkConnectionCopyUserPreferences( NULL, &serviceToDial, &optionsForDial ); if ( ! ok ) { err = SCError(); } } // Create a SCNetworkConnectionRef for it. if (err == 0) { SCNetworkConnectionContext context; // Set up the parameters to our callback function. params.magic = kCallbackParamsMagic; params.forcePrintStatus = true; params.lastMinorStatus = kSCNetworkConnectionDisconnected; params.lastMinorStatus = kSCNetworkConnectionPPPDisconnected; // Set up the context to reference those parameters. context.version = 0; context.info = (void *) ¶ms; context.retain = NULL; context.release = NULL; context.copyDescription = NULL; connection = SCNetworkConnectionCreateWithServiceID( NULL, serviceToDial, MyNetworkConnectionCallBack, &context ); if (connection == NULL) { err = SCError(); } } // Schedule our callback with the runloop. if (err == 0) { ok = SCNetworkConnectionScheduleWithRunLoop( connection, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode ); if ( ! ok ) { err = SCError(); } } // Check the status. If we're already connected tell the user. // If we're not connected, initiate the connection. if (err == 0) { err = ECANCELED; // Most cases involve us bailing out, // so set the error here. switch ( SCNetworkConnectionGetStatus(connection) ) { case kSCNetworkConnectionDisconnected: err = 0; break; case kSCNetworkConnectionConnecting: fprintf(stderr, "Service is already connecting.\n"); break; case kSCNetworkConnectionDisconnecting: fprintf(stderr, "Service is disconnecting.\n"); break; case kSCNetworkConnectionConnected: fprintf(stderr, "Service is already connected.\n"); break; case kSCNetworkConnectionInvalid: fprintf(stderr, "Service is invalid. Weird.\n"); break; default: fprintf(stderr, "Unexpected status.\n"); break; } } // Initiate the connection. if (err == 0) { fprintf(stderr, "Connecting...\n"); ok = SCNetworkConnectionStart( connection, optionsForDial, false ); if ( ! ok ) { err = SCError(); } } // Run the runloop and wait for our connection attempt to be resolved. // Once that happens, print the result. if (err == 0) { CFRunLoopRun(); switch (params.lastMinorStatus) { case kSCNetworkConnectionPPPConnected: fprintf(stderr, "Connection succeeded\n"); break; case kSCNetworkConnectionPPPDisconnected: fprintf(stderr, "Connection failed\n"); err = ECANCELED; break; default: fprintf( stderr, "Bad params.lastMinorStatus (%ld)\n", (long) params.lastMinorStatus ); err = EINVAL; break; } } // Wait for a few seconds. if (err == 0) { fprintf(stderr, "Waiting for a few seconds...\n"); (void) sleep(5); // Initiate a disconnect. params.forcePrintStatus = true; fprintf(stderr, "Disconnecting...\n"); ok = SCNetworkConnectionStop( connection, true ); if ( ! ok ) { err = SCError(); } } // Run the runloop and wait for our disconnection attempt to be // resolved. Once that happens, print the result. if (err == 0) { CFRunLoopRun(); switch (params.lastMinorStatus) { case kSCNetworkConnectionPPPDisconnected: fprintf(stderr, "Disconnection succeeded\n"); break; case kSCNetworkConnectionPPPConnected: fprintf(stderr, "Disconnection failed\n"); err = ECANCELED; break; default: fprintf( stderr, "Bad params.lastMinorStatus (%ld)\n", (long) params.lastMinorStatus ); err = EINVAL; break; } } // Clean up. if (serviceToDial != NULL) { CFRelease(serviceToDial); } if (optionsForDial != NULL) { CFRelease(optionsForDial); } if (connection != NULL) { (void) SCNetworkConnectionUnscheduleFromRunLoop( connection, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode ); CFRelease(connection); } if (err == 0) { return EXIT_SUCCESS; } else { if (err != ECANCELED) { fprintf(stderr, "Failed with error %d\n.", err); } return EXIT_FAILURE; } }