| File: | 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 */ |