Index: macosx/tkMacOSXInit.c =================================================================== RCS file: /cvsroot/tktoolkit/tk/macosx/tkMacOSXInit.c,v retrieving revision 1.8 diff -u -p -r1.8 tkMacOSXInit.c --- macosx/tkMacOSXInit.c 9 Mar 2005 19:40:52 -0000 1.8 +++ macosx/tkMacOSXInit.c 28 Apr 2005 10:05:39 -0000 @@ -115,6 +115,8 @@ TkpInit(interp) static char tkLibPath[PATH_MAX + 1]; static int tkMacOSXInitialized = false; + Tk_MacOSXSetupTkNotifier(); + /* * Since it is possible for TkInit to be called multiple times * and we don't want to do the initialization multiple times @@ -128,7 +130,6 @@ TkpInit(interp) tkMacOSXInitialized = true; - Tk_MacOSXSetupTkNotifier(); TkMacOSXInitAppleEvents(interp); TkMacOSXInitCarbonEvents(interp); TkMacOSXInitMenus(interp); Index: macosx/tkMacOSXNotify.c =================================================================== RCS file: /cvsroot/tktoolkit/tk/macosx/tkMacOSXNotify.c,v retrieving revision 1.10 diff -u -p -r1.10 tkMacOSXNotify.c --- macosx/tkMacOSXNotify.c 28 Apr 2005 08:37:01 -0000 1.10 +++ macosx/tkMacOSXNotify.c 30 Apr 2005 11:59:32 -0000 @@ -1,218 +1,53 @@ /* * tkMacOSXNotify.c -- * - * This file contains the implementation of a merged - * Carbon/select-based notifier, which is the lowest-level part - * of the Tcl event loop. This file works together with - * generic/tclNotify.c. + * This file contains the implementation of a tcl event source + * for the Carbon event loop. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright 2001, Apple Computer, Inc. + * Copyright 2005, Tcl Core Team. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXNotify.c,v 1.10 2005/04/28 08:37:01 dkf Exp $ + * RCS: @(#) $Id: tkMacOSXNotify.c,v 1.8 2005/02/24 00:41:04 das Exp $ */ #include "tclInt.h" #include "tkInt.h" #include "tkMacOSXEvent.h" -#include - -#ifndef TCL_THREADS -#error Mac OS X notifier requires tcl threads! -#endif - -/* - * This structure is used to keep track of the notifier info for a - * a registered file. - */ - -typedef struct FileHandler { - int fd; - int mask; /* Mask of desired events: TCL_READABLE, - * etc. */ - int readyMask; /* Mask of events that have been seen since the - * last time file handlers were invoked for - * this file. */ - Tcl_FileProc *proc; /* Procedure to call, in the style of - * Tcl_CreateFileHandler. */ - ClientData clientData; /* Argument to pass to proc. */ - struct FileHandler *nextPtr;/* Next in list of all files we care about. */ -} FileHandler; - -/* - * The following structure is what is added to the Tcl event queue when - * file handlers are ready to fire. - */ - -typedef struct FileHandlerEvent { - Tcl_Event header; /* Information that is standard for - * all events. */ - int fd; /* File descriptor that is ready. Used - * to find the FileHandler structure for - * the file (can't point directly to the - * FileHandler structure because it could - * go away while the event is queued). */ -} FileHandlerEvent; - -/* - * - * The following structure contains a set of select() masks to track - * readable, writable, and exceptional conditions. - */ - -typedef struct SelectMasks { - fd_set readable; - fd_set writable; - fd_set exceptional; -} SelectMasks; - /* - * The following static structure contains the state information for the - * select based implementation of the Tcl notifier. One of these structures - * is created for each thread that is using the notifier. + * The following static indicates whether this module has been initialized + * in the current thread. */ typedef struct ThreadSpecificData { - FileHandler *firstFileHandlerPtr; - /* Pointer to head of file handler list. */ - - SelectMasks checkMasks; /* This structure is used to build up the masks - * to be used in the next call to select. - * Bits are set in response to calls to - * Tcl_CreateFileHandler. */ - SelectMasks readyMasks; /* This array reflects the readable/writable - * conditions that were found to exist by the - * last call to select. */ - int numFdBits; /* Number of valid bits in checkMasks - * (one more than highest fd for which - * Tcl_WatchFile has been called). */ - int isMainLoop; /* Is this the main Carbon Loop (in which case - * we will call RNE in the actual wait... */ - int onList; /* True if it is in this list */ - unsigned int pollState; /* pollState is used to implement a polling - * handshake between each thread and the - * notifier thread. Bits defined below. */ - struct ThreadSpecificData *nextPtr, *prevPtr; - /* All threads that are currently waiting on - * an event have their ThreadSpecificData - * structure on a doubly-linked listed formed - * from these pointers. You must hold the - * notifierMutex lock before accessing these - * fields. */ - Tcl_Condition waitCV; /* Any other thread alerts a notifier - * that an event is ready to be processed - * by signaling this condition variable. */ - int eventReady; /* True if an event is ready to be processed. - * Used as condition flag together with - * waitCV above. */ + int initialized; } ThreadSpecificData; - static Tcl_ThreadDataKey dataKey; -/* - * The following static indicates the number of threads that have - * initialized notifiers. - * - * You must hold the notifierMutex lock before accessing this variable. - */ - -static int notifierCount = 0; - -/* - * The following variable points to the head of a doubly-linked list of - * of ThreadSpecificData structures for all threads that are currently - * waiting on an event. - * - * You must hold the notifierMutex lock before accessing this list. - */ - -static ThreadSpecificData *waitingListPtr = NULL; - -/* - * The notifier thread spends all its time in select() waiting for a - * file descriptor associated with one of the threads on the waitingListPtr - * list to do something interesting. But if the contents of the - * waitingListPtr list ever changes, we need to wake up and restart - * the select() system call. You can wake up the notifier thread by - * writing a single byte to the file descriptor defined below. This - * file descriptor is the input-end of a pipe and the notifier thread is - * listening for data on the output-end of the same pipe. Hence writing - * to this file descriptor will cause the select() system call to return - * and wake up the notifier thread. - * - * You must hold the notifierMutex lock before accessing this list. - */ - -static int triggerPipe = -1; - -/* - * The notifierMutex locks access to all of the global notifier state. - */ - -TCL_DECLARE_MUTEX(notifierMutex) - -/* - * The notifier thread signals the notifierCV when it has finished - * initializing the triggerPipe and right before the notifier - * thread terminates. - */ - -static Tcl_Condition notifierCV; - -/* - * The pollState bits - * POLL_WANT is set by each thread before it waits on its condition - * variable. It is checked by the notifier before it does - * select. - * POLL_DONE is set by the notifier if it goes into select after - * seeing POLL_WANT. The idea is to ensure it tries a select - * with the same bits the initial thread had set. - */ -#define POLL_WANT 0x1 -#define POLL_DONE 0x2 - -/* - * This is the thread ID of the notifier thread that does select. - */ -static Tcl_ThreadId notifierThread; - -/* - * Static routines defined in this file. - */ -static void NotifierThreadProc(ClientData clientData); -static int FileHandlerEventProc(Tcl_Event *evPtr, int flags); -static void AlertNotifier(ThreadSpecificData *tsdPtr); +static void TkMacOSXNotifyExitHandler _ANSI_ARGS_((ClientData clientData)); +static void CarbonEventsSetupProc _ANSI_ARGS_((ClientData clientData, + int flags)); +static void CarbonEventsCheckProc _ANSI_ARGS_((ClientData clientData, + int flags)); -/* DKF: Should these be static? */ -void TkMacOSXSetTimer(Tcl_Time *timePtr); -void TkMacOSXCreateFileHandler(int fd, int mask, Tcl_FileProc *proc, - ClientData clientData); -void TkMacOSXDeleteFileHandler(int fd); -int TkMacOSXWaitForEvent(Tcl_Time *timePtr); -void TkMacOSXAlertNotifier(ClientData clientData); -ClientData TkMacOSXInitNotifier(); -void TkMacOSXFinalizeNotifier(ClientData clientData); -void TkMacOSXServiceModeHook(int mode); -EventRef TkMacOSXCreateFakeEvent(); /* *---------------------------------------------------------------------- * * Tk_MacOSXSetupTkNotifier -- * - * Replaces the Tcl notifier (from tclUnixNotfy.c) with - * the Mac notifier that melds the Unix select based notifer - * with the Carbon event handling side of the Tk notifier. + * This procedure is called during Tk initialization to create + * the event source for Carbon events. * * Results: - * Replaces the notifier callbacks with MacOS X specific ones. + * None. * * Side effects: - * None. + * A new event source is created. * *---------------------------------------------------------------------- */ @@ -220,25 +55,7 @@ EventRef TkMacOSXCreateFakeEvent(); void Tk_MacOSXSetupTkNotifier() { - EventQueueRef mainEventQueue; - Tcl_NotifierProcs macNotifierProcs = { - TkMacOSXSetTimer, - TkMacOSXWaitForEvent, - TkMacOSXCreateFileHandler, - TkMacOSXDeleteFileHandler, - TkMacOSXInitNotifier, - TkMacOSXFinalizeNotifier, - TkMacOSXAlertNotifier, - TkMacOSXServiceModeHook - }; - - /* - * Dispose of existing unix notifier thread - */ - - TclFinalizeNotifier(); - - Tcl_SetNotifier(&macNotifierProcs); + static EventQueueRef mainEventQueue = NULL; /* 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 @@ -247,243 +64,30 @@ Tk_MacOSXSetupTkNotifier() * the main thread. Calling GetMainEventQueue will force this to * happen. */ - - mainEventQueue = GetMainEventQueue(); - - /* - * Tcl_SetNotifier doesn't call the TclInitNotifier - * so we call it now. If we don't do this the - * ThreadSpecificData will keep a pointer to the original - * InitNotifier. See tclNotify.c:TclInitNotifier(). - */ - - TclInitNotifier(); -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_InitNotifier -- - * - * Initializes the platform specific notifier state. - * - * Results: - * Returns a handle to the notifier state for this thread.. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -ClientData -TkMacOSXInitNotifier() -{ - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - - tsdPtr->eventReady = 0; - - /* - * Start the Notifier thread if necessary. - */ - - Tcl_MutexLock(¬ifierMutex); - if (notifierCount == 0) { - if (Tcl_CreateThread(¬ifierThread, NotifierThreadProc, NULL, - TCL_THREAD_STACK_DEFAULT, TCL_THREAD_NOFLAGS) != TCL_OK) { - Tcl_Panic("Tcl_InitNotifier: unable to start notifier thread"); - } + + if (!mainEventQueue) { + mainEventQueue = GetMainEventQueue(); } - notifierCount++; - + + /* Install Carbon events event source only in main event loop thread */ if (GetCurrentEventLoop() == GetMainEventLoop()) { - tsdPtr->isMainLoop = 1; - } else { - tsdPtr->isMainLoop = 0; - } - - /* - * Wait for the notifier pipe to be created. - */ - - while (triggerPipe < 0) { - Tcl_ConditionWait(¬ifierCV, ¬ifierMutex, NULL); - } - - Tcl_MutexUnlock(¬ifierMutex); - return (ClientData) tsdPtr; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_FinalizeNotifier -- - * - * This function is called to cleanup the notifier state before - * a thread is terminated. - * - * Results: - * None. - * - * Side effects: - * May terminate the background notifier thread if this is the - * last notifier instance. - * - *---------------------------------------------------------------------- - */ - -void -TkMacOSXFinalizeNotifier(clientData) - ClientData clientData; /* Not used. */ -{ - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - - Tcl_MutexLock(¬ifierMutex); - notifierCount--; - - /* - * If this is the last thread to use the notifier, close the notifier - * pipe and wait for the background thread to terminate. - */ - - if (notifierCount == 0) { - if (triggerPipe < 0) { - Tcl_Panic("Tcl_FinalizeNotifier: notifier pipe not initialized"); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + if (!tsdPtr->initialized) { + tsdPtr->initialized = 1; + Tcl_CreateEventSource(CarbonEventsSetupProc, + CarbonEventsCheckProc, GetMainEventQueue()); + TkCreateExitHandler(TkMacOSXNotifyExitHandler, NULL); } - - /* - * Send "q" message to the notifier thread so that it will - * terminate. The notifier will return from its call to select() - * and notice that a "q" message has arrived, it will then close - * its side of the pipe and terminate its thread. Note the we can - * not just close the pipe and check for EOF in the notifier - * thread because if a background child process was created with - * exec, select() would not register the EOF on the pipe until the - * child processes had terminated. [Bug: 4139] - */ - write(triggerPipe, "q", 1); - close(triggerPipe); - - Tcl_ConditionWait(¬ifierCV, ¬ifierMutex, NULL); - } - - /* - * Clean up any synchronization objects in the thread local storage. - */ - - Tcl_ConditionFinalize(&(tsdPtr->waitCV)); - - Tcl_MutexUnlock(¬ifierMutex); -} - -/* - *---------------------------------------------------------------------- - * - * 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: - * Signals the notifier condition variable for the specified - * notifier. - * - *---------------------------------------------------------------------- - */ - -void -TkMacOSXAlertNotifier(clientData) - ClientData clientData; -{ - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData; - Tcl_MutexLock(¬ifierMutex); - tsdPtr->eventReady = 1; - AlertNotifier(tsdPtr); - Tcl_MutexUnlock(¬ifierMutex); -} - -/* - *---------------------------------------------------------------------- - * - * AlertNotifier -- - * - * The core of the notifier alerting scheme. Either we wake up - * the main event loop and stuff the event to it, or we signal - * the thread's condition variable. Note that callers are - * responsible for locking the right mutexes, managing the rest - * of the notifier state, etc. The thread to alert is determined - * by whose tsdPtr we actually have as our argument. The only - * expected callers are TkMacOSXAlertNotifier() and - * NotifierThreadProc(), both of which take appropriate - * precautions. - * - * Results: - * none - * - * Side effects: - * A notifier is alerted. - * - *---------------------------------------------------------------------- - */ - -static void -AlertNotifier(tsdPtr) - ThreadSpecificData *tsdPtr; -{ - if (tsdPtr->isMainLoop) { - /* We need to wake up the main loop, and let it have the event. */ - EventRef fakeEvent = TkMacOSXCreateFakeEvent(); - EventQueueRef mainEventQueue = GetMainEventQueue(); - OSErr err; - - err = PostEventToQueue(mainEventQueue, fakeEvent, kEventPriorityHigh); - ReleaseEvent(fakeEvent); - } else { - Tcl_ConditionNotify(&tsdPtr->waitCV); } } - -/* - *---------------------------------------------------------------------- - * - * Tcl_SetTimer -- - * - * This procedure sets the current notifier timer value. This - * interface is not implemented in this notifier because we are - * always running inside of Tcl_DoOneEvent. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ -void -TkMacOSXSetTimer(timePtr) - Tcl_Time *timePtr; /* Timeout value, may be NULL. */ -{ - /* - * The interval timer doesn't do anything in this implementation, - * because the only event loop is via Tcl_DoOneEvent, which passes - * timeout values to Tcl_WaitForEvent. - */ -} - /* *---------------------------------------------------------------------- * - * Tcl_ServiceModeHook -- + * TkMacOSXNotifyExitHandler -- * - * This function is invoked whenever the service mode changes. + * This function is called during finalization to clean up the + * TkMacOSXNotify module. * * Results: * None. @@ -494,666 +98,80 @@ TkMacOSXSetTimer(timePtr) *---------------------------------------------------------------------- */ -void -TkMacOSXServiceModeHook(mode) - int mode; /* Either TCL_SERVICE_ALL, or - * TCL_SERVICE_NONE. */ -{ -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_CreateFileHandler -- - * - * This procedure registers a file handler with the select notifier. - * - * Results: - * None. - * - * Side effects: - * Creates a new file handler structure. - * - *---------------------------------------------------------------------- - */ - -void -TkMacOSXCreateFileHandler(fd, mask, proc, clientData) - int fd; /* Handle of stream to watch. */ - int mask; /* OR'ed combination of TCL_READABLE, - * TCL_WRITABLE, and TCL_EXCEPTION: - * indicates conditions under which - * proc should be called. */ - Tcl_FileProc *proc; /* Procedure to call for each - * selected event. */ - ClientData clientData; /* Arbitrary data to pass to proc. */ +static void +TkMacOSXNotifyExitHandler(clientData) + ClientData clientData; /* Not used. */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - FileHandler *filePtr; - for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL; - filePtr = filePtr->nextPtr) { - if (filePtr->fd == fd) { - break; - } - } - if (filePtr == NULL) { - filePtr = (FileHandler*) ckalloc(sizeof(FileHandler)); - filePtr->fd = fd; - filePtr->readyMask = 0; - filePtr->nextPtr = tsdPtr->firstFileHandlerPtr; - tsdPtr->firstFileHandlerPtr = filePtr; - } - filePtr->proc = proc; - filePtr->clientData = clientData; - filePtr->mask = mask; - - /* - * Update the check masks for this file. - */ - - if (mask & TCL_READABLE) { - FD_SET(fd, &(tsdPtr->checkMasks.readable)); - } else { - FD_CLR(fd, &(tsdPtr->checkMasks.readable)); - } - if (mask & TCL_WRITABLE) { - FD_SET(fd, &(tsdPtr->checkMasks.writable)); - } else { - FD_CLR(fd, &(tsdPtr->checkMasks.writable)); - } - if (mask & TCL_EXCEPTION) { - FD_SET(fd, &(tsdPtr->checkMasks.exceptional)); - } else { - FD_CLR(fd, &(tsdPtr->checkMasks.exceptional)); - } - if (tsdPtr->numFdBits <= fd) { - tsdPtr->numFdBits = fd+1; - } + Tcl_DeleteEventSource(CarbonEventsSetupProc, + CarbonEventsCheckProc, GetMainEventQueue()); + tsdPtr->initialized = 0; } /* *---------------------------------------------------------------------- * - * Tcl_DeleteFileHandler -- + * CarbonEventsSetupProc -- * - * Cancel a previously-arranged callback arrangement for - * a file. + * This procedure implements the setup part of the Carbon Events + * event source. It is invoked by Tcl_DoOneEvent before entering + * the notifier to check for events. * * Results: * None. * * Side effects: - * If a callback was previously registered on file, remove it. + * If Carbon events are queued, then the maximum block time will be + * set to 0 to ensure that the notifier returns control to Tcl. * *---------------------------------------------------------------------- */ -void -TkMacOSXDeleteFileHandler(fd) - int fd; /* Stream id for which to remove callback procedure. */ +static void +CarbonEventsSetupProc(clientData, flags) + ClientData clientData; + int flags; { - FileHandler *filePtr, *prevPtr; - int i; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - - /* - * Find the entry for the given file (and return if there isn't one). - */ - - for (prevPtr = NULL, filePtr = tsdPtr->firstFileHandlerPtr; ; - prevPtr = filePtr, filePtr = filePtr->nextPtr) { - if (filePtr == NULL) { - return; - } - if (filePtr->fd == fd) { - break; - } - } - - /* - * Update the check masks for this file. - */ + static Tcl_Time blockTime = { 0, 0 }; - if (filePtr->mask & TCL_READABLE) { - FD_CLR(fd, &(tsdPtr->checkMasks.readable)); + if (!(flags & TCL_WINDOW_EVENTS)) { + return; } - if (filePtr->mask & TCL_WRITABLE) { - FD_CLR(fd, &(tsdPtr->checkMasks.writable)); - } - if (filePtr->mask & TCL_EXCEPTION) { - FD_CLR(fd, &(tsdPtr->checkMasks.exceptional)); - } - - /* - * Find current max fd. - */ - - if (fd+1 == tsdPtr->numFdBits) { - tsdPtr->numFdBits = 0; - for (i = fd-1; i >= 0; i--) { - if (FD_ISSET(i, &(tsdPtr->checkMasks.readable)) - || FD_ISSET(i, &(tsdPtr->checkMasks.writable)) - || FD_ISSET(i, &(tsdPtr->checkMasks.exceptional))) { - tsdPtr->numFdBits = i+1; - break; - } - } - } - - /* - * Clean up information in the callback record. - */ - if (prevPtr == NULL) { - tsdPtr->firstFileHandlerPtr = filePtr->nextPtr; - } else { - prevPtr->nextPtr = filePtr->nextPtr; + if (GetNumEventsInQueue((EventQueueRef)clientData)) { + Tcl_SetMaxBlockTime(&blockTime); } - ckfree((char *) filePtr); } - -/* - *---------------------------------------------------------------------- - * - * FileHandlerEventProc -- - * - * This procedure is called by Tcl_ServiceEvent when a file event - * reaches the front of the event queue. This procedure is - * responsible for actually handling the event by invoking the - * callback for the file handler. - * - * Results: - * Returns 1 if the event was handled, meaning it should be removed - * from the queue. Returns 0 if the event was not handled, meaning - * it should stay on the queue. The only time the event isn't - * handled is if the TCL_FILE_EVENTS flag bit isn't set. - * - * Side effects: - * Whatever the file handler's callback procedure does. - * - *---------------------------------------------------------------------- - */ - -static int -FileHandlerEventProc(evPtr, flags) - Tcl_Event *evPtr; /* Event to service. */ - int flags; /* Flags that indicate what events to - * handle, such as TCL_FILE_EVENTS. */ -{ - int mask; - FileHandler *filePtr; - FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) evPtr; - ThreadSpecificData *tsdPtr; - - if (!(flags & TCL_FILE_EVENTS)) { - return 0; - } - - /* - * Search through the file handlers to find the one whose handle matches - * the event. We do this rather than keeping a pointer to the file - * handler directly in the event, so that the handler can be deleted - * while the event is queued without leaving a dangling pointer. - */ - - tsdPtr = TCL_TSD_INIT(&dataKey); - for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL; - filePtr = filePtr->nextPtr) { - if (filePtr->fd != fileEvPtr->fd) { - continue; - } - - /* - * The code is tricky for two reasons: - * 1. The file handler's desired events could have changed - * since the time when the event was queued, so AND the - * ready mask with the desired mask. - * 2. The file could have been closed and re-opened since - * the time when the event was queued. This is why the - * ready mask is stored in the file handler rather than - * the queued event: it will be zeroed when a new - * file handler is created for the newly opened file. - */ - mask = filePtr->readyMask & filePtr->mask; - filePtr->readyMask = 0; - if (mask != 0) { - (*filePtr->proc)(filePtr->clientData, mask); - } - break; - } - return 1; -} - /* *---------------------------------------------------------------------- * - * Tcl_WaitForEvent -- + * CarbonEventsCheckProc -- * - * 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 without blocking. + * This procedure processes events sitting in the Carbon event + * queue. * * Results: - * Returns -1 if the select would block forever, otherwise - * returns 0. - * - * Side effects: - * Queues file events that are detected by the select. - * - *---------------------------------------------------------------------- - */ - -int -TkMacOSXWaitForEvent(timePtr) - Tcl_Time *timePtr; /* Maximum block time, or NULL. */ -{ - FileHandler *filePtr; - FileHandlerEvent *fileEvPtr; - int mask; - Tcl_Time myTime; - int waitForFiles; - Tcl_Time *myTimePtr; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - - /* - * Set up the timeout structure. Note that if there are no events to - * check for, we return with a negative result rather than blocking - * forever. - */ - - if (timePtr != NULL) { - /* TIP #233 (Virtualized Time). Is virtual time in effect ? - * And do we actually have something to scale ? If yes to both - * then we call the handler to do this scaling */ - - myTime.sec = timePtr->sec; - myTime.usec = timePtr->usec; - - if (myTime.sec != 0 || myTime.usec != 0) { - Tcl_ScaleTimeProc* tclScaleTimeProcPtr; - ClientData tclTimeClientData; - - Tcl_QueryTimeProc(NULL, &tclScaleTimeProcPtr, &tclTimeClientData); - (*tclScaleTimeProcPtr) (&myTime, tclTimeClientData); - } - myTimePtr = &myTime; - } else { - myTimePtr = NULL; - } - - /* - * Place this thread on the list of interested threads, signal the - * notifier thread, and wait for a response or a timeout. - */ - - Tcl_MutexLock(¬ifierMutex); - - waitForFiles = (tsdPtr->numFdBits > 0); - if (myTimePtr != NULL && myTimePtr->sec == 0 && myTimePtr->usec == 0) { - /* - * Cannot emulate a polling select with a polling condition variable. - * Instead, pretend to wait for files and tell the notifier - * thread what we are doing. The notifier thread makes sure - * it goes through select with its select mask in the same state - * as ours currently is. We block until that happens. - */ - - waitForFiles = 1; - tsdPtr->pollState = POLL_WANT; - myTimePtr = NULL; - } else { - tsdPtr->pollState = 0; - } - - if (waitForFiles) { - /* - * Add the ThreadSpecificData structure of this thread to the list - * of ThreadSpecificData structures of all threads that are waiting - * on file events. - */ - - tsdPtr->nextPtr = waitingListPtr; - if (waitingListPtr) { - waitingListPtr->prevPtr = tsdPtr; - } - tsdPtr->prevPtr = 0; - waitingListPtr = tsdPtr; - tsdPtr->onList = 1; - - write(triggerPipe, "", 1); - } - - FD_ZERO(&(tsdPtr->readyMasks.readable)); - FD_ZERO(&(tsdPtr->readyMasks.writable)); - FD_ZERO(&(tsdPtr->readyMasks.exceptional)); - - if (!tsdPtr->eventReady) { - if (!tsdPtr->isMainLoop) { - Tcl_ConditionWait(&tsdPtr->waitCV, ¬ifierMutex, myTimePtr); - } else { - OSErr err; - EventRef eventRef; - EventTime waitTime; - - if (myTimePtr == NULL) { - waitTime = kEventDurationForever; - } else { - waitTime = myTimePtr->sec * kEventDurationSecond - + myTimePtr->usec * kEventDurationMicrosecond; - } - Tcl_MutexUnlock(¬ifierMutex); - err = ReceiveNextEvent(0, NULL, waitTime, false, &eventRef); - Tcl_MutexLock(¬ifierMutex); - } - } - tsdPtr->eventReady = 0; - - if (waitForFiles && tsdPtr->onList) { - /* - * Remove the ThreadSpecificData structure of this thread from the - * waiting list. Alert the notifier thread to recompute its select - * masks - skipping this caused a hang when trying to close a pipe - * which the notifier thread was still doing a select on. - */ - - if (tsdPtr->prevPtr) { - tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr; - } else { - waitingListPtr = tsdPtr->nextPtr; - } - if (tsdPtr->nextPtr) { - tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr; - } - tsdPtr->nextPtr = tsdPtr->prevPtr = NULL; - tsdPtr->onList = 0; - write(triggerPipe, "", 1); - } - - /* - * Queue all detected file events before returning. - */ - - for (filePtr = tsdPtr->firstFileHandlerPtr; (filePtr != NULL); - filePtr = filePtr->nextPtr) { - - mask = 0; - if (FD_ISSET(filePtr->fd, &(tsdPtr->readyMasks.readable))) { - mask |= TCL_READABLE; - } - if (FD_ISSET(filePtr->fd, &(tsdPtr->readyMasks.writable))) { - mask |= TCL_WRITABLE; - } - if (FD_ISSET(filePtr->fd, &(tsdPtr->readyMasks.exceptional))) { - mask |= TCL_EXCEPTION; - } - - if (!mask) { - continue; - } - - /* - * Don't bother to queue an event if the mask was previously - * non-zero since an event must still be on the queue. - */ - - if (filePtr->readyMask == 0) { - fileEvPtr = (FileHandlerEvent *) ckalloc(sizeof(FileHandlerEvent)); - fileEvPtr->header.proc = FileHandlerEventProc; - fileEvPtr->fd = filePtr->fd; - Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL); - } - filePtr->readyMask = mask; - } - Tcl_MutexUnlock(¬ifierMutex); - - /* - * Also queue the Mac Events found... - */ - if (tsdPtr->isMainLoop) { - TkMacOSXCountAndProcessMacEvents(); - } - - return 0; -} - -/* - *---------------------------------------------------------------------- - * - * NotifierThreadProc -- - * - * This routine is the initial (and only) function executed by the - * special notifier thread. Its job is to wait for file descriptors - * to become readable or writable or to have an exception condition - * and then to notify other threads who are interested in this - * information by signalling a condition variable. Other threads - * can signal this notifier thread of a change in their interests - * by writing a single byte to a special pipe that the notifier - * thread is monitoring. - * - * Result: - * None. Once started, this routine never exits. It dies with - * the overall process. + * None. * * Side effects: - * The trigger pipe used to signal the notifier thread is created - * when the notifier thread first starts. + * Moves applicable queued Carbon events onto the Tcl event queue. * *---------------------------------------------------------------------- */ static void -NotifierThreadProc(clientData) - ClientData clientData; /* Not used. */ +CarbonEventsCheckProc(clientData, flags) + ClientData clientData; + int flags; { - ThreadSpecificData *tsdPtr; - fd_set readableMask; - fd_set writableMask; - fd_set exceptionalMask; - int fds[2]; - int i, status, numFdBits = 0, receivePipe; - long found; - struct timeval poll = {0., 0.}, *timePtr; - char buf[2]; - - if (pipe(fds) != 0) { - Tcl_Panic("NotifierThreadProc: could not create trigger pipe."); + if (!(flags & TCL_WINDOW_EVENTS)) { + return; } - receivePipe = fds[0]; - - status = fcntl(receivePipe, F_GETFL); - status |= O_NONBLOCK; - if (fcntl(receivePipe, F_SETFL, status) < 0) { - Tcl_Panic("NotifierThreadProc: could not make receive pipe non blocking."); + if (GetNumEventsInQueue((EventQueueRef)clientData)) { + TkMacOSXCountAndProcessMacEvents(); } - status = fcntl(fds[1], F_GETFL); - status |= O_NONBLOCK; - if (fcntl(fds[1], F_SETFL, status) < 0) { - Tcl_Panic("NotifierThreadProc: could not make trigger pipe non blocking."); - } - - /* - * Install the write end of the pipe into the global variable. - */ - - Tcl_MutexLock(¬ifierMutex); - triggerPipe = fds[1]; - - /* - * Signal any threads that are waiting. - */ - - Tcl_ConditionNotify(¬ifierCV); - Tcl_MutexUnlock(¬ifierMutex); - - /* - * Look for file events and report them to interested threads. - */ - - while (1) { - FD_ZERO(&readableMask); - FD_ZERO(&writableMask); - FD_ZERO(&exceptionalMask); - - /* - * Compute the logical OR of the select masks from all the - * waiting notifiers. - */ - - Tcl_MutexLock(¬ifierMutex); - timePtr = NULL; - for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) { - for (i = tsdPtr->numFdBits-1; i >= 0; --i) { - if (FD_ISSET(i, &(tsdPtr->checkMasks.readable))) { - FD_SET(i, &readableMask); - } - if (FD_ISSET(i, &(tsdPtr->checkMasks.writable))) { - FD_SET(i, &writableMask); - } - if (FD_ISSET(i, &(tsdPtr->checkMasks.exceptional))) { - FD_SET(i, &exceptionalMask); - } - } - if (tsdPtr->numFdBits > numFdBits) { - numFdBits = tsdPtr->numFdBits; - } - if (tsdPtr->pollState & POLL_WANT) { - /* - * Here we make sure we go through select() with the same - * mask bits that were present when the thread tried to poll. - */ - - tsdPtr->pollState |= POLL_DONE; - timePtr = &poll; - } - } - Tcl_MutexUnlock(¬ifierMutex); - - /* - * Set up the select mask to include the receive pipe. - */ - - if (receivePipe >= numFdBits) { - numFdBits = receivePipe + 1; - } - FD_SET(receivePipe, &readableMask); - - if (select(numFdBits, &readableMask, &writableMask, &exceptionalMask, - timePtr) == -1) { - /* - * Try again immediately on an error. - */ - - continue; - } - - /* - * Alert any threads that are waiting on a ready file descriptor. - */ - - Tcl_MutexLock(¬ifierMutex); - for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) { - found = 0; - - for (i = tsdPtr->numFdBits-1; i >= 0; --i) { - if (FD_ISSET(i, &(tsdPtr->checkMasks.readable)) - && FD_ISSET(i, &readableMask)) { - FD_SET(i, &(tsdPtr->readyMasks.readable)); - found = 1; - } - if (FD_ISSET(i, &(tsdPtr->checkMasks.writable)) - && FD_ISSET(i, &writableMask)) { - FD_SET(i, &(tsdPtr->readyMasks.writable)); - found = 1; - } - if (FD_ISSET(i, &(tsdPtr->checkMasks.exceptional)) - && FD_ISSET(i, &exceptionalMask)) { - FD_SET(i, &(tsdPtr->readyMasks.exceptional)); - found = 1; - } - } - - if (found || (tsdPtr->pollState & POLL_DONE)) { - tsdPtr->eventReady = 1; - if (tsdPtr->onList) { - /* - * Remove the ThreadSpecificData structure of this - * thread from the waiting list. This prevents us from - * continuously spining on select until the other - * threads runs and services the file event. - */ - - if (tsdPtr->prevPtr) { - tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr; - } else { - waitingListPtr = tsdPtr->nextPtr; - } - if (tsdPtr->nextPtr) { - tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr; - } - tsdPtr->nextPtr = tsdPtr->prevPtr = NULL; - tsdPtr->onList = 0; - tsdPtr->pollState = 0; - } - AlertNotifier(tsdPtr); - } - } - Tcl_MutexUnlock(¬ifierMutex); - - /* - * Consume the next byte from the notifier pipe if the pipe was - * readable. Note that there may be multiple bytes pending, but - * to avoid a race condition we only read one at a time. - */ - - if (FD_ISSET(receivePipe, &readableMask)) { - i = read(receivePipe, buf, 1); - - if ((i == 0) || ((i == 1) && (buf[0] == 'q'))) { - /* - * Someone closed the write end of the pipe or sent us a - * Quit message [Bug: 4139] and then closed the write end - * of the pipe so we need to shut down the notifier thread. - */ - - break; - } - } - } - - /* - * Clean up the read end of the pipe and signal any threads waiting on - * termination of the notifier thread. - */ - - close(receivePipe); - Tcl_MutexLock(¬ifierMutex); - triggerPipe = -1; - Tcl_ConditionNotify(¬ifierCV); - Tcl_MutexUnlock(¬ifierMutex); - - Tcl_ExitThread(0); } -EventRef -TkMacOSXCreateFakeEvent() -{ - EventKind eKind; - EventClass eClass; - EventTime eTime; - EventRef eventRef; - EventAttributes flags; - - eClass = kEventClassWish; - eKind = 0xffff; - eTime = GetLastUserEventTime() + 0.001; - flags = kEventAttributeUserEvent; - if (CreateEvent(NULL,eClass,eKind,eTime,flags,&eventRef) != noErr) { - /* DKF: Printing to stderr? Leaked debug code here? */ - fprintf(stderr, "CreateEvent failed\n"); - return NULL; - } - return eventRef; -} Index: macosx/Wish.pbproj/project.pbxproj =================================================================== RCS file: /cvsroot/tktoolkit/tk/macosx/Wish.pbproj/project.pbxproj,v retrieving revision 1.38 diff -u -p -r1.38 project.pbxproj --- macosx/Wish.pbproj/project.pbxproj 9 Apr 2005 11:19:00 -0000 1.38 +++ macosx/Wish.pbproj/project.pbxproj 28 Apr 2005 09:30:41 -0000 @@ -126,12 +126,6 @@ settings = { }; }; - F51D903E0181474301DC9062 = { - fileRef = F5875C7B016FEF1D01DC9062; - isa = PBXBuildFile; - settings = { - }; - }; F51D903F018149BD01DC9062 = { buildActionMask = 2147483647; dstPath = "Versions/$(FRAMEWORK_VERSION)/Headers/X11"; @@ -1906,6 +1900,7 @@ F53755DF016C38D201DC9062 = { buildPhases = ( F5877FB7031F97ED016F146B, + F92CCC75080CEBA800E72D64, F53755E0016C38D201DC9062, F53755E1016C38D301DC9062, F53755E2016C38D301DC9062, @@ -1929,10 +1924,10 @@ GLOBAL_CFLAGS = "`source \"${TCL_FRAMEWORK_DIR}/Tcl.framework/tclConfig.sh\"; echo $${}{TCL_EXTRA_CFLAGS} $${}{TCL_DEFS} | sed -e 's|\\\\\\\\\\\\\\\"|\\\"|g' -e 's|\\\\\\\\\\\\ |_|g'`"; HEADER_SEARCH_PATHS = "\"$(TCL_FRAMEWORK_DIR)/Tcl.framework/Headers\" \"$(TCL_FRAMEWORK_DIR)/Tcl.framework/PrivateHeaders\" . ../bitmaps ../generic ../xlib"; INSTALL_PATH = "${DYLIB_INSTALL_PATH}"; - LIBRARY_SEARCH_PATHS = ""; + LIBRARY_SEARCH_PATHS = "\"$(TCL_FRAMEWORK_DIR)/Tcl.framework\""; OPTIMIZATION_CFLAGS = "-O0"; - OTHER_CFLAGS = "-DMAC_OSX_TK -DTCL_WIDE_INT_TYPE=\"long long\""; - OTHER_LDFLAGS = "-seg1addr 0xb000000"; + OTHER_CFLAGS = "-DMAC_OSX_TK -DUSE_TCL_STUBS -DTCL_WIDE_INT_TYPE=\"long long\""; + OTHER_LDFLAGS = "-ltclstub${FRAMEWORK_VERSION} -seg1addr 0xb000000 -Wl,-search_paths_first -unexported_symbols_list \"${TEMP_DIR}/tclstub.exp\""; OTHER_LIBTOOL_FLAGS = ""; OTHER_REZFLAGS = "-i \"$(TCL_FRAMEWORK_DIR)/Tcl.framework/Headers\" -i \"../generic\""; PRECOMPILE_PREFIX_HEADER = YES; @@ -2172,7 +2167,6 @@ MacOS X Port by Jim Ingham <jingham@a F53755E3016C38D301DC9062 = { buildActionMask = 2147483647; files = ( - F51D903E0181474301DC9062, F537567E016C3ADB01DC9062, F50D96130196176E01DC9062, ); @@ -4284,6 +4278,19 @@ MacOS X Port by Jim Ingham <jingham@a //F92 //F93 //F94 + F92CCC75080CEBA800E72D64 = { + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + isa = PBXShellScriptBuildPhase; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# extract global symbols in libtclstub so that we can unexport them from Tk.framework\nnm -gjp \"${TCL_FRAMEWORK_DIR}/Tcl.framework/libtclstub${FRAMEWORK_VERSION}.a\" | tail +3 > \"${TEMP_DIR}/tclstub.exp\""; + }; F92ED9910403D0F0006F146B = { fileEncoding = 5; isa = PBXFileReference; Index: unix/configure =================================================================== RCS file: /cvsroot/tktoolkit/tk/unix/configure,v retrieving revision 1.98 diff -u -p -r1.98 configure --- unix/configure 26 Apr 2005 00:46:54 -0000 1.98 +++ unix/configure 28 Apr 2005 09:30:42 -0000 @@ -308,7 +308,7 @@ ac_includes_default="\ # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC MAN_FLAGS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP TCL_THREADS RANLIB ac_ct_RANLIB AR LIBOBJS TCL_LIBS DL_LIBS DL_OBJS PLAT_OBJS PLAT_SRCS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING LDFLAGS_DEBUG LDFLAGS_OPTIMIZE CC_SEARCH_FLAGS LD_SEARCH_FLAGS STLIB_LD SHLIB_LD TCL_SHLIB_LD_EXTRAS TK_SHLIB_LD_EXTRAS SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX MAKE_LIB MAKE_STUB_LIB INSTALL_LIB INSTALL_STUB_LIB CFLAGS_DEFAULT LDFLAGS_DEFAULT XFT_CFLAGS XFT_LIBS UNIX_FONT_OBJS TK_VERSION TK_MAJOR_VERSION TK_MINOR_VERSION TK_PATCH_LEVEL TK_STUB_LIB_FILE TK_STUB_LIB_FLAG TK_BUILD_STUB_LIB_SPEC TK_STUB_LIB_SPEC TK_BUILD_STUB_LIB_PATH TK_STUB_LIB_PATH TK_STUB_FLAGS TK_BUILD_EXP_FILE TK_EXP_FILE TCL_STUB_FLAGS LD_LIBRARY_PATH_VAR TK_BUILD_LIB_SPEC TK_LIB_FILE TK_LIB_FLAG TK_LIB_SPEC TK_INCLUDE_SPEC TK_SRC_DIR XINCLUDES XLIBSW TK_SHARED_BUILD LOCALES LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC MAN_FLAGS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP TCL_THREADS RANLIB ac_ct_RANLIB AR LIBOBJS TCL_LIBS DL_LIBS DL_OBJS PLAT_OBJS PLAT_SRCS PLAT CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING LDFLAGS_DEBUG LDFLAGS_OPTIMIZE CC_SEARCH_FLAGS LD_SEARCH_FLAGS STLIB_LD SHLIB_LD TCL_SHLIB_LD_EXTRAS TK_SHLIB_LD_EXTRAS SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX MAKE_LIB MAKE_STUB_LIB INSTALL_LIB INSTALL_STUB_LIB CFLAGS_DEFAULT LDFLAGS_DEFAULT XFT_CFLAGS XFT_LIBS UNIX_FONT_OBJS TK_VERSION TK_MAJOR_VERSION TK_MINOR_VERSION TK_PATCH_LEVEL TK_STUB_LIB_FILE TK_STUB_LIB_FLAG TK_BUILD_STUB_LIB_SPEC TK_STUB_LIB_SPEC TK_BUILD_STUB_LIB_PATH TK_STUB_LIB_PATH TK_STUB_FLAGS TK_BUILD_EXP_FILE TK_EXP_FILE TCL_STUB_FLAGS LD_LIBRARY_PATH_VAR TK_BUILD_LIB_SPEC TK_LIB_FILE TK_LIB_FLAG TK_LIB_SPEC TK_INCLUDE_SPEC TK_SRC_DIR XINCLUDES XLIBSW TK_SHARED_BUILD LOCALES LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -4394,6 +4394,7 @@ echo "$as_me: error: Required archive to LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH" PLAT_OBJS="" PLAT_SRCS="" + PLAT="" case $system in AIX-*) if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes" ; then @@ -5755,8 +5756,9 @@ echo "${ECHO_T}$tcl_cv_ld_search_paths_f CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH" - PLAT_OBJS="\${MAC_OSX_OBJS}" - PLAT_SRCS="\${MAC_OSX_SRCS}" + PLAT_OBJS='${MAC_OSX_OBJS}' + PLAT_SRCS='${MAC_OSX_SRCS}' + PLAT='MAC_OSX_' TCL_SHLIB_LD_EXTRAS='-compatibility_version ${VERSION} -current_version ${VERSION} -install_name ${DYLIB_INSTALL_DIR}/${TCL_LIB_FILE} -seg1addr 0xa000000' TK_SHLIB_LD_EXTRAS=' -compatibility_version ${VERSION} -current_version ${VERSION} -install_name ${DYLIB_INSTALL_DIR}/${TK_LIB_FILE} -seg1addr 0xb000000 -unexported_symbols_list $$(f=$(TCL_STUB_LIB_FILE).E && nm -gjp $(TCL_BIN_DIR)/$(TCL_STUB_LIB_FILE) | tail +3 > $$f && echo $$f)' LIBS="$LIBS -framework CoreFoundation" @@ -6495,6 +6497,7 @@ fi; + cat >>confdefs.h <<_ACEOF #define TCL_SHLIB_EXT "${SHLIB_SUFFIX}" _ACEOF @@ -9631,6 +9634,7 @@ s,@DL_LIBS@,$DL_LIBS,;t t s,@DL_OBJS@,$DL_OBJS,;t t s,@PLAT_OBJS@,$PLAT_OBJS,;t t s,@PLAT_SRCS@,$PLAT_SRCS,;t t +s,@PLAT@,$PLAT,;t t s,@CFLAGS_DEBUG@,$CFLAGS_DEBUG,;t t s,@CFLAGS_OPTIMIZE@,$CFLAGS_OPTIMIZE,;t t s,@CFLAGS_WARNING@,$CFLAGS_WARNING,;t t Index: unix/tcl.m4 =================================================================== RCS file: /cvsroot/tktoolkit/tk/unix/tcl.m4,v retrieving revision 1.80 diff -u -p -r1.80 tcl.m4 --- unix/tcl.m4 26 Apr 2005 00:46:54 -0000 1.80 +++ unix/tcl.m4 28 Apr 2005 09:30:42 -0000 @@ -909,6 +909,7 @@ dnl AC_CHECK_TOOL(AR, ar) LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH" PLAT_OBJS="" PLAT_SRCS="" + PLAT="" case $system in AIX-*) if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes" ; then @@ -1406,8 +1407,9 @@ dnl AC_CHECK_TOOL(AR, ar) CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH" - PLAT_OBJS="\${MAC_OSX_OBJS}" - PLAT_SRCS="\${MAC_OSX_SRCS}" + PLAT_OBJS='${MAC_OSX_OBJS}' + PLAT_SRCS='${MAC_OSX_SRCS}' + PLAT='MAC_OSX_' TCL_SHLIB_LD_EXTRAS='-compatibility_version ${VERSION} -current_version ${VERSION} -install_name ${DYLIB_INSTALL_DIR}/${TCL_LIB_FILE} -seg1addr 0xa000000' TK_SHLIB_LD_EXTRAS=' -compatibility_version ${VERSION} -current_version ${VERSION} -install_name ${DYLIB_INSTALL_DIR}/${TK_LIB_FILE} -seg1addr 0xb000000 -unexported_symbols_list $$(f=$(TCL_STUB_LIB_FILE).E && nm -gjp $(TCL_BIN_DIR)/$(TCL_STUB_LIB_FILE) | tail +3 > $$f && echo $$f)' LIBS="$LIBS -framework CoreFoundation" @@ -1899,6 +1901,7 @@ dnl esac AC_SUBST(DL_OBJS) AC_SUBST(PLAT_OBJS) AC_SUBST(PLAT_SRCS) + AC_SUBST(PLAT) AC_SUBST(CFLAGS) AC_SUBST(CFLAGS_DEBUG) AC_SUBST(CFLAGS_OPTIMIZE)