void runLoop(TimerCallbackParameters* timerCallbackParameters, float frequency) { CFRunLoopObserverContext observerContext; observerContext.version = 0; observerContext.info = 0; observerContext.retain = 0; observerContext.release = 0; observerContext.copyDescription = 0; auto observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopBeforeTimers, true, 0, observerCallback, &observerContext); CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopCommonModes); CFRunLoopTimerContext timerContext; timerContext.version = 0; timerContext.info = timerCallbackParameters; timerContext.retain = 0; timerContext.release = 0; timerContext.copyDescription = 0; auto timer = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent(), 1.0 / frequency, 0, 0, timerCallBack, &timerContext); CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes); CFRunLoopRun(); }
void apple_start_iteration(void) { if (iterate_observer) return; iterate_observer = CFRunLoopObserverCreate(0, kCFRunLoopBeforeWaiting, true, 0, (CFRunLoopObserverCallBack)do_iteration, 0); CFRunLoopAddObserver(CFRunLoopGetMain(), iterate_observer, kCFRunLoopCommonModes); }
wxCFEventLoop::wxCFEventLoop() { m_shouldExit = false; m_runLoop = CFGetCurrentRunLoop(); CFRunLoopObserverContext ctxt; bzero( &ctxt, sizeof(ctxt) ); ctxt.info = this; m_commonModeRunLoopObserver = CFRunLoopObserverCreate( kCFAllocatorDefault, kCFRunLoopBeforeTimers | kCFRunLoopBeforeWaiting , true /* repeats */, 0, (CFRunLoopObserverCallBack) wxCFEventLoop::OSXCommonModeObserverCallBack, &ctxt ); CFRunLoopAddObserver(m_runLoop, m_commonModeRunLoopObserver, kCFRunLoopCommonModes); CFRelease(m_commonModeRunLoopObserver); m_defaultModeRunLoopObserver = CFRunLoopObserverCreate( kCFAllocatorDefault, kCFRunLoopBeforeTimers | kCFRunLoopBeforeWaiting , true /* repeats */, 0, (CFRunLoopObserverCallBack) wxCFEventLoop::OSXDefaultModeObserverCallBack, &ctxt ); CFRunLoopAddObserver(m_runLoop, m_defaultModeRunLoopObserver, kCFRunLoopDefaultMode); CFRelease(m_defaultModeRunLoopObserver); }
static int start_message_port_runloop() { int status = UIOHOOK_FAILURE; if (tis_message != NULL) { // Create a runloop observer for the main runloop. observer = CFRunLoopObserverCreate( kCFAllocatorDefault, kCFRunLoopExit, //kCFRunLoopEntry | kCFRunLoopExit, //kCFRunLoopAllActivities, true, 0, message_port_status_proc, NULL ); if (observer != NULL) { pthread_mutex_lock(&msg_port_mutex); CFRunLoopSourceContext context = { .version = 0, .info = tis_message, .retain = NULL, .release = NULL, .copyDescription = NULL, .equal = NULL, .hash = NULL, .schedule = NULL, .cancel = NULL, .perform = message_port_proc }; CFRunLoopRef main_loop = CFRunLoopGetMain(); src_msg_port = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context); if (src_msg_port != NULL) { CFRunLoopAddSource(main_loop, src_msg_port, kCFRunLoopDefaultMode); CFRunLoopAddObserver(main_loop, observer, kCFRunLoopDefaultMode); logger(LOG_LEVEL_DEBUG, "%s [%u]: Successful.\n", __FUNCTION__, __LINE__); status = UIOHOOK_SUCCESS; } else { logger(LOG_LEVEL_ERROR, "%s [%u]: CFRunLoopSourceCreate failure!\n", __FUNCTION__, __LINE__); status = UIOHOOK_ERROR_CREATE_RUN_LOOP_SOURCE; } pthread_mutex_unlock(&msg_port_mutex); } else {
wxCFEventLoop::wxCFEventLoop() { m_shouldExit = false; m_processIdleEvents = true; #if wxUSE_UIACTIONSIMULATOR m_shouldWaitForEvent = false; #endif m_runLoop = CFGetCurrentRunLoop(); CFRunLoopObserverContext ctxt; bzero( &ctxt, sizeof(ctxt) ); ctxt.info = this; m_commonModeRunLoopObserver = CFRunLoopObserverCreate( kCFAllocatorDefault, kCFRunLoopBeforeTimers | kCFRunLoopBeforeWaiting , true /* repeats */, 0, (CFRunLoopObserverCallBack) wxCFEventLoop::OSXCommonModeObserverCallBack, &ctxt ); CFRunLoopAddObserver(m_runLoop, m_commonModeRunLoopObserver, kCFRunLoopCommonModes); m_defaultModeRunLoopObserver = CFRunLoopObserverCreate( kCFAllocatorDefault, kCFRunLoopBeforeTimers | kCFRunLoopBeforeWaiting , true /* repeats */, 0, (CFRunLoopObserverCallBack) wxCFEventLoop::OSXDefaultModeObserverCallBack, &ctxt ); CFRunLoopAddObserver(m_runLoop, m_defaultModeRunLoopObserver, kCFRunLoopDefaultMode); }
void RunLoopObserver::schedule(CFRunLoopRef runLoop, CFRunLoopActivity activity) { if (!runLoop) runLoop = CFRunLoopGetCurrent(); // Make sure we wake up the loop or the observer could be delayed until some other source fires. CFRunLoopWakeUp(runLoop); if (m_runLoopObserver) return; CFRunLoopObserverContext context = { 0, this, 0, 0, 0 }; m_runLoopObserver = adoptCF(CFRunLoopObserverCreate(0, activity, true, m_order, runLoopObserverFired, &context)); CFRunLoopAddObserver(runLoop, m_runLoopObserver.get(), kCFRunLoopCommonModes); }
int InputHandler_MacOSX_HID::Run( void *data ) { InputHandler_MacOSX_HID *This = (InputHandler_MacOSX_HID *)data; This->m_LoopRef = CFRunLoopGetCurrent(); CFRetain( This->m_LoopRef ); This->StartDevices(); { const RString sError = SetThreadPrecedence( 1.0f ); if( !sError.empty() ) LOG->Warn( "Could not set precedence of the input thread: %s", sError.c_str() ); } // Add an observer for the start of the run loop { /* The function copies the information out of the structure, so the memory * pointed to by context does not need to persist beyond the function call. */ CFRunLoopObserverContext context = { 0, &This->m_Sem, NULL, NULL, NULL }; CFRunLoopObserverRef o = CFRunLoopObserverCreate( kCFAllocatorDefault, kCFRunLoopEntry, false, 0, RunLoopStarted, &context); CFRunLoopAddObserver( This->m_LoopRef, o, kCFRunLoopDefaultMode ); } /* Add a source for ending the run loop. This serves two purposes: * 1. it provides a way to terminate the run loop when IH_MacOSX_HID exists, * and 2. it ensures that CFRunLoopRun() doesn't return immediately if * there are no other sources. */ { /* Being a little tricky here, the perform callback takes a void* and * returns nothing. CFRunLoopStop takes a CFRunLoopRef (a pointer) so * cast the function and pass the loop ref. */ void *info = This->m_LoopRef; void (*perform)(void *) = (void (*)(void *))CFRunLoopStop; // { version, info, retain, release, copyDescription, equal, hash, schedule, cancel, perform } CFRunLoopSourceContext context = { 0, info, NULL, NULL, NULL, NULL, NULL, NULL, NULL, perform }; // Pass 1 so that it is called after all inputs have been handled (they will have order = 0) This->m_SourceRef = CFRunLoopSourceCreate( kCFAllocatorDefault, 1, &context ); CFRunLoopAddSource( This->m_LoopRef, This->m_SourceRef, kCFRunLoopDefaultMode ); } CFRunLoopRun(); LOG->Trace( "Shutting down input handler thread..." ); return 0; }
void LayerFlushScheduler::schedule() { if (m_isSuspended) return; CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent(); // Make sure we wake up the loop or the observer could be delayed until some other source fires. CFRunLoopWakeUp(currentRunLoop); if (m_runLoopObserver) return; CFRunLoopObserverContext context = { 0, this, 0, 0, 0 }; m_runLoopObserver = adoptCF(CFRunLoopObserverCreate(0, kCFRunLoopBeforeWaiting | kCFRunLoopExit, true, LayerFlushRunLoopOrder, runLoopObserverCallback, &context)); CFRunLoopAddObserver(currentRunLoop, m_runLoopObserver.get(), kCFRunLoopCommonModes); }
int main(int argc, char * argv[]) { int a_flag = 0; struct ether_addr AP_mac; int ch; boolean_t disassociate = FALSE; const char * if_name = NULL; boolean_t has_wireless; const char * key_str = NULL; const char * network = NULL; int scan_current_ssid = FALSE; struct sockaddr_dl w; wireless_t wref; while ((ch = getopt(argc, argv, "adhHi:k:sx:")) != EOF) { switch ((char)ch) { case 'a': a_flag = 1; break; case 'h': case 'H': EAPLOG(LOG_ERR, "usage: wireless [ -i <interface> ] ( -d | -k | -x <ssid> | -s [ -a ])\n"); exit(0); break; case 'x': /* join network */ network = optarg; break; case 'k': /* set the wireless key */ key_str = optarg; break; case 'd': disassociate = TRUE; break; case 'i': /* specify the interface */ if_name = optarg; break; case 's': scan_current_ssid = TRUE; break; default: break; } } if (if_name != NULL) { if (wireless_bind(if_name, &wref) == FALSE) { printf("interface '%s' is not present or not AirPort\n", if_name); exit(1); } } else if ((if_name = wireless_first(&wref)) == NULL) { printf("no AirPort card\n"); exit(0); } get_mac_address(if_name, &w); printf("AirPort: %s %s\n", if_name, ether_ntoa((struct ether_addr *)(w.sdl_data + w.sdl_nlen))); if (wireless_ap_mac(wref, &AP_mac) == FALSE) { printf("Not associated\n"); } else { CFStringRef ssid; printf("Access Point: %s\n", ether_ntoa(&AP_mac)); ssid = wireless_copy_ssid_string(wref); if (ssid != NULL) { printf("SSID: "); fflush(stdout); CFShow(ssid); fflush(stderr); } if (wireless_is_wpa_enterprise(wref) == TRUE) { printf("WPA Enterprise\n"); } else { printf("Not WPA Enterprise\n"); } if (disassociate) { wireless_disassociate(wref); goto done; } else if (scan_current_ssid) { if (a_flag) { if (wireless_async_scan_ssid(wref, ssid)) { CFRunLoopObserverContext context = { 0, NULL, NULL, NULL, NULL }; CFRunLoopObserverRef observer; struct ssid_wref ref; ref.ssid = ssid; ref.wref = wref; context.info = &ref; observer = CFRunLoopObserverCreate(NULL, kCFRunLoopBeforeWaiting, TRUE, 0, before_blocking, &context); if (observer != NULL) { CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode); } else { EAPLOG(LOG_ERR, "start_initialization: " "CFRunLoopObserverCreate failed!"); } CFRunLoopRun(); } else { exit(1); } } else { wireless_scan_ssid(wref, ssid); } } my_CFRelease(&ssid); } if (key_str) { uint8_t key[13]; int key_len; int hex_len = strlen(key_str); if (hex_len & 0x1) { EAPLOG(LOG_ERR, "invalid key, odd number of hex bytes\n"); exit(1); } key_len = hex_len / 2; switch (key_len) { case 5: case 13: hexstrtobin(key_str, hex_len, key, key_len); if (wireless_set_key(wref, 0, 0, key, key_len) == FALSE) { EAPLOG(LOG_ERR, "wireless_set_key failed\n"); } break; default: EAPLOG(LOG_ERR, "invalid key length %d," " must be 5 or 13 hex bytes\n", key_len); exit(1); break; } } else if (network != NULL) { CFDataRef data; CFStringRef ssid_str; data = CFDataCreateWithBytesNoCopy(NULL, (const UInt8 *)network, strlen(network), kCFAllocatorNull); ssid_str = ssid_string_from_data(data); EAPLOG(LOG_ERR, "attempting to join network '%s'\n", network); if (wireless_join(wref, ssid_str) == FALSE) { EAPLOG(LOG_ERR, "wireless_join failed\n"); } } done: wireless_free(wref); exit(0); return (0); }
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); }