Exemple #1
0
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;
}
Exemple #2
0
// -----------------------------------------------------------------------------
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;
}
Exemple #4
0
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);
	}
    }
}
Exemple #5
0
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);
}
Exemple #7
0
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
}
Exemple #10
0
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);
    }
}
Exemple #13
0
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);
}
Exemple #14
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;
}
Exemple #17
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;
}
Exemple #21
0
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;
    }