WidgetNode.c

Go to the documentation of this file.
00001 /* $Xorg: WidgetNode.c,v 1.5 2001/02/09 02:03:53 xorgcvs Exp $ */
00002 
00003 /*
00004  
00005 Copyright 1989, 1998  The Open Group
00006 
00007 Permission to use, copy, modify, distribute, and sell this software and its
00008 documentation for any purpose is hereby granted without fee, provided that
00009 the above copyright notice appear in all copies and that both that
00010 copyright notice and this permission notice appear in supporting
00011 documentation.
00012 
00013 The above copyright notice and this permission notice shall be included in
00014 all copies or substantial portions of the Software.
00015 
00016 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
00019 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00020 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00021 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00022 
00023 Except as contained in this notice, the name of The Open Group shall not be
00024 used in advertising or otherwise to promote the sale, use or other dealings
00025 in this Software without prior written authorization from The Open Group.
00026 
00027 */
00028 
00029 /* $XFree86: xc/lib/Xmu/WidgetNode.c,v 1.12 2002/09/19 13:21:58 tsi Exp $ */
00030 
00031 /*
00032  * Author:  Jim Fulton, MIT X Consortium
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  * Prototypes
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  * Implementation
00054  */
00055 static char *
00056 binsearch(char *key, char *base, int nelems, int elemsize,
00057           int compar(_Xconst void*, _Xconst void*))
00058      /*
00059       * key             - template of object to find
00060       * base            - beginning of array
00061       * nelems          - number of elements in array
00062       * elemsize        - sizeof an element
00063       * compar          - qsort-style compare function
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  *                             Public Interfaces
00141  */
00142 
00143 void
00144 XmuWnInitializeNodes(XmuWidgetNode *nodearray, int nnodes)
00145 {
00146     int i;
00147     XmuWidgetNode *wn;
00148 
00149     /*
00150      * Assume that the node array is in alphabetic order, so we need to
00151      * search backwards to make sure that the children are listed forward.
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         /* XtMalloc exits if failed */
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          * walk up the superclass chain
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;          /* stupid C language */
00191                 }
00192             }
00193             /*
00194              * Hmm, we have a hidden superclass (such as in core in R4); just
00195              * ignore it and keep on walking
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      * walk up tree geting resources; since we've instantiated the widget,
00226      * we know that all of our superclasses have been initialized
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      * Walk up tree removing all resources that appear in superclass; we can
00267      * mash the resource list in place since it was copied out of widget.
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 }

Generated on Sun Mar 4 15:03:56 2007 for Scilab [trunk] by  doxygen 1.5.1