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