diff options
Diffstat (limited to 'unix/tclXtNotify.c')
-rw-r--r-- | unix/tclXtNotify.c | 352 |
1 files changed, 173 insertions, 179 deletions
diff --git a/unix/tclXtNotify.c b/unix/tclXtNotify.c index b78ac8c..6a11c0d 100644 --- a/unix/tclXtNotify.c +++ b/unix/tclXtNotify.c @@ -1,29 +1,30 @@ -/* +/* * tclXtNotify.c -- * - * This file contains the notifier driver implementation for the - * Xt intrinsics. + * This file contains the notifier driver implementation for the Xt + * intrinsics. * * Copyright (c) 1997 by Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include <X11/Intrinsic.h> -#include <tclInt.h> +#include "tclInt.h" /* - * This structure is used to keep track of the notifier info for a - * a registered file. + * 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; /* Events that have been seen since the - last time FileHandlerEventProc was called - for this file. */ + int mask; /* Mask of desired events: TCL_READABLE, + * etc. */ + int readyMask; /* Events that have been seen since the last + * time FileHandlerEventProc was called for + * this file. */ XtInputId read; /* Xt read callback handle. */ XtInputId write; /* Xt write callback handle. */ XtInputId except; /* Xt exception callback handle. */ @@ -34,33 +35,32 @@ typedef struct FileHandler { } FileHandler; /* - * The following structure is what is added to the Tcl event queue when - * file handlers are ready to fire. + * 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). */ + 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 static structure contains the state information for the - * Xt based implementation of the Tcl notifier. + * The following static structure contains the state information for the Xt + * based implementation of the Tcl notifier. */ static struct NotifierState { - XtAppContext appContext; /* The context used by the Xt - * notifier. Can be set with - * TclSetAppContext. */ - int appContextCreated; /* Was it created by us? */ - XtIntervalId currentTimeout; /* Handle of current timer. */ - FileHandler *firstFileHandlerPtr; /* Pointer to head of file handler - * list. */ + XtAppContext appContext; /* The context used by the Xt notifier. Can be + * set with TclSetAppContext. */ + int appContextCreated; /* Was it created by us? */ + XtIntervalId currentTimeout;/* Handle of current timer. */ + FileHandler *firstFileHandlerPtr; + /* Pointer to head of file handler list. */ } notifier; /* @@ -73,26 +73,23 @@ static int initialized = 0; * Static routines defined in this file. */ -static int FileHandlerEventProc _ANSI_ARGS_((Tcl_Event *evPtr, - int flags)); -static void FileProc _ANSI_ARGS_((caddr_t clientData, - int *source, XtInputId *id)); -void InitNotifier _ANSI_ARGS_((void)); -static void NotifierExitHandler _ANSI_ARGS_(( - ClientData clientData)); -static void TimerProc _ANSI_ARGS_((caddr_t clientData, - XtIntervalId *id)); -static void CreateFileHandler _ANSI_ARGS_((int fd, int mask, - Tcl_FileProc * proc, ClientData clientData)); -static void DeleteFileHandler _ANSI_ARGS_((int fd)); -static void SetTimer _ANSI_ARGS_((Tcl_Time * timePtr)); -static int WaitForEvent _ANSI_ARGS_((Tcl_Time * timePtr)); +static int FileHandlerEventProc(Tcl_Event *evPtr, int flags); +static void FileProc(caddr_t clientData, int *source, + XtInputId *id); +void InitNotifier(void); +static void NotifierExitHandler(ClientData clientData); +static void TimerProc(caddr_t clientData, XtIntervalId *id); +static void CreateFileHandler(int fd, int mask, + Tcl_FileProc * proc, ClientData clientData); +static void DeleteFileHandler(int fd); +static void SetTimer(Tcl_Time * timePtr); +static int WaitForEvent(Tcl_Time * timePtr); /* * Functions defined in this file for use by users of the Xt Notifier: */ -EXTERN XtAppContext TclSetAppContext _ANSI_ARGS_((XtAppContext ctx)); +EXTERN XtAppContext TclSetAppContext(XtAppContext ctx); /* *---------------------------------------------------------------------- @@ -105,18 +102,18 @@ EXTERN XtAppContext TclSetAppContext _ANSI_ARGS_((XtAppContext ctx)); * None. * * Side effects: - * Sets the application context used by the notifier. Panics if - * the context is already set when called. + * Sets the application context used by the notifier. Panics if the + * context is already set when called. * *---------------------------------------------------------------------- */ XtAppContext -TclSetAppContext(appContext) - XtAppContext appContext; +TclSetAppContext( + XtAppContext appContext) { if (!initialized) { - InitNotifier(); + InitNotifier(); } /* @@ -124,46 +121,41 @@ TclSetAppContext(appContext) * new context. If so, we panic because we try to prevent switching * contexts by mistake. Otherwise, we return the one we have. */ - - if (notifier.appContext != NULL) { - if (appContext != NULL) { + if (notifier.appContext != NULL) { + if (appContext != NULL) { /* - * We already have a context. We do not allow switching contexts - * after initialization, so we panic. - */ - - panic("TclSetAppContext: multiple application contexts"); + * We already have a context. We do not allow switching contexts + * after initialization, so we panic. + */ - } + Tcl_Panic("TclSetAppContext: multiple application contexts"); + } } else { + /* + * If we get here we have not yet gotten a context, so either create + * one or use the one supplied by our caller. + */ - /* - * If we get here we have not yet gotten a context, so either create - * one or use the one supplied by our caller. - */ - - if (appContext == NULL) { - + if (appContext == NULL) { /* - * We must create a new context and tell our caller what it is, so - * she can use it too. - */ - - notifier.appContext = XtCreateApplicationContext(); - notifier.appContextCreated = 1; - } else { + * We must create a new context and tell our caller what it is, so + * she can use it too. + */ + notifier.appContext = XtCreateApplicationContext(); + notifier.appContextCreated = 1; + } else { /* - * Otherwise we remember the context that our caller gave us - * and use it. - */ - - notifier.appContextCreated = 0; - notifier.appContext = appContext; - } + * Otherwise we remember the context that our caller gave us and + * use it. + */ + + notifier.appContextCreated = 0; + notifier.appContext = appContext; + } } - + return notifier.appContext; } @@ -184,17 +176,18 @@ TclSetAppContext(appContext) */ void -InitNotifier() +InitNotifier(void) { Tcl_NotifierProcs notifier; + /* - * Only reinitialize if we are not in exit handling. The notifier - * can get reinitialized after its own exit handler has run, because - * of exit handlers for the I/O and timer sub-systems (order dependency). + * Only reinitialize if we are not in exit handling. The notifier can get + * reinitialized after its own exit handler has run, because of exit + * handlers for the I/O and timer sub-systems (order dependency). */ if (TclInExit()) { - return; + return; } notifier.createFileHandlerProc = CreateFileHandler; @@ -207,7 +200,7 @@ InitNotifier() * DO NOT create the application context yet; doing so would prevent * external applications from setting it for us to their own ones. */ - + initialized = 1; memset(¬ifier, 0, sizeof(notifier)); Tcl_CreateExitHandler(NotifierExitHandler, NULL); @@ -218,8 +211,8 @@ InitNotifier() * * NotifierExitHandler -- * - * This function is called to cleanup the notifier state before - * Tcl is unloaded. + * This function is called to cleanup the notifier state before Tcl is + * unloaded. * * Results: * None. @@ -235,15 +228,15 @@ NotifierExitHandler( ClientData clientData) /* Not used. */ { if (notifier.currentTimeout != 0) { - XtRemoveTimeOut(notifier.currentTimeout); + XtRemoveTimeOut(notifier.currentTimeout); } for (; notifier.firstFileHandlerPtr != NULL; ) { - Tcl_DeleteFileHandler(notifier.firstFileHandlerPtr->fd); + Tcl_DeleteFileHandler(notifier.firstFileHandlerPtr->fd); } if (notifier.appContextCreated) { - XtDestroyApplicationContext(notifier.appContext); - notifier.appContextCreated = 0; - notifier.appContext = NULL; + XtDestroyApplicationContext(notifier.appContext); + notifier.appContextCreated = 0; + notifier.appContext = NULL; } initialized = 0; } @@ -265,8 +258,8 @@ NotifierExitHandler( */ static void -SetTimer(timePtr) - Tcl_Time *timePtr; /* Timeout value, may be NULL. */ +SetTimer( + Tcl_Time *timePtr) /* Timeout value, may be NULL. */ { long timeout; @@ -280,9 +273,8 @@ SetTimer(timePtr) } if (timePtr) { timeout = timePtr->sec * 1000 + timePtr->usec / 1000; - notifier.currentTimeout = - XtAppAddTimeOut(notifier.appContext, (unsigned long) timeout, - TimerProc, NULL); + notifier.currentTimeout = XtAppAddTimeOut(notifier.appContext, + (unsigned long) timeout, TimerProc, NULL); } else { notifier.currentTimeout = 0; } @@ -293,22 +285,21 @@ SetTimer(timePtr) * * TimerProc -- * - * This procedure is the XtTimerCallbackProc used to handle - * timeouts. + * This procedure is the XtTimerCallbackProc used to handle timeouts. * * Results: * None. * * Side effects: - * Processes all queued events. + * Processes all queued events. * *---------------------------------------------------------------------- */ static void -TimerProc(data, id) - caddr_t data; /* Not used. */ - XtIntervalId *id; +TimerProc( + caddr_t data, /* Not used. */ + XtIntervalId *id) { if (*id != notifier.currentTimeout) { return; @@ -329,22 +320,22 @@ TimerProc(data, id) * None. * * Side effects: - * Creates a new file handler structure and registers one or more - * input procedures with Xt. + * Creates a new file handler structure and registers one or more input + * procedures with Xt. * *---------------------------------------------------------------------- */ static void -CreateFileHandler(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. */ +CreateFileHandler( + 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. */ { FileHandler *filePtr; @@ -380,9 +371,8 @@ CreateFileHandler(fd, mask, proc, clientData) if (mask & TCL_READABLE) { if (!(filePtr->mask & TCL_READABLE)) { - filePtr->read = - XtAppAddInput(notifier.appContext, fd, XtInputReadMask, - FileProc, filePtr); + filePtr->read = XtAppAddInput(notifier.appContext, fd, + XtInputReadMask, FileProc, filePtr); } } else { if (filePtr->mask & TCL_READABLE) { @@ -391,9 +381,8 @@ CreateFileHandler(fd, mask, proc, clientData) } if (mask & TCL_WRITABLE) { if (!(filePtr->mask & TCL_WRITABLE)) { - filePtr->write = - XtAppAddInput(notifier.appContext, fd, XtInputWriteMask, - FileProc, filePtr); + filePtr->write = XtAppAddInput(notifier.appContext, fd, + XtInputWriteMask, FileProc, filePtr); } } else { if (filePtr->mask & TCL_WRITABLE) { @@ -402,9 +391,8 @@ CreateFileHandler(fd, mask, proc, clientData) } if (mask & TCL_EXCEPTION) { if (!(filePtr->mask & TCL_EXCEPTION)) { - filePtr->except = - XtAppAddInput(notifier.appContext, fd, XtInputExceptMask, - FileProc, filePtr); + filePtr->except = XtAppAddInput(notifier.appContext, fd, + XtInputExceptMask, FileProc, filePtr); } } else { if (filePtr->mask & TCL_EXCEPTION) { @@ -419,8 +407,7 @@ CreateFileHandler(fd, mask, proc, clientData) * * DeleteFileHandler -- * - * Cancel a previously-arranged callback arrangement for - * a file. + * Cancel a previously-arranged callback arrangement for a file. * * Results: * None. @@ -432,9 +419,9 @@ CreateFileHandler(fd, mask, proc, clientData) */ static void -DeleteFileHandler(fd) - int fd; /* Stream id for which to remove - * callback procedure. */ +DeleteFileHandler( + int fd) /* Stream id for which to remove callback + * procedure. */ { FileHandler *filePtr, *prevPtr; @@ -445,8 +432,7 @@ DeleteFileHandler(fd) TclSetAppContext(NULL); /* - * Find the entry for the given file (and return if there - * isn't one). + * Find the entry for the given file (and return if there isn't one). */ for (prevPtr = NULL, filePtr = notifier.firstFileHandlerPtr; ; @@ -492,17 +478,16 @@ DeleteFileHandler(fd) * None. * * Side effects: - * Makes an entry on the Tcl event queue if the event is - * interesting. + * Makes an entry on the Tcl event queue if the event is interesting. * *---------------------------------------------------------------------- */ static void -FileProc(clientData, fd, id) - caddr_t clientData; - int *fd; - XtInputId *id; +FileProc( + caddr_t clientData, + int *fd, + XtInputId *id) { FileHandler *filePtr = (FileHandler *)clientData; FileHandlerEvent *fileEvPtr; @@ -527,7 +512,7 @@ FileProc(clientData, fd, id) if (!(filePtr->mask & mask) || (filePtr->readyMask & mask)) { return; } - + /* * This is an interesting event, so put it onto the event queue. */ @@ -550,16 +535,16 @@ FileProc(clientData, fd, id) * * 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. + * 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. + * 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. @@ -568,10 +553,10 @@ FileProc(clientData, fd, id) */ 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. */ +FileHandlerEventProc( + Tcl_Event *evPtr, /* Event to service. */ + int flags) /* Flags that indicate what events to handle, + * such as TCL_FILE_EVENTS. */ { FileHandler *filePtr; FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) evPtr; @@ -583,9 +568,9 @@ FileHandlerEventProc(evPtr, flags) /* * 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. + * 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. */ for (filePtr = notifier.firstFileHandlerPtr; filePtr != NULL; @@ -596,14 +581,14 @@ FileHandlerEventProc(evPtr, flags) /* * 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. + * 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; @@ -621,14 +606,14 @@ FileHandlerEventProc(evPtr, flags) * * 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 without blocking. + * 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. * * Results: - * Returns 1 if an event was found, else 0. This ensures that - * Tcl_DoOneEvent will return 1, even if the event is handled - * by non-Tcl code. + * Returns 1 if an event was found, else 0. This ensures that + * Tcl_DoOneEvent will return 1, even if the event is handled by non-Tcl + * code. * * Side effects: * Queues file events that are detected by the select. @@ -649,18 +634,27 @@ WaitForEvent( TclSetAppContext(NULL); if (timePtr) { - timeout = timePtr->sec * 1000 + timePtr->usec / 1000; - if (timeout == 0) { - if (XtAppPending(notifier.appContext)) { - goto process; - } else { - return 0; - } - } else { - Tcl_SetTimer(timePtr); - } + timeout = timePtr->sec * 1000 + timePtr->usec / 1000; + if (timeout == 0) { + if (XtAppPending(notifier.appContext)) { + goto process; + } else { + return 0; + } + } else { + Tcl_SetTimer(timePtr); + } } -process: + + process: XtAppProcessEvent(notifier.appContext, XtIMAll); return 1; } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ |