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