diff options
Diffstat (limited to 'unix/tclXtNotify.c')
| -rw-r--r-- | unix/tclXtNotify.c | 352 |
1 files changed, 179 insertions, 173 deletions
diff --git a/unix/tclXtNotify.c b/unix/tclXtNotify.c index 6a11c0d..b78ac8c 100644 --- a/unix/tclXtNotify.c +++ b/unix/tclXtNotify.c @@ -1,30 +1,29 @@ -/* +/* * 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. */ @@ -35,32 +34,33 @@ 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,23 +73,26 @@ static int initialized = 0; * Static routines defined in this file. */ -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); +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)); /* * Functions defined in this file for use by users of the Xt Notifier: */ -EXTERN XtAppContext TclSetAppContext(XtAppContext ctx); +EXTERN XtAppContext TclSetAppContext _ANSI_ARGS_((XtAppContext ctx)); /* *---------------------------------------------------------------------- @@ -102,18 +105,18 @@ EXTERN XtAppContext TclSetAppContext(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( - XtAppContext appContext) +TclSetAppContext(appContext) + XtAppContext appContext; { if (!initialized) { - InitNotifier(); + InitNotifier(); } /* @@ -121,41 +124,46 @@ TclSetAppContext( * 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 (appContext != NULL) { + /* - * We already have a context. We do not allow switching contexts - * after initialization, so we panic. - */ + * We already have a context. We do not allow switching contexts + * after initialization, so we panic. + */ + + panic("TclSetAppContext: multiple application contexts"); - 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 (appContext == NULL) { - /* - * We must create a new context and tell our caller what it is, so - * she can use it too. - */ + /* + * 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) { - notifier.appContext = XtCreateApplicationContext(); - notifier.appContextCreated = 1; - } else { /* - * Otherwise we remember the context that our caller gave us and - * use it. - */ + * 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 { - 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; } @@ -176,18 +184,17 @@ TclSetAppContext( */ void -InitNotifier(void) +InitNotifier() { 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; @@ -200,7 +207,7 @@ InitNotifier(void) * 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); @@ -211,8 +218,8 @@ InitNotifier(void) * * 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. @@ -228,15 +235,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; } @@ -258,8 +265,8 @@ NotifierExitHandler( */ static void -SetTimer( - Tcl_Time *timePtr) /* Timeout value, may be NULL. */ +SetTimer(timePtr) + Tcl_Time *timePtr; /* Timeout value, may be NULL. */ { long timeout; @@ -273,8 +280,9 @@ SetTimer( } 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; } @@ -285,21 +293,22 @@ SetTimer( * * 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( - caddr_t data, /* Not used. */ - XtIntervalId *id) +TimerProc(data, id) + caddr_t data; /* Not used. */ + XtIntervalId *id; { if (*id != notifier.currentTimeout) { return; @@ -320,22 +329,22 @@ TimerProc( * 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( - 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(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. */ { FileHandler *filePtr; @@ -371,8 +380,9 @@ CreateFileHandler( 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) { @@ -381,8 +391,9 @@ CreateFileHandler( } 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) { @@ -391,8 +402,9 @@ CreateFileHandler( } 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) { @@ -407,7 +419,8 @@ CreateFileHandler( * * DeleteFileHandler -- * - * Cancel a previously-arranged callback arrangement for a file. + * Cancel a previously-arranged callback arrangement for + * a file. * * Results: * None. @@ -419,9 +432,9 @@ CreateFileHandler( */ static void -DeleteFileHandler( - int fd) /* Stream id for which to remove callback - * procedure. */ +DeleteFileHandler(fd) + int fd; /* Stream id for which to remove + * callback procedure. */ { FileHandler *filePtr, *prevPtr; @@ -432,7 +445,8 @@ DeleteFileHandler( 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; ; @@ -478,16 +492,17 @@ DeleteFileHandler( * 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( - caddr_t clientData, - int *fd, - XtInputId *id) +FileProc(clientData, fd, id) + caddr_t clientData; + int *fd; + XtInputId *id; { FileHandler *filePtr = (FileHandler *)clientData; FileHandlerEvent *fileEvPtr; @@ -512,7 +527,7 @@ FileProc( if (!(filePtr->mask & mask) || (filePtr->readyMask & mask)) { return; } - + /* * This is an interesting event, so put it onto the event queue. */ @@ -535,16 +550,16 @@ FileProc( * * 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. @@ -553,10 +568,10 @@ FileProc( */ static int -FileHandlerEventProc( - Tcl_Event *evPtr, /* Event to service. */ - int flags) /* Flags that indicate what events to handle, - * such as TCL_FILE_EVENTS. */ +FileHandlerEventProc(evPtr, flags) + 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; @@ -568,9 +583,9 @@ FileHandlerEventProc( /* * 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; @@ -581,14 +596,14 @@ FileHandlerEventProc( /* * 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; @@ -606,14 +621,14 @@ FileHandlerEventProc( * * 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. @@ -634,27 +649,18 @@ 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: - */ |
