diff options
Diffstat (limited to 'unix/tkUnixEvent.c')
-rw-r--r-- | unix/tkUnixEvent.c | 289 |
1 files changed, 143 insertions, 146 deletions
diff --git a/unix/tkUnixEvent.c b/unix/tkUnixEvent.c index f06c0ca..1ce015c 100644 --- a/unix/tkUnixEvent.c +++ b/unix/tkUnixEvent.c @@ -1,4 +1,4 @@ -/* +/* * tkUnixEvent.c -- * * This file implements an event source for X displays for the @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkUnixEvent.c,v 1.16 2004/05/03 22:28:45 hobbs Exp $ + * RCS: @(#) $Id: tkUnixEvent.c,v 1.17 2005/11/13 21:00:17 dkf Exp $ */ #include "tkInt.h" @@ -28,40 +28,36 @@ static Tcl_ThreadDataKey dataKey; #if defined(TK_USE_INPUT_METHODS) && defined(PEEK_XCLOSEIM) /* - * Structure used to peek into internal XIM data structure. - * This is only known to work with XFree86. + * Structure used to peek into internal XIM data structure. This is only known + * to work with XFree86. */ + struct XIMPeek { void *junk1, *junk2; - XIC ic_chain; + XIC ic_chain; }; #endif /* - * Prototypes for procedures that are referenced only in this file: + * Prototypes for functions that are referenced only in this file: */ -static void DisplayCheckProc _ANSI_ARGS_((ClientData clientData, - int flags)); -static void DisplayExitHandler _ANSI_ARGS_(( - ClientData clientData)); -static void DisplayFileProc _ANSI_ARGS_((ClientData clientData, - int flags)); -static void DisplaySetupProc _ANSI_ARGS_((ClientData clientData, - int flags)); -static void TransferXEventsToTcl _ANSI_ARGS_((Display *display)); +static void DisplayCheckProc(ClientData clientData, int flags); +static void DisplayExitHandler(ClientData clientData); +static void DisplayFileProc(ClientData clientData, int flags); +static void DisplaySetupProc(ClientData clientData, int flags); +static void TransferXEventsToTcl(Display *display); #ifdef TK_USE_INPUT_METHODS -static void OpenIM _ANSI_ARGS_((TkDisplay *dispPtr)); +static void OpenIM(TkDisplay *dispPtr); #endif - /* *---------------------------------------------------------------------- * * TkCreateXEventSource -- * - * This procedure is called during Tk initialization to create - * the event source for X Window events. + * This function is called during Tk initialization to create the event + * source for X Window events. * * Results: * None. @@ -73,9 +69,9 @@ static void OpenIM _ANSI_ARGS_((TkDisplay *dispPtr)); */ void -TkCreateXEventSource() +TkCreateXEventSource(void) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!tsdPtr->initialized) { @@ -90,8 +86,8 @@ TkCreateXEventSource() * * DisplayExitHandler -- * - * This function is called during finalization to clean up the - * display module. + * This function is called during finalization to clean up the display + * module. * * Results: * None. @@ -103,10 +99,10 @@ TkCreateXEventSource() */ static void -DisplayExitHandler(clientData) - ClientData clientData; /* Not used. */ +DisplayExitHandler( + ClientData clientData) /* Not used. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_DeleteEventSource(DisplaySetupProc, DisplayCheckProc, NULL); @@ -118,8 +114,8 @@ DisplayExitHandler(clientData) * * TkpOpenDisplay -- * - * Allocates a new TkDisplay, opens the X display, and establishes - * the file handler for the connection. + * Allocates a new TkDisplay, opens the X display, and establishes the + * file handler for the connection. * * Results: * A pointer to a Tk display structure. @@ -131,11 +127,11 @@ DisplayExitHandler(clientData) */ TkDisplay * -TkpOpenDisplay(display_name) - CONST char *display_name; +TkpOpenDisplay( + CONST char *displayNameStr) { TkDisplay *dispPtr; - Display *display = XOpenDisplay(display_name); + Display *display = XOpenDisplay(displayNameStr); if (display == NULL) { return NULL; @@ -156,7 +152,7 @@ TkpOpenDisplay(display_name) * * TkpCloseDisplay -- * - * Cancels notifier callbacks and closes a display. + * Cancels notifier callbacks and closes a display. * * Results: * None. @@ -168,8 +164,8 @@ TkpOpenDisplay(display_name) */ void -TkpCloseDisplay(dispPtr) - TkDisplay *dispPtr; +TkpCloseDisplay( + TkDisplay *dispPtr) { TkSendCleanup(dispPtr); @@ -185,19 +181,16 @@ TkpCloseDisplay(dispPtr) #endif if (dispPtr->inputMethod) { /* - * Calling XCloseIM with an input context that has not - * been freed can cause a crash. This crash has been - * reproduced under Linux systems with XFree86 3.3 - * and may have also been seen under Solaris 2.3. - * The crash is caused by a double free of memory - * inside the X library. Memory that was already - * deallocated may be accessed again inside XCloseIM. - * This bug can be avoided by making sure that a - * call to XDestroyIC is made for each XCreateIC call. - * This bug has been fixed in XFree86 4.2.99.2. - * The internal layout of the XIM structure changed - * in the XFree86 4.2 release so the test should - * not be run for with these new releases. + * Calling XCloseIM with an input context that has not been freed can + * cause a crash. This crash has been reproduced under Linux systems + * with XFree86 3.3 and may have also been seen under Solaris 2.3. + * The crash is caused by a double free of memory inside the X + * library. Memory that was already deallocated may be accessed again + * inside XCloseIM. This bug can be avoided by making sure that a call + * to XDestroyIC is made for each XCreateIC call. This bug has been + * fixed in XFree86 4.2.99.2. The internal layout of the XIM structure + * changed in the XFree86 4.2 release so the test should not be run + * for with these new releases. */ #if defined(TK_USE_INPUT_METHODS) && defined(PEEK_XCLOSEIM) @@ -223,8 +216,9 @@ TkpCloseDisplay(dispPtr) if (do_peek) { peek = (struct XIMPeek *) dispPtr->inputMethod; - if (peek->ic_chain != NULL) + if (peek->ic_chain != NULL) { Tcl_Panic("input contexts not freed before XCloseIM"); + } } #endif XCloseIM(dispPtr->inputMethod); @@ -243,11 +237,10 @@ TkpCloseDisplay(dispPtr) * * TkClipCleanup -- * - * This procedure is called to cleanup resources associated with - * claiming clipboard ownership and for receiving selection get - * results. This function is called in tkWindow.c. This has to be - * called by the display cleanup function because we still need the - * access display elements. + * This function is called to cleanup resources associated with claiming + * clipboard ownership and for receiving selection get results. This + * function is called in tkWindow.c. This has to be called by the display + * cleanup function because we still need the access display elements. * * Results: * None. @@ -259,8 +252,8 @@ TkpCloseDisplay(dispPtr) */ void -TkClipCleanup(dispPtr) - TkDisplay *dispPtr; /* display associated with clipboard */ +TkClipCleanup( + TkDisplay *dispPtr) /* Display associated with clipboard */ { if (dispPtr->clipWindow != NULL) { Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom, @@ -279,25 +272,25 @@ TkClipCleanup(dispPtr) * * DisplaySetupProc -- * - * This procedure implements the setup part of the UNIX X display - * event source. It is invoked by Tcl_DoOneEvent before entering - * the notifier to check for events on all displays. + * This function implements the setup part of the UNIX X display event + * source. It is invoked by Tcl_DoOneEvent before entering the notifier + * to check for events on all displays. * * Results: * None. * * Side effects: - * If data is queued on a display inside Xlib, then the maximum - * block time will be set to 0 to ensure that the notifier returns - * control to Tcl even if there is no more data on the X connection. + * If data is queued on a display inside Xlib, then the maximum block + * time will be set to 0 to ensure that the notifier returns control to + * Tcl even if there is no more data on the X connection. * *---------------------------------------------------------------------- */ static void -DisplaySetupProc(clientData, flags) - ClientData clientData; /* Not used. */ - int flags; +DisplaySetupProc( + ClientData clientData, /* Not used. */ + int flags) { TkDisplay *dispPtr; static Tcl_Time blockTime = { 0, 0 }; @@ -307,13 +300,11 @@ DisplaySetupProc(clientData, flags) } for (dispPtr = TkGetDisplayList(); dispPtr != NULL; - dispPtr = dispPtr->nextPtr) { - + dispPtr = dispPtr->nextPtr) { /* - * Flush the display. If data is pending on the X queue, set - * the block time to zero. This ensures that we won't block - * in the notifier if there is data in the X queue, but not on - * the server socket. + * Flush the display. If data is pending on the X queue, set the block + * time to zero. This ensures that we won't block in the notifier if + * there is data in the X queue, but not on the server socket. */ XFlush(dispPtr->display); @@ -340,8 +331,8 @@ DisplaySetupProc(clientData, flags) */ static void -TransferXEventsToTcl(display) - Display *display; +TransferXEventsToTcl( + Display *display) { int numFound; XEvent event; @@ -364,8 +355,7 @@ TransferXEventsToTcl(display) * * DisplayCheckProc -- * - * This procedure checks for events sitting in the X event - * queue. + * This function checks for events sitting in the X event queue. * * Results: * None. @@ -377,9 +367,9 @@ TransferXEventsToTcl(display) */ static void -DisplayCheckProc(clientData, flags) - ClientData clientData; /* Not used. */ - int flags; +DisplayCheckProc( + ClientData clientData, /* Not used. */ + int flags) { TkDisplay *dispPtr; @@ -388,7 +378,7 @@ DisplayCheckProc(clientData, flags) } for (dispPtr = TkGetDisplayList(); dispPtr != NULL; - dispPtr = dispPtr->nextPtr) { + dispPtr = dispPtr->nextPtr) { XFlush(dispPtr->display); TransferXEventsToTcl(dispPtr->display); } @@ -399,22 +389,22 @@ DisplayCheckProc(clientData, flags) * * DisplayFileProc -- * - * This procedure implements the file handler for the X connection. + * This function implements the file handler for the X connection. * * Results: * None. * * Side effects: - * Makes entries on the Tcl event queue for all the events available - * from all the displays. + * Makes entries on the Tcl event queue for all the events available from + * all the displays. * *---------------------------------------------------------------------- */ static void -DisplayFileProc(clientData, flags) - ClientData clientData; /* The display pointer. */ - int flags; /* Should be TCL_READABLE. */ +DisplayFileProc( + ClientData clientData, /* The display pointer. */ + int flags) /* Should be TCL_READABLE. */ { TkDisplay *dispPtr = (TkDisplay *) clientData; Display *display = dispPtr->display; @@ -423,38 +413,34 @@ DisplayFileProc(clientData, flags) XFlush(display); numFound = XEventsQueued(display, QueuedAfterReading); if (numFound == 0) { - /* - * Things are very tricky if there aren't any events readable - * at this point (after all, there was supposedly data - * available on the connection). A couple of things could - * have occurred: - * - * One possibility is that there were only error events in the - * input from the server. If this happens, we should return - * (we don't want to go to sleep in XNextEvent below, since - * this would block out other sources of input to the - * process). + * Things are very tricky if there aren't any events readable at this + * point (after all, there was supposedly data available on the + * connection). A couple of things could have occurred: + * + * One possibility is that there were only error events in the input + * from the server. If this happens, we should return (we don't want + * to go to sleep in XNextEvent below, since this would block out + * other sources of input to the process). * - * Another possibility is that our connection to the server - * has been closed. This will not necessarily be detected in - * XEventsQueued (!!), so if we just return then there will be - * an infinite loop. To detect such an error, generate a NoOp - * protocol request to exercise the connection to the server, - * then return. However, must disable SIGPIPE while sending - * the request, or else the process will die from the signal - * and won't invoke the X error function to print a nice (?!) - * message. + * Another possibility is that our connection to the server has been + * closed. This will not necessarily be detected in XEventsQueued (!!) + * so if we just return then there will be an infinite loop. To detect + * such an error, generate a NoOp protocol request to exercise the + * connection to the server, then return. However, must disable + * SIGPIPE while sending the request, or else the process will die + * from the signal and won't invoke the X error function to print a + * nice (?!) message. */ - + void (*oldHandler)(); - + oldHandler = (void (*)()) signal(SIGPIPE, SIG_IGN); XNoOp(display); XFlush(display); (void) signal(SIGPIPE, oldHandler); } - + TransferXEventsToTcl(display); } @@ -463,13 +449,12 @@ DisplayFileProc(clientData, flags) * * TkUnixDoOneXEvent -- * - * This routine waits for an X event to be processed or for - * a timeout to occur. The timeout is specified as an absolute - * time. This routine is called when Tk needs to wait for a - * particular X event without letting arbitrary events be - * processed. The caller will typically call Tk_RestrictEvents - * to set up an event filter before calling this routine. This - * routine will service at most one event per invocation. + * This routine waits for an X event to be processed or for a timeout to + * occur. The timeout is specified as an absolute time. This routine is + * called when Tk needs to wait for a particular X event without letting + * arbitrary events be processed. The caller will typically call + * Tk_RestrictEvents to set up an event filter before calling this + * routine. This routine will service at most one event per invocation. * * Results: * Returns 0 if the timeout has expired, otherwise returns 1. @@ -481,9 +466,9 @@ DisplayFileProc(clientData, flags) */ int -TkUnixDoOneXEvent(timePtr) - Tcl_Time *timePtr; /* Specifies the absolute time when the - * call should time out. */ +TkUnixDoOneXEvent( + Tcl_Time *timePtr) /* Specifies the absolute time when the call + * should time out. */ { TkDisplay *dispPtr; static fd_mask readMask[MASK_SIZE]; @@ -492,7 +477,7 @@ TkUnixDoOneXEvent(timePtr) int fd, index, bit, numFound, numFdBits = 0; /* - * Look for queued events first. + * Look for queued events first. */ if (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) { @@ -501,8 +486,8 @@ TkUnixDoOneXEvent(timePtr) /* * Compute the next block time and check to see if we have timed out. - * Note that HP-UX defines tv_sec to be unsigned so we have to be - * careful in our arithmetic. + * Note that HP-UX defines tv_sec to be unsigned so we have to be careful + * in our arithmetic. */ if (timePtr) { @@ -525,8 +510,8 @@ TkUnixDoOneXEvent(timePtr) } /* - * Set up the select mask for all of the displays. If a display has - * data pending, then we want to poll instead of blocking. + * Set up the select mask for all of the displays. If a display has data + * pending, then we want to poll instead of blocking. */ memset((VOID *) readMask, 0, MASK_SIZE*sizeof(fd_mask)); @@ -550,8 +535,8 @@ TkUnixDoOneXEvent(timePtr) timeoutPtr); if (numFound <= 0) { /* - * Some systems don't clear the masks after an error, so - * we have to do it here. + * Some systems don't clear the masks after an error, so we have to do + * it here. */ memset((VOID *) readMask, 0, MASK_SIZE*sizeof(fd_mask)); @@ -562,7 +547,7 @@ TkUnixDoOneXEvent(timePtr) */ for (dispPtr = TkGetDisplayList(); dispPtr != NULL; - dispPtr = dispPtr->nextPtr) { + dispPtr = dispPtr->nextPtr) { fd = ConnectionNumber(dispPtr->display); index = fd/(NBBY*sizeof(fd_mask)); bit = 1 << (fd%(NBBY*sizeof(fd_mask))); @@ -587,8 +572,8 @@ TkUnixDoOneXEvent(timePtr) } /* - * We had an event but we did not generate a Tcl event from it. Behave - * as though we dealt with it. (JYL&SS) + * We had an event but we did not generate a Tcl event from it. Behave as + * though we dealt with it. (JYL&SS) */ return 1; @@ -599,9 +584,9 @@ TkUnixDoOneXEvent(timePtr) * * TkpSync -- * - * This routine ensures that all pending X requests have been - * seen by the server, and that any pending X events have been - * moved onto the Tk event queue. + * This routine ensures that all pending X requests have been seen by the + * server, and that any pending X events have been moved onto the Tk + * event queue. * * Results: * None. @@ -613,30 +598,31 @@ TkUnixDoOneXEvent(timePtr) */ void -TkpSync(display) - Display *display; /* Display to sync. */ +TkpSync( + Display *display) /* Display to sync. */ { XSync(display, False); /* * Transfer events from the X event queue to the Tk event queue. */ + TransferXEventsToTcl(display); } #ifdef TK_USE_INPUT_METHODS -/* +/* *-------------------------------------------------------------- * * OpenIM -- * - * Tries to open an X input method, associated with the - * given display. Right now we can only deal with a bare-bones - * input style: no preedit, and no status. + * Tries to open an X input method, associated with the given display. + * Right now we can only deal with a bare-bones input style: no preedit, + * and no status. * * Results: - * Stores the input method in dispPtr->inputMethod; if there isn't - * a suitable input method, then NULL is stored in dispPtr->inputMethod. + * Stores the input method in dispPtr->inputMethod; if there isn't a + * suitable input method, then NULL is stored in dispPtr->inputMethod. * * Side effects: * An input method gets opened. @@ -645,8 +631,8 @@ TkpSync(display) */ static void -OpenIM(dispPtr) - TkDisplay *dispPtr; /* Tk's structure for the display. */ +OpenIM( + TkDisplay *dispPtr) /* Tk's structure for the display. */ { unsigned short i; XIMStyles *stylePtr; @@ -664,10 +650,11 @@ OpenIM(dispPtr) NULL) != NULL) || (stylePtr == NULL)) { goto error; } + #if TK_XIM_SPOT /* - * If we want to do over-the-spot XIM, we have to check that this - * mode is supported. If not we will fall-through to the check below. + * If we want to do over-the-spot XIM, we have to check that this mode is + * supported. If not we will fall-through to the check below. */ for (i = 0; i < stylePtr->count_styles; i++) { if (stylePtr->supported_styles[i] @@ -677,7 +664,8 @@ OpenIM(dispPtr) return; } } -#endif +#endif /* TK_XIM_SPOT */ + for (i = 0; i < stylePtr->count_styles; i++) { if (stylePtr->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing)) { @@ -687,15 +675,24 @@ OpenIM(dispPtr) } XFree(stylePtr); - error: + error: if (dispPtr->inputMethod) { /* - * This call should not suffer from any core dumping problems - * since we have not allocated any input contexts. + * This call should not suffer from any core dumping problems since we + * have not allocated any input contexts. */ + XCloseIM(dispPtr->inputMethod); dispPtr->inputMethod = NULL; } } #endif /* TK_USE_INPUT_METHODS */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ |