diff options
Diffstat (limited to 'cachedGCs.c')
-rw-r--r-- | cachedGCs.c | 864 |
1 files changed, 864 insertions, 0 deletions
diff --git a/cachedGCs.c b/cachedGCs.c new file mode 100644 index 0000000..21d3bb7 --- /dev/null +++ b/cachedGCs.c @@ -0,0 +1,864 @@ +/* $XTermId: cachedGCs.c,v 1.61 2011/09/11 14:59:38 tom Exp $ */ + +/* + * Copyright 2007-2010,2011 by Thomas E. Dickey + * + * All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the + * sale, use or other dealings in this Software without prior written + * authorization. + */ + +#include <data.h> +#include <xstrings.h> + +#include <X11/Xmu/Drawing.h> + +#include <stdio.h> + +/* + * hide (or eliminate) calls to + * XCreateGC() + * XFreeGC() + * XGetGCValues() + * XSetBackground() + * XSetFont() + * XSetForeground() + * XtGetGC() + * XtReleaseGC() + * by associating an integer with each GC, maintaining a cache which + * reflects frequency of use rather than most recent usage. + * + * FIXME: XTermFonts should hold gc, font, fs. + */ +typedef struct { + GC gc; + unsigned used; + unsigned cset; + XTermFonts *font; + Pixel tile; + Pixel fg; + Pixel bg; +} CgsCacheData; + +#define DEPTH 8 +#define ITEM() (int) (me->data - me->list) +#define LIST(item) me->list[item] +#define LINK(item) me->data = (me->list + (item)) +#define THIS(field) me->data->field +#define NEXT(field) me->next.field + +#define HaveFont(font) (Boolean) ((font) != 0 && (font)->fs != 0) + +#define GC_CSet GCFunction + +typedef struct { + CgsCacheData list[DEPTH]; + CgsCacheData *data; /* points to current list[] entry */ + XtGCMask mask; /* changes since the last getCgsGC() */ + CgsCacheData next; /* updated values, apply in getCgsGC() */ +} CgsCache; + +#if OPT_TRACE +#define CASE(name) case gc##name: result = #name; break +static const char * +traceCgsEnum(CgsEnum value) +{ + const char *result = "?"; + switch (value) { + CASE(Norm); + CASE(Bold); + CASE(NormReverse); + CASE(BoldReverse); +#if OPT_BOX_CHARS + CASE(Line); + CASE(Dots); +#endif +#if OPT_DEC_CHRSET + CASE(CNorm); + CASE(CBold); +#endif +#if OPT_WIDE_CHARS + CASE(Wide); + CASE(WBold); + CASE(WideReverse); + CASE(WBoldReverse); +#endif + CASE(VTcursNormal); + CASE(VTcursFilled); + CASE(VTcursReverse); + CASE(VTcursOutline); +#if OPT_TEK4014 + CASE(TKcurs); +#endif + CASE(MAX); + } + return result; +} + +#undef CASE + +static const char * +traceVTwin(XtermWidget xw, VTwin * value) +{ + const char *result = "?"; + if (value == 0) + result = "null"; + else if (value == &(TScreenOf(xw)->fullVwin)) + result = "fullVwin"; +#ifndef NO_ACTIVE_ICON + else if (value == &(TScreenOf(xw)->iconVwin)) + result = "iconVwin"; +#endif + return result; +} + +#if OPT_TRACE > 1 +static String +traceCSet(unsigned cset) +{ + static char result[80]; + switch (cset) { + case CSET_SWL: + strcpy(result, "SWL"); + break; + case CSET_DHL_TOP: + strcpy(result, "DHL_TOP"); + break; + case CSET_DHL_BOT: + strcpy(result, "DHL_BOT"); + break; + case CSET_DWL: + strcpy(result, "DWL"); + break; + default: + sprintf(result, "%#x", cset); + break; + } + return result; +} + +static String +traceFont(XTermFonts * font) +{ + static char result[80]; + + if (HaveFont(font)) { + XFontStruct *fs = font->fs; + sprintf(result, "%p(%dx%d %d %#lx)", + fs, + fs->max_bounds.width, + fs->max_bounds.ascent + fs->max_bounds.descent, + fs->max_bounds.descent, + (unsigned long) (fs->fid)); + } else { + strcpy(result, "null"); + } + return result; +} + +static String +tracePixel(XtermWidget xw, Pixel value) +{ +#define CASE(name) { name, #name } + static struct { + TermColors code; + String name; + } t_colors[] = { + CASE(TEXT_FG), + CASE(TEXT_BG), + CASE(TEXT_CURSOR), + CASE(MOUSE_FG), + CASE(MOUSE_BG), +#if OPT_TEK4014 + CASE(TEK_FG), + CASE(TEK_BG), +#endif +#if OPT_HIGHLIGHT_COLOR + CASE(HIGHLIGHT_BG), + CASE(HIGHLIGHT_FG), +#endif +#if OPT_TEK4014 + CASE(TEK_CURSOR), +#endif + }; + TScreen *screen = TScreenOf(xw); + String result = 0; + int n; + + for (n = 0; n < NCOLORS; ++n) { + if (value == T_COLOR(screen, t_colors[n].code)) { + result = t_colors[n].name; + break; + } + } + + if (result == 0) { + for (n = 0; n < MAXCOLORS; ++n) { +#if OPT_COLOR_RES + if (screen->Acolors[n].mode > 0 + && value == screen->Acolors[n].value) { + result = screen->Acolors[n].resource; + break; + } +#else + if (value == screen->Acolors[n]) { + char temp[80]; + sprintf(temp, "Acolors[%d]", n); + result = x_strdup(temp); + break; + } +#endif + } + } + + if (result == 0) { + char temp[80]; + sprintf(temp, "%#lx", value); + result = x_strdup(temp); + } + + return result; +} + +#undef CASE + +#endif /* OPT_TRACE > 1 */ +#endif /* OPT_TRACE */ + +static CgsCache * +allocCache(void **cache_pointer) +{ + if (*cache_pointer == 0) { + *cache_pointer = TypeCallocN(CgsCache, gcMAX); + TRACE(("allocCache %p\n", *cache_pointer)); + } + return *((CgsCache **) cache_pointer); +} + +static int +dataIndex(CgsCache * me) +{ + return ITEM(); +} + +static void +relinkData(CgsCache * me, int item) +{ + LINK(item); +} + +/* + * Returns the appropriate cache pointer. + */ +static CgsCache * +myCache(XtermWidget xw, VTwin * cgsWin, CgsEnum cgsId) +{ + CgsCache *result = 0; + + if ((int) cgsId >= 0 && cgsId < gcMAX) { +#ifdef NO_ACTIVE_ICON + (void) xw; + (void) cgsWin; +#else + if (cgsWin == &(TScreenOf(xw)->iconVwin)) + result = allocCache(&(TScreenOf(xw)->icon_cgs_cache)); + else +#endif + result = allocCache(&(TScreenOf(xw)->main_cgs_cache)); + + result += cgsId; + if (result->data == 0) { + result->data = result->list; + } + } + + return result; +} + +static Display * +myDisplay(XtermWidget xw) +{ + return TScreenOf(xw)->display; +} + +static Drawable +myDrawable(XtermWidget xw, VTwin * cgsWin) +{ + Drawable drawable = 0; + + if (cgsWin != 0 && cgsWin->window != 0) + drawable = cgsWin->window; + if (drawable == 0) + drawable = RootWindowOfScreen(XtScreen(xw)); + return drawable; +} + +static GC +newCache(XtermWidget xw, VTwin * cgsWin, CgsEnum cgsId, CgsCache * me) +{ + XGCValues xgcv; + XtGCMask mask; + + THIS(font) = NEXT(font); + THIS(cset) = NEXT(cset); + THIS(fg) = NEXT(fg); + THIS(bg) = NEXT(bg); + + memset(&xgcv, 0, sizeof(xgcv)); + xgcv.font = NEXT(font)->fs->fid; + mask = (GCForeground | GCBackground | GCFont); + + switch (cgsId) { + case gcNorm: + case gcBold: + case gcNormReverse: + case gcBoldReverse: +#if OPT_WIDE_CHARS + case gcWide: + case gcWBold: + case gcWideReverse: + case gcWBoldReverse: +#endif + mask |= (GCGraphicsExposures | GCFunction); + xgcv.graphics_exposures = True; /* default */ + xgcv.function = GXcopy; + break; +#if OPT_BOX_CHARS + case gcLine: + mask |= (GCGraphicsExposures | GCFunction); + xgcv.graphics_exposures = True; /* default */ + xgcv.function = GXcopy; + break; + case gcDots: + xgcv.fill_style = FillTiled; + xgcv.tile = + XmuCreateStippledPixmap(XtScreen((Widget) xw), + THIS(fg), + THIS(bg), + xw->core.depth); + THIS(tile) = xgcv.tile; + mask = (GCForeground | GCBackground); + mask |= (GCGraphicsExposures | GCFunction | GCTile | GCFillStyle); + xgcv.graphics_exposures = True; /* default */ + xgcv.function = GXcopy; + break; +#endif +#if OPT_DEC_CHRSET + case gcCNorm: + case gcCBold: + break; +#endif + case gcVTcursNormal: /* FALLTHRU */ + case gcVTcursFilled: /* FALLTHRU */ + case gcVTcursReverse: /* FALLTHRU */ + case gcVTcursOutline: /* FALLTHRU */ + break; +#if OPT_TEK4014 + case gcTKcurs: /* FALLTHRU */ + /* FIXME */ +#endif + case gcMAX: /* should not happen */ + return 0; + } + xgcv.foreground = NEXT(fg); + xgcv.background = NEXT(bg); + + THIS(gc) = XCreateGC(myDisplay(xw), myDrawable(xw, cgsWin), mask, &xgcv); + TRACE(("getCgsGC(%s) created gc %p(%d)\n", + traceCgsEnum(cgsId), (void *) THIS(gc), ITEM())); + + THIS(used) = 0; + return THIS(gc); +} + +static Boolean +SameFont(XTermFonts * a, XTermFonts * b) +{ + return (Boolean) (HaveFont(a) + && HaveFont(b) + && ((a->fs == b->fs) + || !memcmp(a->fs, b->fs, sizeof(*(a->fs))))); +} + +#define SameColor(a,b) ((a) == (b)) +#define SameCSet(a,b) ((a) == (b)) + +static GC +chgCache(XtermWidget xw, CgsEnum cgsId GCC_UNUSED, CgsCache * me, Bool both) +{ + XGCValues xgcv; + XtGCMask mask = (GCForeground | GCBackground | GCFont); + + memset(&xgcv, 0, sizeof(xgcv)); + + TRACE2(("chgCache(%s) old data fg=%s, bg=%s, font=%s cset %s\n", + traceCgsEnum(cgsId), + tracePixel(xw, THIS(fg)), + tracePixel(xw, THIS(bg)), + traceFont(THIS(font)), + traceCSet(THIS(cset)))); +#if OPT_TRACE > 1 + if (!SameFont(THIS(font), NEXT(font))) + TRACE2(("...chgCache new font=%s\n", traceFont(NEXT(font)))); + if (!SameCSet(THIS(cset), NEXT(cset))) + TRACE2(("...chgCache new cset=%s\n", traceCSet(NEXT(cset)))); + if (!SameColor(THIS(fg), NEXT(fg))) + TRACE2(("...chgCache new fg=%s\n", tracePixel(xw, NEXT(fg)))); + if (!SameColor(THIS(bg), NEXT(bg))) + TRACE2(("...chgCache new bg=%s\n", tracePixel(xw, NEXT(bg)))); +#endif + + if (both) { + THIS(font) = NEXT(font); + THIS(cset) = NEXT(cset); + } + THIS(fg) = NEXT(fg); + THIS(bg) = NEXT(bg); + + xgcv.font = THIS(font)->fs->fid; + xgcv.foreground = THIS(fg); + xgcv.background = THIS(bg); + + XChangeGC(myDisplay(xw), THIS(gc), mask, &xgcv); + TRACE2(("...chgCache(%s) updated gc %p(%d)\n", + traceCgsEnum(cgsId), THIS(gc), ITEM())); + + THIS(used) = 0; + return THIS(gc); +} +/* + * Use the "setCgsXXXX()" calls to initialize parameters for a new GC. + */ +void +setCgsFore(XtermWidget xw, VTwin * cgsWin, CgsEnum cgsId, Pixel fg) +{ + CgsCache *me; + + if ((me = myCache(xw, cgsWin, cgsId)) != 0) { + NEXT(fg) = fg; + me->mask |= GCForeground; + } +} + +void +setCgsBack(XtermWidget xw, VTwin * cgsWin, CgsEnum cgsId, Pixel bg) +{ + CgsCache *me; + + if ((me = myCache(xw, cgsWin, cgsId)) != 0) { + NEXT(bg) = bg; + me->mask |= GCBackground; + } +} + +#if OPT_DEC_CHRSET +void +setCgsCSet(XtermWidget xw, VTwin * cgsWin, CgsEnum cgsId, unsigned cset) +{ + CgsCache *me; + + if ((me = myCache(xw, cgsWin, cgsId)) != 0) { + NEXT(cset) = cset; + me->mask |= GC_CSet; + } +} +#else +#define setCgsCSet(xw, cgsWin, dstCgsId, cset) /* nothing */ +#endif + +void +setCgsFont(XtermWidget xw, VTwin * cgsWin, CgsEnum cgsId, XTermFonts * font) +{ + CgsCache *me; + + if ((me = myCache(xw, cgsWin, cgsId)) != 0) { + if (!HaveFont(font)) { + if (cgsId != gcNorm) + (void) getCgsGC(xw, cgsWin, gcNorm); +#ifndef NO_ACTIVE_ICON + if (cgsWin == &(TScreenOf(xw)->iconVwin)) + font = &(TScreenOf(xw)->fnt_icon); + else +#endif + font = &(TScreenOf(xw)->fnts[fNorm]); + } + if (HaveFont(font) && okFont(font->fs)) { + TRACE2(("...updated next font in %p for %s to %s\n", + me, traceCgsEnum(cgsId), traceFont(font))); + TRACE2(("...next font was %s\n", traceFont(NEXT(font)))); + NEXT(font) = font; + me->mask |= GCFont; + } else { + /* EMPTY */ + TRACE2(("...NOT updated font for %s\n", + traceCgsEnum(cgsId))); + } + } +} + +/* + * Discard all of the font information, e.g., we are resizing the font. + * Keep the GC's so we can simply change them rather than creating new ones. + */ +void +clrCgsFonts(XtermWidget xw, VTwin * cgsWin, XTermFonts * font) +{ + CgsCache *me; + int j, k; + + if (HaveFont(font)) { + for_each_gc(j) { + if ((me = myCache(xw, cgsWin, (CgsEnum) j)) != 0) { + for (k = 0; k < DEPTH; ++k) { + if (SameFont(LIST(k).font, font)) { + TRACE2(("clrCgsFonts %s gc %p(%d) %s\n", + traceCgsEnum((CgsEnum) j), + LIST(k).gc, + k, + traceFont(font))); + LIST(k).font = 0; + LIST(k).cset = 0; + } + } + if (SameFont(NEXT(font), font)) { + TRACE2(("clrCgsFonts %s next %s\n", + traceCgsEnum((CgsEnum) j), + traceFont(font))); + NEXT(font) = 0; + NEXT(cset) = 0; + me->mask &= (unsigned) ~(GCFont | GC_CSet); + } + } + } + } +} + +/* + * Return a GC associated with the given id, allocating if needed. + */ +GC +getCgsGC(XtermWidget xw, VTwin * cgsWin, CgsEnum cgsId) +{ + CgsCache *me; + GC result = 0; + int j, k; + unsigned used = 0; + + if ((me = myCache(xw, cgsWin, cgsId)) != 0) { + TRACE2(("getCgsGC(%s, %s)\n", + traceVTwin(xw, cgsWin), traceCgsEnum(cgsId))); + if (me->mask != 0) { + + /* fill in the unchanged fields */ + if (!(me->mask & GC_CSet)) + NEXT(cset) = 0; /* OPT_DEC_CHRSET */ + if (!(me->mask & GCFont)) + NEXT(font) = THIS(font); + if (!(me->mask & GCForeground)) + NEXT(fg) = THIS(fg); + if (!(me->mask & GCBackground)) + NEXT(bg) = THIS(bg); + + if (NEXT(font) == 0) { + setCgsFont(xw, cgsWin, cgsId, 0); + } + + TRACE2(("...Cgs new data fg=%s, bg=%s, font=%s cset %s\n", + tracePixel(xw, NEXT(fg)), + tracePixel(xw, NEXT(bg)), + traceFont(NEXT(font)), + traceCSet(NEXT(cset)))); + + /* try to find the given data in an already-created GC */ + for (j = 0; j < DEPTH; ++j) { + if (LIST(j).gc != 0 + && SameFont(LIST(j).font, NEXT(font)) + && SameCSet(LIST(j).cset, NEXT(cset)) + && SameColor(LIST(j).fg, NEXT(fg)) + && SameColor(LIST(j).bg, NEXT(bg))) { + LINK(j); + result = THIS(gc); + TRACE2(("getCgsGC existing %p(%d)\n", result, ITEM())); + break; + } + } + + if (result == 0) { + /* try to find an empty slot, to create a new GC */ + used = 0; + for (j = 0; j < DEPTH; ++j) { + if (LIST(j).gc == 0) { + LINK(j); + result = newCache(xw, cgsWin, cgsId, me); + break; + } + if (used < LIST(j).used) + used = LIST(j).used; + } + } + + if (result == 0) { + /* if none were empty, pick the least-used slot, to modify */ + for (j = 0, k = -1; j < DEPTH; ++j) { + if (used >= LIST(j).used) { + used = LIST(j).used; + k = j; + } + } + LINK(k); + TRACE2(("...getCgsGC least-used(%d) was %d\n", k, THIS(used))); + result = chgCache(xw, cgsId, me, True); + } + me->next = *(me->data); + } else { + result = THIS(gc); + } + me->mask = 0; + THIS(used) += 1; + TRACE2(("...getCgsGC(%s, %s) gc %p(%d), used %d\n", + traceVTwin(xw, cgsWin), + traceCgsEnum(cgsId), result, ITEM(), THIS(used))); + } + return result; +} + +/* + * Return the font for the given GC. + */ +CgsEnum +getCgsId(XtermWidget xw, VTwin * cgsWin, GC gc) +{ + int n; + CgsEnum result = gcNorm; + + for_each_gc(n) { + CgsCache *me; + + if ((me = myCache(xw, cgsWin, (CgsEnum) n)) != 0) { + if (THIS(gc) == gc) { + result = (CgsEnum) n; + break; + } + } + } + return result; +} + +/* + * Return the font for the given GC. + */ +XTermFonts * +getCgsFont(XtermWidget xw, VTwin * cgsWin, GC gc) +{ + int n; + XTermFonts *result = 0; + + for_each_gc(n) { + CgsCache *me; + + if ((me = myCache(xw, cgsWin, (CgsEnum) n)) != 0) { + if (THIS(gc) == gc) { + result = THIS(font); + break; + } + } + } + return result; +} + +/* + * Return the foreground color for the given GC. + */ +Pixel +getCgsFore(XtermWidget xw, VTwin * cgsWin, GC gc) +{ + int n; + Pixel result = 0; + + for_each_gc(n) { + CgsCache *me; + + if ((me = myCache(xw, cgsWin, (CgsEnum) n)) != 0) { + if (THIS(gc) == gc) { + result = THIS(fg); + break; + } + } + } + return result; +} + +/* + * Return the background color for the given GC. + */ +Pixel +getCgsBack(XtermWidget xw, VTwin * cgsWin, GC gc) +{ + int n; + Pixel result = 0; + + for_each_gc(n) { + CgsCache *me; + + if ((me = myCache(xw, cgsWin, (CgsEnum) n)) != 0) { + if (THIS(gc) == gc) { + result = THIS(bg); + break; + } + } + } + return result; +} + +/* + * Copy the parameters (except GC of course) from one cache record to another. + */ +void +copyCgs(XtermWidget xw, VTwin * cgsWin, CgsEnum dstCgsId, CgsEnum srcCgsId) +{ + if (dstCgsId != srcCgsId) { + CgsCache *me; + + if ((me = myCache(xw, cgsWin, srcCgsId)) != 0) { + TRACE(("copyCgs from %s to %s\n", + traceCgsEnum(srcCgsId), + traceCgsEnum(dstCgsId))); + TRACE2(("copyCgs from %s (me %p, fg %s, bg %s, cset %s) to %s {{\n", + traceCgsEnum(srcCgsId), + me, + tracePixel(xw, THIS(fg)), + tracePixel(xw, THIS(bg)), + traceCSet(THIS(cset)), + traceCgsEnum(dstCgsId))); + setCgsCSet(xw, cgsWin, dstCgsId, THIS(cset)); + setCgsFore(xw, cgsWin, dstCgsId, THIS(fg)); + setCgsBack(xw, cgsWin, dstCgsId, THIS(bg)); + setCgsFont(xw, cgsWin, dstCgsId, THIS(font)); + TRACE2(("...copyCgs }}\n")); + } + } +} + +/* + * Interchange colors in the cache, e.g., for reverse-video. + */ +void +redoCgs(XtermWidget xw, Pixel fg, Pixel bg, CgsEnum cgsId) +{ + int n; + VTwin *cgsWin = WhichVWin(TScreenOf(xw)); + CgsCache *me = myCache(xw, cgsWin, cgsId); + + if (me != 0) { + CgsCacheData *save_data = me->data; + + for (n = 0; n < DEPTH; ++n) { + if (LIST(n).gc != 0 && HaveFont(LIST(n).font)) { + LINK(n); + + if (LIST(n).fg == fg + && LIST(n).bg == bg) { + setCgsFore(xw, cgsWin, cgsId, bg); + setCgsBack(xw, cgsWin, cgsId, fg); + } else if (LIST(n).fg == bg + && LIST(n).bg == fg) { + setCgsFore(xw, cgsWin, cgsId, fg); + setCgsBack(xw, cgsWin, cgsId, bg); + } else { + continue; + } + + (void) chgCache(xw, cgsId, me, False); + } + } + me->data = save_data; + } +} + +/* + * Swap the cache records, e.g., when doing reverse-video. + */ +void +swapCgs(XtermWidget xw, VTwin * cgsWin, CgsEnum dstCgsId, CgsEnum srcCgsId) +{ + if (dstCgsId != srcCgsId) { + CgsCache *dst; + CgsCache *src; + CgsCache tmp; + + if ((src = myCache(xw, cgsWin, srcCgsId)) != 0) { + if ((dst = myCache(xw, cgsWin, dstCgsId)) != 0) { + int srcIndex = dataIndex(src); + int dstIndex = dataIndex(dst); + + EXCHANGE(*src, *dst, tmp); + + relinkData(src, dstIndex); + relinkData(dst, srcIndex); + } + } + } +} + +/* + * Free any GC associated with the given id. + */ +GC +freeCgs(XtermWidget xw, VTwin * cgsWin, CgsEnum cgsId) +{ + CgsCache *me; + int j; + + if ((me = myCache(xw, cgsWin, cgsId)) != 0) { + for (j = 0; j < DEPTH; ++j) { + if (LIST(j).gc != 0) { + TRACE(("freeCgs(%s, %s) gc %p(%d)\n", + traceVTwin(xw, cgsWin), + traceCgsEnum(cgsId), (void *) LIST(j).gc, j)); + clrCgsFonts(xw, cgsWin, LIST(j).font); +#if OPT_BOX_CHARS + if (cgsId == gcDots) { + XmuReleaseStippledPixmap(XtScreen((Widget) xw), LIST(j).tile); + } +#endif + XFreeGC(TScreenOf(xw)->display, LIST(j).gc); + memset(&LIST(j), 0, sizeof(LIST(j))); + } + LINK(0); + } + } + return 0; +} + +#ifdef NO_LEAKS +void +noleaks_cachedCgs(XtermWidget xw) +{ +#ifndef NO_ACTIVE_ICON + free(TScreenOf(xw)->icon_cgs_cache); +#endif + free(TScreenOf(xw)->main_cgs_cache); +} +#endif |