Bug Summary

File:Intrinsic.c
Location:line 99, 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
85#include <stdlib.h>
86
87String XtCXtToolkitError = "XtToolkitError";
88
89Boolean 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)();
1
Within the expansion of the macro 'LOCK_PROCESS':
a
Assuming '_XtProcessLock' is null
99 for (w = widget->core.widget_class; w != NULL((void*)0); w = w->core_class.superclass)
2
Dereference of null pointer
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
110Boolean _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
126Boolean _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
151XtPointer 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
172static 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
207static 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
244static 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
263static 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
285static 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
382void 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
398static 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
443void 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
475void 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
510static Widget NameListToWidget(
511 Widget root,
512 XrmNameList names,
513 XrmBindingList bindings,
514 int in_depth, int *out_depth, int *found_depth);
515
516typedef Widget (*NameMatchProc)(XrmNameList,
517 XrmBindingList,
518 WidgetList, Cardinal, int, int *, int *);
519
520static 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
543static 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
563static 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
585static 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
623Widget 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
661Display *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
671Display *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
679Screen *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
689Screen *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
697Window 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
705Window XtWindow(
706 Widget widget)
707{
708 return widget->core.window;
709}
710
711#undef XtSuperclass
712WidgetClass 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
724WidgetClass 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
736Boolean 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
752Boolean 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
765Boolean 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 */
783Widget _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 &params, &num_params);
796 }
797
798 return object;
799}
800
801#undef XtParent
802Widget 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
810String 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
818Boolean 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)
849static 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
868static 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
944static 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
977static 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
1065String 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
1148static 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
1261static 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 */
1324static 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/lib/X11/%L/%T/%N%C%S:/var/tmp/jhbuild/lib/X11/%l/%T/%N%C%S:/var/tmp/jhbuild/lib/X11/%T/%N%C%S:/var/tmp/jhbuild/lib/X11/%L/%T/%N%S:/var/tmp/jhbuild/lib/X11/%l/%T/%N%S:/var/tmp/jhbuild/lib/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/lib/X11/%L/%T/%N%C%S:/var/tmp/jhbuild/lib/X11/%l/%T/%N%C%S:/var/tmp/jhbuild/lib/X11/%T/%N%C%S:/var/tmp/jhbuild/lib/X11/%L/%T/%N%S:/var/tmp/jhbuild/lib/X11/%l/%T/%N%S:/var/tmp/jhbuild/lib/X11/%T/%N%S";
1344#endif
1345}
1346
1347
1348static 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
1360String 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
1512Boolean 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
1559typedef struct { Boolean geo_tattler ;} GeoDataRec ;
1560
1561static 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. */
1570static 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
1583static int n_tab = 0 ; /* not MT for now */
1584
1585void
1586_XtGeoTab (int direction) /* +1 or -1 */
1587{
1588 n_tab += direction ;
1589}
1590
1591
1592void
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