Qt::Native::Status insertEventHandler_Quartz(QNativeInput *nativeInput, int pid = 0) { uid_t uid = geteuid(); if (uid != 0) qWarning("MacNativeEvents: You must be root to listen for key events!"); CFMachPortRef port; if (!pid){ port = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, kCGEventTapOptionListenOnly, kCGEventMaskForAllEvents, EventHandler_Quartz, nativeInput); } else { ProcessSerialNumber psn; GetProcessForPID(pid, &psn); port = CGEventTapCreateForPSN(&psn, kCGHeadInsertEventTap, kCGEventTapOptionListenOnly, kCGEventMaskForAllEvents, EventHandler_Quartz, nativeInput); } CFRunLoopSourceRef eventSrc = CFMachPortCreateRunLoopSource(NULL, port, 0); CFRunLoopAddSource((CFRunLoopRef) GetCFRunLoopFromEventLoop(GetMainEventLoop()), eventSrc, kCFRunLoopCommonModes); return Qt::Native::Success; }
// ----------------------------------------------------------------------------- OSStatus refr_timer(EventLoopTimerRef * inOutTimer, EventLoopTimerProcPtr inTimerProc, EventTimerInterval inFireDelay, EventTimerInterval inInterval, /* 0 is one-shot */ void * inOutUserData) { OSStatus err = noErr; if (inOutTimer == NULL) { debug0msg0("inOutTimer == NULL"); err = -1; } else if (*inOutTimer == NULL) { EventLoopTimerUPP upp = NewEventLoopTimerUPP(inTimerProc); err = InstallEventLoopTimer(GetMainEventLoop(), inFireDelay, inInterval, upp, inOutUserData, inOutTimer); debug0msg("created new timer, ret code=%ld", err); } else { err = SetEventLoopTimerNextFireTime(*inOutTimer, inInterval); debug0msg("SetEventLoopTimerNextFireTime, ret code=%ld", err); } return err; }
bool Kopete::IdlePlatform::init() { // May already be init'ed. if ( d->mTimerRef ) return true; // According to the docs, InstallEventLoopIdleTimer is new in 10.2. // According to the headers, it has been around since 10.0. // One of them is lying. We'll play it safe and weak-link the function. // Load the "Carbon.framework" bundle. CFBundleRef carbonBundle; if ( LoadFrameworkBundle( CFSTR("Carbon.framework"), &carbonBundle ) != noErr ) return false; // Load the Mach-O function pointers for the routine we will be using. InstallEventLoopIdleTimerPtr myInstallEventLoopIdleTimer = (InstallEventLoopIdleTimerPtr)CFBundleGetFunctionPointerForName( carbonBundle, CFSTR("InstallEventLoopIdleTimer") ); if ( myInstallEventLoopIdleTimer == 0 ) return false; EventLoopIdleTimerUPP timerUPP = NewEventLoopIdleTimerUPP( Private::IdleTimerAction ); if ( (*myInstallEventLoopIdleTimer)(GetMainEventLoop(), kEventDurationSecond, kEventDurationSecond, timerUPP, 0, &d->mTimerRef) ) return true; return false; }
void Tk_MacOSXSetupTkNotifier() { ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!tsdPtr->initialized) { /* HACK ALERT: There is a bug in Jaguar where when it goes to make * the event queue for the Main Event Loop, it stores the Current * event loop rather than the Main Event Loop in the Queue structure. * So we have to make sure that the Main Event Queue gets set up on * the main thread. Calling GetMainEventQueue will force this to * happen. */ GetMainEventQueue(); tsdPtr->initialized = 1; /* Install Carbon events event source in main event loop thread. */ if (GetCurrentEventLoop() == GetMainEventLoop()) { if (!pthread_main_np()) { /* * Panic if the Carbon main event loop thread (i.e. the * thread where HIToolbox was first loaded) is not the * main application thread, as Carbon does not support * this properly. */ Tcl_Panic("Tk_MacOSXSetupTkNotifier: %s", "first [load] of TkAqua has to occur in the main thread!"); } Tcl_CreateEventSource(CarbonEventsSetupProc, CarbonEventsCheckProc, GetMainEventQueue()); TkCreateExitHandler(TkMacOSXNotifyExitHandler, NULL); } } }
void *OpenURL(char *url) { DWORD c,r; pthread_mutex_lock(&lock); // make sure only 1 thread at a time can do the following r=++req; // increment the request counter for this request pthread_mutex_unlock(&lock); RemoveEventLoopTimer(prebuftimer); // stop prebuffer monitoring BASS_StreamFree(chan); // close old stream PostCustomEvent('open',0,0); c=BASS_StreamCreateURL(url,0,BASS_STREAM_BLOCK|BASS_STREAM_STATUS|BASS_STREAM_AUTOFREE,StatusProc,0); free(url); // free temp URL buffer pthread_mutex_lock(&lock); if (r!=req) { // there is a newer request, discard this stream pthread_mutex_unlock(&lock); if (c) BASS_StreamFree(c); return; } chan=c; // this is now the current stream pthread_mutex_unlock(&lock); if (!chan) { PostCustomEvent('end ',0,0); // Error("Can't play the stream"); } else InstallEventLoopTimer(GetMainEventLoop(),kEventDurationNoWait,kEventDurationSecond/20,NewEventLoopTimerUPP(PrebufTimerProc),0,&prebuftimer); // start prebuffer monitoring return NULL; }
AutoAwayPlugin::AutoAwayPlugin(unsigned base, Buffer *config) : Plugin(base), EventReceiver(HighPriority) { load_data(autoAwayData, &data, config); #ifdef WIN32 HINSTANCE hLib = GetModuleHandleA("user32"); if (hLib != NULL){ (DWORD&)_GetLastInputInfo = (DWORD)GetProcAddress(hLib,"GetLastInputInfo"); }else{ hLibUI = LoadLibraryA("idleui.dll"); if (hLibUI != NULL) (DWORD&)_IdleUIGetLastInputTime = (DWORD)GetProcAddress(hLibUI, "IdleUIGetLastInputTime"); } #elif defined(HAVE_CARBON_CARBNON_H) && !defined(HAVE_X) CFBundleRef carbonBundle; if (LoadFrameworkBundle( CFSTR("Carbon.framework"), &carbonBundle ) == noErr) { InstallEventLoopIdleTimerPtr myInstallEventLoopIdleTimer = (InstallEventLoopIdleTimerPtr)CFBundleGetFunctionPointerForName(carbonBundle, CFSTR("InstallEventLoopIdleTimer")); if (myInstallEventLoopIdleTimer){ EventLoopIdleTimerUPP timerUPP = NewEventLoopIdleTimerUPP(Private::IdleTimerAction); (*myInstallEventLoopIdleTimer)(GetMainEventLoop(), kEventDurationSecond, kEventDurationSecond, timerUPP, 0, &mTimerRef); } } #endif Event ePlugin(EventGetPluginInfo, (void*)"_core"); pluginInfo *info = (pluginInfo*)(ePlugin.process()); core = static_cast<CorePlugin*>(info->plugin); bAway = false; bNA = false; bOff = false; m_timer = new QTimer(this); connect(m_timer, SIGNAL(timeout()), this, SLOT(timeout())); m_timer->start(AUTOAWAY_TIME); }
void Shell::EventLoop(ShellIdleFunction idle_function) { OSStatus error; error = InstallApplicationEventHandler(NewEventHandlerUPP(InputMacOSX::EventHandler), GetEventTypeCount(INPUT_EVENTS), INPUT_EVENTS, NULL, NULL); if (error != noErr) DisplayError("Unable to install handler for input events, error: %d.", error); error = InstallWindowEventHandler(window, NewEventHandlerUPP(EventHandler), GetEventTypeCount(WINDOW_EVENTS), WINDOW_EVENTS, NULL, NULL); if (error != noErr) DisplayError("Unable to install handler for window events, error: %d.", error); EventLoopTimerRef timer; error = InstallEventLoopIdleTimer(GetMainEventLoop(), // inEventLoop 0, // inFireDelay 5 * kEventDurationMillisecond, // inInterval (200 Hz) NewEventLoopIdleTimerUPP(IdleTimerCallback), // inTimerProc (void*) idle_function, // inTimerData, &timer // outTimer ); if (error != noErr) DisplayError("Unable to install Carbon event loop timer, error: %d.", error); RunApplicationEventLoop(); }
static void install_mac_timer(void) { EventLoopTimerRef timer; InstallEventLoopTimer(GetMainEventLoop(), .001*kEventDurationSecond,.001*kEventDurationSecond, NewEventLoopTimerUPP(DoRealStuff), NULL, &timer); }
CZeroconfBrowserOSX::CZeroconfBrowserOSX():m_runloop(0) { //aquire the main threads event loop #if !defined(__arm__) EventLoopRef ref = GetMainEventLoop(); m_runloop = (CFRunLoopRef)GetCFRunLoopFromEventLoop(ref); #else m_runloop = CFRunLoopGetMain(); #endif }
void st_scheduler::start_polling() { assert(m_pTimer == NULL); OSStatus lStatus = InstallEventLoopTimer(GetMainEventLoop(), 0 * kEventDurationSecond, kEventDurationMillisecond, m_uppTask, this, &m_pTimer); // TODO - throw on error assert(lStatus == noErr); }
QEventDispatcherMac::QEventDispatcherMac(QObject *parent) : QEventDispatcherUNIX(*new QEventDispatcherMacPrivate, parent) { Q_D(QEventDispatcherMac); CFRunLoopSourceContext context; bzero(&context, sizeof(CFRunLoopSourceContext)); context.info = d->threadData; context.equal = QEventDispatcherMacPrivate::postedEventSourceEqualCallback; context.perform = QEventDispatcherMacPrivate::postedEventsSourcePerformCallback; d->postedEventsSource = CFRunLoopSourceCreate(0, 0, &context); Q_ASSERT(d->postedEventsSource); CFRunLoopAddSource(runLoopForCarbonLoop(GetMainEventLoop()), d->postedEventsSource, kCFRunLoopCommonModes); }
/** * Destroys a keyboard cache entry. * * @param pKeyboardEntry The entry. */ static void darwinHIDKeyboardCacheDestroyEntry(struct KeyboardCacheData *pKeyboardEntry) { unsigned long cRefs; /* * Destroy the queue */ if (pKeyboardEntry->ppHidQueueInterface) { IOHIDQueueInterface **ppHidQueueInterface = pKeyboardEntry->ppHidQueueInterface; pKeyboardEntry->ppHidQueueInterface = NULL; /* stop it just in case we haven't done so. doesn't really matter I think. */ (*ppHidQueueInterface)->stop(ppHidQueueInterface); /* deal with the run loop source. */ CFRunLoopSourceRef RunLoopSrcRef = (*ppHidQueueInterface)->getAsyncEventSource(ppHidQueueInterface); if (RunLoopSrcRef) { CFRunLoopRef RunLoopRef = (CFRunLoopRef)GetCFRunLoopFromEventLoop(GetMainEventLoop()); CFRunLoopRemoveSource(RunLoopRef, RunLoopSrcRef, kCFRunLoopDefaultMode); CFRelease(RunLoopSrcRef); } /* dispose of and release the queue. */ (*ppHidQueueInterface)->dispose(ppHidQueueInterface); cRefs = (*ppHidQueueInterface)->Release(ppHidQueueInterface); MY_CHECK_CREFS(cRefs); } /* * Release the removal hook? */ /** @todo */ /* * Close and release the device interface. */ if (pKeyboardEntry->ppHidDeviceInterface) { IOHIDDeviceInterface **ppHidDeviceInterface = pKeyboardEntry->ppHidDeviceInterface; pKeyboardEntry->ppHidDeviceInterface = NULL; (*ppHidDeviceInterface)->close(ppHidDeviceInterface); cRefs = (*ppHidDeviceInterface)->Release(ppHidDeviceInterface); MY_CHECK_CREFS(cRefs); } }
void cutils_test_refr_timer() { int i, fireTimes = 0; const int kNumRefr = 5; const EventTimerInterval kRefrTime = 0.5; // keep this shorter than 1 sec EventLoopTimerRef timer = NULL, rltimer = NULL; OSStatus err; EventLoopTimerUPP upp; LOG0("---- cutils_test_refr_timer ---------------------------------------"); // start timer with long fire delay refr_timer(&timer, &cutils_test_refr_timercb, 2, 0, &fireTimes); for (i = 0; i < kNumRefr; i++) { // refresh timer with shorter fire delay. This should just (1) override // the previous one-shot fire and (2) continuously prolong the // firing time making the timer fire only once refr_timer(&timer, &cutils_test_refr_timercb, kRefrTime, 0, &fireTimes); } // execution flow never blocks, so given the long fire delays our // fireTimes counter must still be 0 LOG("cutils_test_refr_timer:: fireTimes=%d", fireTimes); assert(fireTimes == 0); // install another timer just to get out of the run loop (see below): // we'll make it fire way after the sum of all previous fire delays upp = NewEventLoopTimerUPP(killrl_timercb); err = InstallEventLoopTimer(GetMainEventLoop(), kNumRefr * kRefrTime * 5, 0, upp, NULL, &rltimer); assert(err == 0); // we need to run the app event loop to actually let the `timer' work RunApplicationEventLoop(); LOG("cutils_test_refr_timer:: fireTimes=%d", fireTimes); assert(fireTimes == 1); err = RemoveEventLoopTimer(rltimer); assert(err == 0); err = RemoveEventLoopTimer(timer); assert(err == 0); }
bool AquaGui::run() { double interval = _interval / 1000.0; OSStatus ret = InstallEventLoopTimer (GetMainEventLoop(), 0, interval, DoAdvanceMovie, this, _advance_timer); if (ret != noErr) { return false; } RepositionWindow(myWindow, NULL, kWindowCascadeOnMainScreen); SelectWindow(myWindow); ShowWindow(myWindow); SetWindowModified(myWindow, false); RunApplicationEventLoop(); return true; }
void myTMReset( myTMTaskPtr task) { if (task->primed) { SetEventLoopTimerNextFireTime(task->task, task->time * kDurationMillisecond); } else { task->primed=true; InstallEventLoopTimer(GetMainEventLoop(), task->time * kEventDurationMillisecond, task->time * kEventDurationMillisecond, timer_upp, task, &task->task); } }
/* * int nativeCreate(int period) */ JNIEXPORT jint JNICALL Java_com_scriptographer_ai_Timer_nativeCreate( JNIEnv *env, jobject obj, jint period) { try { #ifdef WIN_ENV return (jint) SetTimer(NULL, NULL, period, Dialog_onTimer); #endif // WIN_ENV #ifdef MAC_ENV DEFINE_CALLBACK_PROC(Dialog_onTimer); static EventLoopTimerUPP timerUPP = NewEventLoopTimerUPP( (EventLoopTimerProcPtr) CALLBACK_PROC(Dialog_onTimer)); EventLoopTimerRef timer; InstallEventLoopTimer(GetMainEventLoop(), 0, kEventDurationMillisecond * period, timerUPP, NULL, &timer); return (jint) timer; #endif // MAC_ENV } EXCEPTION_CONVERT(env); return 0; }
pxError pxWindow::setAnimationFPS(long fps) { if (theTimer) { RemoveEventLoopTimer(theTimer); } if (fps > 0) { EventLoopRef mainLoop; EventLoopTimerUPP timerUPP; mainLoop = GetMainEventLoop(); timerUPP = NewEventLoopTimerUPP (doPeriodicTask); InstallEventLoopTimer (mainLoop, 0, (1000/fps) * kEventDurationMillisecond, timerUPP, this, &theTimer); } return PX_OK; }
OSErr createWorkerThread ( WorkerActionRoutine actionRoutine, WorkerCancelRoutine cancelRoutine, WorkerResponseMainThreadCallback responseCallback, void *refcon, WorkerThreadRef *outWorker ) { WorkerThreadRef worker; if ( !actionRoutine || !responseCallback || !outWorker ) return paramErr; worker = calloc( 1, sizeof( WorkerThread ) ); if ( ! worker ) return memFullErr; worker->referenceCount = 1; worker->actionRoutine = actionRoutine; worker->cancelRoutine = cancelRoutine; worker->responseCallback = responseCallback; worker->refcon = refcon; // get the OS version Gestalt(gestaltSystemVersion, &worker->osVersion); // create a one-shot event loop timer worker->responseEventLoopTimerUPP = NewEventLoopTimerUPP( runWorkerResponseEventLoopTimer ); InstallEventLoopTimer( GetMainEventLoop(), kEventDurationForever, kEventDurationForever, worker->responseEventLoopTimerUPP, worker, &worker->responseEventLoopTimer ); // sem_init() not yet implemented as of MacOS X 10.3 - so we're going to use the MP APIs instead // the POSIX calls we could use when sem_init() is supported are clearly marked with the POSIX prefix // Named semaphors are available but not really ideal for our needs in this sample // Reference: http://developer.apple.com/documentation/Carbon/Reference/Multiprocessing_Services/multiproc_ref/function_group_3.html //POSIX sem_init( &worker->requestSemaphore, 0 /* not shared */, 0 /* initial value */ ); //POSIX sem_init( &worker->shutdownSemaphore, 0 /* not shared */, 0 /* initial value */ ); MPCreateSemaphore(1, 0, &worker->requestSemaphore); MPCreateSemaphore(1, 0, &worker->shutdownSemaphore); pthread_create( &worker->workerThread, NULL, runWorkerThread, worker ); *outWorker = worker; return noErr; }
void QEventDispatcherMac::registerTimer(int timerId, int interval, QObject *obj) { #ifndef QT_NO_DEBUG if (timerId < 1 || interval < 0 || !obj) { qWarning("QEventDispatcherUNIX::registerTimer: invalid arguments"); return; } else if (obj->thread() != thread() || thread() != QThread::currentThread()) { qWarning("QObject::startTimer: timers cannot be started from another thread"); return; } #endif Q_D(QEventDispatcherMac); if (!d->macTimerList) d->macTimerList = new MacTimerList; MacTimerInfo t; t.id = timerId; t.interval = interval; t.obj = obj; t.mac_timer = 0; t.pending = true; if (interval) { if (!timerUPP) timerUPP = NewEventLoopTimerUPP(qt_mac_activate_timer); EventTimerInterval mint = (((EventTimerInterval)interval) / 1000); d->macTimerList->append(t); //carbon timers go at the end.. if (InstallEventLoopTimer(GetMainEventLoop(), mint, mint, timerUPP, &d->macTimerList->last(), &d->macTimerList->last().mac_timer)) { qFatal("This cannot really happen, can it!?!"); return; //exceptional error } d->macTimerList->last().pending = false; } else { d->zero_timer_count++; if(d->zero_timer_count == 1) wakeUp(); //if we are blocking we need to come out of that state d->macTimerList->prepend(t); //zero timers come first d->macTimerList->first().pending = false; } }
myTMTaskPtr myTMSetup( int32 time, bool (*func)(void)) { myTMTaskPtr result; result= new myTMTask; if (!result) return result; result->func=func; result->time=time; result->primed=true; InstallEventLoopTimer(GetMainEventLoop(), time * kEventDurationMillisecond, time * kEventDurationMillisecond, timer_upp, result, &result->task); return result; }
bool wxCarbonTimerImpl::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") ); m_info->m_timer = this; m_info->m_proc = NewEventLoopTimerUPP( &wxProcessTimer ); OSStatus err = InstallEventLoopTimer( GetMainEventLoop(), m_milli*kEventDurationMillisecond, IsOneShot() ? 0 : m_milli * kEventDurationMillisecond, m_info->m_proc, this, &m_info->m_timerRef ); verify_noerr( err ); return true; }
QEventDispatcherMac::~QEventDispatcherMac() { Q_D(QEventDispatcherMac); //timer cleanup d->zero_timer_count = 0; if(d->macTimerList) { for (int i = 0; i < d->macTimerList->size(); ++i) { const MacTimerInfo &t = d->macTimerList->at(i); if (t.mac_timer) { RemoveEventLoopTimer(t.mac_timer); if (t.pending) { EventComparatorUPP fnc = NewEventComparatorUPP(find_timer_event); FlushSpecificEventsFromQueue(GetMainEventQueue(), fnc, (void *)&t); DisposeEventComparatorUPP(fnc); } } } delete d->macTimerList; d->macTimerList = 0; } if(timerUPP) { DisposeEventLoopTimerUPP(timerUPP); timerUPP = 0; } // Remove CFSockets from the runloop. for (MacSocketHash::ConstIterator it = d->macSockets.constBegin(); it != d->macSockets.constEnd(); ++it) { MacSocketInfo *socketInfo = (*it); if (CFSocketIsValid(socketInfo->socket)) { qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop); CFRunLoopSourceInvalidate(socketInfo->runloop); CFRelease(socketInfo->runloop); CFSocketInvalidate(socketInfo->socket); CFRelease(socketInfo->socket); } } CFRunLoopRemoveSource(runLoopForCarbonLoop(GetMainEventLoop()), d->postedEventsSource, kCFRunLoopCommonModes); CFRelease(d->postedEventsSource); d->postedEventsSource = 0; }
static OSStatus InstallMovieIdlingEventLoopTimer(MyStatePtr myState) { OSStatus error; mEventLoopTimer = NewEventLoopTimerUPP(MyMovieIdlingTimer); error = InstallEventLoopTimer( GetMainEventLoop(), 0, // firedelay kEventDurationMillisecond * kMinimumIdleDurationInMillis, // interval mEventLoopTimer, myState, // This will be passed to us when // the timer fires &myState->theEventTimer); if (!error) { #ifdef __APPLE_CC__ mTaskNeededSoonerCallback = NewQTNextTaskNeededSoonerCallbackUPP(TaskNeededSoonerCallback); // Install a callback that the Idle Manager will use when // QuickTime needs to wake me up immediately error = QTInstallNextTaskNeededSoonerCallback( mTaskNeededSoonerCallback, 1000, // Millisecond timescale 0, // No flags (void*)myState->theEventTimer); // Our refcon, the // callback will // reschedule it #else mTaskNeededSoonerCallback = mNewQTNextPtr(TaskNeededSoonerCallback); // Install a callback that the Idle Manager will use when // QuickTime needs to wake me up immediately error = mQTInstallNextPtr(mTaskNeededSoonerCallback, 1000, // Millisecond timescale 0, // No flags (void*)myState->theEventTimer); #endif } return error; }
OSStatus AUCarbonViewBase::CreateEventLoopTimer (Float32 inDelay, Float32 inInterval) { if (mTimerUPP) return noErr; mTimerUPP = NewEventLoopTimerUPP(TheTimerProc); EventLoopRef mainEventLoop = GetMainEventLoop(); //doesn't seem to like too small a value if (inDelay < 0.005) inDelay = 0.005; OSStatus timerResult = ::InstallEventLoopTimer( mainEventLoop, inDelay, inInterval, mTimerUPP, this, &mTimerRef); return timerResult; }
InputHandler_MacOSX_HID::InputHandler_MacOSX_HID() : m_Sem( "Input thread started" ), m_ChangeLock( "Input handler change lock" ) { InputDevice id = DEVICE_KEYBOARD; // Set up the notify ports. m_NotifyPort = IONotificationPortCreate( kIOMasterPortDefault ); // Add devices. LOG->Trace( "Finding keyboards" ); AddDevices( kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard, id ); LOG->Trace( "Finding mice" ); AddDevices( kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse, id ); LOG->Trace( "Finding joysticks" ); id = DEVICE_JOY1; AddDevices( kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick, id ); AddDevices( kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad, id ); LOG->Trace( "Finding pump" ); id = DEVICE_PUMP1; AddDevices( kHIDPage_VendorDefinedStart, 0x0001, id ); // Pump pads use the first vendor specific usage page. m_bChanged = false; if( PREFSMAN->m_bThreadedInput ) { m_InputThread.SetName( "Input thread" ); m_InputThread.Create( InputHandler_MacOSX_HID::Run, this ); // Wait for the run loop to start before returning. m_Sem.Wait(); } else { m_LoopRef = CFRunLoopRef( GetCFRunLoopFromEventLoop(GetMainEventLoop()) ); CFRetain( m_LoopRef ); StartDevices(); } }
void QEventDispatcherMac::wakeUp() { Q_D(QEventDispatcherMac); CFRunLoopSourceSignal(d->postedEventsSource); CFRunLoopWakeUp(runLoopForCarbonLoop(GetMainEventLoop())); }
CZeroconfBrowserOSX::CZeroconfBrowserOSX():m_runloop(0) { //aquire the main threads event loop EventLoopRef ref = GetMainEventLoop(); m_runloop = (CFRunLoopRef)GetCFRunLoopFromEventLoop(ref); }
IGraphicsCarbon::IGraphicsCarbon(IGraphicsMac* pGraphicsMac, WindowRef pWindow, ControlRef pParentControl, short leftOffset, short topOffset) : mGraphicsMac(pGraphicsMac) , mWindow(pWindow) , mView(0) , mTimer(0) , mControlHandler(0) , mWindowHandler(0) , mCGC(0) , mTextEntryView(0) , mTextEntryHandler(0) , mEdControl(0) , mEdParam(0) , mPrevX(0) , mPrevY(0) //, mRgn(NewRgn()) , mLeftOffset(leftOffset) , mTopOffset(topOffset) { TRACE; Rect r; // Client. r.left = r.top = 0; r.right = pGraphicsMac->Width(); r.bottom = pGraphicsMac->Height(); WindowAttributes winAttrs = 0; GetWindowAttributes(pWindow, &winAttrs); mIsComposited = (winAttrs & kWindowCompositingAttribute); UInt32 features = kControlSupportsFocus | kControlHandlesTracking | kControlSupportsEmbedding; if (mIsComposited) { features |= kHIViewIsOpaque | kHIViewFeatureDoesNotUseSpecialParts; } CreateUserPaneControl(pWindow, &r, features, &mView); const EventTypeSpec controlEvents[] = { { kEventClassControl, kEventControlDraw }, }; InstallControlEventHandler(mView, MainEventHandler, GetEventTypeCount(controlEvents), controlEvents, this, &mControlHandler); const EventTypeSpec windowEvents[] = { { kEventClassMouse, kEventMouseDown }, { kEventClassMouse, kEventMouseUp }, { kEventClassMouse, kEventMouseMoved }, { kEventClassMouse, kEventMouseDragged }, { kEventClassMouse, kEventMouseWheelMoved }, { kEventClassKeyboard, kEventRawKeyDown }, { kEventClassWindow, kEventWindowDeactivated } }; InstallWindowEventHandler(mWindow, MainEventHandler, GetEventTypeCount(windowEvents), windowEvents, this, &mWindowHandler); double t = kEventDurationSecond / (double) pGraphicsMac->FPS(); OSStatus s = InstallEventLoopTimer(GetMainEventLoop(), 0., t, TimerHandler, this, &mTimer); if (mIsComposited) { if (!pParentControl) { HIViewRef hvRoot = HIViewGetRoot(pWindow); s = HIViewFindByID(hvRoot, kHIViewWindowContentID, &pParentControl); } s = HIViewAddSubview(pParentControl, mView); } else { if (!pParentControl) { if (GetRootControl(pWindow, &pParentControl) != noErr) { CreateRootControl(pWindow, &pParentControl); } } s = EmbedControl(mView, pParentControl); } if (s == noErr) { SizeControl(mView, r.right, r.bottom); // offset? } }
/** * Creates a keyboard cache entry. * * @returns true if the entry was created successfully, otherwise false. * @param pKeyboardEntry Pointer to the entry. * @param KeyboardDevice The keyboard device to create the entry for. * */ static bool darwinHIDKeyboardCacheCreateEntry(struct KeyboardCacheData *pKeyboardEntry, io_object_t KeyboardDevice) { unsigned long cRefs = 0; memset(pKeyboardEntry, 0, sizeof(*pKeyboardEntry)); /* * Query the HIDDeviceInterface for this HID (keyboard) object. */ SInt32 Score = 0; IOCFPlugInInterface **ppPlugInInterface = NULL; IOReturn rc = IOCreatePlugInInterfaceForService(KeyboardDevice, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &ppPlugInInterface, &Score); if (rc == kIOReturnSuccess) { IOHIDDeviceInterface **ppHidDeviceInterface = NULL; HRESULT hrc = (*ppPlugInInterface)->QueryInterface(ppPlugInInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (LPVOID *)&ppHidDeviceInterface); cRefs = (*ppPlugInInterface)->Release(ppPlugInInterface); MY_CHECK_CREFS(cRefs); ppPlugInInterface = NULL; if (hrc == S_OK) { rc = (*ppHidDeviceInterface)->open(ppHidDeviceInterface, 0); if (rc == kIOReturnSuccess) { /* * create a removal callback. */ /** @todo */ /* * Create the queue so we can insert elements while searching the properties. */ IOHIDQueueInterface **ppHidQueueInterface = (*ppHidDeviceInterface)->allocQueue(ppHidDeviceInterface); if (ppHidQueueInterface) { rc = (*ppHidQueueInterface)->create(ppHidQueueInterface, 0, 32); if (rc != kIOReturnSuccess) { AssertMsgFailed(("rc=%d\n", rc)); cRefs = (*ppHidQueueInterface)->Release(ppHidQueueInterface); MY_CHECK_CREFS(cRefs); ppHidQueueInterface = NULL; } } else AssertFailed(); pKeyboardEntry->ppHidQueueInterface = ppHidQueueInterface; /* * Brute force getting of attributes. */ /** @todo read up on how to do this in a less resource intensive way! Suggestions are welcome! */ CFMutableDictionaryRef PropertiesRef = 0; kern_return_t krc = IORegistryEntryCreateCFProperties(KeyboardDevice, &PropertiesRef, kCFAllocatorDefault, kNilOptions); if (krc == KERN_SUCCESS) { darwinBruteForcePropertySearch(PropertiesRef, pKeyboardEntry); CFRelease(PropertiesRef); } else AssertMsgFailed(("krc=%#x\n", krc)); if (ppHidQueueInterface) { /* * Now install our queue callback. */ CFRunLoopSourceRef RunLoopSrcRef = NULL; rc = (*ppHidQueueInterface)->createAsyncEventSource(ppHidQueueInterface, &RunLoopSrcRef); if (rc == kIOReturnSuccess) { CFRunLoopRef RunLoopRef = (CFRunLoopRef)GetCFRunLoopFromEventLoop(GetMainEventLoop()); CFRunLoopAddSource(RunLoopRef, RunLoopSrcRef, kCFRunLoopDefaultMode); } /* * Now install our queue callback. */ rc = (*ppHidQueueInterface)->setEventCallout(ppHidQueueInterface, darwinQueueCallback, ppHidQueueInterface, pKeyboardEntry); if (rc != kIOReturnSuccess) AssertMsgFailed(("rc=%d\n", rc)); } /* * Complete the new keyboard cache entry. */ pKeyboardEntry->ppHidDeviceInterface = ppHidDeviceInterface; pKeyboardEntry->ppHidQueueInterface = ppHidQueueInterface; return true; } AssertMsgFailed(("rc=%d\n", rc)); cRefs = (*ppHidDeviceInterface)->Release(ppHidDeviceInterface); MY_CHECK_CREFS(cRefs); } else AssertMsgFailed(("hrc=%#x\n", hrc)); } else AssertMsgFailed(("rc=%d\n", rc)); return false; }
//------------------------------------------------------------------------ bool platform_support::init(unsigned width, unsigned height, unsigned flags) { if(m_specific->m_sys_format == pix_format_undefined) { return false; } m_window_flags = flags; // application EventTypeSpec eventType; EventHandlerUPP handlerUPP; eventType.eventClass = kEventClassApplication; eventType.eventKind = kEventAppQuit; handlerUPP = NewEventHandlerUPP(DoAppQuit); InstallApplicationEventHandler (handlerUPP, 1, &eventType, nil, nil); eventType.eventClass = kEventClassMouse; eventType.eventKind = kEventMouseDown; handlerUPP = NewEventHandlerUPP(DoMouseDown); InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); eventType.eventKind = kEventMouseUp; handlerUPP = NewEventHandlerUPP(DoMouseUp); InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); eventType.eventKind = kEventMouseDragged; handlerUPP = NewEventHandlerUPP(DoMouseDragged); InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); eventType.eventClass = kEventClassKeyboard; eventType.eventKind = kEventRawKeyDown; handlerUPP = NewEventHandlerUPP(DoKeyDown); InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); eventType.eventKind = kEventRawKeyUp; handlerUPP = NewEventHandlerUPP(DoKeyUp); InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); eventType.eventKind = kEventRawKeyRepeat; handlerUPP = NewEventHandlerUPP(DoKeyDown); // 'key repeat' is translated to 'key down' InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); WindowAttributes windowAttrs; Rect bounds; // window windowAttrs = kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute | kWindowStandardHandlerAttribute; SetRect (&bounds, 0, 0, width, height); OffsetRect (&bounds, 100, 100); CreateNewWindow (kDocumentWindowClass, windowAttrs, &bounds, &m_specific->m_window); if(m_specific->m_window == nil) { return false; } // I assume the text is ASCII. // Change to kCFStringEncodingMacRoman, kCFStringEncodingISOLatin1, kCFStringEncodingUTF8 or what else you need. SetWindowTitleWithCFString (m_specific->m_window, CFStringCreateWithCStringNoCopy (nil, m_caption, kCFStringEncodingASCII, nil)); eventType.eventClass = kEventClassWindow; eventType.eventKind = kEventWindowClose; handlerUPP = NewEventHandlerUPP(DoWindowClose); InstallWindowEventHandler (m_specific->m_window, handlerUPP, 1, &eventType, this, NULL); eventType.eventKind = kEventWindowDrawContent; handlerUPP = NewEventHandlerUPP(DoWindowDrawContent); InstallWindowEventHandler (m_specific->m_window, handlerUPP, 1, &eventType, this, NULL); // Periodic task // Instead of an idle function I use the Carbon event timer. // You may decide to change the wait value which is currently 50 milliseconds. EventLoopRef mainLoop; EventLoopTimerUPP timerUPP; EventLoopTimerRef theTimer; mainLoop = GetMainEventLoop(); timerUPP = NewEventLoopTimerUPP (DoPeriodicTask); InstallEventLoopTimer (mainLoop, 0, 50 * kEventDurationMillisecond, timerUPP, this, &theTimer); m_specific->create_pmap(width, height, &m_rbuf_window); m_initial_width = width; m_initial_height = height; on_init(); on_resize(width, height); m_specific->m_redraw_flag = true; ShowWindow (m_specific->m_window); SetPortWindowPort (m_specific->m_window); return true; }