home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / lib / Xt / Resources.c.orig < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-13  |  34.2 KB  |  1,058 lines

  1. /* $XConsortium: Resources.c,v 1.107 91/06/13 19:03:09 converse Exp $ */
  2.  
  3. /*LINTLIBRARY*/
  4.  
  5. /***********************************************************
  6. Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
  7. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  8.  
  9.                         All Rights Reserved
  10.  
  11. Permission to use, copy, modify, and distribute this software and its 
  12. documentation for any purpose and without fee is hereby granted, 
  13. provided that the above copyright notice appear in all copies and that
  14. both that copyright notice and this permission notice appear in 
  15. supporting documentation, and that the names of Digital or MIT not be
  16. used in advertising or publicity pertaining to distribution of the
  17. software without specific, written prior permission.  
  18.  
  19. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  20. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  21. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  22. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  23. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  24. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  25. SOFTWARE.
  26.  
  27. ******************************************************************/
  28.  
  29. #include "IntrinsicI.h"
  30. #include "VarargsI.h"
  31. #include "Shell.h"
  32. #include "ShellP.h"
  33. #include "StringDefs.h"
  34. #include <stdio.h>
  35.  
  36. static XrmClass    QBoolean, QString, QCallProc, QImmediate;
  37. static XrmName QinitialResourcesPersistent, QInitialResourcesPersistent;
  38. static XrmClass QTranslations, QTranslationTable;
  39. static XrmName Qtranslations, QbaseTranslations;
  40. static XrmName Qscreen;
  41. static XrmClass QScreen;
  42.  
  43. #ifdef CRAY
  44. void Cjump();
  45. char *Cjumpp = (char *) Cjump;
  46. void Cjump() {}
  47. #endif
  48.  
  49. void _XtCopyFromParent(widget, offset, value)
  50.     Widget      widget;
  51.     int        offset;
  52.     XrmValue    *value;
  53. {
  54.     if (widget->core.parent == NULL) {
  55.     XtAppWarningMsg(XtWidgetToApplicationContext(widget),
  56.         "invalidParent","xtCopyFromParent",XtCXtToolkitError,
  57.                   "CopyFromParent must have non-NULL parent",
  58.           (String *)NULL, (Cardinal *)NULL);
  59.         value->addr = NULL;
  60.         return;
  61.     }
  62.     value->addr = (XPointer)(((char *)widget->core.parent) + offset);
  63. } /* _XtCopyFromParent */
  64.  
  65.  
  66. /* If the alignment characteristics of your machine are right, these may be
  67.    faster */
  68.  
  69. #ifdef UNALIGNED
  70.  
  71. void _XtCopyFromArg(src, dst, size)
  72.     XtArgVal src;
  73.     char* dst;
  74.     register unsigned int size;
  75. {
  76.     if        (size == sizeof(long))    *(long *)dst = (long)src;
  77.     else if (size == sizeof(short))    *(short *)dst = (short)src;
  78.     else if (size == sizeof(char))    *(char *)dst = (char)src;
  79.     else if (size == sizeof(XtPointer))    *(XtPointer *)dst = (XtPointer)src;
  80.     else if (size == sizeof(char*))    *(char **)dst = (char*)src;
  81.     else if (size == sizeof(XtArgVal))    *(XtArgVal *)dst = src;
  82.     else if (size > sizeof(XtArgVal))
  83.     bcopy((char *)  src, (char *) dst, (int) size);
  84.     else
  85.     bcopy((char *) &src, (char *) dst, (int) size);
  86. } /* _XtCopyFromArg */
  87.  
  88. void _XtCopyToArg(src, dst, size)
  89.     char* src;
  90.     XtArgVal *dst;
  91.     register unsigned int size;
  92. {
  93.     if (! (*dst)) {
  94.     /* old GetValues semantics (storing directly into arglists) are bad,
  95.      * but preserve for compatibility as long as arglist contains NULL.
  96.      */
  97.         if    (size == sizeof(long))       *dst = (XtArgVal)*(long*)src;
  98.     else if (size == sizeof(short))    *dst = (XtArgVal)*(short*)src;
  99.     else if (size == sizeof(char))       *dst = (XtArgVal)*(char*)src;
  100.     else if (size == sizeof(XtPointer)) *dst = (XtArgVal)*(XtPointer*)src;
  101.     else if (size == sizeof(char*))    *dst = (XtArgVal)*(char**)src;
  102.     else if (size == sizeof(XtArgVal)) *dst = *(XtArgVal*)src;
  103.     else bcopy((char*)src, (char*)dst, (int)size);
  104.     }
  105.     else {
  106.     /* proper GetValues semantics: argval is pointer to destination */
  107.     if    (size == sizeof(long))       *((long*)*dst) = *(long*)src;
  108.     else if (size == sizeof(short))    *((short*)*dst) = *(short*)src;
  109.     else if (size == sizeof(char))       *((char*)*dst) = *(char*)src;
  110.     else if (size == sizeof(XtPointer)) *((XtPointer*)*dst) = *(XtPointer*)src;
  111.     else if (size == sizeof(char*))    *((char**)*dst) = *(char**)src;
  112.     else if (size == sizeof(XtArgVal)) *((XtArgVal*)*dst)= *(XtArgVal*)src;
  113.     else bcopy((char*)src, (char*)*dst, (int)size);
  114.     }
  115. } /* _XtCopyToArg */
  116.  
  117. #else
  118. void _XtCopyFromArg(src, dst, size)
  119.     XtArgVal src;
  120.     char* dst;
  121.     register unsigned int size;
  122. {
  123.     if (size > sizeof(XtArgVal))
  124.     bcopy((char *)  src, (char *) dst, (int) size);
  125.     else {
  126.     union {
  127.         long    longval;
  128.         short    shortval;
  129.         char    charval;
  130.         char*    charptr;
  131.         XtPointer    ptr;
  132.     } u;
  133.     char *p = (char*)&u;
  134.     if    (size == sizeof(long))        u.longval = (long)src;
  135.     else if (size == sizeof(short))        u.shortval = (short)src;
  136.     else if (size == sizeof(char))        u.charval = (char)src;
  137.     else if (size == sizeof(XtPointer)) u.ptr = (XtPointer)src;
  138.     else if (size == sizeof(char*))        u.charptr = (char*)src;
  139.     else                    p = (char*)&src;
  140.  
  141.     bcopy(p, (char *) dst, (int) size);
  142.     }
  143. } /* _XtCopyFromArg */
  144.  
  145. void _XtCopyToArg(src, dst, size)
  146.     char* src;
  147.     XtArgVal *dst;
  148.     register unsigned int size;
  149. {
  150.     if (!*dst) {
  151.     /* old GetValues semantics (storing directly into arglists) are bad,
  152.      * but preserve for compatibility as long as arglist contains NULL.
  153.      */
  154.     union {
  155.         long    longval;
  156.         short    shortval;
  157.         char    charval;
  158.         char*    charptr;
  159.         XtPointer    ptr;
  160.     } u;
  161.     if (size <= sizeof(XtArgVal)) {
  162.         bcopy( (char*)src, (char*)&u, (int)size );
  163.         if        (size == sizeof(long))     *dst = (XtArgVal)u.longval;
  164.         else if (size == sizeof(short))    *dst = (XtArgVal)u.shortval;
  165.         else if (size == sizeof(char))    *dst = (XtArgVal)u.charval;
  166.         else if (size == sizeof(char*))    *dst = (XtArgVal)u.charptr;
  167.         else if (size == sizeof(XtPointer))    *dst = (XtArgVal)u.ptr;
  168.         else bcopy( (char*)src, (char*)dst, (int)size );
  169.     }
  170.     else
  171.         bcopy( (char*)src, (char*)dst, (int)size );
  172.     }
  173.     else {
  174.     /* proper GetValues semantics: argval is pointer to destination */
  175.     bcopy( (char*)src, (char*)*dst, (int)size );
  176.     }
  177. } /* _XtCopyToArg */
  178.  
  179. #endif
  180.  
  181. static Cardinal GetNamesAndClasses(w, names, classes)
  182.     register Widget      w;
  183.     register XrmNameList  names;
  184.     register XrmClassList classes;
  185. {
  186.     register Cardinal length, j;
  187.     register XrmQuark t;
  188.     WidgetClass class;
  189.  
  190.     /* Return null-terminated quark arrays, with length the number of
  191.        quarks (not including NULL) */
  192.  
  193.     for (length = 0; w != NULL; w = (Widget) w->core.parent) {
  194.     names[length] = w->core.xrm_name;
  195.     class = XtClass(w);
  196.     /* KLUDGE KLUDGE KLUDGE KLUDGE */
  197.     if (w->core.parent == NULL && XtIsApplicationShell(w)) {
  198.         classes[length] =
  199.         ((ApplicationShellWidget) w)->application.xrm_class;
  200.     } else classes[length] = class->core_class.xrm_class;
  201.     length++;
  202.      }
  203.     /* They're in backwards order, flop them around */
  204.     for (j = 0; j < length/2; j++) {
  205.     t = names[j];
  206.     names[j] = names[length-j-1];
  207.     names[length-j-1] = t;
  208.         t = classes[j];
  209.     classes[j] = classes[length-j-1];
  210.     classes[length-j-1] = t;
  211.     }
  212.     names[length] = NULLQUARK;
  213.     classes[length] = NULLQUARK;
  214.     return length;
  215. } /* GetNamesAndClasses */
  216.  
  217.  
  218. /* Spiffy fast compiled form of resource list.                */
  219. /* XtResourceLists are compiled in-place into XrmResourceLists        */
  220. /* All atoms are replaced by quarks, and offsets are -offset-1 to    */
  221. /* indicate that this list has been compiled already            */
  222.  
  223. void _XtCompileResourceList(resources, num_resources)
  224.     register XtResourceList resources;
  225.              Cardinal       num_resources;
  226. {
  227.     register Cardinal count;
  228.  
  229. #define xrmres  ((XrmResourceList) resources)
  230. #define PSToQ   XrmPermStringToQuark
  231.  
  232.     for (count = 0; count < num_resources; resources++, count++) {
  233.         xrmres->xrm_name     = PSToQ(resources->resource_name);
  234.         xrmres->xrm_class     = PSToQ(resources->resource_class);
  235.         xrmres->xrm_type     = PSToQ(resources->resource_type);
  236. #if defined(CRAY1) && !defined(__STDC__)
  237.     xrmres->xrm_offset = -(resources->resource_offset * sizeof(long) + 1);
  238. #else
  239.         xrmres->xrm_offset     = -resources->resource_offset - 1;
  240. #endif
  241.         xrmres->xrm_default_type = PSToQ(resources->default_type);
  242.     }
  243. #undef PSToQ
  244. #undef xrmres
  245. } /* _XtCompileResourceList */
  246.  
  247. /* Like _XtCompileResourceList, but strings are not permanent */
  248. static void  XrmCompileResourceListEphem(resources, num_resources)
  249.     register XtResourceList resources;
  250.              Cardinal       num_resources;
  251. {
  252.     register Cardinal count;
  253.  
  254. #define xrmres  ((XrmResourceList) resources)
  255.  
  256.     for (count = 0; count < num_resources; resources++, count++) {
  257.         xrmres->xrm_name     = StringToName(resources->resource_name);
  258.         xrmres->xrm_class     = StringToClass(resources->resource_class);
  259.         xrmres->xrm_type     = StringToQuark(resources->resource_type);
  260. #if defined(CRAY1) && !defined(__STDC__)
  261.     xrmres->xrm_offset = -(resources->resource_offset * sizeof(long) + 1);
  262. #else
  263.         xrmres->xrm_offset     = -resources->resource_offset - 1;
  264. #endif
  265.         xrmres->xrm_default_type = StringToQuark(resources->default_type);
  266.     }
  267. #undef xrmres
  268. } /* XrmCompileResourceListEphem */
  269.  
  270. static void BadSize(size, name)
  271.     Cardinal size;
  272.     XrmQuark name;
  273. {
  274.     String params[2];
  275.     Cardinal num_params = 2;
  276.  
  277.     params[0] = (String) size;
  278.     params[1] = XrmQuarkToString(name);
  279.     XtWarningMsg("invalidSizeOverride", "xtDependencies", XtCXtToolkitError,
  280.     "Representation size %d must match superclass's to override %s",
  281.     params, &num_params);
  282. } /* BadType */
  283.  
  284. /*
  285.  * Create a new resource list, with the class resources following the
  286.  * superclass's resources.  If a resource in the class list overrides
  287.  * a superclass resource, then just replace the superclass entry in place.
  288.  *
  289.  * At the same time, add a level of indirection to the XtResourceList to
  290.  * create and XrmResourceList.
  291.  */
  292. void _XtDependencies(class_resp, class_num_resp, super_res, super_num_res,
  293.              super_widget_size)
  294.     XtResourceList  *class_resp;    /* VAR */
  295.     Cardinal        *class_num_resp;    /* VAR */
  296.     XrmResourceList *super_res;
  297.     Cardinal        super_num_res;
  298.     Cardinal        super_widget_size;
  299. {
  300.     register XrmResourceList *new_res;
  301.          Cardinal         new_num_res;
  302.          XrmResourceList class_res = (XrmResourceList) *class_resp;
  303.          Cardinal        class_num_res = *class_num_resp;
  304.     register Cardinal         i, j;
  305.          Cardinal        new_next;
  306.  
  307.     if (class_num_res == 0) {
  308.     /* Just point to superclass resource list */
  309.     *class_resp = (XtResourceList) super_res;
  310.     *class_num_resp = super_num_res;
  311.     return;
  312.     }
  313.  
  314.     /* Allocate and initialize new_res with superclass resource pointers */
  315.     new_num_res = super_num_res + class_num_res;
  316.     new_res = (XrmResourceList *) XtMalloc(new_num_res*sizeof(XrmResourceList));
  317.     XtBCopy(super_res, new_res, super_num_res * sizeof(XrmResourceList));
  318.     
  319.     /* Put pointers to class resource entries into new_res */
  320.     new_next = super_num_res;
  321.     for (i = 0; i < class_num_res; i++) {
  322.     if (-class_res[i].xrm_offset-1 < super_widget_size) {
  323.         /* Probably an override of superclass resources--look for overlap */
  324.         for (j = 0; j < super_num_res; j++) {
  325.         if (class_res[i].xrm_offset == new_res[j]->xrm_offset) {
  326.             /* Spec is silent on what fields subclass can override.
  327.              * The only two of real concern are type & size.
  328.              * Although allowing type to be over-ridden introduces
  329.              * the possibility of errors, it's at present the only
  330.              * reasonable way to allow a subclass to force a private
  331.              * converter to be invoked for a subset of fields.
  332.              */
  333.             /* We do insist that size be identical to superclass */
  334.             if (class_res[i].xrm_size != new_res[j]->xrm_size) {
  335.             BadSize(class_res[i].xrm_size, class_res[i].xrm_name);
  336.             class_res[i].xrm_size = new_res[j]->xrm_size;
  337.             }
  338.             new_res[j] = &(class_res[i]);
  339.             new_num_res--;
  340.             goto NextResource;
  341.         }
  342.         } /* for j */
  343.     }
  344.     /* Not an overlap, add an entry to new_res */
  345.     new_res[new_next++] = &(class_res[i]);
  346. NextResource:;
  347.     } /* for i */
  348.  
  349.     /* Okay, stuff new resources back into class record */
  350.     *class_resp = (XtResourceList) new_res;
  351.     *class_num_resp = new_num_res;
  352. } /* _XtDependencies */
  353.  
  354.  
  355. void _XtResourceDependencies(wc)
  356.     WidgetClass wc;
  357. {
  358.     WidgetClass sc;
  359.  
  360.     sc = wc->core_class.superclass;
  361.     if (sc == NULL) {
  362.     _XtDependencies(&(wc->core_class.resources),
  363.             &(wc->core_class.num_resources),
  364.             (XrmResourceList *) NULL, (unsigned)0, (unsigned)0);
  365.     } else {
  366.     _XtDependencies(&(wc->core_class.resources),
  367.             &(wc->core_class.num_resources),
  368.             (XrmResourceList *) sc->core_class.resources,
  369.             sc->core_class.num_resources,
  370.             sc->core_class.widget_size);
  371.     }
  372. } /* _XtResourceDependencies */
  373.  
  374. void _XtConstraintResDependencies(wc)
  375.     ConstraintWidgetClass wc;
  376. {
  377.     ConstraintWidgetClass sc;
  378.  
  379.     if (wc == (ConstraintWidgetClass) constraintWidgetClass) {
  380.     _XtDependencies(&(wc->constraint_class.resources),
  381.             &(wc->constraint_class.num_resources),
  382.             (XrmResourceList *)NULL, (unsigned)0, (unsigned)0);
  383.     } else {
  384.     sc = (ConstraintWidgetClass) wc->core_class.superclass;
  385.     _XtDependencies(&(wc->constraint_class.resources),
  386.             &(wc->constraint_class.num_resources),
  387.             (XrmResourceList *) sc->constraint_class.resources,
  388.             sc->constraint_class.num_resources,
  389.             sc->constraint_class.constraint_size);
  390.     }
  391. } /* _XtConstraintResDependencies */
  392.  
  393.  
  394.  
  395.     
  396. XrmResourceList* _XtCreateIndirectionTable (resources, num_resources)
  397.     XtResourceList  resources;
  398.     Cardinal        num_resources;
  399. {
  400.     register int idx;
  401.     XrmResourceList* table;
  402.  
  403.     table = (XrmResourceList*)XtMalloc(num_resources * sizeof(XrmResourceList));
  404.     for (idx = 0; idx < num_resources; idx++)
  405.         table[idx] = (XrmResourceList)(&(resources[idx]));
  406.     return table;
  407. }
  408.  
  409. static XtCacheRef *GetResources(widget, base, names, classes,
  410.     table, num_resources, quark_args, args, num_args,
  411.     typed_args, pNumTypedArgs, tm_hack)
  412.     Widget        widget;        /* Widget resources are associated with */
  413.     char*        base;        /* Base address of memory to write to   */
  414.     XrmNameList     names;        /* Full inheritance name of widget      */
  415.     XrmClassList    classes;        /* Full inheritance class of widget     */
  416.     XrmResourceList*  table;        /* The list of resources required.      */
  417.     Cardinal        num_resources;  /* number of items in resource list     */
  418.     XrmQuarkList    quark_args;     /* Arg names quarkified            */
  419.     ArgList        args;        /* ArgList to override resources        */
  420.     Cardinal        num_args;       /* number of items in arg list        */
  421.     XtTypedArgList  typed_args;        /* Typed arg list to override resources */
  422.     Cardinal*        pNumTypedArgs;  /* number of items in typed arg list    */
  423.     Boolean        tm_hack;        /* do baseTranslations            */
  424. {
  425. /*
  426.  * assert: *pNumTypedArgs == 0 if num_args > 0
  427.  * assert: num_args == 0 if *pNumTypedArgs > 0
  428.  */
  429. #define SEARCHLISTLEN 100
  430.  
  431.     XrmValue        value;
  432.     XrmQuark        rawType;
  433.     XrmValue        convValue;
  434.     XrmHashTable    stackSearchList[SEARCHLISTLEN];
  435.     XrmHashTable    *searchList = stackSearchList;
  436.     unsigned int    searchListSize = SEARCHLISTLEN;
  437.     Boolean        found[400];
  438.     int            typed[400];
  439.     XtCacheRef        cache_ref[400];
  440.     XtCacheRef      *cache_ptr, *cache_base;
  441.     Boolean        persistent_resources = True;
  442.     Boolean        found_persistence = False;
  443.     int            num_typed_args = *pNumTypedArgs;
  444.     XrmDatabase     db;
  445.     Boolean        do_tm_hack = False;
  446.  
  447.     if ((args == NULL) && (num_args != 0)) {
  448.         XtAppWarningMsg(XtWidgetToApplicationContext(widget),
  449.         "invalidArgCount","getResources",XtCXtToolkitError,
  450.                  "argument count > 0 on NULL argument list",
  451.                    (String *)NULL, (Cardinal *)NULL);
  452.     num_args = 0;
  453.     }
  454.     if (num_resources == 0) {
  455.     return NULL;
  456.     } else if (table == NULL) {
  457.         XtAppWarningMsg(XtWidgetToApplicationContext(widget),
  458.         "invalidResourceCount","getResources",XtCXtToolkitError,
  459.               "resource count > 0 on NULL resource list",
  460.           (String *)NULL, (Cardinal *)NULL);
  461.     return NULL;
  462.     }
  463.  
  464.     /* Mark each resource as not found on arg list */
  465.     bzero((char *) found, (int) (num_resources * sizeof(Boolean)));
  466.     bzero((char *) typed, (int) (num_resources * sizeof(int)));
  467.  
  468.     /* Copy the args into the resources, mark each as found */
  469.     {
  470.     register ArgList        arg;
  471.     register XtTypedArgList        typed_arg;
  472.     register XrmName        argName;
  473.     register int        j;
  474.     register int        i;
  475.     register XrmResourceList rx;
  476.     register XrmResourceList *res;
  477.     for (arg = args, i = 0; i < num_args; i++, arg++) {
  478.         argName = quark_args[i];
  479.         if (argName == QinitialResourcesPersistent) {
  480.         persistent_resources = (Boolean)arg->value;
  481.         found_persistence = True;
  482.         continue;
  483.         }
  484.         for (j = 0, res = table; j < num_resources; j++, res++) {
  485.         rx = *res;
  486.         if (argName == rx->xrm_name) {
  487.             _XtCopyFromArg(
  488.             arg->value,
  489.             base - rx->xrm_offset - 1,
  490.             rx->xrm_size);
  491.             found[j] = TRUE;
  492.             break;
  493.         }
  494.         }
  495.     }
  496.     for (typed_arg = typed_args, i = 0; i < num_typed_args;
  497.          i++, typed_arg++) {
  498.         argName = quark_args[i];
  499.         if (argName == QinitialResourcesPersistent) {
  500.         persistent_resources = (Boolean)typed_arg->value;
  501.         found_persistence = True;   
  502.         break;
  503.         }
  504.         for (j = 0, res = table; j < num_resources; j++, res++) {
  505.         rx = *res;
  506.         if (argName == rx->xrm_name) {
  507.             if (typed_arg->type != NULL) {
  508.             typed[j] = i + 1;
  509.             } else {
  510.             _XtCopyFromArg(
  511.                        typed_arg->value,
  512.                        base - rx->xrm_offset - 1,
  513.                        rx->xrm_size);
  514.             }
  515.             found[j] = TRUE;
  516.             break;
  517.         }   
  518.         }
  519.     }
  520.     }
  521.  
  522.     /* Ask resource manager for a list of database levels that we can
  523.        do a single-level search on each resource */
  524.  
  525.     db = XtScreenDatabase(XtScreenOfObject(widget));
  526.     while (!XrmQGetSearchList(db, names, classes,
  527.                   searchList, searchListSize)) {
  528.     if (searchList == stackSearchList)
  529.         searchList = NULL;
  530.     searchList = (XrmHashTable*)XtRealloc((char*)searchList,
  531.                           sizeof(XrmHashTable) *
  532.                           (searchListSize *= 2));
  533.     }
  534.     
  535.     if (persistent_resources)
  536.     cache_base = NULL;
  537.     else
  538.     cache_base = cache_ref;
  539.     /* geez, this is an ugly mess */
  540.     if (XtIsShell(widget)) {
  541.     register XrmResourceList  *res;
  542.     register int          j;
  543.     Screen *oldscreen = widget->core.screen;
  544.  
  545.     /* look up screen resource first, since real rdb depends on it */
  546.     for (res = table, j = 0; j < num_resources; j++, res++) {
  547.         if ((*res)->xrm_name != Qscreen)
  548.         continue;
  549.         if (typed[j]) {
  550.         register XtTypedArg* arg = typed_args + typed[j] - 1;
  551.         XrmQuark from_type;
  552.         XrmValue from_val, to_val;
  553.  
  554.         from_type = StringToQuark(arg->type);
  555.         from_val.size = arg->size;
  556.         if ((from_type == QString) || (arg->size > sizeof(XtArgVal)))
  557.             from_val.addr = (XPointer)arg->value;
  558.         else
  559.             from_val.addr = (XPointer)&arg->value;
  560.         to_val.size = sizeof(Screen*);
  561.         to_val.addr = (XPointer)&widget->core.screen;
  562.         found[j] = _XtConvert(widget, from_type, &from_val,
  563.                       QScreen, &to_val, cache_base);
  564.         if (cache_base && *cache_base)
  565.             cache_base++;
  566.         }
  567.         if (!found[j]) {
  568.         if (XrmQGetSearchResource(searchList, Qscreen, QScreen,
  569.                       &rawType, &value)) {
  570.             if (rawType != QScreen) {
  571.             convValue.size = sizeof(Screen*);
  572.             convValue.addr = (XPointer)&widget->core.screen;
  573.             (void)_XtConvert(widget, rawType, &value,
  574.                      QScreen, &convValue, cache_base);
  575.             if (cache_base && *cache_base)
  576.                 cache_base++;
  577.             } else {
  578.             widget->core.screen = *((Screen **)value.addr);
  579.             }
  580.         }
  581.         }
  582.         break;
  583.     }
  584.     /* now get the database to use for the rest of the resources */
  585.     if (widget->core.screen != oldscreen) {
  586.         db = XtScreenDatabase(widget->core.screen);
  587.         while (!XrmQGetSearchList(db, names, classes,
  588.                       searchList, searchListSize)) {
  589.         if (searchList == stackSearchList)
  590.             searchList = NULL;
  591.         searchList = (XrmHashTable*)XtRealloc((char*)searchList,
  592.                               sizeof(XrmHashTable) *
  593.                               (searchListSize *= 2));
  594.         }
  595.     }
  596.     }
  597.  
  598.     /* go to the resource manager for those resources not found yet */
  599.     /* if it's not in the resource database use the default value   */
  600.  
  601.     {
  602.     register XrmResourceList  rx;
  603.     register XrmResourceList  *res;
  604.     register int          j;
  605.     register XrmRepresentation xrm_type;
  606.     register XrmRepresentation xrm_default_type;
  607.     char    char_val;
  608.     short    short_val;
  609.     int    int_val;
  610.     long    long_val;
  611.     char*    char_ptr;
  612.  
  613.     if (!found_persistence) {
  614.         if (XrmQGetSearchResource(searchList, QinitialResourcesPersistent,
  615.             QInitialResourcesPersistent, &rawType, &value)) {
  616.         if (rawType != QBoolean) {
  617.             convValue.size = sizeof(Boolean);
  618.             convValue.addr = (XPointer)&persistent_resources;
  619.             (void)_XtConvert(widget, rawType, &value, QBoolean,
  620.                      &convValue, NULL);
  621.         }
  622.         else
  623.             persistent_resources = *(Boolean*)value.addr;
  624.         }
  625.     }
  626.     if (persistent_resources)
  627.         cache_ptr = NULL;
  628.     else if (cache_base)
  629.         cache_ptr = cache_base;
  630.     else
  631.         cache_ptr = cache_ref;
  632.  
  633.     for (res = table, j = 0; j < num_resources; j++, res++) {
  634.         rx = *res;
  635.         xrm_type = rx->xrm_type;
  636.         if (typed[j]) {
  637.         register XtTypedArg* arg = typed_args + typed[j] - 1;
  638.  
  639.         /*
  640.                  * This resource value has been specified as a typed arg and 
  641.          * has to be converted. Typed arg conversions are done here 
  642.          * to correctly interpose them with normal resource conversions.
  643.                  */
  644.         XrmQuark        from_type;
  645.         XrmValue            from_val, to_val;
  646.         Boolean            converted;
  647.                  
  648.         from_type = StringToQuark(arg->type);
  649.             from_val.size = arg->size;
  650.         if ((from_type == QString) || (arg->size > sizeof(XtArgVal)))
  651.                 from_val.addr = (XPointer)arg->value;
  652.             else
  653.                     from_val.addr = (XPointer)&arg->value;
  654.         to_val.size = rx->xrm_size;
  655.         to_val.addr = base - rx->xrm_offset - 1;
  656.         converted = _XtConvert(widget, from_type, &from_val,
  657.                        xrm_type, &to_val, cache_ptr);
  658.         if (converted) {
  659.             char *vp;
  660.  
  661.             /* Copy the converted value back into the typed argument.
  662.              * normally the data should be <= sizeof(XtArgVal) and
  663.              * is stored directly into the 'value' field .... BUT
  664.              * if the resource size is greater than sizeof(XtArgVal)
  665.              * then we dynamically alloc a block of store to hold the
  666.              * data and zap a copy in there !!! .... freeing it later
  667.              * the size field in the typed arg is negated to indicate
  668.              * that the store pointed to by the value field is
  669.              * dynamic .......
  670.              * "freeing" happens in the case of _XtCreate after the
  671.              * CallInitialize ..... other clients of GetResources
  672.              * using typed args should be aware of the need to free
  673.              * this store .....
  674.              */
  675.  
  676.             if(rx->xrm_size > sizeof(XtArgVal)) {
  677.             arg->value = (XtArgVal)(vp = XtMalloc(rx->xrm_size));
  678.             arg->size = -(arg->size);
  679.             } else { /* will fit - copy directly into value field */
  680.             vp = (char *)&arg->value;
  681.             }
  682.  
  683.             XtBCopy((char *)(base - rx->xrm_offset - 1), vp, rx->xrm_size);
  684.  
  685.         } else {
  686.            /* Conversion failed. Get default value. */
  687.            found[j] = False;
  688.         }
  689.  
  690.         if (cache_ptr && *cache_ptr)
  691.             cache_ptr++;
  692.         }
  693.  
  694.         if (!found[j]) {
  695.         Boolean    already_copied = False;
  696.         Boolean have_value = False;
  697.  
  698.         if (XrmQGetSearchResource(searchList,
  699.             rx->xrm_name, rx->xrm_class, &rawType, &value)) {
  700.             if (rawType != xrm_type) {
  701.             convValue.size = rx->xrm_size;
  702.             convValue.addr = (XPointer)(base - rx->xrm_offset - 1);
  703.             already_copied = have_value =
  704.                 _XtConvert(widget, rawType, &value,
  705.                        xrm_type, &convValue, cache_ptr);
  706.             if (cache_ptr && *cache_ptr)
  707.                 cache_ptr++;
  708.             } else have_value = True;
  709.             if (have_value && rx->xrm_name == Qtranslations)
  710.             do_tm_hack = True;
  711.         }
  712.         if (!have_value
  713.             && ((rx->xrm_default_type == QImmediate)
  714.             || (rx->xrm_default_type == xrm_type)
  715.             || (rx->xrm_default_addr != NULL))) {
  716.             /* Convert default value to proper type */
  717.             xrm_default_type = rx->xrm_default_type;
  718.             if (xrm_default_type == QCallProc) {
  719. #ifdef CRAY
  720.              if ( (int) Cjumpp != (int) Cjump)
  721.                  (*(XtResourceDefaultProc)
  722.                   (((int)(rx->xrm_default_addr))<<2))(
  723.                   widget,-(rx->xrm_offset+1), &value);
  724.             else
  725. #endif
  726.             (*(XtResourceDefaultProc)(rx->xrm_default_addr))(
  727.                   widget,-(rx->xrm_offset+1), &value);
  728.  
  729.             } else if (xrm_default_type == QImmediate) {
  730.             /* XtRImmediate == XtRString for type XtRString */
  731.             if (xrm_type == QString) {
  732.                 value.addr = rx->xrm_default_addr;
  733.             } else if (rx->xrm_size == sizeof(int)) {
  734.                 int_val = (int)(long)rx->xrm_default_addr;
  735.                 value.addr = (XPointer) &int_val;
  736.             } else if (rx->xrm_size == sizeof(short)) {
  737.                 short_val = (short)(long)rx->xrm_default_addr;
  738.                 value.addr = (XPointer) &short_val;
  739.             } else if (rx->xrm_size == sizeof(char)) {
  740.                 char_val = (char)(long)rx->xrm_default_addr;
  741.                 value.addr = (XPointer) &char_val;
  742.             } else if (rx->xrm_size == sizeof(long)) {
  743.                 long_val = (long)rx->xrm_default_addr;
  744.                 value.addr = (XPointer) &long_val;
  745.             } else if (rx->xrm_size == sizeof(char*)) {
  746.                 char_ptr = (char*)rx->xrm_default_addr;
  747.                 value.addr = (XPointer) &char_ptr;
  748.             } else {
  749.                 value.addr = (XPointer) &(rx->xrm_default_addr);
  750.             }
  751.             } else if (xrm_default_type == xrm_type) {
  752.             value.addr = rx->xrm_default_addr;
  753.             } else {
  754.             value.addr = rx->xrm_default_addr;
  755.             if (xrm_default_type == QString) {
  756.                 value.size = strlen((char *)value.addr) + 1;
  757.             } else {
  758.                 value.size = sizeof(XtPointer);
  759.             }
  760.             convValue.size = rx->xrm_size;
  761.             convValue.addr = (XPointer)(base - rx->xrm_offset - 1);
  762.             already_copied =
  763.                 _XtConvert(widget, xrm_default_type, &value,
  764.                        xrm_type, &convValue, cache_ptr);
  765.             if (!already_copied)
  766.                 value.addr = NULL;
  767.             if (cache_ptr && *cache_ptr)
  768.                 cache_ptr++;
  769.             }
  770.         }
  771.         if (!already_copied) {
  772.             if (xrm_type == QString) {
  773.             *((String*)(base - rx->xrm_offset - 1)) = value.addr;
  774.             } else {
  775.             if (value.addr != NULL) {
  776.                 XtBCopy(value.addr, base - rx->xrm_offset - 1,
  777.                     rx->xrm_size);
  778.             } else {
  779.                 /* didn't get value, initialize to NULL... */
  780.                 XtBZero(base - rx->xrm_offset - 1, rx->xrm_size);
  781.             }
  782.             }
  783.         }
  784.  
  785.         if (typed[j]) {
  786.             /*
  787.              * This resource value was specified as a typed arg.
  788.              * However, the default value is being used here since
  789.              * type type conversion failed, so we compress the list.
  790.              */
  791.             register XtTypedArg* arg = typed_args + typed[j] - 1;
  792.             register int i;
  793.  
  794.             for (i = num_typed_args - typed[j]; i; i--, arg++) {
  795.             *arg = *(arg+1);
  796.             }
  797.             num_typed_args--;
  798.         }
  799.         } 
  800.     }
  801.     if (tm_hack)
  802.         widget->core.tm.current_state = NULL;
  803.     if (tm_hack &&
  804.         (!widget->core.tm.translations ||
  805.          (do_tm_hack &&
  806.           widget->core.tm.translations->operation != XtTableReplace)) &&
  807.         XrmQGetSearchResource(searchList, QbaseTranslations,
  808.                   QTranslations, &rawType, &value)) {
  809.         if (rawType != QTranslationTable) {
  810.         convValue.size = sizeof(XtTranslations);
  811.         convValue.addr = (XPointer)&widget->core.tm.current_state;
  812.         (void)_XtConvert(widget, rawType, &value,
  813.                  QTranslationTable, &convValue, cache_ptr);
  814.         if (cache_ptr && *cache_ptr)
  815.             cache_ptr++;
  816.         } else {
  817.         *((XtTranslations *)&widget->core.tm.current_state) =
  818.             *((XtTranslations *)value.addr);
  819.         }
  820.     }
  821.     }
  822.     if (num_typed_args != *pNumTypedArgs) *pNumTypedArgs = num_typed_args;
  823.     if (searchList != stackSearchList) XtFree((char*)searchList);
  824.     if (!cache_ptr)
  825.     cache_ptr = cache_base;
  826.     if (cache_ptr && cache_ptr != cache_ref) {
  827.     int cache_ref_size = cache_ptr - cache_ref;
  828.     XtCacheRef *refs = (XtCacheRef*)
  829.         XtMalloc((unsigned)sizeof(XtCacheRef)*(cache_ref_size + 1));
  830.     bcopy( cache_ref, refs, sizeof(XtCacheRef)*cache_ref_size );
  831.     refs[cache_ref_size] = NULL;
  832.     return refs;
  833.     }
  834.     return (XtCacheRef*)NULL;
  835. }
  836.  
  837.  
  838.  
  839. static void CacheArgs(args, num_args, typed_args, num_typed_args, quark_cache, 
  840.     num_quarks, pQuarks)
  841.     ArgList        args;
  842.     Cardinal        num_args;
  843.     XtTypedArgList  typed_args;
  844.     Cardinal        num_typed_args;
  845.     XrmQuarkList    quark_cache;
  846.     Cardinal        num_quarks;
  847.     XrmQuarkList    *pQuarks;       /* RETURN */
  848. {
  849.     register XrmQuarkList   quarks;
  850.     register Cardinal       i;
  851.     register Cardinal       count;
  852.  
  853.     count = (args != NULL) ? num_args : num_typed_args;
  854.  
  855.     if (num_quarks < count) {
  856.     quarks = (XrmQuarkList) XtMalloc(count * sizeof(XrmQuark));
  857.     } else {
  858.     quarks = quark_cache;
  859.     }
  860.     *pQuarks = quarks;
  861.  
  862.     if (args != NULL) {
  863.     for (i = count; i; i--)
  864.         *quarks++ = StringToQuark((args++)->name);
  865.     }
  866.     else {
  867.     for (i = count; i; i--)
  868.         *quarks++ = StringToQuark((typed_args++)->name);
  869.     }
  870. }
  871.  
  872. #define FreeCache(cache, pointer) \
  873.       if (cache != pointer) XtFree((char *)pointer)
  874.  
  875.  
  876. XtCacheRef *_XtGetResources(w, args, num_args, typed_args, num_typed_args)
  877.     register     Widget          w;
  878.             ArgList          args;
  879.             Cardinal      num_args;
  880.         XtTypedArgList    typed_args;
  881.         Cardinal*    num_typed_args;
  882. {
  883.     XrmName        names[100];
  884.     XrmClass        classes[100];
  885.     XrmQuark        quark_cache[100];
  886.     XrmQuarkList    quark_args;
  887.     WidgetClass     wc;
  888.     ConstraintWidgetClass   cwc;
  889.     XtCacheRef        *cache_refs;
  890.  
  891.     wc = XtClass(w);
  892.  
  893.     /* Get names, classes for widget and ancestors */
  894.     (void) GetNamesAndClasses(w, names, classes);
  895.    
  896.     /* Compile arg list into quarks */
  897.     CacheArgs(args, num_args, typed_args, *num_typed_args, quark_cache,
  898.           XtNumber(quark_cache), &quark_args);
  899.  
  900.     /* Get normal resources */
  901.     cache_refs = GetResources(w, (char*)w, names, classes,
  902.     (XrmResourceList *) wc->core_class.resources,
  903.     wc->core_class.num_resources, quark_args, args, num_args,
  904.     typed_args, num_typed_args, XtIsWidget(w));
  905.  
  906.     if (w->core.constraints != NULL) {
  907.     cwc = (ConstraintWidgetClass) XtClass(w->core.parent);
  908.     GetResources(w, (char*)w->core.constraints, names, classes,
  909.         (XrmResourceList *) cwc->constraint_class.resources,
  910.         cwc->constraint_class.num_resources,
  911.         quark_args, args, num_args, typed_args, num_typed_args, False);
  912.     }
  913.     FreeCache(quark_cache, quark_args);
  914.     return cache_refs;
  915. } /* _XtGetResources */
  916.  
  917.  
  918. #if NeedFunctionPrototypes
  919. void XtGetSubresources (
  920.     Widget      w,
  921.     XtPointer      base,
  922.     _Xconst char* name,
  923.     _Xconst char* class,
  924.     XtResourceList resources,
  925.     Cardinal      num_resources,
  926.     ArgList      args,
  927.     Cardinal      num_args
  928.     )
  929. #else
  930. void XtGetSubresources (w, base, name, class, resources, num_resources,
  931.             args, num_args)
  932.     Widget      w;          /* Widget "parent" of subobject   */
  933.     XtPointer      base;          /* Base address to write to       */
  934.     String      name;          /* name of subobject            */
  935.     String      class;      /* class of subobject            */
  936.     XtResourceList resources;      /* resource list for subobject    */
  937.     Cardinal      num_resources;
  938.     ArgList      args;          /* arg list to override resources */
  939.     Cardinal      num_args;
  940. #endif
  941. {
  942.     XrmName      names[100];
  943.     XrmClass      classes[100];
  944.     register Cardinal      length;
  945.     XrmQuark      quark_cache[100];
  946.     XrmQuarkList  quark_args;
  947.     XrmResourceList* table;
  948.     Cardinal      null_typed_args = 0;
  949.  
  950.     if (num_resources == 0) return;
  951.  
  952.     /* Get full name, class of subobject */
  953.     length = GetNamesAndClasses(w, names, classes);
  954.     names[length] = StringToName(name);
  955.     classes[length] = StringToClass(class);
  956.     length++;
  957.     names[length] = NULLQUARK;
  958.     classes[length] = NULLQUARK;
  959.  
  960.     /* Compile arg list into quarks */
  961.     CacheArgs(args, num_args, (XtTypedArgList)NULL, (Cardinal)0,
  962.           quark_cache, XtNumber(quark_cache), &quark_args);
  963.  
  964.     /* Compile resource list if needed */
  965.     if (((int) resources->resource_offset) >= 0) {
  966.     XrmCompileResourceListEphem(resources, num_resources);
  967.     }
  968.     table = _XtCreateIndirectionTable(resources, num_resources); 
  969.     (void) GetResources(w, (char*)base, names, classes, table, num_resources,
  970.             quark_args, args, num_args,
  971.             (XtTypedArgList)NULL, &null_typed_args, False);
  972.     FreeCache(quark_cache, quark_args);
  973.     XtFree((char *)table);
  974. }
  975.  
  976.  
  977. void XtGetApplicationResources
  978.     (w, base, resources, num_resources, args, num_args)
  979.     Widget        w;          /* Application shell widget       */
  980.     XtPointer        base;      /* Base address to write to       */
  981.     XtResourceList  resources;      /* resource list for subobject    */
  982.     Cardinal        num_resources;
  983.     ArgList        args;      /* arg list to override resources */
  984.     Cardinal        num_args;
  985. {
  986.     XrmName        names[100];
  987.     XrmClass        classes[100];
  988.     XrmQuark        quark_cache[100];
  989.     XrmQuarkList    quark_args;
  990.     XrmResourceList* table;
  991.     Cardinal      null_typed_args = 0;
  992.  
  993.     if (num_resources == 0) return;
  994.  
  995.     /* Get full name, class of application */
  996.     if (w == NULL) {
  997.     /* hack for R2 compatibility */
  998.     XtPerDisplay pd = _XtGetPerDisplay(_XtDefaultAppContext()->list[0]);
  999.     names[0] = pd->name;
  1000.     names[1] = NULLQUARK;
  1001.     classes[0] = pd->class;
  1002.     classes[1] = NULLQUARK;
  1003.     }
  1004.     else {
  1005.     (void) GetNamesAndClasses(w, names, classes);
  1006.     }
  1007.  
  1008.     /* Compile arg list into quarks */
  1009.     CacheArgs(args, num_args, (XtTypedArgList)NULL, (Cardinal)0,  quark_cache, 
  1010.     XtNumber(quark_cache), &quark_args);
  1011.     /* Compile resource list if needed */
  1012.     if (((int) resources->resource_offset) >= 0) {
  1013. #ifdef    CRAY2
  1014.      if (base == 0) {    /* this client is non-portable, but... */
  1015.          int count;
  1016.         XtResourceList  res = resources;
  1017.         for (count = 0; count < num_resources; res++, count++) {
  1018.          res->resource_offset *= sizeof(long);
  1019.          }
  1020.      }
  1021. #endif    /* CRAY2 */
  1022.     XrmCompileResourceListEphem(resources, num_resources);
  1023.     }
  1024.     table = _XtCreateIndirectionTable(resources,num_resources);
  1025.  
  1026.     (void) GetResources(w, (char*)base, names, classes, table, num_resources,
  1027.             quark_args, args, num_args,
  1028.             (XtTypedArgList)NULL, &null_typed_args, False);
  1029.     FreeCache(quark_cache, quark_args);
  1030.     XtFree((char *)table);
  1031. }
  1032.  
  1033. static Boolean initialized = FALSE;
  1034.  
  1035. void _XtResourceListInitialize()
  1036. {
  1037.     if (initialized) {
  1038.     XtWarningMsg("initializationError","xtInitialize",XtCXtToolkitError,
  1039.                   "Initializing Resource Lists twice",
  1040.           (String *)NULL, (Cardinal *)NULL);
  1041.         return;
  1042.     }
  1043.     initialized = TRUE;
  1044.  
  1045.     QBoolean = XrmPermStringToQuark(XtCBoolean);
  1046.     QString = XrmPermStringToQuark(XtCString);
  1047.     QCallProc = XrmPermStringToQuark(XtRCallProc);
  1048.     QImmediate = XrmPermStringToQuark(XtRImmediate);
  1049.     QinitialResourcesPersistent = XrmPermStringToQuark(XtNinitialResourcesPersistent);
  1050.     QInitialResourcesPersistent = XrmPermStringToQuark(XtCInitialResourcesPersistent);
  1051.     Qtranslations = XrmPermStringToQuark(XtNtranslations);
  1052.     QbaseTranslations = XrmPermStringToQuark("baseTranslations");
  1053.     QTranslations = XrmPermStringToQuark(XtCTranslations);
  1054.     QTranslationTable = XrmPermStringToQuark(XtRTranslationTable);
  1055.     Qscreen = XrmPermStringToQuark(XtNscreen);
  1056.     QScreen = XrmPermStringToQuark(XtCScreen);
  1057. }
  1058.