//--------------------------------------------------------------------------- void ofQuickTimePlayer::update(){ if (bLoaded == true){ //-------------------------------------------------------------- #ifdef OF_VIDEO_PLAYER_QUICKTIME //-------------------------------------------------------------- // is this necessary on windows with quicktime? #ifdef TARGET_OSX // call MoviesTask if we're not on the main thread if ( CFRunLoopGetCurrent() != CFRunLoopGetMain() ) { //ofLog( OF_LOG_NOTICE, "not on the main loop, calling MoviesTask") ; MoviesTask(moviePtr,0); } #else // on windows we always call MoviesTask MoviesTask(moviePtr,0); #endif //-------------------------------------------------------------- #endif //-------------------------------------------------------------- } // --------------------------------------------------- // on all platforms, // do "new"ness ever time we idle... // before "isFrameNew" was clearning, // people had issues with that... // and it was badly named so now, newness happens // per-idle not per isNew call // --------------------------------------------------- if (bLoaded == true){ bIsFrameNew = bHavePixelsChanged; if (bHavePixelsChanged == true) { bHavePixelsChanged = false; } } }
void osx_pad_init(void) { if (g_hid_manager) return; g_hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); CFMutableArrayRef matcher = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); append_matching_dictionary(matcher, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick); append_matching_dictionary(matcher, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad); IOHIDManagerSetDeviceMatchingMultiple(g_hid_manager, matcher); CFRelease(matcher); IOHIDManagerRegisterDeviceMatchingCallback(g_hid_manager, hid_manager_device_attached, 0); IOHIDManagerScheduleWithRunLoop(g_hid_manager, CFRunLoopGetMain(), kCFRunLoopCommonModes); IOHIDManagerOpen(g_hid_manager, kIOHIDOptionsTypeNone); }
void start_watches() { CFStringRef watch_paths[100]; int path_count = 0; int i; for (i = 0; i < 100; i += 1) { if (NULL != FSEVENTS_GLOBAL(watches)[i].path) { watch_paths[i] = CFStringCreateWithCString(NULL, FSEVENTS_GLOBAL(watches)[i].path, kCFStringEncodingUTF8); path_count++; } } void *callback_info = NULL; // could put stream-specific data here. CFArrayRef watch_path_array = CFArrayCreate(NULL, (void *) watch_paths, path_count, NULL); CFAbsoluteTime latency = .75; /* Latency in seconds */ CFRunLoopRef run_loop = CFRunLoopGetMain(); FSEventStreamRef stream; /* Create the stream, passing in a callback */ stream = FSEventStreamCreate( NULL, (FSEventStreamCallback)&handle_events, callback_info, watch_path_array, kFSEventStreamEventIdSinceNow, latency, kFSEventStreamCreateFlagNone ); FSEventStreamScheduleWithRunLoop( stream, run_loop, kCFRunLoopDefaultMode ); FSEventStreamStart(stream); CFRunLoopRun(); FSEventStreamFlushSync(stream); FSEventStreamStop(stream); }
internal inline void ConfigureRunLoop() { KWMMach.EventMask = ((1 << kCGEventMouseMoved) | (1 << kCGEventLeftMouseDragged) | (1 << kCGEventLeftMouseDown) | (1 << kCGEventLeftMouseUp) | (1 << kCGEventRightMouseDragged) | (1 << kCGEventRightMouseDown) | (1 << kCGEventRightMouseUp)); KWMMach.EventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault, KWMMach.EventMask, CGEventCallback, NULL); if(!KWMMach.EventTap || !CGEventTapIsEnabled(KWMMach.EventTap)) Fatal("Error: Could not create event-tap!"); CFRunLoopAddSource(CFRunLoopGetMain(), CFMachPortCreateRunLoopSource(kCFAllocatorDefault, KWMMach.EventTap, 0), kCFRunLoopCommonModes); }
void start_remote_debug_server(AMDeviceRef device) { assert(AMDeviceStartService(device, CFSTR("com.apple.debugserver"), &gdbfd, NULL) == 0); CFSocketRef fdvendor = CFSocketCreate(NULL, AF_UNIX, 0, 0, kCFSocketAcceptCallBack, &fdvendor_callback, NULL); int yes = 1; setsockopt(CFSocketGetNative(fdvendor), SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); struct sockaddr_un address; memset(&address, 0, sizeof(address)); address.sun_family = AF_UNIX; strcpy(address.sun_path, FDVENDOR_PATH); CFDataRef address_data = CFDataCreate(NULL, (const UInt8 *)&address, sizeof(address)); unlink(FDVENDOR_PATH); CFSocketSetAddress(fdvendor, address_data); CFRelease(address_data); CFRunLoopAddSource(CFRunLoopGetMain(), CFSocketCreateRunLoopSource(NULL, fdvendor, 0), kCFRunLoopCommonModes); }
dump_hid_value(void) { manager_ = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); if (!manager_) { return; } auto device_matching_dictionaries = iokit_utility::create_device_matching_dictionaries({ std::make_pair(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard), std::make_pair(kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse), std::make_pair(kHIDPage_GenericDesktop, kHIDUsage_GD_Pointer), }); if (device_matching_dictionaries) { IOHIDManagerSetDeviceMatchingMultiple(manager_, device_matching_dictionaries); CFRelease(device_matching_dictionaries); IOHIDManagerRegisterDeviceMatchingCallback(manager_, static_device_matching_callback, this); IOHIDManagerRegisterDeviceRemovalCallback(manager_, static_device_removal_callback, this); IOHIDManagerScheduleWithRunLoop(manager_, CFRunLoopGetMain(), kCFRunLoopDefaultMode); } }
TorcUSBPrivOSX::~TorcUSBPrivOSX() { // free outstanding notifications LOG(VB_GENERAL, LOG_DEBUG, QString("%1 outstanding notifications").arg(m_notifications.size())); { QMutexLocker locker(m_notificationsLock); QMap<io_service_t,QPair<io_object_t,QString> >::iterator it = m_notifications.begin(); for ( ; it != m_notifications.end(); ++it) { QPair<io_object_t,QString> pair = it.value(); IOObjectRelease(pair.first); } m_notifications.clear(); } // release source - for some reason this is unsafe when running outside of the main runloop. if (m_usbRef && gAdminRunLoop && gAdminRunLoop != CFRunLoopGetMain()) { CFRunLoopRemoveSource(gAdminRunLoop, m_usbRef, kCFRunLoopDefaultMode); CFRelease(m_usbRef); m_usbRef = NULL; } // release notify port if (m_usbNotifyPort) { IONotificationPortDestroy(m_usbNotifyPort); m_usbNotifyPort = NULL; } // release iterator if (m_iterator) IOObjectRelease(m_iterator); m_iterator = 0; // delete lock delete m_notificationsLock; m_notificationsLock = NULL; }
bool TCPStream_CFNetwork::connect() { state = Stream::State::Opening; CFStringRef host_cfstring = CFStringCreateWithCString(kCFAllocatorDefault, remoteHostName.c_str(), kCFStringEncodingUTF8); CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, host_cfstring, remotePortNumber, &inputStream, &outputStream); CFRelease(host_cfstring); CFStreamClientContext inputStreamContext; memset(&inputStreamContext, 0, sizeof(inputStreamContext)); inputStreamContext.info = reinterpret_cast<void *>(this); CFReadStreamSetClient(inputStream, kCFStreamEventHasBytesAvailable | kCFStreamEventEndEncountered | kCFStreamEventErrorOccurred, inputStreamCallback, &inputStreamContext); CFReadStreamScheduleWithRunLoop(inputStream, CFRunLoopGetMain(), kCFRunLoopDefaultMode); if (CFReadStreamOpen(inputStream) && CFWriteStreamOpen(outputStream)) { state = Stream::State::Open; return true; } else { CFRelease(outputStream); CFRelease(inputStream); outputStream = nullptr; inputStream = nullptr; state = Stream::State::NotOpen; return false; } }
void DNSResolveQueue::platformResolve(const String& hostname) { ASSERT(isMainThread()); RetainPtr<CFHostRef> host = adoptCF(CFHostCreateWithName(0, hostname.createCFString().get())); if (!host) { decrementRequestCount(); return; } CFHostClientContext context = { 0, 0, 0, 0, 0 }; CFHostRef leakedHost = host.leakRef(); // The host will be released from clientCallback(). Boolean result = CFHostSetClient(leakedHost, clientCallback, &context); ASSERT_UNUSED(result, result); #if !PLATFORM(WIN) CFHostScheduleWithRunLoop(leakedHost, CFRunLoopGetMain(), kCFRunLoopCommonModes); #else // On Windows, we run a separate thread with CFRunLoop, which is where clientCallback will be called. CFHostScheduleWithRunLoop(leakedHost, loaderRunLoop(), kCFRunLoopDefaultMode); #endif CFHostStartInfoResolution(leakedHost, kCFHostAddresses, 0); }
osxPointingDeviceManager::osxPointingDeviceManager() { manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); if (!manager) throw std::runtime_error("IOHIDManagerCreate failed"); const char *plist = hidDeviceFromVendorProductUsagePageUsage(0, 0, kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse).c_str(); CFMutableDictionaryRef device_match = (CFMutableDictionaryRef)getPropertyListFromXML(plist); IOHIDManagerSetDeviceMatching(manager, device_match); IOHIDManagerRegisterDeviceMatchingCallback(manager, AddDevice, (void*)this); IOHIDManagerRegisterDeviceRemovalCallback(manager, RemoveDevice, (void*)this); #if USE_CURRENT_RUNLOOP CFRunLoopRef runLoop = CFRunLoopGetCurrent(); CFStringRef runLoopMode = kCFRunLoopDefaultMode; #else CFRunLoopRef runLoop = CFRunLoopGetMain(); CFStringRef runLoopMode = kCFRunLoopCommonModes; #endif IOHIDManagerScheduleWithRunLoop(manager, runLoop, runLoopMode); }
void DNSResolveQueue::resolve(const String& hostname) { ASSERT(isMainThread()); RetainPtr<CFStringRef> hostnameCF(AdoptCF, hostname.createCFString()); RetainPtr<CFHostRef> host(AdoptCF, CFHostCreateWithName(0, hostnameCF.get())); if (!host) { atomicDecrement(&m_requestsInFlight); return; } CFHostClientContext context = { 0, 0, 0, 0, 0 }; Boolean result = CFHostSetClient(host.get(), clientCallback, &context); ASSERT_UNUSED(result, result); #if !PLATFORM(WIN) CFHostScheduleWithRunLoop(host.get(), CFRunLoopGetMain(), kCFRunLoopCommonModes); #else // On Windows, we run a separate thread with CFRunLoop, which is where clientCallback will be called. CFHostScheduleWithRunLoop(host.get(), loaderRunLoop(), kCFRunLoopDefaultMode); #endif CFHostStartInfoResolution(host.get(), kCFHostAddresses, 0); host.releaseRef(); // The host will be released from clientCallback(). }
void MacRunLoopStop() { pthread_mutex_lock(&run_loop_mutex); while(1) { if (run_loop_state == RLS_BEFORE_START) { pthread_cond_wait(&run_loop_cv, &run_loop_mutex); } else if (run_loop_state == RLS_STARTED) { run_loop_state = RLS_TERMINATING; CFRunLoopStop(CFRunLoopGetMain()); pthread_cond_signal(&run_loop_cv); while (run_loop_state == RLS_TERMINATING) { pthread_cond_wait(&run_loop_cv, &run_loop_mutex); } break; } else { /* * Assume either RLS_TERMINATING (called twice) or RLS_TERMINATED */ break; } } pthread_mutex_unlock(&run_loop_mutex); }
void Create(void) { Destroy(); if (!gLocalContext->FlagIsSet(Torc::AdminThread)) { gAdminRunLoop = CFRunLoopGetMain(); return; } m_createdThread = true; gAdminRunLoopRunning.ref(); m_thread = new TorcOSXCallbackThread(); m_thread->start(); int count = 0; while (count++ < 10 && !m_thread->isRunning()) QThread::msleep(count < 2 ? 10 : 100); if (!m_thread->isRunning()) LOG(VB_GENERAL, LOG_WARNING, "OS X callback thread not started yet!"); }
void CreateApplicationNotifications() { DestroyApplicationNotifications(); if(KWMFocus.Window) { KWMFocus.Application = AXUIElementCreateApplication(KWMFocus.Window->PID); if(!KWMFocus.Application) return; AXError Error = AXObserverCreate(KWMFocus.Window->PID, FocusedAXObserverCallback, &KWMFocus.Observer); if(Error == kAXErrorSuccess) { AXObserverAddNotification(KWMFocus.Observer, KWMFocus.Application, kAXWindowMiniaturizedNotification, NULL); AXObserverAddNotification(KWMFocus.Observer, KWMFocus.Application, kAXWindowMovedNotification, NULL); AXObserverAddNotification(KWMFocus.Observer, KWMFocus.Application, kAXWindowResizedNotification, NULL); AXObserverAddNotification(KWMFocus.Observer, KWMFocus.Application, kAXTitleChangedNotification, NULL); AXObserverAddNotification(KWMFocus.Observer, KWMFocus.Application, kAXFocusedWindowChangedNotification, NULL); AXObserverAddNotification(KWMFocus.Observer, KWMFocus.Application, kAXUIElementDestroyedNotification, NULL); CFRunLoopAddSource(CFRunLoopGetMain(), AXObserverGetRunLoopSource(KWMFocus.Observer), kCFRunLoopDefaultMode); } } }
bool wxOSXTimerImpl::Start( int milliseconds, bool mode ) { (void)wxTimerImpl::Start(milliseconds, mode); wxCHECK_MSG( m_milli > 0, false, wxT("invalid value for timer timeout") ); wxCHECK_MSG( m_info->m_timerRef == NULL, false, wxT("attempting to restart a timer") ); CFGregorianUnits gumilli ; memset(&gumilli,0,sizeof(gumilli) ); gumilli.seconds = m_milli / 1000.0; CFRunLoopTimerContext ctx ; memset( &ctx, 0 , sizeof(ctx) ); ctx.version = 0; ctx.info = this; m_info->m_timer = this; m_info->m_timerRef = CFRunLoopTimerCreate( kCFAllocatorDefault, CFAbsoluteTimeAddGregorianUnits( CFAbsoluteTimeGetCurrent() , NULL, gumilli ), IsOneShot() ? 0 : CFTimeInterval( m_milli / 1000.0 ) , 0, 0, wxProcessTimer, &ctx); wxASSERT_MSG( m_info->m_timerRef != NULL, wxT("unable to create timer")); CFRunLoopRef runLoop = 0; #if wxOSX_USE_IPHONE runLoop = CFRunLoopGetMain(); #else runLoop = CFRunLoopGetCurrent(); #endif CFRunLoopAddTimer( runLoop, m_info->m_timerRef, kCFRunLoopCommonModes) ; return true; }
NetworkStateNotifier::NetworkStateNotifier() : m_isOnLine(false) , m_networkStateChangedFunction(0) , m_networkStateChangeTimer(this, &NetworkStateNotifier::networkStateChangeTimerFired) { SCDynamicStoreContext context = { 0, this, 0, 0, 0 }; m_store.adoptCF(SCDynamicStoreCreate(0, CFSTR("com.apple.WebCore"), dynamicStoreCallback, &context)); if (!m_store) return; RetainPtr<CFRunLoopSourceRef> configSource = SCDynamicStoreCreateRunLoopSource(0, m_store.get(), 0); if (!configSource) return; CFRunLoopAddSource(CFRunLoopGetMain(), configSource.get(), kCFRunLoopCommonModes); RetainPtr<CFMutableArrayRef> keys(AdoptCF, CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks)); RetainPtr<CFMutableArrayRef> patterns(AdoptCF, CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks)); RetainPtr<CFStringRef> key; RetainPtr<CFStringRef> pattern; key.adoptCF(SCDynamicStoreKeyCreateNetworkGlobalEntity(0, kSCDynamicStoreDomainState, kSCEntNetIPv4)); CFArrayAppendValue(keys.get(), key.get()); pattern.adoptCF(SCDynamicStoreKeyCreateNetworkInterfaceEntity(0, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv4)); CFArrayAppendValue(patterns.get(), pattern.get()); key.adoptCF(SCDynamicStoreKeyCreateNetworkGlobalEntity(0, kSCDynamicStoreDomainState, kSCEntNetDNS)); CFArrayAppendValue(keys.get(), key.get()); SCDynamicStoreSetNotificationKeys(m_store.get(), keys.get(), patterns.get()); updateState(); }
CZeroconfOSX::CZeroconfOSX():m_runloop(0) { //aquire the main threads event loop m_runloop = CFRunLoopGetMain(); }
static void do_iteration(void) { int ret = rarch_main_iterate(); if (ret == -1) { main_exit(NULL); return; } CFRunLoopWakeUp(CFRunLoopGetMain()); /* TODO/FIXME I am almost positive that this is not necessary and is actually a bad thing. 1st. Why it is bad thing. This wakes up the main event loop immediately and the main loop has only one observer, which is this function. In other words, this causes the function to be called immediately. I did an experiment where I saved the time before calling this and then reported the difference between it and the start of do_iteration, and as expected it was about 0. As a result, when we remove this, idle performance (i.e. displaying the RetroArch menu) is 0% CPU as desired. 2nd. Why it is not necessary. The event loop will wake up itself when there is input to the process. This includes touch events, keyboard, bluetooth, etc. Thus, it will be woken up and without any intervention so that we can process that event. Nota bene. Why this analysis might be wrong (and what to do about it). If RA is not idle and is running a core, then I believe it is designed to expect to be called in a busy loop like this because it implements its own frame timer to ensure that the emulation simulation isn't too fast. In that case, this change would only allow emulation to run when there was input, which would make all games turn-based. :) There are two good ways to fix this and still have the desired 0% CPU idle behavior. Approach 1: Change main_entry_decide from returning a boolean (two-values) that are interpreted as CONTINUE and QUIT. Into returning a char-sized enum with three values that are interpreted as QUIT, WAIT, and AGAIN, such that QUIT calls main_exit, WAIT doesn't wake up the loop, and AGAIN does. It would then return AGAIN when a core was active. An ugly way to get the same effect is to look have this code just look at g_extern.is_menu and use the WAIT behavior in that case. Approach 2: Instead of signalling outside of RA whether a core is running, instead externalize the frame time that is inside retroarch. change main_entry_decide to return a value in [-1,MAX_INT] where -1 is interpreted as QUIT, [0,MAX_INT) is interpreted as the amount of time to wait until continuing, and MAX_INT is interpreted as WAIT. This could be more robust because we'd be exposing the scheduling behavior of RA to iOS, which might be good in other platforms as well. Approach 1 is the simplest and essentially just pushes down these requirements to rarch_main_iterate. I have gone with the "ugly way" first because it is the most expedient and safe. Other eyeballs should decide if it isn't necessary. */ }
// NOTE: The following callback executes on the same thread that hook_run() is called // from. This is important because hook_run() attaches to the operating systems // event dispatcher and may delay event delivery to the target application. // Furthermore, some operating systems may choose to disable your hook if it // takes to long to process. If you need to do any extended processing, please // do so by copying the event to your own queued dispatch thread. void dispatch_proc(uiohook_event * const event) { char buffer[256] = { 0 }; size_t length = snprintf(buffer, sizeof(buffer), "id=%i,when=%" PRIu64 ",mask=0x%X", event->type, event->time, event->mask); switch (event->type) { case EVENT_HOOK_ENABLED: // Lock the running mutex so we know if the hook is enabled. #ifdef _WIN32 WaitForSingleObject(hook_running_mutex, INFINITE); #else pthread_mutex_lock(&hook_running_mutex); #endif #ifdef _WIN32 // Signal the control event. SetEvent(hook_control_cond); #else // Unlock the control mutex so hook_enable() can continue. pthread_cond_signal(&hook_control_cond); pthread_mutex_unlock(&hook_control_mutex); #endif break; case EVENT_HOOK_DISABLED: // Lock the control mutex until we exit. #ifdef _WIN32 WaitForSingleObject(hook_control_mutex, INFINITE); #else pthread_mutex_lock(&hook_control_mutex); #endif // Unlock the running mutex so we know if the hook is disabled. #ifdef _WIN32 ReleaseMutex(hook_running_mutex); ResetEvent(hook_control_cond); #else #if defined(__APPLE__) && defined(__MACH__) // Stop the main runloop so that this program ends. CFRunLoopStop(CFRunLoopGetMain()); #endif pthread_mutex_unlock(&hook_running_mutex); #endif break; case EVENT_KEY_PRESSED: // If the escape key is pressed, naturally terminate the program. if (event->data.keyboard.keycode == VC_ESCAPE) { int status = hook_stop(); switch (status) { // System level errors. case UIOHOOK_ERROR_OUT_OF_MEMORY: logger_proc(LOG_LEVEL_ERROR, "Failed to allocate memory. (%#X)", status); break; case UIOHOOK_ERROR_X_RECORD_GET_CONTEXT: // NOTE This is the only platform specific error that occurs on hook_stop(). logger_proc(LOG_LEVEL_ERROR, "Failed to get XRecord context. (%#X)", status); break; // Default error. case UIOHOOK_FAILURE: default: logger_proc(LOG_LEVEL_ERROR, "An unknown hook error occurred. (%#X)", status); break; } } case EVENT_KEY_RELEASED: snprintf(buffer + length, sizeof(buffer) - length, ",keycode=%u,rawcode=0x%X", event->data.keyboard.keycode, event->data.keyboard.rawcode); break; case EVENT_KEY_TYPED: snprintf(buffer + length, sizeof(buffer) - length, ",keychar=%lc,rawcode=%u", (wint_t) event->data.keyboard.keychar, event->data.keyboard.rawcode); break; case EVENT_MOUSE_PRESSED: case EVENT_MOUSE_RELEASED: case EVENT_MOUSE_CLICKED: case EVENT_MOUSE_MOVED: case EVENT_MOUSE_DRAGGED: snprintf(buffer + length, sizeof(buffer) - length, ",x=%i,y=%i,button=%i,clicks=%i", event->data.mouse.x, event->data.mouse.y, event->data.mouse.button, event->data.mouse.clicks); break; case EVENT_MOUSE_WHEEL: snprintf(buffer + length, sizeof(buffer) - length, ",type=%i,amount=%i,rotation=%i", event->data.wheel.type, event->data.wheel.amount, event->data.wheel.rotation); break; default: break; } fprintf(stdout, "%s\n", buffer); }
static void DeviceNotificationCallback(am_device_notification_callback_info *info, void *unknown) { struct am_device *device = info->dev; switch (info->msg) { case ADNCI_MSG_CONNECTED: { if (debug) { CFStringRef deviceId = AMDeviceCopyDeviceIdentifier(device); CFStringRef str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("deviceconsole connected: %@"), deviceId); CFRelease(deviceId); CFShow(str); CFRelease(str); } if (requiredDeviceId) { CFStringRef deviceId = AMDeviceCopyDeviceIdentifier(device); Boolean isRequiredDevice = CFEqual(deviceId, requiredDeviceId); CFRelease(deviceId); if (!isRequiredDevice) break; } if (AMDeviceConnect(device) == MDERR_OK) { if (AMDeviceIsPaired(device) && (AMDeviceValidatePairing(device) == MDERR_OK)) { if (AMDeviceStartSession(device) == MDERR_OK) { service_conn_t connection; if (AMDeviceStartService(device, AMSVC_SYSLOG_RELAY, &connection, NULL) == MDERR_OK) { CFSocketRef socket = CFSocketCreateWithNative(kCFAllocatorDefault, connection, kCFSocketDataCallBack, SocketCallback, NULL); if (socket) { CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0); if (source) { CFRunLoopAddSource(CFRunLoopGetMain(), source, kCFRunLoopCommonModes); AMDeviceRetain(device); DeviceConsoleConnection *data = malloc(sizeof *data); data->connection = connection; data->socket = socket; data->source = source; CFDictionarySetValue(liveConnections, device, data); return; } CFRelease(source); } } AMDeviceStopSession(device); } } } AMDeviceDisconnect(device); break; } case ADNCI_MSG_DISCONNECTED: { if (debug) { CFStringRef deviceId = AMDeviceCopyDeviceIdentifier(device); CFStringRef str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("deviceconsole disconnected: %@"), deviceId); CFRelease(deviceId); CFShow(str); CFRelease(str); } DeviceConsoleConnection *data = (DeviceConsoleConnection *)CFDictionaryGetValue(liveConnections, device); if (data) { CFDictionaryRemoveValue(liveConnections, device); AMDeviceRelease(device); CFRunLoopRemoveSource(CFRunLoopGetMain(), data->source, kCFRunLoopCommonModes); CFRelease(data->source); CFRelease(data->socket); free(data); AMDeviceStopSession(device); AMDeviceDisconnect(device); } break; } default: break; } }
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { WNDPROC parentProc = (gWinLauncher) ? (gWinLauncher->usesLayeredWebView() ? DefWebKitProc : DefWindowProc) : DefWindowProc; switch (message) { case WM_NCHITTEST: if (gWinLauncher && gWinLauncher->usesLayeredWebView()) { RECT window; ::GetWindowRect(hWnd, &window); // For testing our transparent window, we need a region to use as a handle for // dragging. The right way to do this would be to query the web view to see what's // under the mouse. However, for testing purposes we just use an arbitrary // 30 pixel band at the top of the view as an arbitrary gripping location. // // When we are within this bad, return HT_CAPTION to tell Windows we want to // treat this region as if it were the title bar on a normal window. int y = HIWORD(lParam); if ((y > window.top) && (y < window.top + dragBarHeight)) return HTCAPTION; } return CallWindowProc(parentProc, hWnd, message, wParam, lParam); case WM_COMMAND: { int wmId = LOWORD(wParam); int wmEvent = HIWORD(wParam); if (wmId >= IDM_HISTORY_LINK0 && wmId <= IDM_HISTORY_LINK9) { if (gWinLauncher) gWinLauncher->navigateToHistory(hWnd, wmId); break; } // Parse the menu selections: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; case IDM_PRINT: PrintView(hWnd, message, wParam, lParam); break; case IDM_WEB_INSPECTOR: if (gWinLauncher) gWinLauncher->launchInspector(); break; case IDM_CACHES: if (!::IsWindow(hCacheWnd)) { hCacheWnd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_CACHES), hWnd, Caches); ::ShowWindow(hCacheWnd, SW_SHOW); } break; case IDM_HISTORY_BACKWARD: case IDM_HISTORY_FORWARD: if (gWinLauncher) gWinLauncher->navigateForwardOrBackward(hWnd, wmId); break; case IDM_AVFOUNDATION: case IDM_ACC_COMPOSITING: case IDM_WK_FULLSCREEN: case IDM_COMPOSITING_BORDERS: case IDM_DISABLE_IMAGES: case IDM_DISABLE_STYLES: case IDM_DISABLE_JAVASCRIPT: case IDM_DISABLE_LOCAL_FILE_RESTRICTIONS: ToggleMenuItem(hWnd, wmId); break; default: return CallWindowProc(parentProc, hWnd, message, wParam, lParam); } } break; case WM_DESTROY: #if USE(CF) CFRunLoopStop(CFRunLoopGetMain()); #endif PostQuitMessage(0); break; case WM_SIZE: if (!gWinLauncher || !gWinLauncher->hasWebView() || gWinLauncher->usesLayeredWebView()) return CallWindowProc(parentProc, hWnd, message, wParam, lParam); resizeSubViews(); break; default: return CallWindowProc(parentProc, hWnd, message, wParam, lParam); } return 0; }
static void tearDown(void) { xsecdebug("exit"); CFRunLoopStop(CFRunLoopGetMain()); }
int main(int argc, char* argv[]) { //tint32 i0 = ITime::GetTimeMS(); // CAutoDelete<ge::IContext> pContext(ge::IContext::Create()); pContext = ge::IContext::Create(); pContext->SetCallback(new CContextCallback()); pContext->Init(); /* pContext->SetApplicationCallback(new CAppCallback()); gWndMain = pContext->CreateMainWindow(ge::SSize(1000, 680)); pContext->ShowWindow(gWndMain, false); */ gpHost = new CAppHost(); gpApp = new CApplication(); //tint32 i1 = ITime::GetTimeMS(); CKSModule* pModule = new CKSModule(gpHost); pContext->SetInstanceData((void*)pModule->GetInstanceHandle()); pContext->SetApplicationCallback(new CAppCallback()); #ifdef WIN32 gWndMain = pContext->CreateMainWindow(ge::SSize(1000, 680), IDC_KS_MENU, IDI_KS); #else WIN32 gWndMain = pContext->CreateMainWindow(ge::SSize(1000, 680)); #endif // #else WIN32 pContext->ShowWindow(gWndMain, false); gpPlugIn = dynamic_cast<CKSPlugIn*>(pModule->CreateProcess(0)); gpPlugIn->PreInitialize(); gpPlugIn->SetMaxBufferSize(512); gpPlugIn->SetSampleRate(44100); gpPlugIn->SetChannelConfiguration(0, 2, 0); gpPlugIn->Initialize(); gpPlugIn->Start(); //tint32 i2 = ITime::GetTimeMS(); // Make windows #ifdef _Mac gWndSplash = pContext->CreateExtraWindow((void*)CFSTR("SplashWnd"), ge::SSize(624, 375)); #endif #ifdef WIN32 gWndSplash = pContext->CreateExtraWindow((void*)"Welcome", ge::SSize(624, 375)); #endif pContext->ShowWindow(gWndSplash); gpGUITrackEdit = dynamic_cast<CKS_TrackEditor*>(gpPlugIn->CreateGUI(0)); gpSplashGUI = dynamic_cast<CKSSplashScreen*>(gpPlugIn->CreateGUI(1)); gpSplashGUI->MakeWindow(gWndSplash); gpSplashGUI->Paint(); /* InstallWindowEventHandler( gWndSplash, GetWindowEventHandlerUPP(), GetEventTypeCount( kWindowEvents ), kWindowEvents, gWndSplash, NULL );*/ /* static const EventTypeSpec kAppEvents[] = { { kEventClassCommand, kEventCommandProcess } };*/ //------------------------ #ifdef _Mac gWndMixer = pContext->CreateExtraWindow((void*)CFSTR("MixerWnd"), ge::SSize(1000, 382)); #endif #ifdef WIN32 gWndMixer = pContext->CreateExtraWindow((void*)"Koblo Studio Mixer", ge::SSize(1000, 382)); #endif gpGUIMixer = dynamic_cast<CKSMixerGUI*>(gpPlugIn->CreateGUI(2)); pContext->ShowWindow(gWndMixer, false); //------------------------ #ifdef _Mac gWndAUX = pContext->CreateExtraWindow((void*)CFSTR("AUXWnd"), ge::SSize(578, 700)); #endif #ifdef WIN32 gWndAUX = pContext->CreateExtraWindow((void*)"Koblo Studio AUX Rack", ge::SSize(578, 700)); #endif gpGUIAUX = dynamic_cast<CKSAUXGUI*>(gpPlugIn->CreateGUI(3)); pContext->ShowWindow(gWndAUX, false); //------------------------ #ifdef _Mac gWndExport = pContext->CreateExtraWindow((void*)CFSTR("ExportWnd"), ge::SSize(386, 242)); #endif #ifdef WIN32 gWndExport = pContext->CreateExtraWindow((void*)"Koblo Studio Export", ge::SSize(386, 242)); #endif gpGUIExport = dynamic_cast<CKSExportGUI*>(gpPlugIn->CreateGUI(5)); pContext->ShowWindow(gWndExport, false); //------------------------ #ifdef _Mac gWndExportForWeb = pContext->CreateExtraWindow((void*)CFSTR("ExportForWebWnd"), ge::SSize(541, 582)); #endif #ifdef WIN32 gWndExportForWeb = pContext->CreateExtraWindow((void*)"Koblo Studio Export For Web", ge::SSize(541, 582)); #endif gpGUIExportForWeb = dynamic_cast<CKSExportForWebGUI*>(gpPlugIn->CreateGUI(6)); pContext->ShowWindow(gWndExportForWeb, false); //------------------------ #ifdef _Mac gWndImport = pContext->CreateExtraWindow((void*)CFSTR("ImportWnd"), ge::SSize(423, 424)); #endif #ifdef WIN32 gWndImport = pContext->CreateExtraWindow((void*)"Koblo Studio Import", ge::SSize(423, 424)); #endif gpGUIImport = dynamic_cast<CKSImportGUI*>(gpPlugIn->CreateGUI(7)); pContext->ShowWindow(gWndImport, false); //------------------------ #ifdef _Mac gWndSetup = pContext->CreateExtraWindow((void*)CFSTR("SetupWnd"), ge::SSize(320, 218)); #endif #ifdef WIN32 gWndSetup = pContext->CreateExtraWindow((void*)"Koblo Studio Setup", ge::SSize(320, 218)); #endif gpGUISetup = dynamic_cast<CKSSetupGUI*>(gpPlugIn->CreateGUI(8)); pContext->ShowWindow(gWndSetup, false); // Notefy PlugIn that the gui is created gpPlugIn->GUI_Created(); // Notefy PlugIn that PlugIn windows created gpPlugIn->All_Plugins_Created(true); //tint32 i3 = ITime::GetTimeMS(); #ifdef _Mac CFRunLoopTimerContext ctxt; ctxt.version = 0; ctxt.info = (void*)gpPlugIn; ctxt.retain = 0; ctxt.release = 0; ctxt.copyDescription = 0; gTimer = ::CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + 0.05f, 0.05f, 0, 0, timerCallbackGUI, &ctxt); ::CFRunLoopAddTimer(CFRunLoopGetMain(), gTimer, kCFRunLoopCommonModes); #endif // _Mac // CStartUpThread* pThread = new CStartUpThread(); //tint32 i4 = ITime::GetTimeMS(); //tint32 i1_0 = i1 - i0; //tint32 i2_1 = i2 - i1; //tint32 i3_2 = i3 - i2; //tint32 i4_3 = i4 - i3; //tchar pszMsg[512]; //sprintf(pszMsg, "i1_0=%d, i2_1=%d, i3_2=%d, i43=%d", i1_0, i2_1, i3_2, i4_3); //ShowMessageBox(pszMsg); pContext->RunMainLoop(); gbClosingDown = true; while (gbInAudioEngine) { } #ifdef WIN32 // (lasse) for Windows it's necessary to close the audio-device before exit to release resources // Maybe that's not so for OS X? gpDSPEngine->CloseAudioDevice_Duplex(); gpDSPEngine->CloseAudioDevice_Input(); gpDSPEngine->CloseAudioDevice_Output(); #endif // WIN32 return 0; // return err; }
/*************************************************************** * * MacIsMainThread - return true if the run loop of this thread * is the main run loop * ***************************************************************/ int MacIsMainThread() { return CFRunLoopGetCurrent() == CFRunLoopGetMain(); }
static void mode_changed() { switch (mmkd_mode) { /* * merge mode enabled: create event tap, cancel idle timer (if any) */ case 1: { if (idle_timer) { dispatch_source_cancel(idle_timer); dispatch_release(idle_timer); idle_timer = NULL; } if (!event_tap) { /* * reset ktab */ struct key_kind *i; for (i=ktab; i->kk_name; i++) i->kk_num_pressed = 0; /* * become root (this is neccessary in order to create event tap) */ seteuid(0); /* * based on alterkeys.c http://osxbook.com and http://dotdotcomorg.net */ CGEventMask event_mask; CFRunLoopSourceRef run_loop_source; // Create an event tap. We are interested in key presses. event_mask = ((1 << kCGEventKeyDown) | (1 << kCGEventKeyUp) | (1<<kCGEventFlagsChanged)); event_tap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0, event_mask, my_cg_event_callback, NULL); /* * revert to self */ seteuid(getuid()); if (!event_tap) { fprintf(stderr, "failed to create event tap\n"); return; } // Create a run loop source. run_loop_source = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, event_tap, 0); // Add to the current run loop. CFRunLoopAddSource(CFRunLoopGetMain(), run_loop_source, kCFRunLoopCommonModes); // Enable the event tap. CGEventTapEnable(event_tap, true); } return; } /* * merge mode disabled: remove event tap (if any), setup idle timer */ case 0: { if (event_tap) { CFMachPortInvalidate(event_tap); CFRelease(event_tap); event_tap = NULL; } if (!idle_timer) { idle_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); if (!idle_timer) { fprintf(stderr, "out of memory\n"); return; } dispatch_source_set_event_handler(idle_timer, ^{ CFRunLoopStop(CFRunLoopGetMain()); }); dispatch_source_set_timer(idle_timer, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC*5LL), -1, NSEC_PER_SEC*1LL); dispatch_resume(idle_timer); } return; }
/*! iSCSI daemon entry point. */ int main(void) { // Connect to the preferences .plist file associated with "iscsid" and // read configuration parameters for the initiator iSCSIPLSynchronize(); CFStringRef initiatorIQN = iSCSIPLCopyInitiatorIQN(); if(initiatorIQN) { iSCSISetInitiatiorName(initiatorIQN); CFRelease(initiatorIQN); } CFStringRef initiatorAlias = iSCSIPLCopyInitiatorAlias(); if(initiatorAlias) { iSCSISetInitiatiorName(initiatorAlias); CFRelease(initiatorAlias); } // Register with launchd so it can manage this daemon launch_data_t reg_request = launch_data_new_string(LAUNCH_KEY_CHECKIN); // Quit if we are unable to checkin... if(!reg_request) { fprintf(stderr,"Failed to checkin with launchd.\n"); goto ERROR_LAUNCH_DATA; } launch_data_t reg_response = launch_msg(reg_request); // Ensure registration was successful if((launch_data_get_type(reg_response) == LAUNCH_DATA_ERRNO)) { fprintf(stderr,"Failed to checkin with launchd.\n"); goto ERROR_NO_SOCKETS; } // Grab label and socket dictionary from daemon's property list launch_data_t label = launch_data_dict_lookup(reg_response,LAUNCH_JOBKEY_LABEL); launch_data_t sockets = launch_data_dict_lookup(reg_response,LAUNCH_JOBKEY_SOCKETS); if(!label || !sockets) { fprintf(stderr,"Could not find socket "); goto ERROR_NO_SOCKETS; } launch_data_t listen_socket_array = launch_data_dict_lookup(sockets,"iscsid"); if(!listen_socket_array || launch_data_array_get_count(listen_socket_array) == 0) goto ERROR_NO_SOCKETS; // Grab handle to socket we want to listen on... launch_data_t listen_socket = launch_data_array_get_index(listen_socket_array,0); if(!iSCSIDRegisterForPowerEvents()) goto ERROR_PWR_MGMT_FAIL; // Create a socket that will CFSocketRef socket = CFSocketCreateWithNative(kCFAllocatorDefault, launch_data_get_fd(listen_socket), kCFSocketReadCallBack, iSCSIDProcessIncomingRequest,0); // Runloop sources associated with socket events of connected clients CFRunLoopSourceRef clientSockSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault,socket,0); CFRunLoopAddSource(CFRunLoopGetMain(),clientSockSource,kCFRunLoopDefaultMode); CFRunLoopRun(); // Deregister for power iSCSIDDeregisterForPowerEvents(); launch_data_free(reg_response); return 0; // TODO: verify that launch data is freed under all possible execution paths ERROR_PWR_MGMT_FAIL: ERROR_NO_SOCKETS: launch_data_free(reg_response); ERROR_LAUNCH_DATA: return ENOTSUP; }
static void SetInterfaceChangedObserver_MacDesktop(OsContext* aContext, InterfaceListChanged aCallback, void* aArg) { SCDynamicStoreContext context = {0, NULL, NULL, NULL, NULL}; CFStringRef pattern = NULL; CFArrayRef patternList = NULL; CFRunLoopRef runLoop = NULL; if (NULL != aContext->iInterfaceChangedObserver) { return; } aContext->iInterfaceChangedObserver = (InterfaceChangedObserver*)malloc(sizeof(*(aContext->iInterfaceChangedObserver))); if (NULL == aContext->iInterfaceChangedObserver) { goto Error; } aContext->iInterfaceChangedObserver->iCallback = aCallback; aContext->iInterfaceChangedObserver->iArg = aArg; aContext->iInterfaceChangedObserver->iStore = NULL; aContext->iInterfaceChangedObserver->iRunLoopSource = NULL; context.info = aContext->iInterfaceChangedObserver; aContext->iInterfaceChangedObserver->iStore = SCDynamicStoreCreate(NULL, CFSTR("AddIPAddressListChangeCallbackSCF"), &InterfaceChangedDynamicStoreCallback, &context); if (NULL == aContext->iInterfaceChangedObserver->iStore) { goto Error; } pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv4); if (NULL == pattern) { goto Error; } patternList = CFArrayCreate(NULL, (const void **)&pattern, 1, &kCFTypeArrayCallBacks); if (NULL == patternList) { goto Error; } if (false == SCDynamicStoreSetNotificationKeys(aContext->iInterfaceChangedObserver->iStore, NULL, patternList)) { goto Error; } aContext->iInterfaceChangedObserver->iRunLoopSource = SCDynamicStoreCreateRunLoopSource(NULL, aContext->iInterfaceChangedObserver->iStore, 0); if (NULL == aContext->iInterfaceChangedObserver->iRunLoopSource) { goto Error; } runLoop = CFRunLoopGetMain(); if (NULL == runLoop) { goto Error; } CFRunLoopAddSource(runLoop, aContext->iInterfaceChangedObserver->iRunLoopSource, kCFRunLoopCommonModes); CFRelease(pattern); CFRelease(patternList); return; Error: if (NULL != pattern) { CFRelease(pattern); } if (NULL != patternList) { CFRelease(patternList); } if (NULL != aContext->iInterfaceChangedObserver) { if (aContext->iInterfaceChangedObserver->iStore != NULL) { CFRelease(aContext->iInterfaceChangedObserver->iStore); } if (aContext->iInterfaceChangedObserver->iRunLoopSource != NULL) { CFRelease(aContext->iInterfaceChangedObserver->iRunLoopSource); } free(aContext->iInterfaceChangedObserver); aContext->iInterfaceChangedObserver = NULL; } }
void osxHIDInputDevice::AddDevice(void *context, IOReturn /*result*/, void */*sender*/, IOHIDDeviceRef device) { osxHIDInputDevice *self = (osxHIDInputDevice*)context ; URI devUri = hidDeviceURI(device) ; // std::cerr << std::endl << self->uri.asString() << std::endl << devUri.asString() << std::endl << std::endl ; bool match = self->theDevice==0 && (self->uri.isEmpty() || self->uri.scheme=="any" || self->uri.resemble(devUri)) ; if (self->debugLevel>0) { std::cerr << (match?"+ ":" ") ; hidDebugDevice(device, std::cerr) ; std::cerr << std::endl ; } if (!match) return ; self->theDevice = new __device(device) ; self->uri = devUri ; CFDataRef descriptor = (CFDataRef)IOHIDDeviceGetProperty(self->theDevice->device, CFSTR(kIOHIDReportDescriptorKey)) ; if (descriptor) { const UInt8 *bytes = CFDataGetBytePtr(descriptor) ; CFIndex length = CFDataGetLength(descriptor) ; if (self->inputreport_callback && !self->parser->setDescriptor(bytes, length)) std::cerr << "osxHIDInputDevice::AddDevice: unable to parse the HID report descriptor" << std::endl; if (self->debugLevel > 1) { std::cerr << " HID report descriptor: [ " << std::flush ; for (int i=0; i<length; ++i) std::cerr << std::hex << std::setfill('0') << std::setw(2) << (int)bytes[i] << " " ; std::cerr << "]" << std::endl ; } } #if DEBUG_MODE std::cerr << "Setting up callbacks" << std::endl ; #endif // ---------------------------------------------------------------- if (self->inputreport_callback) { #if DEBUG_MODE std::cerr << "Setting up report callback" << std::endl ; #endif #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000 IOHIDDeviceRegisterInputReportWithTimeStampCallback(device, self->theDevice->report, sizeof(self->theDevice->report), self->inputreport_callback, self->inputreport_context) ; #else IOHIDDeviceRegisterInputReportCallback(device, self->theDevice->report, sizeof(self->theDevice->report), self->inputreport_callback, self->inputreport_context) ; #endif } // ---------------------------------------------------------------- if (self->value_callback) { #if DEBUG_MODE std::cerr << "Setting up value callback" << std::endl ; #endif IOHIDDeviceSetInputValueMatchingMultiple(device, self->elements_match) ; IOHIDDeviceRegisterInputValueCallback(device, self->value_callback, self->value_context) ; } // ---------------------------------------------------------------- if (self->queue_callback) { #if DEBUG_MODE std::cerr << "Setting up queue callback" << std::endl ; #endif self->theDevice->queue = IOHIDQueueCreate(kCFAllocatorDefault, device, queueSize, kIOHIDOptionsTypeNone) ; if (self->elements_match) { #if DEBUG && DEBUG_MATCHING_ELEMENTS std::cerr << "Queue, elements_match" << std::endl ; #endif CFIndex mcount = CFArrayGetCount(self->elements_match) ; for (CFIndex mindex=0; mindex<mcount; ++mindex) { CFDictionaryRef matching = (CFDictionaryRef)CFArrayGetValueAtIndex(self->elements_match, mindex) ; CFArrayRef elements = IOHIDDeviceCopyMatchingElements(device, matching, kIOHIDOptionsTypeNone) ; if (!elements) continue ; CFIndex ecount = CFArrayGetCount(elements) ; for (CFIndex eindex=0; eindex<ecount; ++eindex) { IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, eindex) ; IOHIDQueueAddElement(self->theDevice->queue, e) ; #if DEBUG && DEBUG_MATCHING_ELEMENTS std::cerr << "elements_match EINDEX: " << eindex << ", usagepage: " << IOHIDElementGetUsagePage(e) << ", usage: " << IOHIDElementGetUsage(e) << std::endl ; #endif } } } else { #if DEBUG && DEBUG_MATCHING_ELEMENTS std::cerr << "Queue, no elements_match" << std::endl ; #endif CFArrayRef elements = IOHIDDeviceCopyMatchingElements(device, 0, kIOHIDOptionsTypeNone) ; if (elements) { CFIndex ecount = CFArrayGetCount(elements) ; for (CFIndex eindex=0; eindex<ecount; ++eindex) { IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, eindex) ; IOHIDQueueAddElement(self->theDevice->queue, e) ; #if DEBUG && DEBUG_MATCHING_ELEMENTS std::cerr << "!elements_match EINDEX: " << eindex << ", usagepage: " << IOHIDElementGetUsagePage(e) << ", usage: " << IOHIDElementGetUsage(e) << std::endl ; #endif } } } IOHIDQueueRegisterValueAvailableCallback(self->theDevice->queue, self->queue_callback, self->queue_context) ; IOHIDQueueScheduleWithRunLoop(self->theDevice->queue, CFRunLoopGetMain(), kCFRunLoopDefaultMode) ; IOHIDQueueStart(self->theDevice->queue) ; } // ---------------------------------------------------------------- }
void StartDebuggingAndDetach(char *udid, char *app_path) { SDMMD_AMDeviceRef device = FindDeviceFromUDID(udid); if (device) { CFStringRef bundleId = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)app_path, strlen(app_path), kCFStringEncodingUTF8, false); CFURLRef relative_url = CFURLCreateWithFileSystemPath(NULL, bundleId, kCFURLPOSIXPathStyle, false); CFURLRef disk_app_url = CFURLCopyAbsoluteURL(relative_url); CFStringRef bundle_identifier = copy_disk_app_identifier(disk_app_url); SDMMD_AMDebugConnectionRef debug = SDMMD_AMDebugConnectionCreateForDevice(device); SDMMD_AMDebugConnectionStart(debug); uintptr_t socket = SDMMD_AMDServiceConnectionGetSocket(debug->connection); CFSocketContext context = { 0, (void*)socket, NULL, NULL, NULL }; CFSocketRef fdvendor = CFSocketCreate(NULL, AF_UNIX, 0, 0, kCFSocketAcceptCallBack, &socket_callback, &context); int yes = 1; setsockopt(CFSocketGetNative(fdvendor), SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); struct sockaddr_un address; memset(&address, 0, sizeof(address)); address.sun_family = AF_UNIX; strcpy(address.sun_path, SDM_LLDB_SOCKET); address.sun_len = SUN_LEN(&address); CFDataRef address_data = CFDataCreate(NULL, (const UInt8 *)&address, sizeof(address)); unlink(SDM_LLDB_SOCKET); CFSocketSetAddress(fdvendor, address_data); CFRelease(address_data); CFRunLoopAddSource(CFRunLoopGetMain(), CFSocketCreateRunLoopSource(NULL, fdvendor, 0), kCFRunLoopCommonModes); SDMMD_AMDeviceRef device = SDMMD_AMDServiceConnectionGetDevice(debug->connection); CFMutableStringRef cmds = CFStringCreateMutableCopy(NULL, 0, LLDB_PREP_CMDS); CFRange range = { 0, CFStringGetLength(cmds) }; CFURLRef device_app_url = copy_device_app_url(device, bundle_identifier); CFStringRef device_app_path = CFURLCopyFileSystemPath(device_app_url, kCFURLPOSIXPathStyle); CFStringFindAndReplace(cmds, CFSTR("{DEVICE_PATH}"), device_app_path, range, 0); range.length = CFStringGetLength(cmds); CFStringRef disk_app_path = CFURLCopyFileSystemPath(disk_app_url, kCFURLPOSIXPathStyle); CFStringFindAndReplace(cmds, CFSTR("{APP_PATH}"), disk_app_path, range, 0); range.length = CFStringGetLength(cmds); CFURLRef device_container_url = CFURLCreateCopyDeletingLastPathComponent(NULL, device_app_url); CFStringRef device_container_path = CFURLCopyFileSystemPath(device_container_url, kCFURLPOSIXPathStyle); CFMutableStringRef dcp_noprivate = CFStringCreateMutableCopy(NULL, 0, device_container_path); range.length = CFStringGetLength(dcp_noprivate); CFStringFindAndReplace(dcp_noprivate, CFSTR("/private/var/"), CFSTR("/var/"), range, 0); range.length = CFStringGetLength(cmds); CFStringFindAndReplace(cmds, CFSTR("{device_container}"), dcp_noprivate, range, 0); range.length = CFStringGetLength(cmds); CFURLRef disk_container_url = CFURLCreateCopyDeletingLastPathComponent(NULL, disk_app_url); CFStringRef disk_container_path = CFURLCopyFileSystemPath(disk_container_url, kCFURLPOSIXPathStyle); CFStringFindAndReplace(cmds, CFSTR("{disk_container}"), disk_container_path, range, 0); CFDataRef cmds_data = CFStringCreateExternalRepresentation(NULL, cmds, kCFStringEncodingASCII, 0); FILE *out = fopen(PREP_CMDS_PATH, "w"); fwrite(CFDataGetBytePtr(cmds_data), CFDataGetLength(cmds_data), 1, out); fclose(out); CFSafeRelease(cmds); CFSafeRelease(bundle_identifier); CFSafeRelease(device_app_url); CFSafeRelease(device_app_path); CFSafeRelease(disk_app_path); CFSafeRelease(device_container_url); CFSafeRelease(device_container_path); CFSafeRelease(dcp_noprivate); CFSafeRelease(disk_container_url); CFSafeRelease(disk_container_path); CFSafeRelease(cmds_data); signal(SIGHUP, exit); pid_t parent = getpid(); int pid = fork(); if (pid == 0) { system("xcrun -sdk iphoneos lldb /tmp/sdmmd-lldb-prep"); kill(parent, SIGHUP); _exit(0); } CFRunLoopRun(); } }
void AXLibStopObserver(ax_observer *Observer) { CFRunLoopRemoveSource(CFRunLoopGetMain(), AXObserverGetRunLoopSource(Observer->Ref), kCFRunLoopDefaultMode); }