3 Copyright 1989, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
28 * Author: Jim Fulton, MIT X Consortium
39 #include <X11/IntrinsicP.h>
40 #include <X11/Xmu/CharSet.h>
41 #include <X11/Xmu/WidgetNode.h>
46 static char *binsearch(char*, char*, int, int,
47 int (*__compar)(_Xconst void*, _Xconst void*));
48 static int compare_resource_entries(_Xconst void *a, _Xconst void *b);
49 static XmuWidgetNode *find_resource(XmuWidgetNode*, char*, Bool);
50 static void mark_resource_owner(XmuWidgetNode*);
55 binsearch(char *key, char *base, int nelems, int elemsize,
56 int compar(_Xconst void*, _Xconst void*))
58 * key - template of object to find
59 * base - beginning of array
60 * nelems - number of elements in array
61 * elemsize - sizeof an element
62 * compar - qsort-style compare function
65 int lower = 0, upper = nelems - 1;
67 while (lower <= upper) {
68 int middle = (lower + upper) / 2;
69 char *p = base + middle * elemsize;
70 int res = (*compar) (p, key);
74 } else if (res == 0) {
86 compare_resource_entries(register _Xconst void *a,
87 register _Xconst void *b)
89 return strcmp (((_Xconst XtResource *)a)->resource_name,
90 ((_Xconst XtResource *)b)->resource_name);
94 static XmuWidgetNode *
95 find_resource(XmuWidgetNode *node, char *name, Bool cons)
97 register XmuWidgetNode *sup;
100 #define reslist ((char *) (cons ? sup->constraints : sup->resources))
101 #define nreslist (int) (cons ? sup->nconstraints : sup->nresources)
103 res.resource_name = name;
104 for (sup = node->superclass;
105 sup && (XtResourceList) binsearch ((char *) &res,
108 compare_resource_entries);
109 node = sup, sup = sup->superclass) ;
119 mark_resource_owner(register XmuWidgetNode *node)
122 XtResourceList childres;
124 childres = node->resources;
125 for (i = 0; i < node->nresources; i++, childres++) {
126 node->resourcewn[i] = find_resource (node, childres->resource_name,
130 childres = node->constraints;
131 for (i = 0; i < node->nconstraints; i++, childres++) {
132 node->constraintwn[i] = find_resource (node, childres->resource_name,
143 XmuWnInitializeNodes(XmuWidgetNode *nodearray, int nnodes)
149 * Assume that the node array is in alphabetic order, so we need to
150 * search backwards to make sure that the children are listed forward.
152 for (i = nnodes - 1, wn = nodearray + (nnodes - 1); i >= 0; i--, wn--) {
153 WidgetClass superclass = XmuWnSuperclass(wn);
156 int lablen = strlen (wn->label);
157 int namelen = strlen (XmuWnClassname(wn));
159 wn->lowered_label = XtMalloc (lablen + namelen + 2);
161 /* XtMalloc exits if failed */
162 if (!wn->lowered_label) {
164 "%s: unable to allocate %d bytes for widget name\n",
165 "XmuWnInitializeNodes", lablen + namelen + 2);
169 wn->lowered_classname = wn->lowered_label + (lablen + 1);
170 XmuCopyISOLatin1Lowered (wn->lowered_label, wn->label);
171 XmuCopyISOLatin1Lowered (wn->lowered_classname, XmuWnClassname(wn));
172 wn->superclass = NULL;
173 wn->have_resources = False;
174 wn->resources = NULL;
175 wn->resourcewn = NULL;
177 wn->constraints = NULL;
178 wn->constraintwn = NULL;
179 wn->nconstraints = 0;
180 wn->data = (XtPointer) NULL;
183 * walk up the superclass chain
186 for (j = 0, swn = nodearray; j < nnodes; j++, swn++) {
187 if (superclass == XmuWnClass(swn)) {
188 wn->superclass = swn;
189 goto done; /* stupid C language */
193 * Hmm, we have a hidden superclass (such as in core in R4); just
194 * ignore it and keep on walking
196 superclass = superclass->core_class.superclass;
199 if (wn->superclass) {
200 wn->siblings = wn->superclass->children;
201 wn->superclass->children = wn;
210 XmuWnFetchResources(XmuWidgetNode *node, Widget toplevel,
211 XmuWidgetNode *topnode)
216 if (node->have_resources) return;
218 dummy = XtCreateWidget (node->label, XmuWnClass(node), toplevel,
220 if (dummy) XtDestroyWidget (dummy);
224 * walk up tree geting resources; since we've instantiated the widget,
225 * we know that all of our superclasses have been initialized
227 for (wn = node; wn && !wn->have_resources; wn = wn->superclass) {
228 XtGetResourceList (XmuWnClass(wn), &wn->resources, &wn->nresources);
230 qsort ((char *) wn->resources, wn->nresources,
231 sizeof(XtResource), compare_resource_entries);
233 wn->resourcewn = (XmuWidgetNode **) XtCalloc (wn->nresources,
234 sizeof (XmuWidgetNode *));
235 if (!wn->resourcewn) {
237 "%s: unable to calloc %d %ld byte widget node ptrs\n",
238 "XmuWnFetchResources", wn->nresources,
239 (unsigned long)sizeof (XmuWidgetNode *));
243 XtGetConstraintResourceList (XmuWnClass(wn), &wn->constraints,
245 if (wn->constraints) {
246 qsort ((char *) wn->constraints, wn->nconstraints,
247 sizeof(XtResource), compare_resource_entries);
249 wn->constraintwn = (XmuWidgetNode **)
250 XtCalloc (wn->nconstraints, sizeof (XmuWidgetNode *));
251 if (!wn->constraintwn) {
253 "%s: unable to calloc %d %ld byte widget node ptrs\n",
254 "XmuWnFetchResources", wn->nconstraints,
255 (unsigned long)sizeof (XmuWidgetNode *));
259 wn->have_resources = True;
260 if (wn == topnode) break;
265 * Walk up tree removing all resources that appear in superclass; we can
266 * mash the resource list in place since it was copied out of widget.
268 for (wn = node; wn; wn = wn->superclass) {
269 mark_resource_owner (wn);
270 if (wn == topnode) break;
278 XmuWnCountOwnedResources(XmuWidgetNode *node, XmuWidgetNode *ownernode,
282 XmuWidgetNode **wn = (cons ? node->constraintwn : node->resourcewn);
285 for (i = (cons ? node->nconstraints : node->nresources); i > 0; i--, wn++)
286 if (*wn == ownernode) nmatches++;
292 XmuWnNameToNode(XmuWidgetNode *nodelist, int nnodes, _Xconst char *name)
298 XmuNCopyISOLatin1Lowered(tmp, name, sizeof(tmp));
299 for (i = 0, wn = nodelist; i < nnodes; i++, wn++) {
300 if (strcmp (tmp, wn->lowered_label) == 0 ||
301 strcmp (tmp, wn->lowered_classname) == 0) {