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