File: | GCManager.c |
Location: | line 209, column 10 |
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 */ |