summaryrefslogtreecommitdiffstats
path: root/unix/tkUnixXId.c
diff options
context:
space:
mode:
Diffstat (limited to 'unix/tkUnixXId.c')
-rw-r--r--unix/tkUnixXId.c353
1 files changed, 173 insertions, 180 deletions
diff --git a/unix/tkUnixXId.c b/unix/tkUnixXId.c
index 428d5fe..928c4d5 100644
--- a/unix/tkUnixXId.c
+++ b/unix/tkUnixXId.c
@@ -1,12 +1,11 @@
-/*
+/*
* tkUnixXId.c --
*
- * This file provides a replacement function for the default X
- * resource allocator (_XAllocID). The problem with the default
- * allocator is that it never re-uses ids, which causes long-lived
- * applications to crash when X resource identifiers wrap around.
- * The replacement functions in this file re-use old identifiers
- * to prevent this problem.
+ * This file provides a replacement function for the default X resource
+ * allocator (_XAllocID). The problem with the default allocator is that
+ * it never re-uses ids, which causes long-lived applications to crash
+ * when X resource identifiers wrap around. The replacement functions in
+ * this file re-use old identifiers to prevent this problem.
*
* The code in this file is based on similar implementations by
* George C. Kaplan and Michael Hoegeman.
@@ -14,54 +13,52 @@
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1994-1997 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.
*/
/*
- * The definition below is needed on some systems so that we can access
- * the resource_alloc field of Display structures in order to replace
- * the resource allocator.
+ * The definition below is needed on some systems so that we can access the
+ * resource_alloc field of Display structures in order to replace the resource
+ * allocator.
*/
#define XLIB_ILLEGAL_ACCESS 1
#include "tkUnixInt.h"
-#include "tkPort.h"
/*
- * A structure of the following type is used to hold one or more
- * available resource identifiers. There is a list of these structures
- * for each display.
+ * A structure of the following type is used to hold one or more available
+ * resource identifiers. There is a list of these structures for each display.
*/
#define IDS_PER_STACK 10
typedef struct TkIdStack {
- XID ids[IDS_PER_STACK]; /* Array of free identifiers. */
- int numUsed; /* Indicates how many of the entries
- * in ids are currently in use. */
- TkDisplay *dispPtr; /* Display to which ids belong. */
- struct TkIdStack *nextPtr; /* Next bunch of free identifiers
- * for the same display. */
+ XID ids[IDS_PER_STACK]; /* Array of free identifiers. */
+ int numUsed; /* Indicates how many of the entries in ids
+ * are currently in use. */
+ TkDisplay *dispPtr; /* Display to which ids belong. */
+ struct TkIdStack *nextPtr; /* Next bunch of free identifiers for the same
+ * display. */
} TkIdStack;
/*
- * Forward declarations for procedures defined in this file:
+ * Forward declarations for functions defined in this file:
*/
-static XID AllocXId _ANSI_ARGS_((Display *display));
-static Tk_RestrictAction CheckRestrictProc _ANSI_ARGS_((
- ClientData clientData, XEvent *eventPtr));
-static void WindowIdCleanup _ANSI_ARGS_((ClientData clientData));
-static void WindowIdCleanup2 _ANSI_ARGS_((ClientData clientData));
+static XID AllocXId(Display *display);
+static Tk_RestrictAction CheckRestrictProc(ClientData clientData,
+ XEvent *eventPtr);
+static void WindowIdCleanup(ClientData clientData);
+static void WindowIdCleanup2(ClientData clientData);
/*
*----------------------------------------------------------------------
*
* TkInitXId --
*
- * This procedure is called to initialize the id allocator for
- * a given display.
+ * This function is called to initialize the id allocator for a given
+ * display.
*
* Results:
* None.
@@ -73,13 +70,12 @@ static void WindowIdCleanup2 _ANSI_ARGS_((ClientData clientData));
*/
void
-TkInitXId(dispPtr)
- TkDisplay *dispPtr; /* Tk's information about the
- * display. */
+TkInitXId(
+ TkDisplay *dispPtr) /* Tk's information about the display. */
{
dispPtr->idStackPtr = NULL;
- dispPtr->defaultAllocProc = (XID (*) _ANSI_ARGS_((Display *display)))
- dispPtr->display->resource_alloc;
+ dispPtr->defaultAllocProc = (XID (*) _ANSI_ARGS_((Display *display)))
+ dispPtr->display->resource_alloc;
dispPtr->display->resource_alloc = AllocXId;
dispPtr->windowStackPtr = NULL;
dispPtr->idCleanupScheduled = (Tcl_TimerToken) 0;
@@ -90,8 +86,8 @@ TkInitXId(dispPtr)
*
* TkFreeXId --
*
- * This procedure is called to free resources for the id allocator
- * for a given display.
+ * This function is called to free resources for the id allocator for a
+ * given display.
*
* Results:
* None.
@@ -103,9 +99,8 @@ TkInitXId(dispPtr)
*/
void
-TkFreeXId(dispPtr)
- TkDisplay *dispPtr; /* Tk's information about the
- * display. */
+TkFreeXId(
+ TkDisplay *dispPtr) /* Tk's information about the display. */
{
TkIdStack *stackPtr, *freePtr;
@@ -133,23 +128,23 @@ TkFreeXId(dispPtr)
*
* AllocXId --
*
- * This procedure is invoked by Xlib as the resource allocator
- * for a display.
+ * This function is invoked by Xlib as the resource allocator for a
+ * display.
*
* Results:
- * The return value is an X resource identifier that isn't currently
- * in use.
+ * The return value is an X resource identifier that isn't currently in
+ * use.
*
* Side effects:
- * The identifier is removed from the stack of free identifiers,
- * if it was previously on the stack.
+ * The identifier is removed from the stack of free identifiers, if it
+ * was previously on the stack.
*
*----------------------------------------------------------------------
*/
static XID
-AllocXId(display)
- Display *display; /* Display for which to allocate. */
+AllocXId(
+ Display *display) /* Display for which to allocate. */
{
TkDisplay *dispPtr;
TkIdStack *stackPtr;
@@ -159,10 +154,10 @@ AllocXId(display)
*/
dispPtr = TkGetDisplay(display);
-
+
/*
- * If the topmost chunk on the stack is empty then free it. Then
- * check for a free id on the stack and return it if it exists.
+ * If the topmost chunk on the stack is empty then free it. Then check for
+ * a free id on the stack and return it if it exists.
*/
stackPtr = dispPtr->idStackPtr;
@@ -180,11 +175,10 @@ AllocXId(display)
}
/*
- * No free ids in the stack: just get one from the default
- * allocator.
+ * No free ids in the stack: just get one from the default allocator.
*/
- defAlloc:
+ defAlloc:
return (*dispPtr->defaultAllocProc)(display);
}
@@ -193,8 +187,8 @@ AllocXId(display)
*
* Tk_FreeXId --
*
- * This procedure is called to indicate that an X resource identifier
- * is now free.
+ * This function is called to indicate that an X resource identifier is
+ * now free.
*
* Results:
* None.
@@ -207,11 +201,9 @@ AllocXId(display)
*/
void
-Tk_FreeXId(display, xid)
- Display *display; /* Display for which xid was
- * allocated. */
- XID xid; /* Identifier that is no longer
- * in use. */
+Tk_FreeXId(
+ Display *display, /* Display for which xid was allocated. */
+ XID xid) /* Identifier that is no longer in use. */
{
TkDisplay *dispPtr;
TkIdStack *stackPtr;
@@ -225,7 +217,7 @@ Tk_FreeXId(display, xid)
/*
* Add a new chunk to the stack if the current chunk is full.
*/
-
+
stackPtr = dispPtr->idStackPtr;
if ((stackPtr == NULL) || (stackPtr->numUsed >= IDS_PER_STACK)) {
stackPtr = (TkIdStack *) ckalloc(sizeof(TkIdStack));
@@ -248,68 +240,64 @@ Tk_FreeXId(display, xid)
*
* TkFreeWindowId --
*
- * This procedure is invoked instead of TkFreeXId for window ids.
- * See below for the reason why.
+ * This function is invoked instead of TkFreeXId for window ids. See
+ * below for the reason why.
*
* Results:
* None.
*
* Side effects:
- * The id given by w will eventually be freed, so that it can be
- * reused for other resources.
+ * The id given by w will eventually be freed, so that it can be reused
+ * for other resources.
*
* Design:
- * Freeing window ids is very tricky because there could still be
- * events pending for a window in the event queue (or even in the
- * server) at the time the window is destroyed. If the window
- * id were to get reused immediately for another window, old
- * events could "drop in" on the new window, causing unexpected
- * behavior.
- *
- * Thus we have to wait to re-use a window id until we know that
- * there are no events left for it. Right now this is done in
- * two steps. First, we wait until we know that the server
- * has seen the XDestroyWindow request, so we can be sure that
- * it won't generate more events for the window and that any
- * existing events are in our queue. Second, we make sure that
- * there are no events whatsoever in our queue (this is conservative
- * but safe).
- *
- * The first step is done by remembering the request id of the
- * XDestroyWindow request and using LastKnownRequestProcessed to
- * see what events the server has processed. If multiple windows
- * get destroyed at about the same time, we just remember the
- * most recent request number for any of them (again, conservative
- * but safe).
- *
- * There are a few other complications as well. When Tk destroys a
- * sub-tree of windows, it only issues a single XDestroyWindow call,
- * at the very end for the root of the subtree. We can't free any of
- * the window ids until the final XDestroyWindow call. To make sure
- * that this happens, we have to keep track of deletions in progress,
- * hence the need for the "destroyCount" field of the display.
- *
- * One final problem. Some servers, like Sun X11/News servers still
- * seem to have problems with ids getting reused too quickly. I'm
- * not completely sure why this is a problem, but delaying the
- * recycling of ids appears to eliminate it. Therefore, we wait
- * an additional few seconds, even after "the coast is clear"
- * before reusing the ids.
+ * Freeing window ids is very tricky because there could still be events
+ * pending for a window in the event queue (or even in the server) at the
+ * time the window is destroyed. If the window id were to get reused
+ * immediately for another window, old events could "drop in" on the new
+ * window, causing unexpected behavior.
+ *
+ * Thus we have to wait to re-use a window id until we know that there
+ * are no events left for it. Right now this is done in two steps. First,
+ * we wait until we know that the server has seen the XDestroyWindow
+ * request, so we can be sure that it won't generate more events for the
+ * window and that any existing events are in our queue. Second, we make
+ * sure that there are no events whatsoever in our queue (this is
+ * conservative but safe).
+ *
+ * The first step is done by remembering the request id of the
+ * XDestroyWindow request and using LastKnownRequestProcessed to see what
+ * events the server has processed. If multiple windows get destroyed at
+ * about the same time, we just remember the most recent request number
+ * for any of them (again, conservative but safe).
+ *
+ * There are a few other complications as well. When Tk destroys a
+ * sub-tree of windows, it only issues a single XDestroyWindow call, at
+ * the very end for the root of the subtree. We can't free any of the
+ * window ids until the final XDestroyWindow call. To make sure that this
+ * happens, we have to keep track of deletions in progress, hence the
+ * need for the "destroyCount" field of the display.
+ *
+ * One final problem. Some servers, like Sun X11/News servers still seem
+ * to have problems with ids getting reused too quickly. I'm not
+ * completely sure why this is a problem, but delaying the recycling of
+ * ids appears to eliminate it. Therefore, we wait an additional few
+ * seconds, even after "the coast is clear" before reusing the ids.
*
*----------------------------------------------------------------------
*/
void
-TkFreeWindowId(dispPtr, w)
- TkDisplay *dispPtr; /* Display that w belongs to. */
- Window w; /* X identifier for window on dispPtr. */
+TkFreeWindowId(
+ TkDisplay *dispPtr, /* Display that w belongs to. */
+ Window w) /* X identifier for window on dispPtr. */
{
TkIdStack *stackPtr;
/*
- * Put the window id on a separate stack of window ids, rather
- * than the main stack, so it won't get reused right away. Add
- * a new chunk to the stack if the current chunk is full.
+ * Put the window id on a separate stack of window ids, rather than the
+ * main stack, so it won't get reused right away. Add a new chunk to the
+ * stack if the current chunk is full.
*/
stackPtr = dispPtr->windowStackPtr;
@@ -329,13 +317,12 @@ TkFreeWindowId(dispPtr, w)
stackPtr->numUsed++;
/*
- * Schedule a call to WindowIdCleanup if one isn't already
- * scheduled.
+ * Schedule a call to WindowIdCleanup if one isn't already scheduled.
*/
if (!dispPtr->idCleanupScheduled) {
- dispPtr->idCleanupScheduled =
- Tcl_CreateTimerHandler(100, WindowIdCleanup, (ClientData) dispPtr);
+ dispPtr->idCleanupScheduled = Tcl_CreateTimerHandler(100,
+ WindowIdCleanup, (ClientData) dispPtr);
}
}
@@ -344,24 +331,23 @@ TkFreeWindowId(dispPtr, w)
*
* WindowIdCleanup --
*
- * See if we can now free up all the accumulated ids of
- * deleted windows.
+ * See if we can now free up all the accumulated ids of deleted windows.
*
* Results:
* None.
*
* Side effects:
- * If it's safe to move the window ids back to the main free
- * list, we schedule this to happen after a few mores seconds
- * of delay. If it's not safe to move them yet, a timer handler
- * gets invoked to try again later.
+ * If it's safe to move the window ids back to the main free list, we
+ * schedule this to happen after a few mores seconds of delay. If it's
+ * not safe to move them yet, a timer handler gets invoked to try again
+ * later.
*
*----------------------------------------------------------------------
*/
static void
-WindowIdCleanup(clientData)
- ClientData clientData; /* Pointer to TkDisplay for display */
+WindowIdCleanup(
+ ClientData clientData) /* Pointer to TkDisplay for display */
{
TkDisplay *dispPtr = (TkDisplay *) clientData;
int anyEvents, delta;
@@ -372,14 +358,14 @@ WindowIdCleanup(clientData)
dispPtr->idCleanupScheduled = (Tcl_TimerToken) 0;
/*
- * See if it's safe to recycle the window ids. It's safe if:
+ * See if it's safe to recycle the window ids. It's safe if:
* (a) no deletions are in progress.
* (b) the server has seen all of the requests up to the last
* XDestroyWindow request.
- * (c) there are no events in the event queue; the only way to
- * test for this right now is to create a restrict proc that
- * will filter the events, then call Tcl_DoOneEvent to see if
- * the procedure gets invoked.
+ * (c) there are no events in the event queue; the only way to test for
+ * this right now is to create a restrict proc that will filter the
+ * events, then call Tcl_DoOneEvent to see if the function gets
+ * invoked.
*/
if (dispPtr->destroyCount > 0) {
@@ -400,8 +386,8 @@ WindowIdCleanup(clientData)
}
/*
- * These ids look safe to recycle, but we still need to delay a bit
- * more (see comments for TkFreeWindowId). Schedule the final freeing.
+ * These ids look safe to recycle, but we still need to delay a bit more
+ * (see comments for TkFreeWindowId). Schedule the final freeing.
*/
if (dispPtr->windowStackPtr != NULL) {
@@ -412,12 +398,12 @@ WindowIdCleanup(clientData)
return;
/*
- * It's still not safe to free up the ids. Try again a bit later.
+ * It's still not safe to free up the ids. Try again a bit later.
*/
- tryAgain:
- dispPtr->idCleanupScheduled =
- Tcl_CreateTimerHandler(500, WindowIdCleanup, (ClientData) dispPtr);
+ tryAgain:
+ dispPtr->idCleanupScheduled = Tcl_CreateTimerHandler(500,
+ WindowIdCleanup, (ClientData) dispPtr);
}
/*
@@ -425,9 +411,9 @@ WindowIdCleanup(clientData)
*
* WindowIdCleanup2 --
*
- * This procedure is the last one in the chain that recycles
- * window ids. It takes all of the ids indicated by its
- * argument and adds them back to the main id free list.
+ * This function is the last one in the chain that recycles window ids.
+ * It takes all of the ids indicated by its argument and adds them back
+ * to the main id free list.
*
* Results:
* None.
@@ -439,8 +425,8 @@ WindowIdCleanup(clientData)
*/
static void
-WindowIdCleanup2(clientData)
- ClientData clientData; /* Pointer to TkIdStack list. */
+WindowIdCleanup2(
+ ClientData clientData) /* Pointer to TkIdStack list. */
{
TkIdStack *stackPtr = (TkIdStack *) clientData;
TkIdStack *lastPtr;
@@ -458,9 +444,9 @@ WindowIdCleanup2(clientData)
*
* CheckRestrictProc --
*
- * This procedure is a restrict procedure, called by Tcl_DoOneEvent
- * to filter X events. All it does is to set a flag to indicate
- * that there are X events present.
+ * This function is a restrict function, called by Tcl_DoOneEvent to
+ * filter X events. All it does is to set a flag to indicate that there
+ * are X events present.
*
* Results:
* Sets the integer pointed to by the argument, then returns
@@ -473,9 +459,9 @@ WindowIdCleanup2(clientData)
*/
static Tk_RestrictAction
-CheckRestrictProc(clientData, eventPtr)
- ClientData clientData; /* Pointer to flag to set. */
- XEvent *eventPtr; /* Event to filter; not used. */
+CheckRestrictProc(
+ ClientData clientData, /* Pointer to flag to set. */
+ XEvent *eventPtr) /* Event to filter; not used. */
{
int *flag = (int *) clientData;
*flag = 1;
@@ -487,8 +473,8 @@ CheckRestrictProc(clientData, eventPtr)
*
* Tk_GetPixmap --
*
- * Same as the XCreatePixmap procedure except that it manages
- * resource identifiers better.
+ * Same as the XCreatePixmap function except that it manages resource
+ * identifiers better.
*
* Results:
* Returns a new pixmap.
@@ -500,11 +486,11 @@ CheckRestrictProc(clientData, eventPtr)
*/
Pixmap
-Tk_GetPixmap(display, d, width, height, depth)
- Display *display; /* Display for new pixmap. */
- Drawable d; /* Drawable where pixmap will be used. */
- int width, height; /* Dimensions of pixmap. */
- int depth; /* Bits per pixel for pixmap. */
+Tk_GetPixmap(
+ Display *display, /* Display for new pixmap. */
+ Drawable d, /* Drawable where pixmap will be used. */
+ int width, int height, /* Dimensions of pixmap. */
+ int depth) /* Bits per pixel for pixmap. */
{
return XCreatePixmap(display, d, (unsigned) width, (unsigned) height,
(unsigned) depth);
@@ -515,23 +501,23 @@ Tk_GetPixmap(display, d, width, height, depth)
*
* Tk_FreePixmap --
*
- * Same as the XFreePixmap procedure except that it also marks
- * the resource identifier as free.
+ * Same as the XFreePixmap function except that it also marks the
+ * resource identifier as free.
*
* Results:
* None.
*
* Side effects:
- * The pixmap is freed in the X server and its resource identifier
- * is saved for re-use.
+ * The pixmap is freed in the X server and its resource identifier is
+ * saved for re-use.
*
*----------------------------------------------------------------------
*/
void
-Tk_FreePixmap(display, pixmap)
- Display *display; /* Display for which pixmap was allocated. */
- Pixmap pixmap; /* Identifier for pixmap. */
+Tk_FreePixmap(
+ Display *display, /* Display for which pixmap was allocated. */
+ Pixmap pixmap) /* Identifier for pixmap. */
{
XFreePixmap(display, pixmap);
Tk_FreeXId(display, (XID) pixmap);
@@ -542,10 +528,10 @@ Tk_FreePixmap(display, pixmap)
*
* TkpWindowWasRecentlyDeleted --
*
- * Checks whether the window was recently deleted. This is called
- * by the generic error handler to detect asynchronous notification
- * of errors due to operations by Tk on a window that was already
- * deleted by the server.
+ * Checks whether the window was recently deleted. This is called by the
+ * generic error handler to detect asynchronous notification of errors
+ * due to operations by Tk on a window that was already deleted by the
+ * server.
*
* Results:
* 1 if the window was deleted recently, 0 otherwise.
@@ -557,21 +543,20 @@ Tk_FreePixmap(display, pixmap)
*/
int
-TkpWindowWasRecentlyDeleted(win, dispPtr)
- Window win; /* The window to check for. */
- TkDisplay *dispPtr; /* The window belongs to this display. */
+TkpWindowWasRecentlyDeleted(
+ Window win, /* The window to check for. */
+ TkDisplay *dispPtr) /* The window belongs to this display. */
{
TkIdStack *stackPtr;
int i;
- for (stackPtr = dispPtr->windowStackPtr;
- stackPtr != NULL;
- stackPtr = stackPtr->nextPtr) {
- for (i = 0; i < stackPtr->numUsed; i++) {
- if ((Window) stackPtr->ids[i] == win) {
- return 1;
- }
- }
+ for (stackPtr = dispPtr->windowStackPtr; stackPtr != NULL;
+ stackPtr = stackPtr->nextPtr) {
+ for (i = 0; i < stackPtr->numUsed; i++) {
+ if ((Window) stackPtr->ids[i] == win) {
+ return 1;
+ }
+ }
}
return 0;
}
@@ -584,10 +569,10 @@ TkpWindowWasRecentlyDeleted(win, dispPtr)
* Given a string, produce the corresponding Window Id.
*
* Results:
- * The return value is normally TCL_OK; in this case *idPtr
- * will be set to the Window value equivalent to string. If
- * string is improperly formed then TCL_ERROR is returned and
- * an error message will be left in the interp's result.
+ * The return value is normally TCL_OK; in this case *idPtr will be set
+ * to the Window value equivalent to string. If string is improperly
+ * formed then TCL_ERROR is returned and an error message will be left in
+ * the interp's result.
*
* Side effects:
* None.
@@ -596,16 +581,24 @@ TkpWindowWasRecentlyDeleted(win, dispPtr)
*/
int
-TkpScanWindowId(interp, string, idPtr)
- Tcl_Interp *interp;
- CONST char *string;
- Window *idPtr;
+TkpScanWindowId(
+ Tcl_Interp *interp,
+ CONST char *string,
+ Window *idPtr)
{
int value;
+
if (Tcl_GetInt(interp, string, &value) != TCL_OK) {
return TCL_ERROR;
}
*idPtr = (Window) value;
return TCL_OK;
}
-
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */