File: | Intrinsic.c |
Location: | line 99, column 14 |
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 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, 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 | #define INTRINSIC_C | ||||
72 | |||||
73 | #ifdef HAVE_CONFIG_H1 | ||||
74 | #include <config.h> | ||||
75 | #endif | ||||
76 | #include "IntrinsicI.h" | ||||
77 | #include "VarargsI.h" /* for geoTattler */ | ||||
78 | #ifndef NO_IDENTIFY_WINDOWS | ||||
79 | #include <X11/Xatom.h> | ||||
80 | #endif | ||||
81 | #ifndef VMS | ||||
82 | #include <sys/stat.h> | ||||
83 | #endif /* VMS */ | ||||
84 | |||||
85 | #include <stdlib.h> | ||||
86 | |||||
87 | String XtCXtToolkitError = "XtToolkitError"; | ||||
88 | |||||
89 | Boolean XtIsSubclass( | ||||
90 | Widget widget, | ||||
91 | WidgetClass widgetClass) | ||||
92 | { | ||||
93 | register WidgetClass w; | ||||
94 | Boolean retval = FALSE0; | ||||
95 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); | ||||
96 | |||||
97 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | ||||
98 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | ||||
| |||||
99 | for (w = widget->core.widget_class; w != NULL((void*)0); w = w->core_class.superclass) | ||||
| |||||
100 | if (w == widgetClass) { | ||||
101 | retval = TRUE1; | ||||
102 | break; | ||||
103 | } | ||||
104 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | ||||
105 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | ||||
106 | return retval; | ||||
107 | } /* XtIsSubclass */ | ||||
108 | |||||
109 | |||||
110 | Boolean _XtCheckSubclassFlag( | ||||
111 | Widget object, | ||||
112 | _XtXtEnumXtEnum flag) | ||||
113 | { | ||||
114 | Boolean retval; | ||||
115 | |||||
116 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | ||||
117 | if (object->core.widget_class->core_class.class_inited & flag) | ||||
118 | retval = TRUE1; | ||||
119 | else | ||||
120 | retval = FALSE0; | ||||
121 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | ||||
122 | return retval; | ||||
123 | } /*_XtVerifySubclass */ | ||||
124 | |||||
125 | |||||
126 | Boolean _XtIsSubclassOf( | ||||
127 | Widget object, | ||||
128 | WidgetClass widgetClass, | ||||
129 | WidgetClass superClass, | ||||
130 | _XtXtEnumXtEnum flag) | ||||
131 | { | ||||
132 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | ||||
133 | if (!(object->core.widget_class->core_class.class_inited & flag)) { | ||||
134 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | ||||
135 | return False0; | ||||
136 | } else { | ||||
137 | register WidgetClass c = object->core.widget_class; | ||||
138 | while (c != superClass) { | ||||
139 | if (c == widgetClass) { | ||||
140 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | ||||
141 | return True1; | ||||
142 | } | ||||
143 | c = c->core_class.superclass; | ||||
144 | } | ||||
145 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | ||||
146 | return False0; | ||||
147 | } | ||||
148 | } /*_XtIsSubclassOf */ | ||||
149 | |||||
150 | |||||
151 | XtPointer XtGetClassExtension( | ||||
152 | WidgetClass object_class, | ||||
153 | Cardinal byte_offset, | ||||
154 | XrmQuark type, | ||||
155 | long version, | ||||
156 | Cardinal record_size) | ||||
157 | { | ||||
158 | ObjectClassExtension ext; | ||||
159 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | ||||
160 | |||||
161 | ext = *(ObjectClassExtension *)((char *)object_class + byte_offset); | ||||
162 | while (ext && (ext->record_type != type || ext->version < version | ||||
163 | || ext->record_size < record_size)) { | ||||
164 | ext = (ObjectClassExtension) ext->next_extension; | ||||
165 | } | ||||
166 | |||||
167 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | ||||
168 | return (XtPointer) ext; | ||||
169 | } | ||||
170 | |||||
171 | |||||
172 | static void ComputeWindowAttributes( | ||||
173 | Widget widget, | ||||
174 | XtValueMask *value_mask, | ||||
175 | XSetWindowAttributes *values) | ||||
176 | { | ||||
177 | XtExposeProc expose; | ||||
178 | |||||
179 | *value_mask = CWEventMask(1L<<11) | CWColormap(1L<<13); | ||||
180 | (*values).event_mask = XtBuildEventMask(widget); | ||||
181 | (*values).colormap = widget->core.colormap; | ||||
182 | if (widget->core.background_pixmap != XtUnspecifiedPixmap((Pixmap)2)) { | ||||
183 | *value_mask |= CWBackPixmap(1L<<0); | ||||
184 | (*values).background_pixmap = widget->core.background_pixmap; | ||||
185 | } else { | ||||
186 | *value_mask |= CWBackPixel(1L<<1); | ||||
187 | (*values).background_pixel = widget->core.background_pixel; | ||||
188 | } | ||||
189 | if (widget->core.border_pixmap != XtUnspecifiedPixmap((Pixmap)2)) { | ||||
190 | *value_mask |= CWBorderPixmap(1L<<2); | ||||
191 | (*values).border_pixmap = widget->core.border_pixmap; | ||||
192 | } else { | ||||
193 | *value_mask |= CWBorderPixel(1L<<3); | ||||
194 | (*values).border_pixel = widget->core.border_pixel; | ||||
195 | } | ||||
196 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | ||||
197 | expose = widget->core.widget_class->core_class.expose; | ||||
198 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | ||||
199 | if (expose == (XtExposeProc) NULL((void*)0)) { | ||||
200 | /* Try to avoid redisplay upon resize by making bit_gravity the same | ||||
201 | as the default win_gravity */ | ||||
202 | *value_mask |= CWBitGravity(1L<<4); | ||||
203 | (*values).bit_gravity = NorthWestGravity1; | ||||
204 | } | ||||
205 | } /* ComputeWindowAttributes */ | ||||
206 | |||||
207 | static void CallChangeManaged( | ||||
208 | register Widget widget) | ||||
209 | { | ||||
210 | register Cardinal i; | ||||
211 | XtWidgetProc change_managed; | ||||
212 | register WidgetList children; | ||||
213 | int managed_children = 0; | ||||
214 | |||||
215 | register CompositePtr cpPtr; | ||||
216 | register CompositePartPtr clPtr; | ||||
217 | |||||
218 | if (XtIsComposite (widget)(((Object)(widget))->object.widget_class->core_class.class_inited & 0x08)) { | ||||
219 | cpPtr = (CompositePtr)&((CompositeWidget) widget)->composite; | ||||
220 | clPtr = (CompositePartPtr)&((CompositeWidgetClass) | ||||
221 | widget->core.widget_class)->composite_class; | ||||
222 | } else return; | ||||
223 | |||||
224 | children = cpPtr->children; | ||||
225 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | ||||
226 | change_managed = clPtr->change_managed; | ||||
227 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | ||||
228 | |||||
229 | /* CallChangeManaged for all children */ | ||||
230 | for (i = cpPtr->num_children; i != 0; --i) { | ||||
231 | CallChangeManaged (children[i-1]); | ||||
232 | if (XtIsManaged(children[i-1])) managed_children++; | ||||
233 | } | ||||
234 | |||||
235 | if (change_managed != NULL((void*)0) && managed_children != 0) { | ||||
236 | CALLGEOTAT(_XtGeoTrace(widget,"Call \"%s\"[%d,%d]'s changemanaged\n", | ||||
237 | XtName(widget), | ||||
238 | widget->core.width, widget->core.height)); | ||||
239 | (*change_managed) (widget); | ||||
240 | } | ||||
241 | } /* CallChangeManaged */ | ||||
242 | |||||
243 | |||||
244 | static void MapChildren( | ||||
245 | CompositePart *cwp) | ||||
246 | { | ||||
247 | Cardinal i; | ||||
248 | WidgetList children; | ||||
249 | register Widget child; | ||||
250 | |||||
251 | children = cwp->children; | ||||
252 | for (i = 0; i < cwp->num_children; i++) { | ||||
253 | child = children[i]; | ||||
254 | if (XtIsWidget (child)(((Object)(child))->object.widget_class->core_class.class_inited & 0x04)){ | ||||
255 | if (child->core.managed && child->core.mapped_when_managed) { | ||||
256 | XtMapWidget (children[i])XMapWindow(XtDisplay(children[i]), XtWindow(children[i])); | ||||
257 | } | ||||
258 | } | ||||
259 | } | ||||
260 | } /* MapChildren */ | ||||
261 | |||||
262 | |||||
263 | static Boolean ShouldMapAllChildren( | ||||
264 | CompositePart *cwp) | ||||
265 | { | ||||
266 | Cardinal i; | ||||
267 | WidgetList children; | ||||
268 | register Widget child; | ||||
269 | |||||
270 | children = cwp->children; | ||||
271 | for (i = 0; i < cwp->num_children; i++) { | ||||
272 | child = children[i]; | ||||
273 | if (XtIsWidget(child)(((Object)(child))->object.widget_class->core_class.class_inited & 0x04)) { | ||||
274 | if (XtIsRealized(child) && (! (child->core.managed | ||||
275 | && child->core.mapped_when_managed))){ | ||||
276 | return False0; | ||||
277 | } | ||||
278 | } | ||||
279 | } | ||||
280 | |||||
281 | return True1; | ||||
282 | } /* ShouldMapAllChildren */ | ||||
283 | |||||
284 | |||||
285 | static void RealizeWidget( | ||||
286 | Widget widget) | ||||
287 | { | ||||
288 | XtValueMask value_mask; | ||||
289 | XSetWindowAttributes values; | ||||
290 | XtRealizeProc realize; | ||||
291 | Window window; | ||||
292 | Display* display; | ||||
293 | String class_name; | ||||
294 | Widget hookobj; | ||||
295 | |||||
296 | if (!XtIsWidget(widget)(((Object)(widget))->object.widget_class->core_class.class_inited & 0x04) || XtIsRealized(widget)) return; | ||||
297 | display = XtDisplay(widget); | ||||
298 | _XtInstallTranslations(widget); | ||||
299 | |||||
300 | ComputeWindowAttributes (widget, &value_mask, &values); | ||||
301 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | ||||
302 | realize = widget->core.widget_class->core_class.realize; | ||||
303 | class_name = widget->core.widget_class->core_class.class_name; | ||||
304 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | ||||
305 | if (realize == NULL((void*)0)) | ||||
306 | XtAppErrorMsg(XtWidgetToApplicationContext(widget), | ||||
307 | "invalidProcedure","realizeProc",XtCXtToolkitError, | ||||
308 | "No realize class procedure defined", | ||||
309 | (String *)NULL((void*)0), (Cardinal *)NULL((void*)0)); | ||||
310 | else { | ||||
311 | CALLGEOTAT(_XtGeoTrace(widget,"Call \"%s\"[%d,%d]'s realize proc\n", | ||||
312 | XtName(widget), | ||||
313 | widget->core.width, widget->core.height)); | ||||
314 | (*realize) (widget, &value_mask, &values); | ||||
315 | } | ||||
316 | window = XtWindow(widget); | ||||
317 | hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget)); | ||||
318 | if (XtHasCallbacks(hookobj,XtNchangeHook((char*)&XtStrings[2061])) == XtCallbackHasSome) { | ||||
319 | XtChangeHookDataRec call_data; | ||||
320 | |||||
321 | call_data.type = XtHrealizeWidget((char*)&XtStrings[2281]); | ||||
322 | call_data.widget = widget; | ||||
323 | XtCallCallbackList(hookobj, | ||||
324 | ((HookObject)hookobj)->hooks.changehook_callbacks, | ||||
325 | (XtPointer)&call_data); | ||||
326 | } | ||||
327 | #ifndef NO_IDENTIFY_WINDOWS | ||||
328 | if (_XtGetPerDisplay(display)->appContext->identify_windows) { | ||||
329 | int len_nm, len_cl; | ||||
330 | char *s; | ||||
331 | |||||
332 | len_nm = widget->core.name ? strlen(widget->core.name) : 0; | ||||
333 | len_cl = strlen(class_name); | ||||
334 | s = __XtMalloc((unsigned) (len_nm + len_cl + 2)); | ||||
335 | s[0] = '\0'; | ||||
336 | if (len_nm) | ||||
337 | strcpy(s, widget->core.name); | ||||
338 | strcpy(s + len_nm + 1, class_name); | ||||
339 | XChangeProperty(display, window, | ||||
340 | XInternAtom(display, "_MIT_OBJ_CLASS", | ||||
341 | False0), | ||||
342 | XA_STRING((Atom) 31), 8, PropModeReplace0, (unsigned char *) s, | ||||
343 | len_nm + len_cl + 2); | ||||
344 | XtFree(s); | ||||
345 | } | ||||
346 | #endif | ||||
347 | #ifdef notdef | ||||
348 | _XtRegisterAsyncHandlers(widget); | ||||
349 | #endif | ||||
350 | /* (re)register any grabs extant in the translations */ | ||||
351 | _XtRegisterGrabs(widget); | ||||
352 | /* reregister any grabs added with XtGrab{Button,Key} */ | ||||
353 | _XtRegisterPassiveGrabs(widget); | ||||
354 | XtRegisterDrawable (display, window, widget); | ||||
355 | _XtExtensionSelect(widget); | ||||
356 | |||||
357 | if (XtIsComposite (widget)(((Object)(widget))->object.widget_class->core_class.class_inited & 0x08)) { | ||||
358 | Cardinal i; | ||||
359 | CompositePart *cwp = &(((CompositeWidget)widget)->composite); | ||||
360 | WidgetList children = cwp->children; | ||||
361 | /* Realize all children */ | ||||
362 | for (i = cwp->num_children; i != 0; --i) { | ||||
363 | RealizeWidget (children[i-1]); | ||||
364 | } | ||||
365 | /* Map children that are managed and mapped_when_managed */ | ||||
366 | |||||
367 | if (cwp->num_children != 0) { | ||||
368 | if (ShouldMapAllChildren(cwp)) { | ||||
369 | XMapSubwindows (display, window); | ||||
370 | } else { | ||||
371 | MapChildren(cwp); | ||||
372 | } | ||||
373 | } | ||||
374 | } | ||||
375 | |||||
376 | /* If this is the application's popup shell, map it */ | ||||
377 | if (widget->core.parent == NULL((void*)0) && widget->core.mapped_when_managed) { | ||||
378 | XtMapWidget (widget)XMapWindow(XtDisplay(widget), XtWindow(widget)); | ||||
379 | } | ||||
380 | } /* RealizeWidget */ | ||||
381 | |||||
382 | void XtRealizeWidget ( | ||||
383 | Widget widget) | ||||
384 | { | ||||
385 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); | ||||
386 | |||||
387 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | ||||
388 | if (XtIsRealized (widget)) { | ||||
389 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | ||||
390 | return; | ||||
391 | } | ||||
392 | CallChangeManaged(widget); | ||||
393 | RealizeWidget(widget); | ||||
394 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | ||||
395 | } /* XtRealizeWidget */ | ||||
396 | |||||
397 | |||||
398 | static void UnrealizeWidget( | ||||
399 | Widget widget) | ||||
400 | { | ||||
401 | CompositeWidget cw; | ||||
402 | Cardinal i; | ||||
403 | WidgetList children; | ||||
404 | |||||
405 | if (!XtIsWidget(widget)(((Object)(widget))->object.widget_class->core_class.class_inited & 0x04) || !XtIsRealized(widget)) return; | ||||
406 | |||||
407 | /* If this is the application's popup shell, unmap it? */ | ||||
408 | /* no, the window is being destroyed */ | ||||
409 | |||||
410 | /* Recurse on children */ | ||||
411 | if (XtIsComposite (widget)(((Object)(widget))->object.widget_class->core_class.class_inited & 0x08)) { | ||||
412 | cw = (CompositeWidget) widget; | ||||
413 | children = cw->composite.children; | ||||
414 | /* Unrealize all children */ | ||||
415 | for (i = cw->composite.num_children; i != 0; --i) { | ||||
416 | UnrealizeWidget (children[i-1]); | ||||
417 | } | ||||
418 | /* Unmap children that are managed and mapped_when_managed? */ | ||||
419 | /* No, it's ok to be managed and unrealized as long as your parent */ | ||||
420 | /* is unrealized. XtUnrealize widget makes sure the "top" widget */ | ||||
421 | /* is unmanaged, we can ignore all descendents */ | ||||
422 | } | ||||
423 | |||||
424 | if (XtHasCallbacks(widget, XtNunrealizeCallback((char*)&XtStrings[815])) == XtCallbackHasSome) | ||||
425 | XtCallCallbacks(widget, XtNunrealizeCallback((char*)&XtStrings[815]), NULL((void*)0)); | ||||
426 | |||||
427 | /* Unregister window */ | ||||
428 | XtUnregisterDrawable(XtDisplay(widget), XtWindow(widget)); | ||||
429 | |||||
430 | /* Remove Event Handlers */ | ||||
431 | /* remove grabs. Happens automatically when window is destroyed. */ | ||||
432 | |||||
433 | /* Destroy X Window, done at outer level with one request */ | ||||
434 | widget->core.window = None0L; | ||||
435 | |||||
436 | /* Removing the event handler here saves having to keep track if | ||||
437 | * the translation table is changed while the widget is unrealized. | ||||
438 | */ | ||||
439 | _XtRemoveTranslations(widget); | ||||
440 | } /* UnrealizeWidget */ | ||||
441 | |||||
442 | |||||
443 | void XtUnrealizeWidget ( | ||||
444 | Widget widget) | ||||
445 | { | ||||
446 | Window window; | ||||
447 | Widget hookobj; | ||||
448 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); | ||||
449 | |||||
450 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | ||||
451 | window = XtWindow(widget); | ||||
452 | if (! XtIsRealized (widget)) { | ||||
453 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | ||||
454 | return; | ||||
455 | } | ||||
456 | if (widget->core.managed && widget->core.parent != NULL((void*)0)) | ||||
457 | XtUnmanageChild(widget); | ||||
458 | UnrealizeWidget(widget); | ||||
459 | if (window != None0L) | ||||
460 | XDestroyWindow(XtDisplay(widget), window); | ||||
461 | hookobj = XtHooksOfDisplay(XtDisplayOfObject(widget)); | ||||
462 | if (XtHasCallbacks(hookobj, XtNchangeHook((char*)&XtStrings[2061])) == XtCallbackHasSome) { | ||||
463 | XtChangeHookDataRec call_data; | ||||
464 | |||||
465 | call_data.type = XtHunrealizeWidget((char*)&XtStrings[2297]); | ||||
466 | call_data.widget = widget; | ||||
467 | XtCallCallbackList(hookobj, | ||||
468 | ((HookObject)hookobj)->hooks.changehook_callbacks, | ||||
469 | (XtPointer)&call_data); | ||||
470 | } | ||||
471 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | ||||
472 | } /* XtUnrealizeWidget */ | ||||
473 | |||||
474 | |||||
475 | void XtCreateWindow( | ||||
476 | Widget widget, | ||||
477 | unsigned int window_class, | ||||
478 | Visual *visual, | ||||
479 | XtValueMask value_mask, | ||||
480 | XSetWindowAttributes *attributes) | ||||
481 | { | ||||
482 | XtAppContext app = XtWidgetToApplicationContext(widget); | ||||
483 | |||||
484 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | ||||
485 | if (widget->core.window == None0L) { | ||||
486 | if (widget->core.width == 0 || widget->core.height == 0) { | ||||
487 | Cardinal count = 1; | ||||
488 | XtAppErrorMsg(app, | ||||
489 | "invalidDimension", "xtCreateWindow", XtCXtToolkitError, | ||||
490 | "Widget %s has zero width and/or height", | ||||
491 | &widget->core.name, &count); | ||||
492 | } | ||||
493 | widget->core.window = | ||||
494 | XCreateWindow ( | ||||
495 | XtDisplay (widget), | ||||
496 | (widget->core.parent ? | ||||
497 | widget->core.parent->core.window : | ||||
498 | widget->core.screen->root), | ||||
499 | (int)widget->core.x, (int)widget->core.y, | ||||
500 | (unsigned)widget->core.width, (unsigned)widget->core.height, | ||||
501 | (unsigned)widget->core.border_width, (int) widget->core.depth, | ||||
502 | window_class, visual, value_mask, attributes); | ||||
503 | } | ||||
504 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | ||||
505 | } /* XtCreateWindow */ | ||||
506 | |||||
507 | |||||
508 | /* ---------------- XtNameToWidget ----------------- */ | ||||
509 | |||||
510 | static Widget NameListToWidget( | ||||
511 | Widget root, | ||||
512 | XrmNameList names, | ||||
513 | XrmBindingList bindings, | ||||
514 | int in_depth, int *out_depth, int *found_depth); | ||||
515 | |||||
516 | typedef Widget (*NameMatchProc)(XrmNameList, | ||||
517 | XrmBindingList, | ||||
518 | WidgetList, Cardinal, int, int *, int *); | ||||
519 | |||||
520 | static Widget MatchExactChildren( | ||||
521 | XrmNameList names, | ||||
522 | XrmBindingList bindings, | ||||
523 | register WidgetList children, | ||||
524 | register Cardinal num, | ||||
525 | int in_depth, int *out_depth, int *found_depth) | ||||
526 | { | ||||
527 | register Cardinal i; | ||||
528 | register XrmName name = *names; | ||||
529 | Widget w, result = NULL((void*)0); | ||||
530 | int d, min = 10000; | ||||
531 | |||||
532 | for (i = 0; i < num; i++) { | ||||
533 | if (name == children[i]->core.xrm_name) { | ||||
534 | w = NameListToWidget(children[i], &names[1], &bindings[1], | ||||
535 | in_depth+1, &d, found_depth); | ||||
536 | if (w != NULL((void*)0) && d < min) {result = w; min = d;} | ||||
537 | } | ||||
538 | } | ||||
539 | *out_depth = min; | ||||
540 | return result; | ||||
541 | } | ||||
542 | |||||
543 | static Widget MatchWildChildren( | ||||
544 | XrmNameList names, | ||||
545 | XrmBindingList bindings, | ||||
546 | register WidgetList children, | ||||
547 | register Cardinal num, | ||||
548 | int in_depth, int *out_depth, int *found_depth) | ||||
549 | { | ||||
550 | register Cardinal i; | ||||
551 | Widget w, result = NULL((void*)0); | ||||
552 | int d, min = 10000; | ||||
553 | |||||
554 | for (i = 0; i < num; i++) { | ||||
555 | w = NameListToWidget(children[i], names, bindings, | ||||
556 | in_depth+1, &d, found_depth); | ||||
557 | if (w != NULL((void*)0) && d < min) {result = w; min = d;} | ||||
558 | } | ||||
559 | *out_depth = min; | ||||
560 | return result; | ||||
561 | } | ||||
562 | |||||
563 | static Widget SearchChildren( | ||||
564 | Widget root, | ||||
565 | XrmNameList names, | ||||
566 | XrmBindingList bindings, | ||||
567 | NameMatchProc matchproc, | ||||
568 | int in_depth, int *out_depth, int *found_depth) | ||||
569 | { | ||||
570 | Widget w1 = NULL((void*)0), w2; | ||||
571 | int d1, d2; | ||||
572 | |||||
573 | if (XtIsComposite(root)(((Object)(root))->object.widget_class->core_class.class_inited & 0x08)) { | ||||
574 | w1 = (*matchproc)(names, bindings, | ||||
575 | ((CompositeWidget) root)->composite.children, | ||||
576 | ((CompositeWidget) root)->composite.num_children, | ||||
577 | in_depth, &d1, found_depth); | ||||
578 | } else d1 = 10000; | ||||
579 | w2 = (*matchproc)(names, bindings, root->core.popup_list, | ||||
580 | root->core.num_popups, in_depth, &d2, found_depth); | ||||
581 | *out_depth = (d1 < d2 ? d1 : d2); | ||||
582 | return (d1 < d2 ? w1 : w2); | ||||
583 | } | ||||
584 | |||||
585 | static Widget NameListToWidget( | ||||
586 | register Widget root, | ||||
587 | XrmNameList names, | ||||
588 | XrmBindingList bindings, | ||||
589 | int in_depth, int *out_depth, int *found_depth) | ||||
590 | { | ||||
591 | Widget w1, w2; | ||||
592 | int d1, d2; | ||||
593 | |||||
594 | if (in_depth >= *found_depth) { | ||||
595 | *out_depth = 10000; | ||||
596 | return NULL((void*)0); | ||||
597 | } | ||||
598 | |||||
599 | if (names[0] == NULLQUARK((XrmQuark) 0)) { | ||||
600 | *out_depth = *found_depth = in_depth; | ||||
601 | return root; | ||||
602 | } | ||||
603 | |||||
604 | if (! XtIsWidget(root)(((Object)(root))->object.widget_class->core_class.class_inited & 0x04)) { | ||||
605 | *out_depth = 10000; | ||||
606 | return NULL((void*)0); | ||||
607 | } | ||||
608 | |||||
609 | if (*bindings == XrmBindTightly) { | ||||
610 | return SearchChildren(root, names, bindings, MatchExactChildren, | ||||
611 | in_depth, out_depth, found_depth); | ||||
612 | |||||
613 | } else { /* XrmBindLoosely */ | ||||
614 | w1 = SearchChildren(root, names, bindings, MatchExactChildren, | ||||
615 | in_depth, &d1, found_depth); | ||||
616 | w2 = SearchChildren(root, names, bindings, MatchWildChildren, | ||||
617 | in_depth, &d2, found_depth); | ||||
618 | *out_depth = (d1 < d2 ? d1 : d2); | ||||
619 | return (d1 < d2 ? w1 : w2); | ||||
620 | } | ||||
621 | } /* NameListToWidget */ | ||||
622 | |||||
623 | Widget XtNameToWidget( | ||||
624 | Widget root, | ||||
625 | _Xconstconst char* name) | ||||
626 | { | ||||
627 | XrmName *names; | ||||
628 | XrmBinding *bindings; | ||||
629 | int len, depth, found = 10000; | ||||
630 | Widget result; | ||||
631 | WIDGET_TO_APPCON(root)XtAppContext app = (root && _XtProcessLock ? XtWidgetToApplicationContext (root) : ((void*)0)); | ||||
632 | |||||
633 | len = strlen(name); | ||||
634 | if (len == 0) return NULL((void*)0); | ||||
635 | |||||
636 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | ||||
637 | names = (XrmName *) ALLOCATE_LOCAL((unsigned) (len+1) * sizeof(XrmName))__builtin_alloca ((int)((unsigned) (len+1) * sizeof(XrmName)) ); | ||||
638 | bindings = (XrmBinding *) | ||||
639 | ALLOCATE_LOCAL((unsigned) (len+1) * sizeof(XrmBinding))__builtin_alloca ((int)((unsigned) (len+1) * sizeof(XrmBinding ))); | ||||
640 | if (names == NULL((void*)0) || bindings == NULL((void*)0)) _XtAllocError(NULL((void*)0)); | ||||
641 | |||||
642 | XrmStringToBindingQuarkList(name, bindings, names); | ||||
643 | if (names[0] == NULLQUARK((XrmQuark) 0)) { | ||||
644 | DEALLOCATE_LOCAL((char *) bindings)do {} while(0); | ||||
645 | DEALLOCATE_LOCAL((char *) names)do {} while(0); | ||||
646 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | ||||
647 | return NULL((void*)0); | ||||
648 | } | ||||
649 | |||||
650 | result = NameListToWidget(root, names, bindings, 0, &depth, &found); | ||||
651 | |||||
652 | DEALLOCATE_LOCAL((char *) bindings)do {} while(0); | ||||
653 | DEALLOCATE_LOCAL((char *) names)do {} while(0); | ||||
654 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | ||||
655 | return result; | ||||
656 | } /* XtNameToWidget */ | ||||
657 | |||||
658 | /* Define user versions of intrinsics macros */ | ||||
659 | |||||
660 | #undef XtDisplayOfObject | ||||
661 | Display *XtDisplayOfObject( | ||||
662 | Widget object) | ||||
663 | { | ||||
664 | /* Attempts to LockApp() here will generate endless recursive loops */ | ||||
665 | if (XtIsSubclass(object, hookObjectClass)) | ||||
666 | return DisplayOfScreen(((HookObject)object)->hooks.screen)((((HookObject)object)->hooks.screen)->display); | ||||
667 | return XtDisplay(XtIsWidget(object)(((Object)(object))->object.widget_class->core_class.class_inited & 0x04) ? object : _XtWindowedAncestor(object)); | ||||
668 | } | ||||
669 | |||||
670 | #undef XtDisplay | ||||
671 | Display *XtDisplay( | ||||
672 | Widget widget) | ||||
673 | { | ||||
674 | /* Attempts to LockApp() here will generate endless recursive loops */ | ||||
675 | return DisplayOfScreen(widget->core.screen)((widget->core.screen)->display); | ||||
676 | } | ||||
677 | |||||
678 | #undef XtScreenOfObject | ||||
679 | Screen *XtScreenOfObject( | ||||
680 | Widget object) | ||||
681 | { | ||||
682 | /* Attempts to LockApp() here will generate endless recursive loops */ | ||||
683 | if (XtIsSubclass(object, hookObjectClass)) | ||||
684 | return ((HookObject)object)->hooks.screen; | ||||
685 | return XtScreen(XtIsWidget(object)(((Object)(object))->object.widget_class->core_class.class_inited & 0x04) ? object : _XtWindowedAncestor(object)); | ||||
686 | } | ||||
687 | |||||
688 | #undef XtScreen | ||||
689 | Screen *XtScreen( | ||||
690 | Widget widget) | ||||
691 | { | ||||
692 | /* Attempts to LockApp() here will generate endless recursive loops */ | ||||
693 | return widget->core.screen; | ||||
694 | } | ||||
695 | |||||
696 | #undef XtWindowOfObject | ||||
697 | Window XtWindowOfObject( | ||||
698 | Widget object) | ||||
699 | { | ||||
700 | return XtWindow(XtIsWidget(object)(((Object)(object))->object.widget_class->core_class.class_inited & 0x04) ? object : _XtWindowedAncestor(object)); | ||||
701 | } | ||||
702 | |||||
703 | |||||
704 | #undef XtWindow | ||||
705 | Window XtWindow( | ||||
706 | Widget widget) | ||||
707 | { | ||||
708 | return widget->core.window; | ||||
709 | } | ||||
710 | |||||
711 | #undef XtSuperclass | ||||
712 | WidgetClass XtSuperclass( | ||||
713 | Widget widget) | ||||
714 | { | ||||
715 | WidgetClass retval; | ||||
716 | |||||
717 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | ||||
718 | retval = XtClass(widget)->core_class.superclass; | ||||
719 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | ||||
720 | return retval; | ||||
721 | } | ||||
722 | |||||
723 | #undef XtClass | ||||
724 | WidgetClass XtClass( | ||||
725 | Widget widget) | ||||
726 | { | ||||
727 | WidgetClass retval; | ||||
728 | |||||
729 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | ||||
730 | retval = widget->core.widget_class; | ||||
731 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | ||||
732 | return retval; | ||||
733 | } | ||||
734 | |||||
735 | #undef XtIsManaged | ||||
736 | Boolean XtIsManaged( | ||||
737 | Widget object) | ||||
738 | { | ||||
739 | Boolean retval; | ||||
740 | WIDGET_TO_APPCON(object)XtAppContext app = (object && _XtProcessLock ? XtWidgetToApplicationContext (object) : ((void*)0)); | ||||
741 | |||||
742 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | ||||
743 | if (XtIsRectObj(object)(((Object)(object))->object.widget_class->core_class.class_inited & 0x02)) | ||||
744 | retval = object->core.managed; | ||||
745 | else | ||||
746 | retval = False0; | ||||
747 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | ||||
748 | return retval; | ||||
749 | } | ||||
750 | |||||
751 | #undef XtIsRealized | ||||
752 | Boolean XtIsRealized ( | ||||
753 | Widget object) | ||||
754 | { | ||||
755 | Boolean retval; | ||||
756 | WIDGET_TO_APPCON(object)XtAppContext app = (object && _XtProcessLock ? XtWidgetToApplicationContext (object) : ((void*)0)); | ||||
757 | |||||
758 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | ||||
759 | retval = XtWindowOfObject(object) != None0L; | ||||
760 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | ||||
761 | return retval; | ||||
762 | } /* XtIsRealized */ | ||||
763 | |||||
764 | #undef XtIsSensitive | ||||
765 | Boolean XtIsSensitive( | ||||
766 | Widget object) | ||||
767 | { | ||||
768 | Boolean retval; | ||||
769 | WIDGET_TO_APPCON(object)XtAppContext app = (object && _XtProcessLock ? XtWidgetToApplicationContext (object) : ((void*)0)); | ||||
770 | |||||
771 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | ||||
772 | if (XtIsRectObj(object)(((Object)(object))->object.widget_class->core_class.class_inited & 0x02)) | ||||
773 | retval = object->core.sensitive && object->core.ancestor_sensitive; | ||||
774 | else | ||||
775 | retval = False0; | ||||
776 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | ||||
777 | return retval; | ||||
778 | } | ||||
779 | |||||
780 | /* | ||||
781 | * Internal routine; must be called only after XtIsWidget returns false | ||||
782 | */ | ||||
783 | Widget _XtWindowedAncestor( | ||||
784 | register Widget object) | ||||
785 | { | ||||
786 | Widget obj = object; | ||||
787 | for (object = XtParent(object); object && !XtIsWidget(object)(((Object)(object))->object.widget_class->core_class.class_inited & 0x04);) | ||||
788 | object = XtParent(object); | ||||
789 | |||||
790 | if (object == NULL((void*)0)) { | ||||
791 | String params = XtName(obj); | ||||
792 | Cardinal num_params = 1; | ||||
793 | XtErrorMsg("noWidgetAncestor", "windowedAncestor", XtCXtToolkitError, | ||||
794 | "Object \"%s\" does not have windowed ancestor", | ||||
795 | ¶ms, &num_params); | ||||
796 | } | ||||
797 | |||||
798 | return object; | ||||
799 | } | ||||
800 | |||||
801 | #undef XtParent | ||||
802 | Widget XtParent( | ||||
803 | Widget widget) | ||||
804 | { | ||||
805 | /* Attempts to LockApp() here will generate endless recursive loops */ | ||||
806 | return widget->core.parent; | ||||
807 | } | ||||
808 | |||||
809 | #undef XtName | ||||
810 | String XtName( | ||||
811 | Widget object) | ||||
812 | { | ||||
813 | /* Attempts to LockApp() here will generate endless recursive loops */ | ||||
814 | return XrmQuarkToString(object->core.xrm_name); | ||||
815 | } | ||||
816 | |||||
817 | |||||
818 | Boolean XtIsObject( | ||||
819 | Widget object) | ||||
820 | { | ||||
821 | WidgetClass wc; | ||||
822 | String class_name; | ||||
823 | |||||
824 | /* perform basic sanity checks */ | ||||
825 | if (object->core.self != object || object->core.xrm_name == NULLQUARK((XrmQuark) 0)) | ||||
826 | return False0; | ||||
827 | |||||
828 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | ||||
829 | wc = object->core.widget_class; | ||||
830 | if (wc->core_class.class_name == NULL((void*)0) || | ||||
831 | wc->core_class.xrm_class == NULLQUARK((XrmQuark) 0) || | ||||
832 | (class_name = XrmClassToString(wc->core_class.xrm_class)XrmQuarkToString(wc->core_class.xrm_class)) == NULL((void*)0) || | ||||
833 | strcmp(wc->core_class.class_name, class_name) != 0) { | ||||
834 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | ||||
835 | return False0; | ||||
836 | } | ||||
837 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | ||||
838 | |||||
839 | if (XtIsWidget(object)(((Object)(object))->object.widget_class->core_class.class_inited & 0x04)) { | ||||
840 | if (object->core.name == NULL((void*)0) || | ||||
841 | (class_name = XrmNameToString(object->core.xrm_name)XrmQuarkToString(object->core.xrm_name)) == NULL((void*)0) || | ||||
842 | strcmp(object->core.name, class_name) != 0) | ||||
843 | return False0; | ||||
844 | } | ||||
845 | return True1; | ||||
846 | } | ||||
847 | |||||
848 | #if defined(WIN32) | ||||
849 | static int access_file ( | ||||
850 | char* path, | ||||
851 | char* pathbuf, | ||||
852 | int len_pathbuf, | ||||
853 | char** pathret) | ||||
854 | { | ||||
855 | if (access (path, F_OK0) == 0) { | ||||
856 | if (strlen (path) < len_pathbuf) | ||||
857 | *pathret = pathbuf; | ||||
858 | else | ||||
859 | *pathret = XtMalloc (strlen (path)); | ||||
860 | if (*pathret) { | ||||
861 | strcpy (*pathret, path); | ||||
862 | return 1; | ||||
863 | } | ||||
864 | } | ||||
865 | return 0; | ||||
866 | } | ||||
867 | |||||
868 | static int AccessFile ( | ||||
869 | char* path, | ||||
870 | char* pathbuf, | ||||
871 | int len_pathbuf, | ||||
872 | char** pathret) | ||||
873 | { | ||||
874 | unsigned long drives; | ||||
875 | int i, len; | ||||
876 | char* drive; | ||||
877 | char buf[MAX_PATH]; | ||||
878 | char* bufp; | ||||
879 | |||||
880 | /* just try the "raw" name first and see if it works */ | ||||
881 | if (access_file (path, pathbuf, len_pathbuf, pathret)) | ||||
882 | return 1; | ||||
883 | |||||
884 | #if defined(WIN32) && defined(__MINGW32__) | ||||
885 | /* don't try others */ | ||||
886 | return 0; | ||||
887 | #endif | ||||
888 | |||||
889 | /* try the places set in the environment */ | ||||
890 | drive = getenv ("_XBASEDRIVE"); | ||||
891 | #ifdef __UNIXOS2__ | ||||
892 | if (!drive) | ||||
893 | drive = getenv ("X11ROOT"); | ||||
894 | #endif | ||||
895 | if (!drive) | ||||
896 | drive = "C:"; | ||||
897 | len = strlen (drive) + strlen (path); | ||||
898 | bufp = XtStackAlloc (len + 1, buf)((len + 1) <= sizeof(buf) ? (XtPointer)(buf) : XtMalloc((unsigned )(len + 1))); | ||||
899 | strcpy (bufp, drive); | ||||
900 | strcat (bufp, path); | ||||
901 | if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { | ||||
902 | XtStackFree (bufp, buf){ if ((bufp) != ((XtPointer)(buf))) XtFree(bufp); }; | ||||
903 | return 1; | ||||
904 | } | ||||
905 | |||||
906 | #ifndef __UNIXOS2__ | ||||
907 | /* one last place to look */ | ||||
908 | drive = getenv ("HOMEDRIVE"); | ||||
909 | if (drive) { | ||||
910 | len = strlen (drive) + strlen (path); | ||||
911 | bufp = XtStackAlloc (len + 1, buf)((len + 1) <= sizeof(buf) ? (XtPointer)(buf) : XtMalloc((unsigned )(len + 1))); | ||||
912 | strcpy (bufp, drive); | ||||
913 | strcat (bufp, path); | ||||
914 | if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { | ||||
915 | XtStackFree (bufp, buf){ if ((bufp) != ((XtPointer)(buf))) XtFree(bufp); }; | ||||
916 | return 1; | ||||
917 | } | ||||
918 | } | ||||
919 | |||||
920 | /* does OS/2 (with or with gcc-emx) have getdrives()? */ | ||||
921 | /* tried everywhere else, go fishing */ | ||||
922 | drives = _getdrives (); | ||||
923 | #define C_DRIVE ('C' - 'A') | ||||
924 | #define Z_DRIVE ('Z' - 'A') | ||||
925 | for (i = C_DRIVE; i <= Z_DRIVE; i++) { /* don't check on A: or B: */ | ||||
926 | if ((1 << i) & drives) { | ||||
927 | len = 2 + strlen (path); | ||||
928 | bufp = XtStackAlloc (len + 1, buf)((len + 1) <= sizeof(buf) ? (XtPointer)(buf) : XtMalloc((unsigned )(len + 1))); | ||||
929 | *bufp = 'A' + i; | ||||
930 | *(bufp + 1) = ':'; | ||||
931 | *(bufp + 2) = '\0'; | ||||
932 | strcat (bufp, path); | ||||
933 | if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { | ||||
934 | XtStackFree (bufp, buf){ if ((bufp) != ((XtPointer)(buf))) XtFree(bufp); }; | ||||
935 | return 1; | ||||
936 | } | ||||
937 | } | ||||
938 | } | ||||
939 | #endif | ||||
940 | return 0; | ||||
941 | } | ||||
942 | #endif | ||||
943 | |||||
944 | static Boolean TestFile( | ||||
945 | String path) | ||||
946 | { | ||||
947 | #ifndef VMS | ||||
948 | int ret = 0; | ||||
949 | struct stat status; | ||||
950 | #if defined(WIN32) | ||||
951 | char buf[MAX_PATH]; | ||||
952 | char* bufp; | ||||
953 | int len; | ||||
954 | UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); | ||||
955 | |||||
956 | if (AccessFile (path, buf, MAX_PATH, &bufp)) | ||||
957 | path = bufp; | ||||
958 | |||||
959 | (void) SetErrorMode (olderror); | ||||
960 | #endif | ||||
961 | ret = (access(path, R_OK4) == 0 && /* exists and is readable */ | ||||
962 | stat(path, &status) == 0 && /* get the status */ | ||||
963 | #ifndef X_NOT_POSIX | ||||
964 | S_ISDIR(status.st_mode)((((status.st_mode)) & 0170000) == (0040000)) == 0); /* not a directory */ | ||||
965 | #else | ||||
966 | (status.st_mode & S_IFMT0170000) != S_IFDIR0040000); /* not a directory */ | ||||
967 | #endif /* X_NOT_POSIX else */ | ||||
968 | return ret; | ||||
969 | #else /* VMS */ | ||||
970 | return TRUE1; /* Who knows what to do here? */ | ||||
971 | #endif /* VMS */ | ||||
972 | } | ||||
973 | |||||
974 | /* return of TRUE = resolved string fit, FALSE = didn't fit. Not | ||||
975 | null-terminated and not collapsed if it didn't fit */ | ||||
976 | |||||
977 | static Boolean Resolve( | ||||
978 | register _Xconstconst char *source, /* The source string */ | ||||
979 | register int len, /* The length in bytes of *source */ | ||||
980 | Substitution sub, /* Array of string values to substitute */ | ||||
981 | Cardinal num, /* Number of substitution entries */ | ||||
982 | char *buf, /* Where to put the resolved string; */ | ||||
983 | char collapse) /* Character to collapse */ | ||||
984 | { | ||||
985 | register int bytesLeft = PATH_MAX4096; | ||||
986 | register char* bp = buf; | ||||
987 | #ifndef DONT_COLLAPSE | ||||
988 | Boolean atBeginning = TRUE1; | ||||
989 | Boolean prevIsCollapse = FALSE0; | ||||
990 | |||||
991 | #define PUT(ch) \ | ||||
992 | { \ | ||||
993 | if (--bytesLeft == 0) return FALSE0; \ | ||||
994 | if (prevIsCollapse) \ | ||||
995 | if ((*bp = ch) != collapse) { \ | ||||
996 | prevIsCollapse = FALSE0; \ | ||||
997 | bp++; \ | ||||
998 | } \ | ||||
999 | else bytesLeft++; \ | ||||
1000 | else if ((*bp++ = ch) == collapse && !atBeginning) \ | ||||
1001 | prevIsCollapse = TRUE1; \ | ||||
1002 | } | ||||
1003 | #else /* DONT_COLLAPSE */ | ||||
1004 | |||||
1005 | #define PUT(ch) \ | ||||
1006 | { \ | ||||
1007 | if (--bytesLeft == 0) return FALSE0; \ | ||||
1008 | *bp++ = ch; \ | ||||
1009 | } | ||||
1010 | #endif /* DONT_COLLAPSE */ | ||||
1011 | #define escape '%' | ||||
1012 | |||||
1013 | while (len--) { | ||||
1014 | #ifndef DONT_COLLAPSE | ||||
1015 | if (*source == collapse) { | ||||
1016 | PUT(*source); | ||||
1017 | source++; | ||||
1018 | continue; | ||||
1019 | } | ||||
1020 | else | ||||
1021 | #endif /* DONT_COLLAPSE */ | ||||
1022 | if (*source != escape) { | ||||
1023 | PUT(*source); | ||||
1024 | } | ||||
1025 | else { | ||||
1026 | source++; | ||||
1027 | if (len-- == 0) { | ||||
1028 | PUT(escape); | ||||
1029 | break; | ||||
1030 | } | ||||
1031 | |||||
1032 | if (*source == ':' || *source == escape) | ||||
1033 | PUT(*source) | ||||
1034 | else { | ||||
1035 | /* Match the character against the match array */ | ||||
1036 | register Cardinal j; | ||||
1037 | |||||
1038 | for (j = 0; j < num && sub[j].match != *source; j++) {} | ||||
1039 | |||||
1040 | /* Substitute the substitution string */ | ||||
1041 | |||||
1042 | if (j >= num) PUT(*source) | ||||
1043 | else if (sub[j].substitution != NULL((void*)0)) { | ||||
1044 | char *sp = sub[j].substitution; | ||||
1045 | while (*sp) { | ||||
1046 | PUT(*sp); | ||||
1047 | sp++; | ||||
1048 | } | ||||
1049 | } | ||||
1050 | } | ||||
1051 | } | ||||
1052 | source++; | ||||
1053 | #ifndef DONT_COLLAPSE | ||||
1054 | atBeginning = FALSE0; | ||||
1055 | #endif /* DONT_COLLAPSE */ | ||||
1056 | } | ||||
1057 | PUT('\0'); | ||||
1058 | |||||
1059 | return TRUE1; | ||||
1060 | #undef PUT | ||||
1061 | #undef escape | ||||
1062 | } | ||||
1063 | |||||
1064 | |||||
1065 | String XtFindFile( | ||||
1066 | _Xconstconst char* path, | ||||
1067 | Substitution substitutions, | ||||
1068 | Cardinal num_substitutions, | ||||
1069 | XtFilePredicate predicate) | ||||
1070 | { | ||||
1071 | char *buf, *buf1, *buf2, *colon; | ||||
1072 | int len; | ||||
1073 | Boolean firstTime = TRUE1; | ||||
1074 | |||||
1075 | buf = buf1 = __XtMalloc((unsigned)PATH_MAX4096); | ||||
1076 | buf2 = __XtMalloc((unsigned)PATH_MAX4096); | ||||
1077 | |||||
1078 | if (predicate == NULL((void*)0)) predicate = TestFile; | ||||
1079 | |||||
1080 | while (1) { | ||||
1081 | colon = (String)path; | ||||
1082 | /* skip leading colons */ | ||||
1083 | while (*colon) { | ||||
1084 | if (*colon != ':') break; | ||||
1085 | colon++; | ||||
1086 | path++; | ||||
1087 | } | ||||
1088 | /* now look for an un-escaped colon */ | ||||
1089 | for ( ; *colon ; colon++) { | ||||
1090 | if (*colon == '%' && *(path+1)) { | ||||
1091 | colon++; /* bump it an extra time to skip %. */ | ||||
1092 | continue; | ||||
1093 | } | ||||
1094 | if (*colon == ':') | ||||
1095 | #ifdef __UNIXOS2__ | ||||
1096 | if (colon > (path+1)) | ||||
1097 | #endif | ||||
1098 | break; | ||||
1099 | } | ||||
1100 | len = colon - path; | ||||
1101 | if (Resolve(path, len, substitutions, num_substitutions, | ||||
1102 | buf, '/')) { | ||||
1103 | if (firstTime || strcmp(buf1,buf2) != 0) { | ||||
1104 | #ifdef __UNIXOS2__ | ||||
1105 | { | ||||
1106 | char *bufx = (char*)__XOS2RedirRoot(buf); | ||||
1107 | strcpy(buf,bufx); | ||||
1108 | } | ||||
1109 | #endif | ||||
1110 | #ifdef XNL_DEBUG | ||||
1111 | printf("Testing file %s\n", buf); | ||||
1112 | #endif /* XNL_DEBUG */ | ||||
1113 | /* Check out the file */ | ||||
1114 | if ((*predicate) (buf)) { | ||||
1115 | /* We've found it, return it */ | ||||
1116 | #ifdef XNL_DEBUG | ||||
1117 | printf("File found.\n"); | ||||
1118 | #endif /* XNL_DEBUG */ | ||||
1119 | if (buf == buf1) XtFree(buf2); | ||||
1120 | else XtFree(buf1); | ||||
1121 | return buf; | ||||
1122 | } | ||||
1123 | if (buf == buf1) | ||||
1124 | buf = buf2; | ||||
1125 | else | ||||
1126 | buf = buf1; | ||||
1127 | firstTime = FALSE0; | ||||
1128 | } | ||||
1129 | } | ||||
1130 | |||||
1131 | /* Nope...any more paths? */ | ||||
1132 | |||||
1133 | if (*colon == '\0') break; | ||||
1134 | path = colon+1; | ||||
1135 | } | ||||
1136 | |||||
1137 | /* No file found */ | ||||
1138 | |||||
1139 | XtFree(buf1); | ||||
1140 | XtFree(buf2); | ||||
1141 | return NULL((void*)0); | ||||
1142 | } | ||||
1143 | |||||
1144 | |||||
1145 | /* The implementation of this routine is operating system dependent */ | ||||
1146 | /* Should match the code in Xlib _XlcMapOSLocaleName */ | ||||
1147 | |||||
1148 | static char *ExtractLocaleName( | ||||
1149 | String lang) | ||||
1150 | { | ||||
1151 | |||||
1152 | #if defined(hpux) || defined(CSRG_BASED) || defined(sun) || defined(SVR4) || defined(sgi) || defined(__osf__) || defined(AIXV3) || defined(ultrix) || defined(WIN32) || defined(__UNIXOS2__) || defined (linux1) | ||||
1153 | # ifdef hpux | ||||
1154 | /* | ||||
1155 | * We need to discriminated between HPUX 9 and HPUX 10. The equivalent | ||||
1156 | * code in Xlib in SetLocale.c does include locale.h via X11/Xlocale.h. | ||||
1157 | */ | ||||
1158 | # include <locale.h> | ||||
1159 | # ifndef _LastCategory | ||||
1160 | /* HPUX 9 and earlier */ | ||||
1161 | # define SKIPCOUNT 2 | ||||
1162 | # define STARTCHAR ':' | ||||
1163 | # define ENDCHAR ';' | ||||
1164 | # else | ||||
1165 | /* HPUX 10 */ | ||||
1166 | # define ENDCHAR ' ' | ||||
1167 | # endif | ||||
1168 | # else | ||||
1169 | # ifdef ultrix | ||||
1170 | # define SKIPCOUNT 2 | ||||
1171 | # define STARTCHAR '\001' | ||||
1172 | # define ENDCHAR '\001' | ||||
1173 | # else | ||||
1174 | # if defined(WIN32) || defined(__UNIXOS2__) | ||||
1175 | # define SKIPCOUNT 1 | ||||
1176 | # define STARTCHAR '=' | ||||
1177 | # define ENDCHAR ';' | ||||
1178 | # define WHITEFILL | ||||
1179 | # else | ||||
1180 | # if defined(__osf__) || (defined(AIXV3) && !defined(AIXV4)) | ||||
1181 | # define STARTCHAR ' ' | ||||
1182 | # define ENDCHAR ' ' | ||||
1183 | # else | ||||
1184 | # if defined(linux1) | ||||
1185 | # define STARTSTR"LC_CTYPE=" "LC_CTYPE=" | ||||
1186 | # define ENDCHAR ';' | ||||
1187 | # else | ||||
1188 | # if !defined(sun) || defined(SVR4) | ||||
1189 | # define STARTCHAR '/' | ||||
1190 | # define ENDCHAR '/' | ||||
1191 | # endif | ||||
1192 | # endif | ||||
1193 | # endif | ||||
1194 | # endif | ||||
1195 | # endif | ||||
1196 | # endif | ||||
1197 | |||||
1198 | char *start; | ||||
1199 | char *end; | ||||
1200 | int len; | ||||
1201 | # ifdef SKIPCOUNT | ||||
1202 | int n; | ||||
1203 | # endif | ||||
1204 | static char* buf = NULL((void*)0); | ||||
1205 | |||||
1206 | start = lang; | ||||
1207 | # ifdef SKIPCOUNT | ||||
1208 | for (n = SKIPCOUNT; | ||||
1209 | --n >= 0 && start && (start = strchr (start, STARTCHAR)); | ||||
1210 | start++) | ||||
1211 | ; | ||||
1212 | if (!start) | ||||
1213 | start = lang; | ||||
1214 | # endif | ||||
1215 | # ifdef STARTCHAR | ||||
1216 | if (start && (start = strchr (start, STARTCHAR))) | ||||
1217 | # elif defined (STARTSTR"LC_CTYPE=") | ||||
1218 | if (start && (start = strstr (start,STARTSTR"LC_CTYPE="))) | ||||
1219 | # endif | ||||
1220 | { | ||||
1221 | # ifdef STARTCHAR | ||||
1222 | start++; | ||||
1223 | # elif defined (STARTSTR"LC_CTYPE=") | ||||
1224 | start += strlen(STARTSTR"LC_CTYPE="); | ||||
1225 | # endif | ||||
1226 | |||||
1227 | if ((end = strchr (start, ENDCHAR))) { | ||||
1228 | len = end - start; | ||||
1229 | if (buf != NULL((void*)0)) XtFree (buf); | ||||
1230 | buf = XtMalloc (len + 1); | ||||
1231 | if (buf == NULL((void*)0)) return NULL((void*)0); | ||||
1232 | strncpy(buf, start, len); | ||||
1233 | *(buf + len) = '\0'; | ||||
1234 | # ifdef WHITEFILL | ||||
1235 | for (start = buf; start = strchr(start, ' '); ) | ||||
1236 | *start++ = '-'; | ||||
1237 | # endif | ||||
1238 | return buf; | ||||
1239 | } else /* if no ENDCHAR is found we are at the end of the line */ | ||||
1240 | return start; | ||||
1241 | } | ||||
1242 | # ifdef WHITEFILL | ||||
1243 | if (strchr(lang, ' ')) { | ||||
1244 | if (buf != NULL((void*)0)) XtFree (buf); | ||||
1245 | else buf = XtMalloc (strlen (lang) + 1); | ||||
1246 | if (buf == NULL((void*)0)) return NULL((void*)0); | ||||
1247 | strcpy(buf, lang); | ||||
1248 | for (start = buf; start = strchr(start, ' '); ) | ||||
1249 | *start++ = '-'; | ||||
1250 | return buf; | ||||
1251 | } | ||||
1252 | # endif | ||||
1253 | # undef STARTCHAR | ||||
1254 | # undef ENDCHAR | ||||
1255 | # undef WHITEFILL | ||||
1256 | #endif | ||||
1257 | |||||
1258 | return lang; | ||||
1259 | } | ||||
1260 | |||||
1261 | static void FillInLangSubs( | ||||
1262 | Substitution subs, | ||||
1263 | XtPerDisplay pd) | ||||
1264 | { | ||||
1265 | int len; | ||||
1266 | char *string, *p1, *p2, *p3; | ||||
1267 | char **rest; | ||||
1268 | char *ch; | ||||
1269 | |||||
1270 | if (pd->language == NULL((void*)0) || | ||||
1271 | (pd->language != NULL((void*)0) && pd->language[0] == '\0')) { | ||||
1272 | subs[0].substitution = subs[1].substitution = | ||||
1273 | subs[2].substitution = subs[3].substitution = NULL((void*)0); | ||||
1274 | return; | ||||
1275 | } | ||||
1276 | |||||
1277 | string = ExtractLocaleName(pd->language); | ||||
1278 | |||||
1279 | if (string == NULL((void*)0) || | ||||
1280 | (string != NULL((void*)0) && string[0] == '\0')) { | ||||
1281 | subs[0].substitution = subs[1].substitution = | ||||
1282 | subs[2].substitution = subs[3].substitution = NULL((void*)0); | ||||
1283 | return; | ||||
1284 | } | ||||
1285 | |||||
1286 | len = strlen(string) + 1; | ||||
1287 | subs[0].substitution = string; | ||||
1288 | p1 = subs[1].substitution = __XtMalloc((Cardinal) 3*len); | ||||
1289 | p2 = subs[2].substitution = subs[1].substitution + len; | ||||
1290 | p3 = subs[3].substitution = subs[2].substitution + len; | ||||
1291 | |||||
1292 | /* Everything up to the first "_" goes into p1. From "_" to "." in | ||||
1293 | p2. The rest in p3. If no delimiters, all goes into p1. We | ||||
1294 | assume p1, p2, and p3 are large enough. */ | ||||
1295 | |||||
1296 | *p1 = *p2 = *p3 = '\0'; | ||||
1297 | |||||
1298 | ch = strchr(string, '_'); | ||||
1299 | if (ch != NULL((void*)0)) { | ||||
1300 | len = ch - string; | ||||
1301 | (void) strncpy(p1, string, len); | ||||
1302 | p1[len] = '\0'; | ||||
1303 | string = ch + 1; | ||||
1304 | rest = &p2; | ||||
1305 | } else rest = &p1; | ||||
1306 | |||||
1307 | /* Rest points to where we put the first part */ | ||||
1308 | |||||
1309 | ch = strchr(string, '.'); | ||||
1310 | if (ch != NULL((void*)0)) { | ||||
1311 | len = ch - string; | ||||
1312 | strncpy(*rest, string, len); | ||||
1313 | (*rest)[len] = '\0'; | ||||
1314 | (void) strcpy(p3, ch+1); | ||||
1315 | } else (void) strcpy(*rest, string); | ||||
1316 | } | ||||
1317 | |||||
1318 | /* | ||||
1319 | * default path used if environment variable XFILESEARCHPATH | ||||
1320 | * is not defined. Also substitued for %D. | ||||
1321 | * The exact value should be documented in the implementation | ||||
1322 | * notes for any Xt implementation. | ||||
1323 | */ | ||||
1324 | static const char *implementation_default_path(void) | ||||
1325 | { | ||||
1326 | #if defined(WIN32) | ||||
1327 | static char xfilesearchpath[] = ""; | ||||
1328 | |||||
1329 | return xfilesearchpath; | ||||
1330 | #elif defined(__UNIXOS2__) | ||||
1331 | /* if you know how to pass % thru the compiler let me know */ | ||||
1332 | static char xfilesearchpath[] = XFILESEARCHPATHDEFAULT"/var/tmp/jhbuild/etc/X11/%L/%T/%N%C%S:/var/tmp/jhbuild/etc/X11/%l/%T/%N%C%S:/var/tmp/jhbuild/etc/X11/%T/%N%C%S:/var/tmp/jhbuild/etc/X11/%L/%T/%N%S:/var/tmp/jhbuild/etc/X11/%l/%T/%N%S:/var/tmp/jhbuild/etc/X11/%T/%N%S:/var/tmp/jhbuild/share/X11/%L/%T/%N%C%S:/var/tmp/jhbuild/share/X11/%l/%T/%N%C%S:/var/tmp/jhbuild/share/X11/%T/%N%C%S:/var/tmp/jhbuild/share/X11/%L/%T/%N%S:/var/tmp/jhbuild/share/X11/%l/%T/%N%S:/var/tmp/jhbuild/share/X11/%T/%N%S:/var/tmp/jhbuild/lib64/X11/%L/%T/%N%C%S:/var/tmp/jhbuild/lib64/X11/%l/%T/%N%C%S:/var/tmp/jhbuild/lib64/X11/%T/%N%C%S:/var/tmp/jhbuild/lib64/X11/%L/%T/%N%S:/var/tmp/jhbuild/lib64/X11/%l/%T/%N%S:/var/tmp/jhbuild/lib64/X11/%T/%N%S"; | ||||
1333 | static Boolint fixed; | ||||
1334 | char *ch; | ||||
1335 | |||||
1336 | if (!fixed) { | ||||
1337 | for (ch = xfilesearchpath; ch = strchr(ch, ';'); ch++) | ||||
1338 | *ch = '%'; | ||||
1339 | fixed = True1; | ||||
1340 | } | ||||
1341 | return xfilesearchpath; | ||||
1342 | #else | ||||
1343 | return XFILESEARCHPATHDEFAULT"/var/tmp/jhbuild/etc/X11/%L/%T/%N%C%S:/var/tmp/jhbuild/etc/X11/%l/%T/%N%C%S:/var/tmp/jhbuild/etc/X11/%T/%N%C%S:/var/tmp/jhbuild/etc/X11/%L/%T/%N%S:/var/tmp/jhbuild/etc/X11/%l/%T/%N%S:/var/tmp/jhbuild/etc/X11/%T/%N%S:/var/tmp/jhbuild/share/X11/%L/%T/%N%C%S:/var/tmp/jhbuild/share/X11/%l/%T/%N%C%S:/var/tmp/jhbuild/share/X11/%T/%N%C%S:/var/tmp/jhbuild/share/X11/%L/%T/%N%S:/var/tmp/jhbuild/share/X11/%l/%T/%N%S:/var/tmp/jhbuild/share/X11/%T/%N%S:/var/tmp/jhbuild/lib64/X11/%L/%T/%N%C%S:/var/tmp/jhbuild/lib64/X11/%l/%T/%N%C%S:/var/tmp/jhbuild/lib64/X11/%T/%N%C%S:/var/tmp/jhbuild/lib64/X11/%L/%T/%N%S:/var/tmp/jhbuild/lib64/X11/%l/%T/%N%S:/var/tmp/jhbuild/lib64/X11/%T/%N%S"; | ||||
1344 | #endif | ||||
1345 | } | ||||
1346 | |||||
1347 | |||||
1348 | static SubstitutionRec defaultSubs[] = { | ||||
1349 | {'N', NULL((void*)0)}, | ||||
1350 | {'T', NULL((void*)0)}, | ||||
1351 | {'S', NULL((void*)0)}, | ||||
1352 | {'C', NULL((void*)0)}, | ||||
1353 | {'L', NULL((void*)0)}, | ||||
1354 | {'l', NULL((void*)0)}, | ||||
1355 | {'t', NULL((void*)0)}, | ||||
1356 | {'c', NULL((void*)0)} | ||||
1357 | }; | ||||
1358 | |||||
1359 | |||||
1360 | String XtResolvePathname( | ||||
1361 | Display *dpy, | ||||
1362 | _Xconstconst char* type, | ||||
1363 | _Xconstconst char* filename, | ||||
1364 | _Xconstconst char* suffix, | ||||
1365 | _Xconstconst char* path, | ||||
1366 | Substitution substitutions, | ||||
1367 | Cardinal num_substitutions, | ||||
1368 | XtFilePredicate predicate) | ||||
1369 | { | ||||
1370 | XtPerDisplay pd; | ||||
1371 | static const char *defaultPath = NULL((void*)0); | ||||
1372 | const char *impl_default = implementation_default_path(); | ||||
1373 | int idef_len = strlen(impl_default); | ||||
1374 | char *massagedPath; | ||||
1375 | int bytesAllocd, bytesLeft; | ||||
1376 | char *ch, *result; | ||||
1377 | Substitution merged_substitutions; | ||||
1378 | XrmRepresentation db_type; | ||||
1379 | XrmValue value; | ||||
1380 | XrmName name_list[3]; | ||||
1381 | XrmClass class_list[3]; | ||||
1382 | Boolean pathMallocd = False0; | ||||
1383 | |||||
1384 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | ||||
1385 | pd = _XtGetPerDisplay(dpy); | ||||
1386 | if (path == NULL((void*)0)) { | ||||
1387 | #ifndef VMS | ||||
1388 | if (defaultPath == NULL((void*)0)) { | ||||
1389 | defaultPath = getenv("XFILESEARCHPATH"); | ||||
1390 | if (defaultPath == NULL((void*)0)) | ||||
1391 | defaultPath = impl_default; | ||||
1392 | } | ||||
1393 | path = defaultPath; | ||||
1394 | #endif /* VMS */ | ||||
1395 | } | ||||
1396 | |||||
1397 | if (path == NULL((void*)0)) | ||||
1398 | path = ""; /* NULL would kill us later */ | ||||
1399 | |||||
1400 | if (filename == NULL((void*)0)) { | ||||
1401 | filename = XrmClassToString(pd->class)XrmQuarkToString(pd->class); | ||||
1402 | } | ||||
1403 | |||||
1404 | bytesAllocd = bytesLeft = 1000; | ||||
1405 | massagedPath = ALLOCATE_LOCAL(bytesAllocd)__builtin_alloca ((int)(bytesAllocd)); | ||||
1406 | if (massagedPath == NULL((void*)0)) _XtAllocError(NULL((void*)0)); | ||||
1407 | |||||
1408 | if (path[0] == ':') { | ||||
1409 | strcpy(massagedPath, "%N%S"); | ||||
1410 | ch = &massagedPath[4]; | ||||
1411 | bytesLeft -= 4; | ||||
1412 | } else ch = massagedPath; | ||||
1413 | |||||
1414 | /* Insert %N%S between adjacent colons | ||||
1415 | * and default path for %D. | ||||
1416 | * Default path should not have any adjacent colons of its own. | ||||
1417 | */ | ||||
1418 | |||||
1419 | while (*path != '\0') { | ||||
1420 | if (bytesLeft < idef_len) { | ||||
1421 | int bytesUsed = bytesAllocd - bytesLeft; | ||||
1422 | char *new; | ||||
1423 | bytesAllocd +=1000; | ||||
1424 | new = __XtMalloc((Cardinal) bytesAllocd); | ||||
1425 | strncpy( new, massagedPath, bytesUsed ); | ||||
1426 | ch = new + bytesUsed; | ||||
1427 | if (pathMallocd) | ||||
1428 | XtFree(massagedPath); | ||||
1429 | else | ||||
1430 | DEALLOCATE_LOCAL(massagedPath)do {} while(0); | ||||
1431 | pathMallocd = True1; | ||||
1432 | massagedPath = new; | ||||
1433 | bytesLeft = bytesAllocd - bytesUsed; | ||||
1434 | } | ||||
1435 | if (*path == '%' && *(path+1) == ':') { | ||||
1436 | *ch++ = '%'; | ||||
1437 | *ch++ = ':'; | ||||
1438 | path += 2; | ||||
1439 | bytesLeft -= 2; | ||||
1440 | continue; | ||||
1441 | } | ||||
1442 | if (*path == ':' && *(path+1) == ':') { | ||||
1443 | strcpy(ch, ":%N%S:"); | ||||
1444 | ch += 6; | ||||
1445 | bytesLeft -= 6; | ||||
1446 | while (*path == ':') path++; | ||||
1447 | continue; | ||||
1448 | } | ||||
1449 | if (*path == '%' && *(path+1) == 'D') { | ||||
1450 | strcpy(ch, impl_default); | ||||
1451 | ch += idef_len; | ||||
1452 | bytesLeft -= idef_len; | ||||
1453 | path += 2; | ||||
1454 | continue; | ||||
1455 | } | ||||
1456 | *ch++ = *path++; | ||||
1457 | bytesLeft--; | ||||
1458 | } | ||||
1459 | *ch = '\0'; | ||||
1460 | #ifdef XNL_DEBUG | ||||
1461 | printf("Massaged path: %s\n", massagedPath); | ||||
1462 | #endif /* XNL_DEBUG */ | ||||
1463 | |||||
1464 | if (num_substitutions == 0) | ||||
1465 | merged_substitutions = defaultSubs; | ||||
1466 | else { | ||||
1467 | int i = XtNumber(defaultSubs)((Cardinal) (sizeof(defaultSubs) / sizeof(defaultSubs[0]))); | ||||
1468 | Substitution sub, def; | ||||
1469 | merged_substitutions = sub = (Substitution) | ||||
1470 | ALLOCATE_LOCAL((unsigned)(num_substitutions+i)*sizeof(SubstitutionRec))__builtin_alloca ((int)((unsigned)(num_substitutions+i)*sizeof (SubstitutionRec))); | ||||
1471 | if (sub == NULL((void*)0)) _XtAllocError(NULL((void*)0)); | ||||
1472 | for (def = defaultSubs; i--; sub++, def++) sub->match = def->match; | ||||
1473 | for (i = num_substitutions; i--; ) *sub++ = *substitutions++; | ||||
1474 | } | ||||
1475 | merged_substitutions[0].substitution = (String)filename; | ||||
1476 | merged_substitutions[1].substitution = (String)type; | ||||
1477 | merged_substitutions[2].substitution = (String)suffix; | ||||
1478 | name_list[0] = pd->name; | ||||
1479 | name_list[1] = XrmPermStringToQuark("customization"); | ||||
1480 | name_list[2] = NULLQUARK((XrmQuark) 0); | ||||
1481 | class_list[0] = pd->class; | ||||
1482 | class_list[1] = XrmPermStringToQuark("Customization"); | ||||
1483 | class_list[2] = NULLQUARK((XrmQuark) 0); | ||||
1484 | if (XrmQGetResource(XrmGetDatabase(dpy), name_list, class_list, | ||||
1485 | &db_type, &value) && | ||||
1486 | db_type == _XtQString) | ||||
1487 | merged_substitutions[3].substitution = (char *)value.addr; | ||||
1488 | else | ||||
1489 | merged_substitutions[3].substitution = NULL((void*)0); | ||||
1490 | FillInLangSubs(&merged_substitutions[4], pd); | ||||
1491 | |||||
1492 | result = XtFindFile(massagedPath, merged_substitutions, | ||||
1493 | num_substitutions + XtNumber(defaultSubs)((Cardinal) (sizeof(defaultSubs) / sizeof(defaultSubs[0]))), | ||||
1494 | predicate); | ||||
1495 | |||||
1496 | if (merged_substitutions[5].substitution != NULL((void*)0)) | ||||
1497 | XtFree( (XtPointer)merged_substitutions[5].substitution ); | ||||
1498 | |||||
1499 | if (merged_substitutions != defaultSubs) | ||||
1500 | DEALLOCATE_LOCAL(merged_substitutions)do {} while(0); | ||||
1501 | |||||
1502 | if (pathMallocd) | ||||
1503 | XtFree(massagedPath); | ||||
1504 | else | ||||
1505 | DEALLOCATE_LOCAL(massagedPath)do {} while(0); | ||||
1506 | |||||
1507 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | ||||
1508 | return result; | ||||
1509 | } | ||||
1510 | |||||
1511 | |||||
1512 | Boolean XtCallAcceptFocus( | ||||
1513 | Widget widget, | ||||
1514 | Time *time) | ||||
1515 | { | ||||
1516 | XtAcceptFocusProc ac; | ||||
1517 | Boolean retval; | ||||
1518 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); | ||||
1519 | |||||
1520 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | ||||
1521 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | ||||
1522 | ac = XtClass(widget)->core_class.accept_focus; | ||||
1523 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | ||||
1524 | |||||
1525 | if (ac != NULL((void*)0)) | ||||
1526 | retval = (*ac) (widget, time); | ||||
1527 | else | ||||
1528 | retval = FALSE0; | ||||
1529 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | ||||
1530 | return retval; | ||||
1531 | } | ||||
1532 | |||||
1533 | #ifdef XT_GEO_TATTLER | ||||
1534 | /************************************************************************** | ||||
1535 | GeoTattler: This is used to debug Geometry management in Xt. | ||||
1536 | |||||
1537 | It uses a pseudo resource XtNgeotattler. | ||||
1538 | |||||
1539 | E.G. if those lines are found in the resource database: | ||||
1540 | |||||
1541 | myapp*draw.XmScale.geoTattler: ON | ||||
1542 | *XmScrollBar.geoTattler:ON | ||||
1543 | *XmRowColumn.exit_button.geoTattler:ON | ||||
1544 | |||||
1545 | then: | ||||
1546 | |||||
1547 | all the XmScale children of the widget named draw, | ||||
1548 | all the XmScrollBars, | ||||
1549 | the widget named exit_button in any XmRowColumn | ||||
1550 | |||||
1551 | will return True to the function IsTattled(), and will generate | ||||
1552 | outlined trace to stdout. | ||||
1553 | |||||
1554 | *************************************************************************/ | ||||
1555 | |||||
1556 | #define XtNgeoTattler "geoTattler" | ||||
1557 | #define XtCGeoTattler "GeoTattler" | ||||
1558 | |||||
1559 | typedef struct { Boolean geo_tattler ;} GeoDataRec ; | ||||
1560 | |||||
1561 | static XtResource geo_resources[] = { | ||||
1562 | { XtNgeoTattler, XtCGeoTattler, XtRBoolean((char*)&XtStrings[1561]), sizeof(Boolean), | ||||
1563 | XtOffsetOf(GeoDataRec, geo_tattler)__builtin_offsetof(GeoDataRec, geo_tattler), | ||||
1564 | XtRImmediate((char*)&XtStrings[1695]), (XtPointer) False0 } | ||||
1565 | }; | ||||
1566 | |||||
1567 | /************************************************************************ | ||||
1568 | This function uses XtGetSubresources to find out if a widget | ||||
1569 | needs to be geo-spied by the caller. */ | ||||
1570 | static Boolean IsTattled (Widget widget) | ||||
1571 | { | ||||
1572 | GeoDataRec geo_data ; | ||||
1573 | |||||
1574 | XtGetSubresources(widget, (XtPointer)&geo_data, | ||||
1575 | (String)NULL((void*)0), (String)NULL((void*)0), | ||||
1576 | geo_resources, XtNumber(geo_resources)((Cardinal) (sizeof(geo_resources) / sizeof(geo_resources[0]) )), | ||||
1577 | NULL((void*)0), 0); | ||||
1578 | |||||
1579 | return geo_data.geo_tattler; | ||||
1580 | |||||
1581 | } /* IsTattled */ | ||||
1582 | |||||
1583 | static int n_tab = 0 ; /* not MT for now */ | ||||
1584 | |||||
1585 | void | ||||
1586 | _XtGeoTab (int direction) /* +1 or -1 */ | ||||
1587 | { | ||||
1588 | n_tab += direction ; | ||||
1589 | } | ||||
1590 | |||||
1591 | |||||
1592 | void | ||||
1593 | _XtGeoTrace (Widget widget, ...) | ||||
1594 | { | ||||
1595 | va_list args; | ||||
1596 | char *fmt; | ||||
1597 | int i ; | ||||
1598 | if (IsTattled(widget)) { | ||||
1599 | va_start(args, widget)__builtin_va_start(args, widget); | ||||
1600 | fmt = va_arg(args, char *)__builtin_va_arg(args, char *); | ||||
1601 | for (i=0; i<n_tab; i++) printf(" "); | ||||
1602 | (void) vprintf(fmt, args); | ||||
1603 | va_end(args)__builtin_va_end(args); | ||||
1604 | } | ||||
1605 | } | ||||
1606 | |||||
1607 | #endif /* XT_GEO_TATTLER */ | ||||
1608 |