Bug Summary

File:src/Intrinsic.c
Location:line 102, column 14
Description:Dereference of null pointer

Annotated Source Code

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