| File: | src/GCManager.c |
| Location: | line 311, column 11 |
| Description: | Dereference of null pointer |
| 1 | /*********************************************************** | |||||
| 2 | Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved. | |||||
| 3 | ||||||
| 4 | Permission is hereby granted, free of charge, to any person obtaining a | |||||
| 5 | copy of this software and associated documentation files (the "Software"), | |||||
| 6 | to deal in the Software without restriction, including without limitation | |||||
| 7 | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
| 8 | and/or sell copies of the Software, and to permit persons to whom the | |||||
| 9 | Software is furnished to do so, subject to the following conditions: | |||||
| 10 | ||||||
| 11 | The above copyright notice and this permission notice (including the next | |||||
| 12 | paragraph) shall be included in all copies or substantial portions of the | |||||
| 13 | Software. | |||||
| 14 | ||||||
| 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
| 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
| 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||||
| 18 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
| 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||||
| 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||||
| 21 | DEALINGS IN THE SOFTWARE. | |||||
| 22 | ||||||
| 23 | Copyright 1987, 1988, 1990 by Digital Equipment Corporation, Maynard, Massachusetts. | |||||
| 24 | ||||||
| 25 | All Rights Reserved | |||||
| 26 | ||||||
| 27 | Permission to use, copy, modify, and distribute this software and its | |||||
| 28 | documentation for any purpose and without fee is hereby granted, | |||||
| 29 | provided that the above copyright notice appear in all copies and that | |||||
| 30 | both that copyright notice and this permission notice appear in | |||||
| 31 | supporting documentation, and that the name of Digital not be | |||||
| 32 | used in advertising or publicity pertaining to distribution of the | |||||
| 33 | software without specific, written prior permission. | |||||
| 34 | ||||||
| 35 | DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING | |||||
| 36 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL | |||||
| 37 | DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR | |||||
| 38 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |||||
| 39 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |||||
| 40 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |||||
| 41 | SOFTWARE. | |||||
| 42 | ||||||
| 43 | ******************************************************************/ | |||||
| 44 | ||||||
| 45 | /* | |||||
| 46 | ||||||
| 47 | Copyright 1987, 1988, 1990, 1994, 1998 The Open Group | |||||
| 48 | ||||||
| 49 | Permission to use, copy, modify, distribute, and sell this software and its | |||||
| 50 | documentation for any purpose is hereby granted without fee, provided that | |||||
| 51 | the above copyright notice appear in all copies and that both that | |||||
| 52 | copyright notice and this permission notice appear in supporting | |||||
| 53 | documentation. | |||||
| 54 | ||||||
| 55 | The above copyright notice and this permission notice shall be included in | |||||
| 56 | all copies or substantial portions of the Software. | |||||
| 57 | ||||||
| 58 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
| 59 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
| 60 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
| 61 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||||
| 62 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||||
| 63 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||||
| 64 | ||||||
| 65 | Except as contained in this notice, the name of The Open Group shall not be | |||||
| 66 | used in advertising or otherwise to promote the sale, use or other dealings | |||||
| 67 | in this Software without prior written authorization from The Open Group. | |||||
| 68 | ||||||
| 69 | */ | |||||
| 70 | ||||||
| 71 | #ifdef HAVE_CONFIG_H1 | |||||
| 72 | #include <config.h> | |||||
| 73 | #endif | |||||
| 74 | #include "IntrinsicI.h" | |||||
| 75 | ||||||
| 76 | ||||||
| 77 | typedef struct _GCrec { | |||||
| 78 | unsigned char screen; /* Screen for GC */ | |||||
| 79 | unsigned char depth; /* Depth for GC */ | |||||
| 80 | char dashes; /* Dashes value */ | |||||
| 81 | Pixmap clip_mask; /* Clip_mask value */ | |||||
| 82 | Cardinal ref_count; /* # of shareholders */ | |||||
| 83 | GC gc; /* The GC itself. */ | |||||
| 84 | XtGCMask dynamic_mask; /* Writable values */ | |||||
| 85 | XtGCMask unused_mask; /* Unused values */ | |||||
| 86 | struct _GCrec *next; /* Next GC for this widgetkind. */ | |||||
| 87 | } GCrec, *GCptr; | |||||
| 88 | ||||||
| 89 | #define GCVAL(bit,mask,val,default)((bit&mask) ? val : default) ((bit&mask) ? val : default) | |||||
| 90 | ||||||
| 91 | #define CHECK(bit,comp,default)if ((checkMask & bit) && (((bit&valueMask) ? v ->comp : default) != gcv.comp)) return 0 \ | |||||
| 92 | if ((checkMask & bit) && \ | |||||
| 93 | (GCVAL(bit,valueMask,v->comp,default)((bit&valueMask) ? v->comp : default) != gcv.comp)) return False0 | |||||
| 94 | ||||||
| 95 | #define ALLGCVALS((1L<<0) | (1L<<1) | (1L<<2) | (1L<<3 ) | (1L<<4) | (1L<<5) | (1L<<6) | (1L<< 7) | (1L<<8) | (1L<<9) | (1L<<10) | (1L<< 11) | (1L<<12) | (1L<<13) | (1L<<14) | (1L<< 15) | (1L<<16) | (1L<<17) | (1L<<18) | (1L<< 20) | (1L<<22)) (GCFunction(1L<<0) | GCPlaneMask(1L<<1) | GCForeground(1L<<2) | \ | |||||
| 96 | GCBackground(1L<<3) | GCLineWidth(1L<<4) | GCLineStyle(1L<<5) | \ | |||||
| 97 | GCCapStyle(1L<<6) | GCJoinStyle(1L<<7) | GCFillStyle(1L<<8) | \ | |||||
| 98 | GCFillRule(1L<<9) | GCTile(1L<<10) | GCStipple(1L<<11) | \ | |||||
| 99 | GCTileStipXOrigin(1L<<12) | GCTileStipYOrigin(1L<<13) | \ | |||||
| 100 | GCFont(1L<<14) | GCSubwindowMode(1L<<15) | GCGraphicsExposures(1L<<16) | \ | |||||
| 101 | GCClipXOrigin(1L<<17) | GCClipYOrigin(1L<<18) | GCDashOffset(1L<<20) | \ | |||||
| 102 | GCArcMode(1L<<22)) | |||||
| 103 | ||||||
| 104 | static Boolint Matches( | |||||
| 105 | Display *dpy, | |||||
| 106 | GCptr ptr, | |||||
| 107 | register XtGCMask valueMask, | |||||
| 108 | register XGCValues *v, | |||||
| 109 | XtGCMask readOnlyMask, | |||||
| 110 | XtGCMask dynamicMask) | |||||
| 111 | { | |||||
| 112 | XGCValues gcv; | |||||
| 113 | register XtGCMask checkMask; | |||||
| 114 | ||||||
| 115 | if (readOnlyMask & ptr->dynamic_mask) | |||||
| 116 | return False0; | |||||
| 117 | if (((ptr->dynamic_mask|ptr->unused_mask) & dynamicMask) != dynamicMask) | |||||
| 118 | return False0; | |||||
| 119 | if (!XGetGCValues(dpy, ptr->gc, ALLGCVALS((1L<<0) | (1L<<1) | (1L<<2) | (1L<<3 ) | (1L<<4) | (1L<<5) | (1L<<6) | (1L<< 7) | (1L<<8) | (1L<<9) | (1L<<10) | (1L<< 11) | (1L<<12) | (1L<<13) | (1L<<14) | (1L<< 15) | (1L<<16) | (1L<<17) | (1L<<18) | (1L<< 20) | (1L<<22)), &gcv)) | |||||
| 120 | return False0; | |||||
| 121 | checkMask = readOnlyMask & ~ptr->unused_mask; | |||||
| 122 | CHECK(GCForeground, foreground, 0)if ((checkMask & (1L<<2)) && ((((1L<< 2)&valueMask) ? v->foreground : 0) != gcv.foreground)) return 0; | |||||
| 123 | CHECK(GCBackground, background, 1)if ((checkMask & (1L<<3)) && ((((1L<< 3)&valueMask) ? v->background : 1) != gcv.background)) return 0; | |||||
| 124 | CHECK(GCFont, font, ~0UL)if ((checkMask & (1L<<14)) && ((((1L<< 14)&valueMask) ? v->font : ~0UL) != gcv.font)) return 0; | |||||
| 125 | CHECK(GCFillStyle, fill_style, FillSolid)if ((checkMask & (1L<<8)) && ((((1L<< 8)&valueMask) ? v->fill_style : 0) != gcv.fill_style)) return 0; | |||||
| 126 | CHECK(GCLineWidth, line_width, 0)if ((checkMask & (1L<<4)) && ((((1L<< 4)&valueMask) ? v->line_width : 0) != gcv.line_width)) return 0; | |||||
| 127 | CHECK(GCFunction, function, GXcopy)if ((checkMask & (1L<<0)) && ((((1L<< 0)&valueMask) ? v->function : 0x3) != gcv.function)) return 0; | |||||
| 128 | CHECK(GCGraphicsExposures, graphics_exposures, True)if ((checkMask & (1L<<16)) && ((((1L<< 16)&valueMask) ? v->graphics_exposures : 1) != gcv.graphics_exposures )) return 0; | |||||
| 129 | CHECK(GCTile, tile, ~0UL)if ((checkMask & (1L<<10)) && ((((1L<< 10)&valueMask) ? v->tile : ~0UL) != gcv.tile)) return 0; | |||||
| 130 | CHECK(GCSubwindowMode, subwindow_mode, ClipByChildren)if ((checkMask & (1L<<15)) && ((((1L<< 15)&valueMask) ? v->subwindow_mode : 0) != gcv.subwindow_mode )) return 0; | |||||
| 131 | CHECK(GCPlaneMask, plane_mask, AllPlanes)if ((checkMask & (1L<<1)) && ((((1L<< 1)&valueMask) ? v->plane_mask : ((unsigned long)~0L)) != gcv.plane_mask)) return 0; | |||||
| 132 | CHECK(GCLineStyle, line_style, LineSolid)if ((checkMask & (1L<<5)) && ((((1L<< 5)&valueMask) ? v->line_style : 0) != gcv.line_style)) return 0; | |||||
| 133 | CHECK(GCCapStyle, cap_style, CapButt)if ((checkMask & (1L<<6)) && ((((1L<< 6)&valueMask) ? v->cap_style : 1) != gcv.cap_style)) return 0; | |||||
| 134 | CHECK(GCJoinStyle, join_style, JoinMiter)if ((checkMask & (1L<<7)) && ((((1L<< 7)&valueMask) ? v->join_style : 0) != gcv.join_style)) return 0; | |||||
| 135 | CHECK(GCFillRule, fill_rule, EvenOddRule)if ((checkMask & (1L<<9)) && ((((1L<< 9)&valueMask) ? v->fill_rule : 0) != gcv.fill_rule)) return 0; | |||||
| 136 | CHECK(GCArcMode, arc_mode, ArcPieSlice)if ((checkMask & (1L<<22)) && ((((1L<< 22)&valueMask) ? v->arc_mode : 1) != gcv.arc_mode)) return 0; | |||||
| 137 | CHECK(GCStipple, stipple, ~0UL)if ((checkMask & (1L<<11)) && ((((1L<< 11)&valueMask) ? v->stipple : ~0UL) != gcv.stipple)) return 0; | |||||
| 138 | CHECK(GCTileStipXOrigin, ts_x_origin, 0)if ((checkMask & (1L<<12)) && ((((1L<< 12)&valueMask) ? v->ts_x_origin : 0) != gcv.ts_x_origin )) return 0; | |||||
| 139 | CHECK(GCTileStipYOrigin, ts_y_origin, 0)if ((checkMask & (1L<<13)) && ((((1L<< 13)&valueMask) ? v->ts_y_origin : 0) != gcv.ts_y_origin )) return 0; | |||||
| 140 | CHECK(GCClipXOrigin, clip_x_origin, 0)if ((checkMask & (1L<<17)) && ((((1L<< 17)&valueMask) ? v->clip_x_origin : 0) != gcv.clip_x_origin )) return 0; | |||||
| 141 | CHECK(GCClipYOrigin, clip_y_origin, 0)if ((checkMask & (1L<<18)) && ((((1L<< 18)&valueMask) ? v->clip_y_origin : 0) != gcv.clip_y_origin )) return 0; | |||||
| 142 | CHECK(GCDashOffset, dash_offset, 0)if ((checkMask & (1L<<20)) && ((((1L<< 20)&valueMask) ? v->dash_offset : 0) != gcv.dash_offset )) return 0; | |||||
| 143 | gcv.clip_mask = ptr->clip_mask; | |||||
| 144 | CHECK(GCClipMask, clip_mask, None)if ((checkMask & (1L<<19)) && ((((1L<< 19)&valueMask) ? v->clip_mask : 0L) != gcv.clip_mask)) return 0; | |||||
| 145 | gcv.dashes = ptr->dashes; | |||||
| 146 | CHECK(GCDashList, dashes, 4)if ((checkMask & (1L<<21)) && ((((1L<< 21)&valueMask) ? v->dashes : 4) != gcv.dashes)) return 0; | |||||
| 147 | valueMask &= ptr->unused_mask | dynamicMask; | |||||
| 148 | if (valueMask) { | |||||
| 149 | XChangeGC(dpy, ptr->gc, valueMask, v); | |||||
| 150 | if (valueMask & GCDashList(1L<<21)) | |||||
| 151 | ptr->dashes = v->dashes; | |||||
| 152 | if (valueMask & GCClipMask(1L<<19)) | |||||
| 153 | ptr->clip_mask = v->clip_mask; | |||||
| 154 | } | |||||
| 155 | ptr->unused_mask &= ~(dynamicMask | readOnlyMask); | |||||
| 156 | ptr->dynamic_mask |= dynamicMask; | |||||
| 157 | return True1; | |||||
| 158 | } /* Matches */ | |||||
| 159 | ||||||
| 160 | /* Called by CloseDisplay to free the per-display GC list */ | |||||
| 161 | void _XtGClistFree( | |||||
| 162 | Display *dpy, | |||||
| 163 | register XtPerDisplay pd) | |||||
| 164 | { | |||||
| 165 | register GCptr GClist, next; | |||||
| 166 | register int i; | |||||
| 167 | ||||||
| 168 | GClist = pd->GClist; | |||||
| 169 | while (GClist) { | |||||
| 170 | next = GClist->next; | |||||
| 171 | XtFree((char*)GClist); | |||||
| 172 | GClist = next; | |||||
| 173 | } | |||||
| 174 | if (pd->pixmap_tab) { | |||||
| 175 | for (i = ScreenCount(dpy)(((_XPrivDisplay)(dpy))->nscreens); --i >= 0; ) { | |||||
| 176 | if (pd->pixmap_tab[i]) | |||||
| 177 | XtFree((char *)pd->pixmap_tab[i]); | |||||
| 178 | } | |||||
| 179 | XtFree((char *)pd->pixmap_tab); | |||||
| 180 | } | |||||
| 181 | } | |||||
| 182 | ||||||
| 183 | ||||||
| 184 | /* | |||||
| 185 | * Return a GC with the given values and characteristics. | |||||
| 186 | */ | |||||
| 187 | ||||||
| 188 | GC XtAllocateGC( | |||||
| 189 | register Widget widget, | |||||
| 190 | Cardinal depth, | |||||
| 191 | XtGCMask valueMask, | |||||
| 192 | XGCValues *values, | |||||
| 193 | XtGCMask dynamicMask, | |||||
| 194 | XtGCMask unusedMask) | |||||
| 195 | { | |||||
| 196 | register GCptr *prev; | |||||
| 197 | register GCptr cur; | |||||
| 198 | Screen *screen; | |||||
| 199 | register Display *dpy; | |||||
| 200 | register XtPerDisplay pd; | |||||
| 201 | Drawable drawable; | |||||
| 202 | Drawable *pixmaps; | |||||
| 203 | XtGCMask readOnlyMask; | |||||
| 204 | GC retval; | |||||
| 205 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); | |||||
| 206 | ||||||
| 207 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | |||||
| 208 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||||
| 209 | if (!XtIsWidget(widget)(((Object)(widget))->object.widget_class->core_class.class_inited & 0x04)) | |||||
| 210 | widget = _XtWindowedAncestor(widget); | |||||
| 211 | if (!depth) | |||||
| 212 | depth = widget->core.depth; | |||||
| 213 | screen = XtScreen(widget)((widget)->core.screen); | |||||
| 214 | dpy = DisplayOfScreen(screen)((screen)->display); | |||||
| 215 | pd = _XtGetPerDisplay(dpy); | |||||
| 216 | unusedMask &= ~valueMask; | |||||
| 217 | readOnlyMask = ~(dynamicMask | unusedMask); | |||||
| 218 | ||||||
| 219 | /* Search for existing GC that matches exactly */ | |||||
| 220 | for (prev = &pd->GClist; (cur = *prev); prev = &cur->next) { | |||||
| 221 | if (cur->depth == depth && | |||||
| 222 | ScreenOfDisplay(dpy, cur->screen)(&((_XPrivDisplay)(dpy))->screens[cur->screen]) == screen && | |||||
| 223 | Matches(dpy, cur, valueMask, values, readOnlyMask, dynamicMask)) { | |||||
| 224 | cur->ref_count++; | |||||
| 225 | /* Move this GC to front of list */ | |||||
| 226 | *prev = cur->next; | |||||
| 227 | cur->next = pd->GClist; | |||||
| 228 | pd->GClist = cur; | |||||
| 229 | retval = cur->gc; | |||||
| 230 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||||
| 231 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | |||||
| 232 | return retval; | |||||
| 233 | } | |||||
| 234 | } | |||||
| 235 | ||||||
| 236 | /* No matches, have to create a new one */ | |||||
| 237 | cur = XtNew(GCrec)((GCrec *) XtMalloc((unsigned) sizeof(GCrec))); | |||||
| 238 | cur->screen = XScreenNumberOfScreen(screen); | |||||
| 239 | cur->depth = depth; | |||||
| 240 | cur->ref_count = 1; | |||||
| 241 | cur->dynamic_mask = dynamicMask; | |||||
| 242 | cur->unused_mask = (unusedMask & ~dynamicMask); | |||||
| 243 | cur->dashes = GCVAL(GCDashList, valueMask, values->dashes, 4)(((1L<<21)&valueMask) ? values->dashes : 4); | |||||
| 244 | cur->clip_mask = GCVAL(GCClipMask, valueMask, values->clip_mask, None)(((1L<<19)&valueMask) ? values->clip_mask : 0L); | |||||
| 245 | drawable = 0; | |||||
| 246 | if (depth == widget->core.depth) | |||||
| 247 | drawable = XtWindow(widget)((widget)->core.window); | |||||
| 248 | if (!drawable && depth == (Cardinal) DefaultDepthOfScreen(screen)((screen)->root_depth)) | |||||
| 249 | drawable = RootWindowOfScreen(screen)((screen)->root); | |||||
| 250 | if (!drawable) { | |||||
| 251 | if (!pd->pixmap_tab) { | |||||
| 252 | int n; | |||||
| 253 | pd->pixmap_tab = (Drawable **)__XtMalloc((unsigned)ScreenCount(dpy)(((_XPrivDisplay)(dpy))->nscreens) * | |||||
| 254 | sizeof(Drawable *)); | |||||
| 255 | for (n = 0; n < ScreenCount(dpy)(((_XPrivDisplay)(dpy))->nscreens); n++) | |||||
| 256 | pd->pixmap_tab[n] = NULL((void*)0); | |||||
| 257 | } | |||||
| 258 | pixmaps = pd->pixmap_tab[cur->screen]; | |||||
| 259 | if (!pixmaps) { | |||||
| 260 | int max, n, *depths; | |||||
| 261 | depths = XListDepths(dpy, cur->screen, &n); | |||||
| 262 | n--; | |||||
| 263 | max = depths[n]; | |||||
| 264 | while (n--) { | |||||
| 265 | if (depths[n] > max) | |||||
| 266 | max = depths[n]; | |||||
| 267 | } | |||||
| 268 | XFree((char *)depths); | |||||
| 269 | pixmaps = (Drawable *)__XtCalloc((unsigned)max, sizeof(Drawable)); | |||||
| 270 | pd->pixmap_tab[cur->screen] = pixmaps; | |||||
| 271 | } | |||||
| 272 | drawable = pixmaps[cur->depth - 1]; | |||||
| 273 | if (!drawable) { | |||||
| 274 | drawable = XCreatePixmap(dpy, RootWindowOfScreen(screen)((screen)->root), 1, 1, | |||||
| 275 | cur->depth); | |||||
| 276 | pixmaps[cur->depth - 1] = drawable; | |||||
| 277 | } | |||||
| 278 | } | |||||
| 279 | cur->gc = XCreateGC(dpy, drawable, valueMask, values); | |||||
| 280 | cur->next = pd->GClist; | |||||
| 281 | pd->GClist = cur; | |||||
| 282 | retval = cur->gc; | |||||
| 283 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||||
| 284 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | |||||
| 285 | return retval; | |||||
| 286 | } /* XtAllocateGC */ | |||||
| 287 | ||||||
| 288 | /* | |||||
| 289 | * Return a read-only GC with the given values. | |||||
| 290 | */ | |||||
| 291 | ||||||
| 292 | GC XtGetGC( | |||||
| 293 | register Widget widget, | |||||
| 294 | XtGCMask valueMask, | |||||
| 295 | XGCValues *values) | |||||
| 296 | { | |||||
| 297 | return XtAllocateGC(widget, 0, valueMask, values, 0, 0); | |||||
| 298 | } /* XtGetGC */ | |||||
| 299 | ||||||
| 300 | void XtReleaseGC( | |||||
| 301 | Widget widget, | |||||
| 302 | register GC gc) | |||||
| 303 | { | |||||
| 304 | register GCptr cur, *prev; | |||||
| 305 | Display* dpy; | |||||
| 306 | XtPerDisplay pd; | |||||
| 307 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); | |||||
| ||||||
| 308 | ||||||
| 309 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | |||||
| 310 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||||
| 311 | dpy = XtDisplayOfObject(widget)((((Object)(widget))->object.widget_class->core_class.class_inited & 0x04) ? (widget)->core.screen->display : _XtIsHookObject (widget) ? ((HookObject)(widget))->hooks.screen->display : _XtWindowedAncestor(widget)->core.screen->display); | |||||
| ||||||
| 312 | pd = _XtGetPerDisplay(dpy); | |||||
| 313 | ||||||
| 314 | for (prev = &pd->GClist; (cur = *prev); prev = &cur->next) { | |||||
| 315 | if (cur->gc == gc) { | |||||
| 316 | if (--(cur->ref_count) == 0) { | |||||
| 317 | *prev = cur->next; | |||||
| 318 | XFreeGC(dpy, gc); | |||||
| 319 | XtFree((char *) cur); | |||||
| 320 | } | |||||
| 321 | break; | |||||
| 322 | } | |||||
| 323 | } | |||||
| 324 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||||
| 325 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | |||||
| 326 | } /* XtReleaseGC */ | |||||
| 327 | ||||||
| 328 | /* The following interface is broken and supplied only for backwards | |||||
| 329 | * compatibility. It will work properly in all cases only if there | |||||
| 330 | * is exactly 1 Display created by the application. | |||||
| 331 | */ | |||||
| 332 | ||||||
| 333 | void XtDestroyGC(register GC gc) | |||||
| 334 | { | |||||
| 335 | GCptr cur, *prev; | |||||
| 336 | XtAppContext app; | |||||
| 337 | ||||||
| 338 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||||
| 339 | app = _XtGetProcessContext()->appContextList; | |||||
| 340 | /* This is awful; we have to search through all the lists | |||||
| 341 | to find the GC. */ | |||||
| 342 | for (; app; app = app->next) { | |||||
| 343 | int i; | |||||
| 344 | for (i = app->count; i ;) { | |||||
| 345 | Display *dpy = app->list[--i]; | |||||
| 346 | XtPerDisplay pd = _XtGetPerDisplay(dpy); | |||||
| 347 | for (prev = &pd->GClist; (cur = *prev); prev = &cur->next) { | |||||
| 348 | if (cur->gc == gc) { | |||||
| 349 | if (--(cur->ref_count) == 0) { | |||||
| 350 | *prev = cur->next; | |||||
| 351 | XFreeGC(dpy, gc); | |||||
| 352 | XtFree((char *) cur); | |||||
| 353 | } | |||||
| 354 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||||
| 355 | return; | |||||
| 356 | } | |||||
| 357 | } | |||||
| 358 | } | |||||
| 359 | } | |||||
| 360 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||||
| 361 | } /* XtDestroyGC */ |