summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authortreectrl <treectrl>2006-12-06 00:52:03 (GMT)
committertreectrl <treectrl>2006-12-06 00:52:03 (GMT)
commit5e40f524d201a69d005903615a1e02aea2a8ac27 (patch)
tree580d6cd961143c7cd77ec979ca5b8728cdfa4965 /generic
parent4204b2f78309da5ae8fc5a788ba3489655d442de (diff)
downloadtktreectrl-5e40f524d201a69d005903615a1e02aea2a8ac27.zip
tktreectrl-5e40f524d201a69d005903615a1e02aea2a8ac27.tar.gz
tktreectrl-5e40f524d201a69d005903615a1e02aea2a8ac27.tar.bz2
Created a stack of TkRegions to avoid creating/destroying them repeatedly.
Fixed a leak on X11 where the clipping region was not being freed after drawing dotted rectangles.
Diffstat (limited to 'generic')
-rw-r--r--generic/tkTreeCtrl.c6
-rw-r--r--generic/tkTreeCtrl.h7
-rw-r--r--generic/tkTreeDisplay.c52
-rw-r--r--generic/tkTreeElem.c10
-rw-r--r--generic/tkTreeUtils.c63
5 files changed, 103 insertions, 35 deletions
diff --git a/generic/tkTreeCtrl.c b/generic/tkTreeCtrl.c
index 77607cf..bc6b540 100644
--- a/generic/tkTreeCtrl.c
+++ b/generic/tkTreeCtrl.c
@@ -7,7 +7,7 @@
* Copyright (c) 2002-2003 Christian Krone
* Copyright (c) 2003-2005 ActiveState, a division of Sophos
*
- * RCS: @(#) $Id: tkTreeCtrl.c,v 1.94 2006/12/06 00:03:21 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeCtrl.c,v 1.95 2006/12/06 00:52:03 treectrl Exp $
*/
#include "tkTreeCtrl.h"
@@ -1782,6 +1782,10 @@ TreeDestroy(
Tree_FreeColumns(tree);
+dbwin("tree->regionStackLen = %d", tree->regionStackLen);
+ while (tree->regionStackLen > 0)
+ TkDestroyRegion(tree->regionStack[--tree->regionStackLen]);
+
QE_DeleteBindingTable(tree->bindingTable);
for (i = STATE_USER - 1; i < 32; i++)
diff --git a/generic/tkTreeCtrl.h b/generic/tkTreeCtrl.h
index 2cb1ef3..79e52bc 100644
--- a/generic/tkTreeCtrl.h
+++ b/generic/tkTreeCtrl.h
@@ -7,7 +7,7 @@
* Copyright (c) 2002-2003 Christian Krone
* Copyright (c) 2003 ActiveState Corporation
*
- * RCS: @(#) $Id: tkTreeCtrl.h,v 1.82 2006/12/06 00:03:21 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeCtrl.h,v 1.83 2006/12/06 00:52:04 treectrl Exp $
*/
#include "tkPort.h"
@@ -376,6 +376,9 @@ struct TreeCtrl
TreeThemeData themeData;
GCCache *gcCache; /* Graphics contexts for elements. */
+
+ TkRegion regionStack[8]; /* Temp region stack. */
+ int regionStackLen; /* Number of unused regions in regionStack. */
};
#define TREE_CONF_FONT 0x0001
@@ -877,6 +880,8 @@ extern void Tree_DrawBitmapWithGC(TreeCtrl *tree, Pixmap bitmap, Drawable drawab
extern void Tree_DrawBitmap(TreeCtrl *tree, Pixmap bitmap, Drawable drawable,
XColor *fg, XColor *bg,
int src_x, int src_y, int width, int height, int dest_x, int dest_y);
+extern TkRegion Tree_GetRegion(TreeCtrl *tree);
+extern void Tree_FreeRegion(TreeCtrl *tree, TkRegion region);
extern void Tk_FillRegion(Display *display, Drawable drawable, GC gc, TkRegion rgn);
extern void Tk_OffsetRegion(TkRegion region, int xOffset, int yOffset);
extern int Tree_ScrollWindow(TreeCtrl *tree, GC gc, int x, int y,
diff --git a/generic/tkTreeDisplay.c b/generic/tkTreeDisplay.c
index 0842889..3e1150b 100644
--- a/generic/tkTreeDisplay.c
+++ b/generic/tkTreeDisplay.c
@@ -5,7 +5,7 @@
*
* Copyright (c) 2002-2006 Tim Baker
*
- * RCS: @(#) $Id: tkTreeDisplay.c,v 1.73 2006/12/06 00:03:21 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeDisplay.c,v 1.74 2006/12/06 00:52:04 treectrl Exp $
*/
#include "tkTreeCtrl.h"
@@ -3792,13 +3792,13 @@ ScrollVerticalComplex(
}
/* Copy */
- damageRgn = TkCreateRegion();
+ damageRgn = Tree_GetRegion(tree);
if (Tree_ScrollWindow(tree, dInfo->scrollGC,
oldX, oldY, width, height, 0, offset, damageRgn)) {
DisplayDelay(tree);
Tree_InvalidateRegion(tree, damageRgn);
}
- TkDestroyRegion(damageRgn);
+ Tree_FreeRegion(tree, damageRgn);
}
return numCopy;
}
@@ -3888,7 +3888,7 @@ ScrollHorizontalSimple(
dirtyMin = minX + width;
dirtyMax = maxX - width;
- damageRgn = TkCreateRegion();
+ damageRgn = Tree_GetRegion(tree);
if (tree->doubleBuffer == DOUBLEBUFFER_WINDOW) {
XCopyArea(tree->display, dInfo->pixmap, dInfo->pixmap,
@@ -3900,7 +3900,7 @@ ScrollHorizontalSimple(
else
dirtyMin = minX;
Tree_InvalidateArea(tree, dirtyMin, minY, dirtyMax, maxY);
- TkDestroyRegion(damageRgn);
+ Tree_FreeRegion(tree, damageRgn);
return;
}
@@ -3909,7 +3909,7 @@ ScrollHorizontalSimple(
DisplayDelay(tree);
Tree_InvalidateRegion(tree, damageRgn);
}
- TkDestroyRegion(damageRgn);
+ Tree_FreeRegion(tree, damageRgn);
#ifndef WIN32
if (offset < 0)
dirtyMax = maxX;
@@ -3996,7 +3996,7 @@ ScrollVerticalSimple(
dirtyMin = minY + height;
dirtyMax = maxY - height;
- damageRgn = TkCreateRegion();
+ damageRgn = Tree_GetRegion(tree);
if (tree->doubleBuffer == DOUBLEBUFFER_WINDOW) {
XCopyArea(tree->display, dInfo->pixmap, dInfo->pixmap,
@@ -4008,7 +4008,7 @@ ScrollVerticalSimple(
else
dirtyMin = minY;
Tree_InvalidateArea(tree, minX, dirtyMin, maxX, dirtyMax);
- TkDestroyRegion(damageRgn);
+ Tree_FreeRegion(tree, damageRgn);
return;
}
@@ -4017,7 +4017,7 @@ ScrollVerticalSimple(
DisplayDelay(tree);
Tree_InvalidateRegion(tree, damageRgn);
}
- TkDestroyRegion(damageRgn);
+ Tree_FreeRegion(tree, damageRgn);
#ifndef WIN32
if (offset < 0)
dirtyMax = maxY;
@@ -4177,13 +4177,13 @@ ScrollHorizontalComplex(
}
/* Copy */
- damageRgn = TkCreateRegion();
+ damageRgn = Tree_GetRegion(tree);
if (Tree_ScrollWindow(tree, dInfo->scrollGC,
oldX, oldY, width, height, offset, 0, damageRgn)) {
DisplayDelay(tree);
Tree_InvalidateRegion(tree, damageRgn);
}
- TkDestroyRegion(damageRgn);
+ Tree_FreeRegion(tree, damageRgn);
}
return numCopy;
}
@@ -4395,7 +4395,7 @@ CalcWhiteSpaceRegion(
x = 0 - tree->xOrigin;
y = 0 - tree->yOrigin;
- wsRgn = TkCreateRegion();
+ wsRgn = Tree_GetRegion(tree);
/* Erase area below left columns */
if (!dInfo->emptyL) {
@@ -4853,7 +4853,7 @@ DrawWhitespace(
else
height = tree->minItemHeight;
- columnRgn = TkCreateRegion();
+ columnRgn = Tree_GetRegion(tree);
range = dInfo->rangeFirst;
if (range == NULL)
@@ -4934,7 +4934,7 @@ DrawWhitespace(
}
}
- TkDestroyRegion(columnRgn);
+ Tree_FreeRegion(tree, columnRgn);
}
#endif /* COMPLEX_WHITESPACE */
@@ -5572,7 +5572,7 @@ displayRetry:
dInfo->yOrigin != tree->yOrigin) {
wsRgnDif = wsRgnNew;
} else {
- wsRgnDif = TkCreateRegion();
+ wsRgnDif = Tree_GetRegion(tree);
TkSubtractRegion(wsRgnNew, dInfo->wsRgn, wsRgnDif);
}
TkClipBox(wsRgnDif, &wsBox);
@@ -5618,8 +5618,8 @@ displayRetry:
}
}
if (wsRgnDif != wsRgnNew)
- TkDestroyRegion(wsRgnDif);
- TkDestroyRegion(dInfo->wsRgn);
+ Tree_FreeRegion(tree, wsRgnDif);
+ Tree_FreeRegion(tree, dInfo->wsRgn);
dInfo->wsRgn = wsRgnNew;
}
@@ -5633,7 +5633,7 @@ displayRetry:
/* Calculate the current whitespace region, subtract the old whitespace
* region, and fill the difference with the background color. */
wsRgnNew = CalcWhiteSpaceRegion(tree);
- wsRgnDif = TkCreateRegion();
+ wsRgnDif = Tree_GetRegion(tree);
TkSubtractRegion(wsRgnNew, dInfo->wsRgn, wsRgnDif);
TkClipBox(wsRgnDif, &wsBox);
if ((wsBox.width > 0) && (wsBox.height > 0)) {
@@ -5657,8 +5657,8 @@ displayRetry:
dInfo->dirty[BOTTOM] = MAX(dInfo->dirty[BOTTOM], wsBox.y + wsBox.height);
}
}
- TkDestroyRegion(wsRgnDif);
- TkDestroyRegion(dInfo->wsRgn);
+ Tree_FreeRegion(tree, wsRgnDif);
+ Tree_FreeRegion(tree, dInfo->wsRgn);
dInfo->wsRgn = wsRgnNew;
}
@@ -6946,7 +6946,7 @@ Tree_InvalidateArea(
if ((x1 < x2 && y1 < y2) && TkRectInRegion(dInfo->wsRgn, x1, y1,
x2 - x1, y2 - y1)) {
XRectangle rect;
- TkRegion rgn = TkCreateRegion();
+ TkRegion rgn = Tree_GetRegion(tree);
rect.x = x1;
rect.y = y1;
@@ -6954,7 +6954,7 @@ Tree_InvalidateArea(
rect.height = y2 - y1;
TkUnionRectWithRegion(&rect, rgn, rgn);
TkSubtractRegion(dInfo->wsRgn, rgn, dInfo->wsRgn);
- TkDestroyRegion(rgn);
+ Tree_FreeRegion(tree, rgn);
}
if (tree->debug.enable && tree->debug.display && tree->debug.eraseColor) {
@@ -7005,7 +7005,7 @@ Tree_InvalidateRegion(
!= RectangleOut)
dInfo->flags |= DINFO_DRAW_HEADER;
- rgn = TkCreateRegion();
+ rgn = Tree_GetRegion(tree);
dItem = dInfo->dItem;
while (dItem != NULL) {
@@ -7071,7 +7071,7 @@ Tree_InvalidateRegion(
/* Invalidate part of the whitespace */
TkSubtractRegion(dInfo->wsRgn, region, dInfo->wsRgn);
- TkDestroyRegion(rgn);
+ Tree_FreeRegion(tree, rgn);
if (tree->debug.enable && tree->debug.display && tree->debug.eraseColor) {
Tk_FillRegion(tree->display, Tk_WindowId(tree->tkwin),
@@ -7180,7 +7180,7 @@ TreeDInfo_Init(
gcValues.graphics_exposures = True;
dInfo->scrollGC = Tk_GetGC(tree->tkwin, GCGraphicsExposures, &gcValues);
dInfo->flags = DINFO_OUT_OF_DATE;
- dInfo->wsRgn = TkCreateRegion();
+ dInfo->wsRgn = Tree_GetRegion(tree);
Tcl_InitHashTable(&dInfo->itemVisHash, TCL_ONE_WORD_KEYS);
tree->dInfo = dInfo;
}
@@ -7236,7 +7236,7 @@ TreeDInfo_Free(
ckfree((char *) dInfo->xScrollIncrements);
if (dInfo->yScrollIncrements != NULL)
ckfree((char *) dInfo->yScrollIncrements);
- TkDestroyRegion(dInfo->wsRgn);
+ Tree_FreeRegion(tree, dInfo->wsRgn);
#ifdef DCOLUMN
hPtr = Tcl_FirstHashEntry(&dInfo->itemVisHash, &search);
while (hPtr != NULL) {
diff --git a/generic/tkTreeElem.c b/generic/tkTreeElem.c
index 98e761a..c0cd626 100644
--- a/generic/tkTreeElem.c
+++ b/generic/tkTreeElem.c
@@ -5,7 +5,7 @@
*
* Copyright (c) 2002-2006 Tim Baker
*
- * RCS: @(#) $Id: tkTreeElem.c,v 1.57 2006/12/06 00:03:21 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeElem.c,v 1.58 2006/12/06 00:52:04 treectrl Exp $
*/
#include "tkTreeCtrl.h"
@@ -3020,7 +3020,7 @@ static void DisplayProcText(ElementArgs *args)
/* Use clipping if text is taller than display height */
if (height > args->display.height) {
XRectangle rect;
- clipRgn = TkCreateRegion();
+ clipRgn = Tree_GetRegion(tree);
rect.x = x;
rect.y = y;
rect.width = args->display.width;
@@ -3032,7 +3032,7 @@ static void DisplayProcText(ElementArgs *args)
layout, x, y, 0, -1, underline);
if (clipRgn != NULL) {
UnsetClipMask(tree, args->display.drawable, gc);
- TkDestroyRegion(clipRgn);
+ Tree_FreeRegion(tree, clipRgn);
}
return;
}
@@ -3054,7 +3054,7 @@ static void DisplayProcText(ElementArgs *args)
/* Use clipping if text is taller than display height */
if (height > args->display.height) {
XRectangle rect;
- clipRgn = TkCreateRegion();
+ clipRgn = Tree_GetRegion(tree);
rect.x = x;
rect.y = y;
rect.width = args->display.width;
@@ -3102,7 +3102,7 @@ static void DisplayProcText(ElementArgs *args)
}
if (clipRgn != NULL) {
UnsetClipMask(tree, args->display.drawable, gc);
- TkDestroyRegion(clipRgn);
+ Tree_FreeRegion(tree, clipRgn);
}
}
diff --git a/generic/tkTreeUtils.c b/generic/tkTreeUtils.c
index 2b81889..f4d6e4b 100644
--- a/generic/tkTreeUtils.c
+++ b/generic/tkTreeUtils.c
@@ -5,7 +5,7 @@
*
* Copyright (c) 2002-2006 Tim Baker
*
- * RCS: @(#) $Id: tkTreeUtils.c,v 1.58 2006/12/06 00:03:22 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeUtils.c,v 1.59 2006/12/06 00:52:04 treectrl Exp $
*/
#include "tkTreeCtrl.h"
@@ -569,7 +569,7 @@ DotRect_Setup(
dotState->gc = Tk_GetGC(tree->tkwin, mask, &gcValues);
/* Keep drawing inside the contentbox */
- dotState->rgn = TkCreateRegion();
+ dotState->rgn = Tree_GetRegion(tree);
xrect.x = Tree_ContentLeft(tree);
xrect.y = Tree_ContentTop(tree);
xrect.width = Tree_ContentRight(tree) - xrect.x;
@@ -721,6 +721,7 @@ DotRect_Restore(
SetGWorld(dotState->saveWorld, dotState->saveDevice);
#else
XSetClipMask(dotState->tree->display, dotState->gc, None);
+ Tree_FreeRegion(dotState->tree, dotState->rgn);
Tk_FreeGC(dotState->tree->display, dotState->gc);
#endif
}
@@ -780,6 +781,64 @@ DrawXORLine(
/*
*----------------------------------------------------------------------
*
+ * Tree_GetRegion --
+ *
+ * Return a pre-allocated TkRegion or create a new one.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TkRegion
+Tree_GetRegion(
+ TreeCtrl *tree /* Widget info. */
+ )
+{
+ TkRegion region;
+
+ if (tree->regionStackLen == 0) {
+ return TkCreateRegion();
+ }
+ region = tree->regionStack[--tree->regionStackLen];
+ TkSubtractRegion(region, region, region);
+ return region;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tree_FreeRegion --
+ *
+ * Push a region onto the free stack.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tree_FreeRegion(
+ TreeCtrl *tree, /* Widget info. */
+ TkRegion region /* Region being released. */
+ )
+{
+ if (tree->regionStackLen == sizeof(tree->regionStack) / sizeof(TkRegion))
+ panic("Tree_FreeRegion: the stack is full");
+ tree->regionStack[tree->regionStackLen++] = region;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* Tk_FillRegion --
*
* Paint a region with the foreground color of a graphics context.