2
* Motif Tools Library, Version 3.1
5
* Written by David Flanagan.
6
* Copyright (c) 1992-2001 by David Flanagan.
7
* All Rights Reserved. See the file COPYRIGHT for details.
8
* This is open source software. See the file LICENSE for details.
9
* There is no warranty for this software. See NO_WARRANTY for details.
12
* Revision 1.1.1.1 2001/07/18 11:06:02 root
15
* Revision 1.2 2001/06/12 16:25:28 andre
16
* *** empty log message ***
22
* Portions of this file are derived from the Xt source code.
23
* See the file COPYRIGHT for the MIT and Digital copyrights.
28
#include <Xmt/AppRes.h>
29
#include <X11/IntrinsicP.h>
31
static XrmQuark selfq = NULLQUARK;
32
static XrmQuark questionq = NULLQUARK;
34
#if NeedFunctionPrototypes
35
static Widget GetParent(Widget w)
37
static Widget GetParent(w)
41
if (w == NULL) return NULL;
42
if (XtParent(w) != NULL) return XtParent(w);
46
#if NeedFunctionPrototypes
47
static Widget GetNamedAncestor(Widget ref, char *name)
49
static Widget GetNamedAncestor(ref, name)
56
XrmQuark q = XrmStringToQuark(name);
58
if (ref == NULL) return NULL;
60
/* see if the supplied name matches any ancestor's names */
61
for(w = XtParent(ref); w != NULL; w = XtParent(w))
62
if (w->core.xrm_name == q) return w;
65
* if not, start checking classes. Check the class name, and
66
* all the superclass names of each ancestor widget.
67
* This is done with WidgetClass, but should work for objects too.
69
for(w = XtParent(ref); w != NULL; w = XtParent(w))
70
for(c = XtClass(w); c != NULL; c = c->core_class.superclass)
71
if (c->core_class.xrm_class == q) return w;
73
/* if no name or class matches, return NULL */
77
#if NeedFunctionPrototypes
78
static Widget GetChild(Widget w, XrmName q)
80
static Widget GetChild(w, q)
85
CompositeWidget parent = (CompositeWidget) w;
89
* Check the names of all normal children.
90
* Check the names of all popup children.
91
* Check the class names of all normal children.
92
* Check the class names of all popup children.
93
* Note that we don't check superclass names.
96
if (w == NULL) return NULL;
98
/* normal children names */
99
if (XtIsComposite(w)) {
100
for(i = 0; i < parent->composite.num_children; i++)
101
if (parent->composite.children[i]->core.xrm_name == q)
102
return parent->composite.children[i];
105
/* popup children names */
106
for(i = 0; i < w->core.num_popups; i++)
107
if (w->core.popup_list[i]->core.xrm_name == q)
108
return w->core.popup_list[i];
110
/* normal children classes */
111
if (XtIsComposite(w)) {
112
for(i = 0; i < parent->composite.num_children; i++)
113
if (XtClass(parent->composite.children[i])->core_class.xrm_class
115
return parent->composite.children[i];
118
/* popup children classes */
119
for(i = 0; i < w->core.num_popups; i++)
120
if (XtClass(w->core.popup_list[i])->core_class.xrm_class == q)
121
return w->core.popup_list[i];
123
/* no child matches */
128
#if NeedFunctionPrototypes
129
static Widget ParseWidgetModifiers(Widget w, StringConst *name)
131
static Widget ParseWidgetModifiers(w, name)
136
if (*name == NULL || **name == '\0')
137
return w; /* no recursion */
138
else if (**name == '.') {
140
* ignore '.' if there are following modifiers, or
141
* return w if no modifiers follow it.
144
return ParseWidgetModifiers(w, name);
146
else if (**name == '~') {
148
return XmtGetShell(ParseWidgetModifiers(w, name));
150
else if (**name == '^') {
151
if (*(*name+1) != '{') {
153
return GetParent(ParseWidgetModifiers(w, name));
159
while (**name && **name != '}') {
160
ancestor[i++] = **name;
164
if (**name == '}') *name += 1;
165
return GetNamedAncestor(ParseWidgetModifiers(w, name),
169
else /* there are no more modifiers, so don't recurse */
175
* The following 5 procedures are code modified from the internals
176
* of the function XtNameToWidget. This code appears in the file
177
* Intrinsic.c in the MIT Xt distribution, with the following RCS info:
178
* $XConsortium: Intrinsic.c,v 1.171 91/07/16 18:30:20 converse Exp $
180
#if NeedFunctionPrototypes
181
static Widget NameListToWidget(register Widget root,
182
XrmNameList names, XrmBindingList bindings,
183
int num_quarks, int in_depth, int *out_depth,
186
static Widget NameListToWidget();
189
typedef Widget (*NameMatchProc)();
191
#if NeedFunctionPrototypes
192
static Widget MatchExactChildren(XrmNameList names, XrmBindingList bindings,
193
int num_quarks, register WidgetList children,
194
register int num, int in_depth,
195
int *out_depth, int *found_depth)
197
static Widget MatchExactChildren(names, bindings, num_quarks, children, num,
198
in_depth, out_depth, found_depth)
200
XrmBindingList bindings;
202
register WidgetList children;
210
register XrmName name = *names;
211
Widget w, result = NULL;
214
/* check the names of children. '?' always matches -- djf */
215
for (i = 0; i < num; i++) {
216
if ((name == children[i]->core.xrm_name) ||
217
(name == questionq)) /* djf */ {
218
w = NameListToWidget(children[i], &names[1], &bindings[1],
220
in_depth+1, &d, found_depth);
221
if (w != NULL && d < min) {result = w; min = d;}
229
#if NeedFunctionPrototypes
230
static Widget MatchExactClass(XrmNameList names, XrmBindingList bindings,
231
int num_quarks, register WidgetList children,
232
register int num, int in_depth, int *out_depth,
235
static Widget MatchExactClass(names, bindings, num_quarks, children, num,
236
in_depth, out_depth, found_depth)
238
XrmBindingList bindings;
240
register WidgetList children;
248
register XrmName name = *names;
249
Widget w, result = NULL;
252
/* like the above, but check classes -- djf */
253
for (i = 0; i < num; i++) {
254
if (name == XtClass(children[i])->core_class.xrm_class) {
255
w = NameListToWidget(children[i], &names[1], &bindings[1],
257
in_depth+1, &d, found_depth);
258
if (w != NULL && d < min) {result = w; min = d;}
267
#if NeedFunctionPrototypes
268
static Widget MatchWildChildren(XrmNameList names, XrmBindingList bindings,
269
int num_quarks, register WidgetList children,
270
register int num, int in_depth,
271
int *out_depth, int *found_depth)
273
static Widget MatchWildChildren(names, bindings, num_quarks, children, num,
274
in_depth, out_depth, found_depth)
276
XrmBindingList bindings;
278
register WidgetList children;
286
Widget w, result = NULL;
289
for (i = 0; i < num; i++) {
290
w = NameListToWidget(children[i], names, bindings, num_quarks,
291
in_depth+1, &d, found_depth);
292
if (w != NULL && d < min) {result = w; min = d;}
298
#if NeedFunctionPrototypes
299
static Widget SearchChildren(Widget root,
300
XrmNameList names, XrmBindingList bindings,
301
int num_quarks, NameMatchProc matchproc,
302
int in_depth, int *out_depth, int *found_depth)
304
static Widget SearchChildren(root, names, bindings, num_quarks, matchproc,
305
in_depth, out_depth, found_depth)
308
XrmBindingList bindings;
310
NameMatchProc matchproc;
319
if (XtIsComposite(root)) {
320
w1 = (*matchproc)(names, bindings, num_quarks,
321
((CompositeWidget) root)->composite.children,
322
((CompositeWidget) root)->composite.num_children,
323
in_depth, &d1, found_depth);
329
w2 = (*matchproc)(names, bindings, num_quarks, root->core.popup_list,
330
root->core.num_popups, in_depth, &d2, found_depth);
331
*out_depth = (d1 < d2 ? d1 : d2);
332
return (d1 < d2 ? w1 : w2);
335
#if NeedFunctionPrototypes
336
static Widget NameListToWidget(register Widget root,
337
XrmNameList names, XrmBindingList bindings,
338
int num_quarks, int in_depth,
339
int *out_depth, int *found_depth)
341
static Widget NameListToWidget(root, names, bindings, num_quarks, in_depth,
342
out_depth, found_depth)
343
register Widget root;
345
XrmBindingList bindings;
355
if (in_depth >= *found_depth) {
360
if (num_quarks == 0) {
361
*out_depth = *found_depth = in_depth;
365
if (! XtIsWidget(root)) {
370
if (*bindings == XrmBindTightly) {
371
w1 = SearchChildren(root, names, bindings, num_quarks,
373
in_depth, out_depth, found_depth);
374
/* if no names match, look for a class name that matches -- djf */
376
w1 = SearchChildren(root, names, bindings, num_quarks,
378
in_depth, out_depth, found_depth);
384
else { /* XrmBindLoosely */
385
w1 = SearchChildren(root, names, bindings, num_quarks,
387
in_depth, &d1, found_depth);
388
if (w1 == NULL) { /* if no names match exactly, check classes -- djf */
389
w1 = SearchChildren(root, names, bindings, num_quarks,
391
in_depth, &d1, found_depth);
393
w2 = SearchChildren(root, names, bindings, num_quarks,
395
in_depth, &d2, found_depth);
396
*out_depth = (d1 < d2 ? d1 : d2);
397
return (d1 < d2 ? w1 : w2);
400
return NULL; /* but return something anyway to keep gcc -Wall quiet */
401
} /* NameListToWidget */
404
/* modified X Consortium code ends here. */
406
#if NeedFunctionPrototypes
407
Widget XmtNameToWidget(Widget ref, StringConst name)
409
Widget XmtNameToWidget(ref, name)
415
Boolean modifiers = False;
416
XrmQuark quark_array[50];
417
XrmBinding binding_array[50];
419
XrmBindingList bindings;
425
/* initialize quarks used by lots of functions */
426
if (selfq == NULLQUARK) selfq = XrmStringToQuark("self");
427
if (questionq == NULLQUARK) questionq = XrmStringToQuark("?");
430
/* if the name begins with a modifier, go parse them */
431
if ((name[0] == '.') || (name[0] == '^') || (name[0] == '~')) {
433
ref = ParseWidgetModifiers(ref, &newname);
437
* if no name, or nothing following the modifiers,
438
* then just return the reference widget. This is
439
* so names like "^^" work.
441
if (!newname || !*newname) return ref;
443
/* quarkify the name and count the quarks */
444
quarks = quark_array;
445
bindings = binding_array;
446
XrmStringToBindingQuarkList(newname, bindings, quarks);
447
for(numquarks = 0; quarks[numquarks] != NULLQUARK; numquarks++);
450
/* if the name begins with '*', it is relative to the root. */
452
ref = XmtGetApplicationShell(ref);
455
* if first quark is 'self', skip it.
456
* if first quark is a sibling of ref, ref = parent
457
* otherwise if first quark doesn't name a child, maybe it
458
* names a root widget. If it doesn't name any known root,
461
if (quarks[0] == selfq) {
466
else if (GetChild(XtParent(ref), quarks[0]))
468
else if (!GetChild(ref, quarks[0])) {
469
ref = XmtLookupApplicationShell(quarks[0]);
470
if (!ref) return NULL;
478
w = NameListToWidget(ref, quarks, bindings, numquarks,