diff options
Diffstat (limited to 'mac/tclMacNotify.c')
| -rw-r--r-- | mac/tclMacNotify.c | 581 | 
1 files changed, 0 insertions, 581 deletions
| diff --git a/mac/tclMacNotify.c b/mac/tclMacNotify.c deleted file mode 100644 index 81f4082..0000000 --- a/mac/tclMacNotify.c +++ /dev/null @@ -1,581 +0,0 @@ -/*  - * tclMacNotify.c -- - * - *	This file contains Macintosh-specific procedures for the notifier, - *	which is the lowest-level part of the Tcl event loop.  This file - *	works together with ../generic/tclNotify.c. - * - *	The Mac notifier only polls for system and OS events, so it is process - *	wide, rather than thread specific.  However, this means that the convert - *	event proc will have to arbitrate which events go to which threads. - * - * Copyright (c) 1995-1996 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacNotify.c,v 1.8.4.1 2003/03/21 03:24:08 dgp Exp $ - */ - -#include "tclInt.h" -#include "tclPort.h" -#include "tclMac.h" -#include "tclMacInt.h" -#include <signal.h> -#include <Events.h> -#include <LowMem.h> -#include <Processes.h> -#include <Timer.h> -#include <Threads.h> - - -/*  - * This is necessary to work around a bug in Apple's Universal header files - * for the CFM68K libraries. - */ - -#ifdef __CFM68K__ -#undef GetEventQueue -extern pascal QHdrPtr GetEventQueue(void) - THREEWORDINLINE(0x2EBC, 0x0000, 0x014A); -#pragma import list GetEventQueue -#define GetEvQHdr() GetEventQueue() -#endif - -/* - * Need this for replacing Tcl_SetTimer and Tcl_WaitForEvent defined  - * in THIS file with ones defined in the stub table. - */ -  -extern TclStubs tclStubs; -extern Tcl_NotifierProcs tclOriginalNotifier; - -/* - * The follwing static indicates whether this module has been initialized. - */ - -static int initialized = 0; - -/* - * The following structure contains the state information for the - * notifier module. - */ - -static struct { -    int timerActive;		/* 1 if timer is running. */ -    Tcl_Time timer;		/* Time when next timer event is expected. */ -    int flags;			/* OR'ed set of flags defined below. */ -    Point lastMousePosition;	/* Last known mouse location. */ -    RgnHandle utilityRgn;	/* Region used as the mouse region for -				 * WaitNextEvent and the update region when -				 * checking for events. */    -    Tcl_MacConvertEventPtr eventProcPtr; -				/* This pointer holds the address of the -				 * function that will handle all incoming -				 * Macintosh events. */ -} notifier; - -/* - * The following defines are used in the flags field of the notifier struct. - */ - -#define NOTIFY_IDLE	(1<<1)	/* Tcl_ServiceIdle should be called. */ -#define NOTIFY_TIMER	(1<<2)	/* Tcl_ServiceTimer should be called. */ - -/* - * Prototypes for procedures that are referenced only in this file: - */ - -static int		HandleMacEvents _ANSI_ARGS_((void)); -static void		InitNotifier _ANSI_ARGS_((void)); -static void		NotifierExitHandler _ANSI_ARGS_(( -			    ClientData clientData)); - -/* - *---------------------------------------------------------------------- - * - * Tcl_InitNotifier -- - * - *	Initializes the platform specific notifier state.  There is no thread - *	specific platform notifier on the Mac, so this really doesn't do  - *	anything.  However, we need to return the ThreadID, since the generic - *	notifier hands this back to us in AlertThread. - * - * Results: - *	Returns the threadID for this thread.   - * - * Side effects: - *	None. - * - *---------------------------------------------------------------------- - */ - -ClientData -Tcl_InitNotifier() -{ -     -#ifdef TCL_THREADS -    ThreadID curThread; -    if (TclMacHaveThreads()) { -        GetCurrentThread(&curThread); -        return (ClientData) curThread; -    } else { -        return NULL; -    } -#else -    return NULL; -#endif - -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_FinalizeNotifier -- - * - *	This function is called to cleanup the notifier state before - *	a thread is terminated.  There is no platform thread specific - *	notifier, so this does nothing. - * - * Results: - *	None. - * - * Side effects: - *	None. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_FinalizeNotifier(clientData) -    ClientData clientData;	/* Pointer to notifier data. */ -{ -    /* Nothing to do on the Mac */ -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_AlertNotifier -- - * - *	Wake up the specified notifier from any thread. This routine - *	is called by the platform independent notifier code whenever - *	the Tcl_ThreadAlert routine is called.  This routine is - *	guaranteed not to be called on a given notifier after - *	Tcl_FinalizeNotifier is called for that notifier. - * - * Results: - *	None. - * - * Side effects: - *	Calls YieldToThread from this thread. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_AlertNotifier(clientData) -    ClientData clientData;	/* Pointer to thread data. */ -{ - -#ifdef TCL_THREADS -    if (TclMacHaveThreads()) { -        YieldToThread((ThreadID) clientData); -    } -#endif - -} - -/* - *---------------------------------------------------------------------- - * - * InitNotifier -- - * - *	Initializes the notifier structure.  Note - this function is never - *	used. - * - * Results: - *	None. - * - * Side effects: - *	Creates a new exit handler. - * - *---------------------------------------------------------------------- - */ - -static void -InitNotifier(void) -{ -    initialized = 1; -    memset(¬ifier, 0, sizeof(notifier)); -    Tcl_CreateExitHandler(NotifierExitHandler, NULL); -} - -/* - *---------------------------------------------------------------------- - * - * NotifierExitHandler -- - * - *	This function is called to cleanup the notifier state before - *	Tcl is unloaded.  This function is never used, since InitNotifier - *	isn't either. - * - * Results: - *	None. - * - * Side effects: - *	None. - * - *---------------------------------------------------------------------- - */ - -static void -NotifierExitHandler( -    ClientData clientData)	/* Not used. */ -{ -    initialized = 0; -} - -/* - *---------------------------------------------------------------------- - * - * HandleMacEvents -- - * - *	This function checks for events from the Macintosh event queue. - * - * Results: - *	Returns 1 if event found, 0 otherwise. - * - * Side effects: - *	Pulls events off of the Mac event queue and then calls - *	convertEventProc. - * - *---------------------------------------------------------------------- - */ - -static int -HandleMacEvents(void) -{ -    EventRecord theEvent; -    int eventFound = 0, needsUpdate = 0; -    Point currentMouse; -    WindowRef windowRef; -    Rect mouseRect; - -    /* -     * Check for mouse moved events.  These events aren't placed on the -     * system event queue unless we call WaitNextEvent. -     */ - -    GetGlobalMouseTcl(¤tMouse); -    if ((notifier.eventProcPtr != NULL) && -	    !EqualPt(currentMouse, notifier.lastMousePosition)) { -	notifier.lastMousePosition = currentMouse; -	theEvent.what = nullEvent; -	if ((*notifier.eventProcPtr)(&theEvent) == true) { -	    eventFound = 1; -	} -    } - -    /* -     * Check for update events.  Since update events aren't generated -     * until we call GetNextEvent, we may need to force a call to -     * GetNextEvent, even if the queue is empty. -     */ - -    for (windowRef = FrontWindow(); windowRef != NULL; -	    windowRef = GetNextWindow(windowRef)) { -	GetWindowUpdateRgn(windowRef, notifier.utilityRgn); -	if (!EmptyRgn(notifier.utilityRgn)) { -	    needsUpdate = 1; -	    break; -	} -    } -     -    /* -     * Process events from the OS event queue. -     */ - -    while (needsUpdate || (GetEvQHdr()->qHead != NULL)) { -	GetGlobalMouseTcl(¤tMouse); -	SetRect(&mouseRect, currentMouse.h, currentMouse.v, -		currentMouse.h + 1, currentMouse.v + 1); -	RectRgn(notifier.utilityRgn, &mouseRect); -	 -	WaitNextEvent(everyEvent, &theEvent, 5, notifier.utilityRgn); -	needsUpdate = 0; -	if ((notifier.eventProcPtr != NULL) -		&& ((*notifier.eventProcPtr)(&theEvent) == true)) { -	    eventFound = 1; -	} -    } -     -    return eventFound; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_SetTimer -- - * - *	This procedure sets the current notifier timer value.  The - *	notifier will ensure that Tcl_ServiceAll() is called after - *	the specified interval, even if no events have occurred. - * - * Results: - *	None. - * - * Side effects: - *	Replaces any previous timer. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_SetTimer( -    Tcl_Time *timePtr)		/* New value for interval timer. */ -{ -    /* -     * Allow the notifier to be hooked.  This may not make sense -     * on the Mac, but mirrors the UNIX hook. -     */ - -    if (tclStubs.tcl_SetTimer != tclOriginalNotifier.setTimerProc) { -	tclStubs.tcl_SetTimer(timePtr); -	return; -    } - -    if (!timePtr) { -	notifier.timerActive = 0; -    } else { -	/* -	 * Compute when the timer should fire. -	 */ -	 -	Tcl_GetTime(¬ifier.timer); -	notifier.timer.sec += timePtr->sec; -	notifier.timer.usec += timePtr->usec; -	if (notifier.timer.usec >= 1000000) { -	    notifier.timer.usec -= 1000000; -	    notifier.timer.sec += 1; -	} -	notifier.timerActive = 1; -    } -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_ServiceModeHook -- - * - *	This function is invoked whenever the service mode changes. - * - * Results: - *	None. - * - * Side effects: - *	None. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_ServiceModeHook(mode) -    int mode;			/* Either TCL_SERVICE_ALL, or -				 * TCL_SERVICE_NONE. */ -{ -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_WaitForEvent -- - * - *	This function is called by Tcl_DoOneEvent to wait for new - *	events on the message queue.  If the block time is 0, then - *	Tcl_WaitForEvent just polls the event queue without blocking. - * - * Results: - *	Always returns 0. - * - * Side effects: - *	None. - * - *---------------------------------------------------------------------- - */ - -int -Tcl_WaitForEvent( -    Tcl_Time *timePtr)		/* Maximum block time. */ -{ -    int found; -    EventRecord macEvent; -    long sleepTime = 5; -    long ms; -    Point currentMouse; -    void * timerToken; -    Rect mouseRect; - -    /* -     * Allow the notifier to be hooked.  This may not make -     * sense on the Mac, but mirrors the UNIX hook. -     */ - -    if (tclStubs.tcl_WaitForEvent != tclOriginalNotifier.waitForEventProc) { -	return tclStubs.tcl_WaitForEvent(timePtr); -    } - -    /* -     * Compute the next timeout value. -     */ - -    if (!timePtr) { -	ms = INT_MAX; -    } else { -	ms = (timePtr->sec * 1000) + (timePtr->usec / 1000); -    } -    timerToken = TclMacStartTimer((long) ms); -    -    /* -     * Poll the Mac event sources.  This loop repeats until something -     * happens: a timeout, a socket event, mouse motion, or some other -     * window event.  Note that we don't call WaitNextEvent if another -     * event is found to avoid context switches.  This effectively gives -     * events coming in via WaitNextEvent a slightly lower priority. -     */ - -    found = 0; -    if (notifier.utilityRgn == NULL) { -	notifier.utilityRgn = NewRgn(); -    } - -    while (!found) { -	/* -	 * Check for generated and queued events. -	 */ - -	if (HandleMacEvents()) { -	    found = 1; -	} - -	/* -	 * Check for time out. -	 */ - -	if (!found && TclMacTimerExpired(timerToken)) { -	    found = 1; -	} - -	/* -	 * Check for window events.  We may receive a NULL event for -	 * various reasons. 1) the timer has expired, 2) a mouse moved -	 * event is occuring or 3) the os is giving us time for idle -	 * events.  Note that we aren't sharing the processor very -	 * well here.  We really ought to do a better job of calling -	 * WaitNextEvent for time slicing purposes. -	 */ - -	if (!found) { -	    /* -	     * Set up mouse region so we will wake if the mouse is moved. -	     * We do this by defining the smallest possible region around -	     * the current mouse position. -	     */ - -	    GetGlobalMouseTcl(¤tMouse); -	    SetRect(&mouseRect, currentMouse.h, currentMouse.v, -		    currentMouse.h + 1, currentMouse.v + 1); -	    RectRgn(notifier.utilityRgn, &mouseRect); -	 -	    WaitNextEvent(everyEvent, &macEvent, sleepTime, -		    notifier.utilityRgn); - -	    if (notifier.eventProcPtr != NULL) { -		if ((*notifier.eventProcPtr)(&macEvent) == true) { -		    found = 1; -		} -	    } -	} -    } -    TclMacRemoveTimer(timerToken); -     -    /* -     * Yield time to nay other thread at this point.  If we find that the -     * apps thrash too switching between threads, we can put a timer here, -     * and only yield when the timer fires. -     */ -      -    if (TclMacHaveThreads()) { -        YieldToAnyThread(); -    } -     -    return 0; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_Sleep -- - * - *	Delay execution for the specified number of milliseconds.  This - *	is not a very good call to make.  It will block the system - - *	you will not even be able to switch applications. - * - * Results: - *	None. - * - * Side effects: - *	Time passes. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_Sleep( -    int ms)			/* Number of milliseconds to sleep. */ -{ -    EventRecord dummy; -    void *timerToken; -     -    if (ms <= 0) { -	return; -    } -     -    timerToken = TclMacStartTimer((long) ms); -    while (1) { -	WaitNextEvent(0, &dummy, (ms / 16.66) + 1, NULL); -        if (TclMacHaveThreads()) { -	    YieldToAnyThread(); -	} -	if (TclMacTimerExpired(timerToken)) { -	    break; -	} -    } -    TclMacRemoveTimer(timerToken); -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_MacSetEventProc -- - * - *	This function sets the event handling procedure for the  - *	application.  This function will be passed all incoming Mac - *	events.  This function usually controls the console or some - *	other entity like Tk. - * - * Results: - *	None. - * - * Side effects: - *	Changes the event handling function. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_MacSetEventProc( -    Tcl_MacConvertEventPtr procPtr) -{ -    notifier.eventProcPtr = procPtr; -} | 
