diff options
Diffstat (limited to 'tk8.6/generic/tkError.c')
-rw-r--r-- | tk8.6/generic/tkError.c | 291 |
1 files changed, 0 insertions, 291 deletions
diff --git a/tk8.6/generic/tkError.c b/tk8.6/generic/tkError.c deleted file mode 100644 index fc223e6..0000000 --- a/tk8.6/generic/tkError.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * tkError.c -- - * - * This file provides a high-performance mechanism for selectively - * dealing with errors that occur in talking to the X server. This is - * useful, for example, when communicating with a window that may not - * exist. - * - * Copyright (c) 1990-1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkInt.h" - -/* - * The default X error handler gets saved here, so that it can be invoked if - * an error occurs that we can't handle. - */ - -typedef int (*TkXErrorHandler)(Display *display, XErrorEvent *eventPtr); -static TkXErrorHandler defaultHandler = NULL; - -/* - * Forward references to procedures declared later in this file: - */ - -static int ErrorProc(Display *display, XErrorEvent *errEventPtr); - -/* - *-------------------------------------------------------------- - * - * Tk_CreateErrorHandler -- - * - * Arrange for all a given procedure to be invoked whenever certain - * errors occur. - * - * Results: - * The return value is a token identifying the handler; it must be passed - * to Tk_DeleteErrorHandler to delete the handler. - * - * Side effects: - * If an X error occurs that matches the error, request, and minor - * arguments, then errorProc will be invoked. ErrorProc should have the - * following structure: - * - * int - * errorProc(caddr_t clientData, XErrorEvent *errorEventPtr) { - * } - * - * The clientData argument will be the same as the clientData argument to - * this procedure, and errorEvent will describe the error. If errorProc - * returns 0, it means that it completely "handled" the error: no further - * processing should be done. If errorProc returns 1, it means that it - * didn't know how to deal with the error, so we should look for other - * error handlers, or invoke the default error handler if no other - * handler returns zero. Handlers are invoked in order of age: youngest - * handler first. - * - * Note: errorProc will only be called for errors associated with X - * requests made AFTER this call, but BEFORE the handler is deleted by - * calling Tk_DeleteErrorHandler. - * - *-------------------------------------------------------------- - */ - -Tk_ErrorHandler -Tk_CreateErrorHandler( - Display *display, /* Display for which to handle errors. */ - int error, /* Consider only errors with this error_code - * (-1 means consider all errors). */ - int request, /* Consider only errors with this major - * request code (-1 means consider all major - * codes). */ - int minorCode, /* Consider only errors with this minor - * request code (-1 means consider all minor - * codes). */ - Tk_ErrorProc *errorProc, /* Procedure to invoke when a matching error - * occurs. NULL means just ignore matching - * errors. */ - ClientData clientData) /* Arbitrary value to pass to errorProc. */ -{ - register TkErrorHandler *errorPtr; - register TkDisplay *dispPtr; - - /* - * Find the display. If Tk doesn't know about this display then it's an - * error: panic. - */ - - dispPtr = TkGetDisplay(display); - if (dispPtr == NULL) { - Tcl_Panic("Unknown display passed to Tk_CreateErrorHandler"); - } - - /* - * Make sure that X calls us whenever errors occur. - */ - - if (defaultHandler == NULL) { - defaultHandler = XSetErrorHandler(ErrorProc); - } - - /* - * Create the handler record. - */ - - errorPtr = ckalloc(sizeof(TkErrorHandler)); - errorPtr->dispPtr = dispPtr; - errorPtr->firstRequest = NextRequest(display); - errorPtr->lastRequest = (unsigned) -1; - errorPtr->error = error; - errorPtr->request = request; - errorPtr->minorCode = minorCode; - errorPtr->errorProc = errorProc; - errorPtr->clientData = clientData; - errorPtr->nextPtr = dispPtr->errorPtr; - dispPtr->errorPtr = errorPtr; - - return (Tk_ErrorHandler) errorPtr; -} - -/* - *-------------------------------------------------------------- - * - * Tk_DeleteErrorHandler -- - * - * Do not use an error handler anymore. - * - * Results: - * None. - * - * Side effects: - * The handler denoted by the "handler" argument will not be invoked for - * any X errors associated with requests made after this call. However, - * if errors arrive later for requests made BEFORE this call, then the - * handler will still be invoked. Call XSync if you want to be sure that - * all outstanding errors have been received and processed. - * - *-------------------------------------------------------------- - */ - -void -Tk_DeleteErrorHandler( - Tk_ErrorHandler handler) /* Token for handler to delete; was previous - * return value from Tk_CreateErrorHandler. */ -{ - register TkErrorHandler *errorPtr = (TkErrorHandler *) handler; - register TkDisplay *dispPtr = errorPtr->dispPtr; - - errorPtr->lastRequest = NextRequest(dispPtr->display) - 1; - - /* - * Every once-in-a-while, cleanup handlers that are no longer active. We - * probably won't be able to free the handler that was just deleted (need - * to wait for any outstanding requests to be processed by server), but - * there may be previously-deleted handlers that are now ready for garbage - * collection. To reduce the cost of the cleanup, let a few dead handlers - * pile up, then clean them all at once. This adds a bit of overhead to - * errors that might occur while the dead handlers are hanging around, but - * reduces the overhead of scanning the list to clean up (particularly if - * there are many handlers that stay around forever). - */ - - dispPtr->deleteCount += 1; - if (dispPtr->deleteCount >= 10) { - register TkErrorHandler *prevPtr; - TkErrorHandler *nextPtr; - int lastSerial; - - dispPtr->deleteCount = 0; - lastSerial = LastKnownRequestProcessed(dispPtr->display); - errorPtr = dispPtr->errorPtr; - for (prevPtr = NULL; errorPtr != NULL; errorPtr = nextPtr) { - nextPtr = errorPtr->nextPtr; - if ((errorPtr->lastRequest != (unsigned long) -1) - && (errorPtr->lastRequest <= (unsigned long) lastSerial)) { - if (prevPtr == NULL) { - dispPtr->errorPtr = nextPtr; - } else { - prevPtr->nextPtr = nextPtr; - } - ckfree(errorPtr); - continue; - } - prevPtr = errorPtr; - } - } -} - -/* - *-------------------------------------------------------------- - * - * ErrorProc -- - * - * This procedure is invoked by the X system when error events arrive. - * - * Results: - * If it returns, the return value is zero. However, it is possible that - * one of the error handlers may just exit. - * - * Side effects: - * This procedure does two things. First, it uses the serial # in the - * error event to eliminate handlers whose expiration serials are now in - * the past. Second, it invokes any handlers that want to deal with the - * error. - * - *-------------------------------------------------------------- - */ - -static int -ErrorProc( - Display *display, /* Display for which error occurred. */ - register XErrorEvent *errEventPtr) - /* Information about error. */ -{ - register TkDisplay *dispPtr; - register TkErrorHandler *errorPtr; - - /* - * See if we know anything about the display. If not, then invoke the - * default error handler. - */ - - dispPtr = TkGetDisplay(display); - if (dispPtr == NULL) { - goto couldntHandle; - } - - /* - * Otherwise invoke any relevant handlers for the error, in order. - */ - - for (errorPtr = dispPtr->errorPtr; errorPtr != NULL; - errorPtr = errorPtr->nextPtr) { - if ((errorPtr->firstRequest > errEventPtr->serial) - || ((errorPtr->error != -1) - && (errorPtr->error != errEventPtr->error_code)) - || ((errorPtr->request != -1) - && (errorPtr->request != errEventPtr->request_code)) - || ((errorPtr->minorCode != -1) - && (errorPtr->minorCode != errEventPtr->minor_code)) - || ((errorPtr->lastRequest != (unsigned long) -1) - && (errorPtr->lastRequest < errEventPtr->serial))) { - continue; - } - if (errorPtr->errorProc == NULL || - errorPtr->errorProc(errorPtr->clientData, errEventPtr) == 0) { - return 0; - } - } - - /* - * See if the error is a BadWindow error. If so, and it refers to a window - * that still exists in our window table, then ignore the error. Errors - * like this can occur if a window owned by us is deleted by someone - * externally, like a window manager. We'll ignore the errors at least - * long enough to clean up internally and remove the entry from the window - * table. - * - * NOTE: For embedding, we must also check whether the window was recently - * deleted. If so, it may be that Tk generated operations on windows that - * were deleted by the container. Now we are getting the errors - * (BadWindow) after Tk already deleted the window itself. - */ - - if (errEventPtr->error_code == BadWindow) { - Window w = (Window) errEventPtr->resourceid; - - if (Tk_IdToWindow(display, w) != NULL) { - return 0; - } - } - - /* - * We couldn't handle the error. Use the default handler. - */ - - couldntHandle: - return defaultHandler(display, errEventPtr); -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ |