00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <stdio.h>
00038 #include <stdlib.h>
00039 #include <X11/Xos.h>
00040 #include <X11/IntrinsicP.h>
00041 #include <X11/Xmu/CharSet.h>
00042 #include <X11/Xmu/WidgetNode.h>
00043
00044
00045
00046
00047 static char *binsearch(char*, char*, int, int,
00048 int (*__compar)(_Xconst void*, _Xconst void*));
00049 static int compare_resource_entries(_Xconst void *a, _Xconst void *b);
00050 static XmuWidgetNode *find_resource(XmuWidgetNode*, char*, Bool);
00051 static void mark_resource_owner(XmuWidgetNode*);
00052
00053
00054
00055 static char *
00056 binsearch(char *key, char *base, int nelems, int elemsize,
00057 int compar(_Xconst void*, _Xconst void*))
00058
00059
00060
00061
00062
00063
00064
00065 {
00066 int lower = 0, upper = nelems - 1;
00067
00068 while (lower <= upper) {
00069 int middle = (lower + upper) / 2;
00070 char *p = base + middle * elemsize;
00071 int res = (*compar) (p, key);
00072
00073 if (res < 0) {
00074 lower = middle + 1;
00075 } else if (res == 0) {
00076 return p;
00077 } else {
00078 upper = middle - 1;
00079 }
00080 }
00081
00082 return NULL;
00083 }
00084
00085
00086 static int
00087 compare_resource_entries(register _Xconst void *a,
00088 register _Xconst void *b)
00089 {
00090 return strcmp (((XtResourceList)a)->resource_name,
00091 ((XtResourceList)b)->resource_name);
00092 }
00093
00094
00095 static XmuWidgetNode *
00096 find_resource(XmuWidgetNode *node, char *name, Bool cons)
00097 {
00098 register XmuWidgetNode *sup;
00099 XtResource res;
00100
00101 #define reslist ((char *) (cons ? sup->constraints : sup->resources))
00102 #define nreslist (int) (cons ? sup->nconstraints : sup->nresources)
00103
00104 res.resource_name = name;
00105 for (sup = node->superclass;
00106 sup && (XtResourceList) binsearch ((char *) &res,
00107 reslist, nreslist,
00108 sizeof(XtResource),
00109 compare_resource_entries);
00110 node = sup, sup = sup->superclass) ;
00111
00112 #undef reslist
00113 #undef nreslist
00114
00115 return node;
00116 }
00117
00118
00119 static void
00120 mark_resource_owner(register XmuWidgetNode *node)
00121 {
00122 register Cardinal i;
00123 XtResourceList childres;
00124
00125 childres = node->resources;
00126 for (i = 0; i < node->nresources; i++, childres++) {
00127 node->resourcewn[i] = find_resource (node, childres->resource_name,
00128 False);
00129 }
00130
00131 childres = node->constraints;
00132 for (i = 0; i < node->nconstraints; i++, childres++) {
00133 node->constraintwn[i] = find_resource (node, childres->resource_name,
00134 True);
00135 }
00136 }
00137
00138
00139
00140
00141
00142
00143 void
00144 XmuWnInitializeNodes(XmuWidgetNode *nodearray, int nnodes)
00145 {
00146 int i;
00147 XmuWidgetNode *wn;
00148
00149
00150
00151
00152
00153 for (i = nnodes - 1, wn = nodearray + (nnodes - 1); i >= 0; i--, wn--) {
00154 WidgetClass superclass = XmuWnSuperclass(wn);
00155 int j;
00156 XmuWidgetNode *swn;
00157 int lablen = strlen (wn->label);
00158 int namelen = strlen (XmuWnClassname(wn));
00159
00160 wn->lowered_label = XtMalloc (lablen + namelen + 2);
00161 #if 0
00162
00163 if (!wn->lowered_label) {
00164 fprintf (stderr,
00165 "%s: unable to allocate %d bytes for widget name\n",
00166 "XmuWnInitializeNodes", lablen + namelen + 2);
00167 exit (1);
00168 }
00169 #endif
00170 wn->lowered_classname = wn->lowered_label + (lablen + 1);
00171 XmuCopyISOLatin1Lowered (wn->lowered_label, wn->label);
00172 XmuCopyISOLatin1Lowered (wn->lowered_classname, XmuWnClassname(wn));
00173 wn->superclass = NULL;
00174 wn->have_resources = False;
00175 wn->resources = NULL;
00176 wn->resourcewn = NULL;
00177 wn->nresources = 0;
00178 wn->constraints = NULL;
00179 wn->constraintwn = NULL;
00180 wn->nconstraints = 0;
00181 wn->data = (XtPointer) NULL;
00182
00183
00184
00185
00186 while (superclass) {
00187 for (j = 0, swn = nodearray; j < nnodes; j++, swn++) {
00188 if (superclass == XmuWnClass(swn)) {
00189 wn->superclass = swn;
00190 goto done;
00191 }
00192 }
00193
00194
00195
00196
00197 superclass = superclass->core_class.superclass;
00198 }
00199 done:
00200 if (wn->superclass) {
00201 wn->siblings = wn->superclass->children;
00202 wn->superclass->children = wn;
00203 }
00204 }
00205
00206 return;
00207 }
00208
00209
00210 void
00211 XmuWnFetchResources(XmuWidgetNode *node, Widget toplevel,
00212 XmuWidgetNode *topnode)
00213 {
00214 Widget dummy;
00215 XmuWidgetNode *wn;
00216
00217 if (node->have_resources) return;
00218
00219 dummy = XtCreateWidget (node->label, XmuWnClass(node), toplevel,
00220 NULL, 0);
00221 if (dummy) XtDestroyWidget (dummy);
00222
00223
00224
00225
00226
00227
00228 for (wn = node; wn && !wn->have_resources; wn = wn->superclass) {
00229 XtGetResourceList (XmuWnClass(wn), &wn->resources, &wn->nresources);
00230 if (wn->resources) {
00231 qsort ((char *) wn->resources, wn->nresources,
00232 sizeof(XtResource), compare_resource_entries);
00233 }
00234 wn->resourcewn = (XmuWidgetNode **) XtCalloc (wn->nresources,
00235 sizeof (XmuWidgetNode *));
00236 if (!wn->resourcewn) {
00237 fprintf (stderr,
00238 "%s: unable to calloc %d %ld byte widget node ptrs\n",
00239 "XmuWnFetchResources", wn->nresources,
00240 (unsigned long)sizeof (XmuWidgetNode *));
00241 exit (1);
00242 }
00243
00244 XtGetConstraintResourceList (XmuWnClass(wn), &wn->constraints,
00245 &wn->nconstraints);
00246 if (wn->constraints) {
00247 qsort ((char *) wn->constraints, wn->nconstraints,
00248 sizeof(XtResource), compare_resource_entries);
00249 }
00250 wn->constraintwn = (XmuWidgetNode **)
00251 XtCalloc (wn->nconstraints, sizeof (XmuWidgetNode *));
00252 if (!wn->constraintwn) {
00253 fprintf (stderr,
00254 "%s: unable to calloc %d %ld byte widget node ptrs\n",
00255 "XmuWnFetchResources", wn->nconstraints,
00256 (unsigned long)sizeof (XmuWidgetNode *));
00257 exit (1);
00258 }
00259
00260 wn->have_resources = True;
00261 if (wn == topnode) break;
00262 }
00263
00264
00265
00266
00267
00268
00269 for (wn = node; wn; wn = wn->superclass) {
00270 mark_resource_owner (wn);
00271 if (wn == topnode) break;
00272 }
00273
00274 return;
00275 }
00276
00277
00278 int
00279 XmuWnCountOwnedResources(XmuWidgetNode *node, XmuWidgetNode *ownernode,
00280 Bool cons)
00281 {
00282 register int i;
00283 XmuWidgetNode **wn = (cons ? node->constraintwn : node->resourcewn);
00284 int nmatches = 0;
00285
00286 for (i = (cons ? node->nconstraints : node->nresources); i > 0; i--, wn++)
00287 if (*wn == ownernode) nmatches++;
00288 return nmatches;
00289 }
00290
00291
00292 XmuWidgetNode *
00293 XmuWnNameToNode(XmuWidgetNode *nodelist, int nnodes, _Xconst char *name)
00294 {
00295 int i;
00296 XmuWidgetNode *wn;
00297 char tmp[1024];
00298
00299 XmuNCopyISOLatin1Lowered(tmp, name, sizeof(tmp));
00300 for (i = 0, wn = nodelist; i < nnodes; i++, wn++) {
00301 if (strcmp (tmp, wn->lowered_label) == 0 ||
00302 strcmp (tmp, wn->lowered_classname) == 0) {
00303 return wn;
00304 }
00305 }
00306 return NULL;
00307 }