home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / lib / Xmu / WidgetNode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-19  |  7.8 KB  |  291 lines

  1. /*
  2.  * $XConsortium: WidgetNode.c,v 1.4 90/12/19 18:16:32 converse Exp $
  3.  *
  4.  * Copyright 1989 Massachusetts Institute of Technology
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software and its
  7.  * documentation for any purpose and without fee is hereby granted, provided
  8.  * that the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of M.I.T. not be used in advertising
  11.  * or publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  M.I.T. makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * Author:  Jim Fulton, MIT X Consortium
  24.  */
  25.  
  26.  
  27.  
  28. #include <stdio.h>
  29. #include <X11/Xos.h>
  30. #include <X11/IntrinsicP.h>
  31. #include <X11/Xaw/Cardinals.h>
  32. #include <X11/Xmu/CharSet.h>
  33. #include <X11/Xmu/WidgetNode.h>
  34.  
  35.  
  36. static char *binsearch (key, base, nelems, elemsize, compar)
  37.     char *key;                /* template of object to find */
  38.     char *base;                /* beginning of array */
  39.     int nelems;                /* number of elements in array */
  40.     int elemsize;            /* sizeof an element */
  41.     int (*compar)();            /* qsort-style compare function */
  42. {
  43.     int lower = 0, upper = nelems - 1;
  44.  
  45.     while (lower <= upper) {
  46.     int middle = (lower + upper) / 2;
  47.     char *p = base + middle * elemsize;
  48.     int res = (*compar) (p, key);
  49.  
  50.     if (res < 0) {
  51.         lower = middle + 1;
  52.     } else if (res == 0) {
  53.         return p;
  54.     } else {
  55.         upper = middle - 1;
  56.     }
  57.     }
  58.  
  59.     return NULL;
  60. }
  61.  
  62.  
  63. static int compare_resource_entries (a, b)
  64.     register char *a, *b;
  65. {
  66.     return strcmp (((XtResourceList)a)->resource_name,
  67.            ((XtResourceList)b)->resource_name);
  68. }
  69.  
  70.  
  71. static XmuWidgetNode *find_resource (node, name, cons)
  72.     XmuWidgetNode *node;
  73.     char *name;
  74.     Bool cons;
  75. {
  76.     register XmuWidgetNode *sup;
  77.     XtResource res;
  78.  
  79. #define reslist ((char *) (cons ? sup->constraints : sup->resources))
  80. #define nreslist (int) (cons ? sup->nconstraints : sup->nresources)
  81.  
  82.     res.resource_name = name;
  83.     for (sup = node->superclass; 
  84.      sup && (XtResourceList) binsearch ((char *) &res,
  85.                         reslist, nreslist,
  86.                         sizeof(XtResource),
  87.                         compare_resource_entries);
  88.      node = sup, sup = sup->superclass) ;
  89.  
  90. #undef reslist
  91. #undef nreslist
  92.  
  93.     return node;
  94. }
  95.  
  96.  
  97. static void mark_resource_owner (node)
  98.     register XmuWidgetNode *node;
  99. {
  100.     register int i;
  101.     XtResourceList childres;
  102.  
  103.     childres = node->resources;
  104.     for (i = 0; i < node->nresources; i++, childres++) {
  105.     node->resourcewn[i] = find_resource (node, childres->resource_name,
  106.                          False);
  107.     }
  108.  
  109.     childres = node->constraints;
  110.     for (i = 0; i < node->nconstraints; i++, childres++) {
  111.     node->constraintwn[i] = find_resource (node, childres->resource_name,
  112.                         True);
  113.     }
  114. }
  115.  
  116.  
  117. /*
  118.  *                    Public Interfaces
  119.  */
  120.  
  121. void XmuWnInitializeNodes (nodearray, nnodes)
  122.     XmuWidgetNode *nodearray;
  123.     int nnodes;
  124. {
  125.     int i;
  126.     XmuWidgetNode *wn;
  127.  
  128.     /*
  129.      * Assume that the node array is in alphabetic order, so we need to
  130.      * search backwards to make sure that the children are listed forward.
  131.      */
  132.     for (i = nnodes - 1, wn = nodearray + (nnodes - 1); i >= 0; i--, wn--) {
  133.     WidgetClass superclass = XmuWnSuperclass(wn);
  134.     int j;
  135.     XmuWidgetNode *swn;
  136.     int lablen = strlen (wn->label);
  137.     int namelen = strlen (XmuWnClassname(wn));
  138.  
  139.     wn->lowered_label = XtMalloc (lablen + namelen + 2);
  140.     if (!wn->lowered_label) {
  141.         fprintf (stderr,
  142.              "%s:  unable to allocate %d bytes for widget name\n",
  143.              "XmuWnInitializeNodes");
  144.         exit (1);
  145.     }
  146.     wn->lowered_classname = wn->lowered_label + (lablen + 1);
  147.     XmuCopyISOLatin1Lowered (wn->lowered_label, wn->label);
  148.     XmuCopyISOLatin1Lowered (wn->lowered_classname, XmuWnClassname(wn));
  149.     wn->superclass = NULL;
  150.     wn->have_resources = False;
  151.     wn->resources = NULL;
  152.     wn->resourcewn = NULL;
  153.     wn->nresources = 0;
  154.     wn->constraints = NULL;
  155.     wn->constraintwn = NULL;
  156.     wn->nconstraints = 0;
  157.     wn->data = (XtPointer) NULL;
  158.  
  159.     /*
  160.      * walk up the superclass chain
  161.      */
  162.     while (superclass) {
  163.         for (j = 0, swn = nodearray; j < nnodes; j++, swn++) {
  164.         if (superclass == XmuWnClass(swn)) {
  165.             wn->superclass = swn;
  166.             goto done;        /* stupid C language */
  167.             }
  168.         }
  169.         /*
  170.          * Hmm, we have a hidden superclass (such as in core in R4); just
  171.          * ignore it and keep on walking
  172.          */
  173.         superclass = superclass->core_class.superclass;
  174.     }
  175.       done: 
  176.     if (wn->superclass) {
  177.         wn->siblings = wn->superclass->children;
  178.         wn->superclass->children = wn;
  179.     }
  180.     }
  181.  
  182.     return;
  183. }
  184.  
  185.  
  186. void XmuWnFetchResources (node, toplevel, topnode)
  187.     XmuWidgetNode *node;
  188.     Widget toplevel;
  189.     XmuWidgetNode *topnode;
  190. {
  191.     Widget dummy;
  192.     XmuWidgetNode *wn;
  193.  
  194.     if (node->have_resources) return;
  195.  
  196.     dummy = XtCreateWidget (node->label, XmuWnClass(node), toplevel,
  197.                 NULL, ZERO);
  198.     if (dummy) XtDestroyWidget (dummy);
  199.  
  200.  
  201.     /*
  202.      * walk up tree geting resources; since we've instantiated the widget,
  203.      * we know that all of our superclasses have been initialized
  204.      */
  205.     for (wn = node; wn && !wn->have_resources; wn = wn->superclass) {
  206.     XtGetResourceList (XmuWnClass(wn), &wn->resources, &wn->nresources);
  207.     if (wn->resources) {
  208.         qsort ((char *) wn->resources, wn->nresources,
  209.            sizeof(XtResource), compare_resource_entries);
  210.     }
  211.     wn->resourcewn = (XmuWidgetNode **) XtCalloc (wn->nresources,
  212.                           sizeof (XmuWidgetNode *));
  213.     if (!wn->resourcewn) {
  214.         fprintf (stderr,
  215.              "%s:  unable to calloc %d %d byte widget node ptrs\n",
  216.              "XmuWnFetchResources",wn->nresources,
  217.              sizeof (XmuWidgetNode *));
  218.         exit (1);
  219.     }
  220.  
  221.     XtGetConstraintResourceList (XmuWnClass(wn), &wn->constraints,
  222.                      &wn->nconstraints);
  223.     if (wn->constraints) {
  224.         qsort ((char *) wn->constraints, wn->nconstraints,
  225.            sizeof(XtResource), compare_resource_entries);
  226.     }
  227.     wn->constraintwn = (XmuWidgetNode **)
  228.       XtCalloc (wn->nconstraints, sizeof (XmuWidgetNode *));
  229.     if (!wn->constraintwn) {
  230.         fprintf (stderr,
  231.              "%s:  unable to calloc %d %d byte widget node ptrs\n",
  232.              "XmuWnFetchResources", wn->nconstraints,
  233.              sizeof (XmuWidgetNode *));
  234.         exit (1);
  235.     }
  236.  
  237.     wn->have_resources = True;
  238.     if (wn == topnode) break;
  239.     }
  240.  
  241.  
  242.     /*
  243.      * Walk up tree removing all resources that appear in superclass; we can
  244.      * mash the resource list in place since it was copied out of widget.
  245.      */
  246.     for (wn = node; wn; wn = wn->superclass) {
  247.     mark_resource_owner (wn);
  248.     if (wn == topnode) break;
  249.     }
  250.  
  251.     return;
  252. }
  253.  
  254.  
  255. int XmuWnCountOwnedResources (node, ownernode, cons)
  256.     XmuWidgetNode *node, *ownernode;
  257.     Bool cons;
  258. {
  259.     register int i;
  260.     XmuWidgetNode **wn = (cons ? node->constraintwn : node->resourcewn);
  261.     int nmatches = 0;
  262.  
  263.     for (i = (cons ? node->nconstraints : node->nresources); i > 0; i--, wn++)
  264.       if (*wn == ownernode) nmatches++;
  265.     return nmatches;
  266. }
  267.  
  268.  
  269. #if NeedFunctionPrototypes
  270. XmuWidgetNode *XmuWnNameToNode (XmuWidgetNode *nodelist, int nnodes, 
  271.                 _Xconst char *name)
  272. #else
  273. XmuWidgetNode *XmuWnNameToNode (nodelist, nnodes, name)
  274.     XmuWidgetNode *nodelist;
  275.     int nnodes;
  276.     char *name;
  277. #endif
  278. {
  279.     int i;
  280.     XmuWidgetNode *wn;
  281.     char tmp[1024];
  282.  
  283.     XmuCopyISOLatin1Lowered (tmp, name);
  284.     for (i = 0, wn = nodelist; i < nnodes; i++, wn++) {
  285.     if (strcmp (tmp, wn->lowered_label) == 0 ||
  286.         strcmp (tmp, wn->lowered_classname) == 0)
  287.       return wn;
  288.     }
  289.     return NULL;
  290. }
  291.