Resources.c revision 9e7bcd65
1444c061aSmrg/***********************************************************
2249c3046SmrgCopyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
31477040fSmrg
41477040fSmrgPermission is hereby granted, free of charge, to any person obtaining a
51477040fSmrgcopy of this software and associated documentation files (the "Software"),
61477040fSmrgto deal in the Software without restriction, including without limitation
71477040fSmrgthe rights to use, copy, modify, merge, publish, distribute, sublicense,
81477040fSmrgand/or sell copies of the Software, and to permit persons to whom the
91477040fSmrgSoftware is furnished to do so, subject to the following conditions:
101477040fSmrg
111477040fSmrgThe above copyright notice and this permission notice (including the next
121477040fSmrgparagraph) shall be included in all copies or substantial portions of the
131477040fSmrgSoftware.
141477040fSmrg
151477040fSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
161477040fSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171477040fSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
181477040fSmrgTHE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
191477040fSmrgLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
201477040fSmrgFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
211477040fSmrgDEALINGS IN THE SOFTWARE.
221477040fSmrg
231477040fSmrgCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
24444c061aSmrg
25444c061aSmrg                        All Rights Reserved
26444c061aSmrg
271477040fSmrgPermission to use, copy, modify, and distribute this software and its
281477040fSmrgdocumentation for any purpose and without fee is hereby granted,
29444c061aSmrgprovided that the above copyright notice appear in all copies and that
301477040fSmrgboth that copyright notice and this permission notice appear in
311477040fSmrgsupporting documentation, and that the name of Digital not be
32444c061aSmrgused in advertising or publicity pertaining to distribution of the
331477040fSmrgsoftware without specific, written prior permission.
34444c061aSmrg
35444c061aSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
36444c061aSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
37444c061aSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
38444c061aSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
39444c061aSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
40444c061aSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
41444c061aSmrgSOFTWARE.
42444c061aSmrg
43444c061aSmrg******************************************************************/
44444c061aSmrg
45444c061aSmrg/*
46444c061aSmrg
47444c061aSmrgCopyright 1987, 1988, 1994, 1998  The Open Group
48444c061aSmrg
49444c061aSmrgPermission to use, copy, modify, distribute, and sell this software and its
50444c061aSmrgdocumentation for any purpose is hereby granted without fee, provided that
51444c061aSmrgthe above copyright notice appear in all copies and that both that
52444c061aSmrgcopyright notice and this permission notice appear in supporting
53444c061aSmrgdocumentation.
54444c061aSmrg
55444c061aSmrgThe above copyright notice and this permission notice shall be included in
56444c061aSmrgall copies or substantial portions of the Software.
57444c061aSmrg
58444c061aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59444c061aSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60444c061aSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
61444c061aSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
62444c061aSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
63444c061aSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
64444c061aSmrg
65444c061aSmrgExcept as contained in this notice, the name of The Open Group shall not be
66444c061aSmrgused in advertising or otherwise to promote the sale, use or other dealings
67444c061aSmrgin this Software without prior written authorization from The Open Group.
68444c061aSmrg
69444c061aSmrg*/
70444c061aSmrg
71444c061aSmrg/*LINTLIBRARY*/
72444c061aSmrg#ifdef HAVE_CONFIG_H
73444c061aSmrg#include <config.h>
74444c061aSmrg#endif
75444c061aSmrg#include "IntrinsicI.h"
76444c061aSmrg#include "VarargsI.h"
77444c061aSmrg#include "Shell.h"
78444c061aSmrg#include "ShellP.h"
79444c061aSmrg#include "StringDefs.h"
80444c061aSmrg#include <stdio.h>
81444c061aSmrg
82444c061aSmrgstatic XrmClass	QBoolean, QString, QCallProc, QImmediate;
83444c061aSmrgstatic XrmName QinitialResourcesPersistent, QInitialResourcesPersistent;
84444c061aSmrgstatic XrmClass QTranslations, QTranslationTable;
85444c061aSmrgstatic XrmName Qtranslations, QbaseTranslations;
86444c061aSmrgstatic XrmName Qscreen;
87444c061aSmrgstatic XrmClass QScreen;
88444c061aSmrg
89444c061aSmrg#ifdef CRAY
90444c061aSmrgvoid Cjump();
91444c061aSmrgchar *Cjumpp = (char *) Cjump;
92444c061aSmrgvoid Cjump() {}
93444c061aSmrg#endif
94444c061aSmrg
95444c061aSmrgvoid _XtCopyFromParent(
96444c061aSmrg    Widget      widget,
97444c061aSmrg    int		offset,
98444c061aSmrg    XrmValue    *value)
99444c061aSmrg{
100444c061aSmrg    if (widget->core.parent == NULL) {
101444c061aSmrg	XtAppWarningMsg(XtWidgetToApplicationContext(widget),
102444c061aSmrg		"invalidParent","xtCopyFromParent",XtCXtToolkitError,
103444c061aSmrg                  "CopyFromParent must have non-NULL parent",
104444c061aSmrg		  (String *)NULL, (Cardinal *)NULL);
105444c061aSmrg        value->addr = NULL;
106444c061aSmrg        return;
107444c061aSmrg    }
108444c061aSmrg    value->addr = (XPointer)(((char *)widget->core.parent) + offset);
109444c061aSmrg} /* _XtCopyFromParent */
110444c061aSmrg
111444c061aSmrg
112444c061aSmrgvoid _XtCopyFromArg(
113444c061aSmrg    XtArgVal src,
114444c061aSmrg    char* dst,
115444c061aSmrg    register unsigned int size)
116444c061aSmrg{
117444c061aSmrg    if (size > sizeof(XtArgVal))
118444c061aSmrg	(void) memmove((char *) dst, (char *)  src, (int) size);
119444c061aSmrg    else {
120444c061aSmrg	union {
121444c061aSmrg	    long	longval;
122444c061aSmrg#ifdef LONG64
123444c061aSmrg	    int		intval;
124444c061aSmrg#endif
125444c061aSmrg	    short	shortval;
126444c061aSmrg	    char	charval;
127444c061aSmrg	    char*	charptr;
128444c061aSmrg	    XtPointer	ptr;
129444c061aSmrg	} u;
130444c061aSmrg	char *p = (char*)&u;
131444c061aSmrg	if	(size == sizeof(long))	    u.longval = (long)src;
132444c061aSmrg#ifdef LONG64
133444c061aSmrg	else if (size == sizeof(int))	    u.intval = (int)src;
134444c061aSmrg#endif
135444c061aSmrg	else if (size == sizeof(short))	    u.shortval = (short)src;
136444c061aSmrg	else if (size == sizeof(char))	    u.charval = (char)src;
137444c061aSmrg	else if (size == sizeof(XtPointer)) u.ptr = (XtPointer)src;
138444c061aSmrg	else if (size == sizeof(char*))	    u.charptr = (char*)src;
139444c061aSmrg	else				    p = (char*)&src;
140444c061aSmrg
141444c061aSmrg	(void) memmove(dst, p, (int) size);
142444c061aSmrg    }
143444c061aSmrg} /* _XtCopyFromArg */
144444c061aSmrg
145444c061aSmrgvoid _XtCopyToArg(
146444c061aSmrg    char* src,
147444c061aSmrg    XtArgVal *dst,
148444c061aSmrg    register unsigned int size)
149444c061aSmrg{
150444c061aSmrg    if (!*dst) {
151444c061aSmrg#ifdef GETVALUES_BUG
152444c061aSmrg	/* old GetValues semantics (storing directly into arglists) are bad,
153444c061aSmrg	 * but preserve for compatibility as long as arglist contains NULL.
154444c061aSmrg	 */
155444c061aSmrg	union {
156444c061aSmrg	    long	longval;
157444c061aSmrg#ifdef LONG64
158444c061aSmrg	    int		intval;
159444c061aSmrg#endif
160444c061aSmrg	    short	shortval;
161444c061aSmrg	    char	charval;
162444c061aSmrg	    char*	charptr;
163444c061aSmrg	    XtPointer	ptr;
164444c061aSmrg	} u;
165444c061aSmrg	if (size <= sizeof(XtArgVal)) {
166444c061aSmrg	    (void) memmove((char*)&u, (char*)src, (int)size );
167444c061aSmrg	    if	    (size == sizeof(long)) 	*dst = (XtArgVal)u.longval;
168444c061aSmrg#ifdef LONG64
169444c061aSmrg	    else if (size == sizeof(int))	*dst = (XtArgVal)u.intval;
170444c061aSmrg#endif
171444c061aSmrg	    else if (size == sizeof(short))	*dst = (XtArgVal)u.shortval;
172444c061aSmrg	    else if (size == sizeof(char))	*dst = (XtArgVal)u.charval;
173444c061aSmrg	    else if (size == sizeof(char*))	*dst = (XtArgVal)u.charptr;
174444c061aSmrg	    else if (size == sizeof(XtPointer))	*dst = (XtArgVal)u.ptr;
175444c061aSmrg	    else (void) memmove((char*)dst, (char*)src, (int)size );
176444c061aSmrg	}
177444c061aSmrg	else
178444c061aSmrg	    (void) memmove((char*)dst, (char*)src, (int)size );
179444c061aSmrg#else
180444c061aSmrg	XtErrorMsg("invalidGetValues", "xtGetValues", XtCXtToolkitError,
181444c061aSmrg	    "NULL ArgVal in XtGetValues", (String*) NULL, (Cardinal*) NULL);
182444c061aSmrg#endif
183444c061aSmrg    }
184444c061aSmrg    else {
185444c061aSmrg	/* proper GetValues semantics: argval is pointer to destination */
186444c061aSmrg	(void) memmove((char*)*dst, (char*)src, (int)size );
187444c061aSmrg    }
188444c061aSmrg} /* _XtCopyToArg */
189444c061aSmrg
190444c061aSmrgstatic void CopyToArg(
191444c061aSmrg    char* src,
192444c061aSmrg    XtArgVal *dst,
193444c061aSmrg    register unsigned int size)
194444c061aSmrg{
195444c061aSmrg    if (!*dst) {
196444c061aSmrg	/* old GetValues semantics (storing directly into arglists) are bad,
197444c061aSmrg	 * but preserve for compatibility as long as arglist contains NULL.
198444c061aSmrg	 */
199444c061aSmrg	union {
200444c061aSmrg	    long	longval;
201444c061aSmrg#ifdef LONG64
202444c061aSmrg	    int		intval;
203444c061aSmrg#endif
204444c061aSmrg	    short	shortval;
205444c061aSmrg	    char	charval;
206444c061aSmrg	    char*	charptr;
207444c061aSmrg	    XtPointer	ptr;
208444c061aSmrg	} u;
209444c061aSmrg	if (size <= sizeof(XtArgVal)) {
210444c061aSmrg	    (void) memmove((char*)&u, (char*)src, (int)size );
211444c061aSmrg	    if	    (size == sizeof(long)) 	*dst = (XtArgVal)u.longval;
212444c061aSmrg#ifdef LONG64
213444c061aSmrg	    else if (size == sizeof(int))	*dst = (XtArgVal)u.intval;
214444c061aSmrg#endif
215444c061aSmrg	    else if (size == sizeof(short))	*dst = (XtArgVal)u.shortval;
216444c061aSmrg	    else if (size == sizeof(char))	*dst = (XtArgVal)u.charval;
217444c061aSmrg	    else if (size == sizeof(char*))	*dst = (XtArgVal)u.charptr;
218444c061aSmrg	    else if (size == sizeof(XtPointer))	*dst = (XtArgVal)u.ptr;
219444c061aSmrg	    else (void) memmove((char*)dst, (char*)src, (int)size );
220444c061aSmrg	}
221444c061aSmrg	else
222444c061aSmrg	    (void) memmove((char*)dst, (char*)src, (int)size );
223444c061aSmrg    }
224444c061aSmrg    else {
225444c061aSmrg	/* proper GetValues semantics: argval is pointer to destination */
226444c061aSmrg	(void) memmove((char*)*dst, (char*)src, (int)size );
227444c061aSmrg    }
228444c061aSmrg} /* CopyToArg */
229444c061aSmrg
230444c061aSmrg
231444c061aSmrgstatic Cardinal CountTreeDepth(
232444c061aSmrg    Widget w)
233444c061aSmrg{
234444c061aSmrg    Cardinal count;
235444c061aSmrg
2369e7bcd65Smrg    for (count = 1; w != NULL; w = (Widget) w->core.parent)
237444c061aSmrg	count++;
238444c061aSmrg
239444c061aSmrg    return count;
240444c061aSmrg}
241444c061aSmrg
242444c061aSmrgstatic void GetNamesAndClasses(
243444c061aSmrg    register Widget	  w,
244444c061aSmrg    register XrmNameList  names,
245444c061aSmrg    register XrmClassList classes)
246444c061aSmrg{
247444c061aSmrg    register Cardinal length, j;
248444c061aSmrg    register XrmQuark t;
249444c061aSmrg    WidgetClass class;
250444c061aSmrg
251444c061aSmrg    /* Return null-terminated quark arrays, with length the number of
252444c061aSmrg       quarks (not including NULL) */
253444c061aSmrg
254444c061aSmrg    LOCK_PROCESS;
255444c061aSmrg    for (length = 0; w != NULL; w = (Widget) w->core.parent) {
256444c061aSmrg	names[length] = w->core.xrm_name;
257444c061aSmrg	class = XtClass(w);
258444c061aSmrg	/* KLUDGE KLUDGE KLUDGE KLUDGE */
259444c061aSmrg	if (w->core.parent == NULL && XtIsApplicationShell(w)) {
260444c061aSmrg	    classes[length] =
261444c061aSmrg		((ApplicationShellWidget) w)->application.xrm_class;
262444c061aSmrg	} else classes[length] = class->core_class.xrm_class;
263444c061aSmrg	length++;
264444c061aSmrg     }
265444c061aSmrg    UNLOCK_PROCESS;
266444c061aSmrg    /* They're in backwards order, flop them around */
267444c061aSmrg    for (j = 0; j < length/2; j++) {
268444c061aSmrg	t = names[j];
269444c061aSmrg	names[j] = names[length-j-1];
270444c061aSmrg	names[length-j-1] = t;
271444c061aSmrg        t = classes[j];
272444c061aSmrg	classes[j] = classes[length-j-1];
273444c061aSmrg	classes[length-j-1] = t;
274444c061aSmrg    }
275444c061aSmrg    names[length] = NULLQUARK;
276444c061aSmrg    classes[length] = NULLQUARK;
277444c061aSmrg} /* GetNamesAndClasses */
278444c061aSmrg
279444c061aSmrg
280444c061aSmrg/* Spiffy fast compiled form of resource list.				*/
281444c061aSmrg/* XtResourceLists are compiled in-place into XrmResourceLists		*/
282444c061aSmrg/* All atoms are replaced by quarks, and offsets are -offset-1 to	*/
283444c061aSmrg/* indicate that this list has been compiled already			*/
284444c061aSmrg
285444c061aSmrgvoid _XtCompileResourceList(
286444c061aSmrg    register XtResourceList resources,
287444c061aSmrg    	     Cardinal       num_resources)
288444c061aSmrg{
289444c061aSmrg    register Cardinal count;
290444c061aSmrg
291444c061aSmrg#define xrmres  ((XrmResourceList) resources)
292444c061aSmrg#define PSToQ   XrmPermStringToQuark
293444c061aSmrg
294444c061aSmrg    for (count = 0; count < num_resources; resources++, count++) {
295444c061aSmrg    	xrmres->xrm_name	 = PSToQ(resources->resource_name);
296444c061aSmrg    	xrmres->xrm_class	 = PSToQ(resources->resource_class);
297444c061aSmrg    	xrmres->xrm_type	 = PSToQ(resources->resource_type);
298444c061aSmrg        xrmres->xrm_offset	 = (Cardinal)
299444c061aSmrg		(-(int)resources->resource_offset - 1);
300444c061aSmrg    	xrmres->xrm_default_type = PSToQ(resources->default_type);
301444c061aSmrg    }
302444c061aSmrg#undef PSToQ
303444c061aSmrg#undef xrmres
304444c061aSmrg} /* _XtCompileResourceList */
305444c061aSmrg
306444c061aSmrg/* Like _XtCompileResourceList, but strings are not permanent */
307444c061aSmrgstatic void  XrmCompileResourceListEphem(
308444c061aSmrg    register XtResourceList resources,
309444c061aSmrg    	     Cardinal       num_resources)
310444c061aSmrg{
311444c061aSmrg    register Cardinal count;
312444c061aSmrg
313444c061aSmrg#define xrmres  ((XrmResourceList) resources)
314444c061aSmrg
315444c061aSmrg    for (count = 0; count < num_resources; resources++, count++) {
316444c061aSmrg    	xrmres->xrm_name	 = StringToName(resources->resource_name);
317444c061aSmrg    	xrmres->xrm_class	 = StringToClass(resources->resource_class);
318444c061aSmrg    	xrmres->xrm_type	 = StringToQuark(resources->resource_type);
319444c061aSmrg        xrmres->xrm_offset	 = (Cardinal)
320444c061aSmrg		(-(int)resources->resource_offset - 1);
321444c061aSmrg    	xrmres->xrm_default_type = StringToQuark(resources->default_type);
322444c061aSmrg    }
323444c061aSmrg#undef xrmres
324444c061aSmrg} /* XrmCompileResourceListEphem */
325444c061aSmrg
326444c061aSmrgstatic void BadSize(
327444c061aSmrg    Cardinal size,
328444c061aSmrg    XrmQuark name)
329444c061aSmrg{
330444c061aSmrg    String params[2];
331444c061aSmrg    Cardinal num_params = 2;
332444c061aSmrg
333444c061aSmrg    params[0] = (String)(long) size;
334444c061aSmrg    params[1] = XrmQuarkToString(name);
335444c061aSmrg    XtWarningMsg("invalidSizeOverride", "xtDependencies", XtCXtToolkitError,
336444c061aSmrg	"Representation size %d must match superclass's to override %s",
337444c061aSmrg	params, &num_params);
338444c061aSmrg} /* BadType */
339444c061aSmrg
340444c061aSmrg/*
341444c061aSmrg * Create a new resource list, with the class resources following the
342444c061aSmrg * superclass's resources.  If a resource in the class list overrides
343444c061aSmrg * a superclass resource, then just replace the superclass entry in place.
344444c061aSmrg *
345444c061aSmrg * At the same time, add a level of indirection to the XtResourceList to
346444c061aSmrg * create and XrmResourceList.
347444c061aSmrg */
348444c061aSmrgvoid _XtDependencies(
349444c061aSmrg    XtResourceList  *class_resp,	/* VAR */
350444c061aSmrg    Cardinal	    *class_num_resp,    /* VAR */
351444c061aSmrg    XrmResourceList *super_res,
352444c061aSmrg    Cardinal	    super_num_res,
353444c061aSmrg    Cardinal	    super_widget_size)
354444c061aSmrg{
355444c061aSmrg    register XrmResourceList *new_res;
356444c061aSmrg	     Cardinal	     new_num_res;
357444c061aSmrg	     XrmResourceList class_res = (XrmResourceList) *class_resp;
358444c061aSmrg	     Cardinal        class_num_res = *class_num_resp;
359444c061aSmrg    register Cardinal	     i, j;
360444c061aSmrg	     Cardinal        new_next;
361444c061aSmrg
362444c061aSmrg    if (class_num_res == 0) {
363444c061aSmrg	/* Just point to superclass resource list */
364444c061aSmrg	*class_resp = (XtResourceList) super_res;
365444c061aSmrg	*class_num_resp = super_num_res;
366444c061aSmrg	return;
367444c061aSmrg    }
368444c061aSmrg
369444c061aSmrg    /* Allocate and initialize new_res with superclass resource pointers */
370444c061aSmrg    new_num_res = super_num_res + class_num_res;
371444c061aSmrg    new_res = (XrmResourceList *) __XtMalloc(new_num_res*sizeof(XrmResourceList));
372444c061aSmrg    if (super_num_res > 0)
373444c061aSmrg	XtMemmove(new_res, super_res, super_num_res * sizeof(XrmResourceList));
3749e7bcd65Smrg
375444c061aSmrg    /* Put pointers to class resource entries into new_res */
376444c061aSmrg    new_next = super_num_res;
377444c061aSmrg    for (i = 0; i < class_num_res; i++) {
378444c061aSmrg	if ((Cardinal)(-class_res[i].xrm_offset-1) < super_widget_size) {
379444c061aSmrg	    /* Probably an override of superclass resources--look for overlap */
380444c061aSmrg	    for (j = 0; j < super_num_res; j++) {
381444c061aSmrg		if (class_res[i].xrm_offset == new_res[j]->xrm_offset) {
382444c061aSmrg		    /* Spec is silent on what fields subclass can override.
383444c061aSmrg		     * The only two of real concern are type & size.
384444c061aSmrg		     * Although allowing type to be over-ridden introduces
385444c061aSmrg		     * the possibility of errors, it's at present the only
386444c061aSmrg		     * reasonable way to allow a subclass to force a private
387444c061aSmrg		     * converter to be invoked for a subset of fields.
388444c061aSmrg		     */
389444c061aSmrg		    /* We do insist that size be identical to superclass */
390444c061aSmrg		    if (class_res[i].xrm_size != new_res[j]->xrm_size) {
391444c061aSmrg			BadSize(class_res[i].xrm_size,
392444c061aSmrg				(XrmQuark) class_res[i].xrm_name);
393444c061aSmrg			class_res[i].xrm_size = new_res[j]->xrm_size;
394444c061aSmrg		    }
395444c061aSmrg		    new_res[j] = &(class_res[i]);
396444c061aSmrg		    new_num_res--;
397444c061aSmrg		    goto NextResource;
398444c061aSmrg		}
399444c061aSmrg	    } /* for j */
400444c061aSmrg	}
401444c061aSmrg	/* Not an overlap, add an entry to new_res */
402444c061aSmrg	new_res[new_next++] = &(class_res[i]);
403444c061aSmrgNextResource:;
404444c061aSmrg    } /* for i */
405444c061aSmrg
406444c061aSmrg    /* Okay, stuff new resources back into class record */
407444c061aSmrg    *class_resp = (XtResourceList) new_res;
408444c061aSmrg    *class_num_resp = new_num_res;
409444c061aSmrg} /* _XtDependencies */
410444c061aSmrg
411444c061aSmrg
412444c061aSmrgvoid _XtResourceDependencies(
413444c061aSmrg    WidgetClass wc)
414444c061aSmrg{
415444c061aSmrg    WidgetClass sc;
416444c061aSmrg
417444c061aSmrg    sc = wc->core_class.superclass;
418444c061aSmrg    if (sc == NULL) {
419444c061aSmrg	_XtDependencies(&(wc->core_class.resources),
420444c061aSmrg			&(wc->core_class.num_resources),
421444c061aSmrg			(XrmResourceList *) NULL, (unsigned)0, (unsigned)0);
422444c061aSmrg    } else {
423444c061aSmrg	_XtDependencies(&(wc->core_class.resources),
424444c061aSmrg			&(wc->core_class.num_resources),
425444c061aSmrg			(XrmResourceList *) sc->core_class.resources,
426444c061aSmrg			sc->core_class.num_resources,
427444c061aSmrg			sc->core_class.widget_size);
428444c061aSmrg    }
429444c061aSmrg} /* _XtResourceDependencies */
430444c061aSmrg
431444c061aSmrgvoid _XtConstraintResDependencies(
432444c061aSmrg    ConstraintWidgetClass wc)
433444c061aSmrg{
434444c061aSmrg    ConstraintWidgetClass sc;
435444c061aSmrg
436444c061aSmrg    if (wc == (ConstraintWidgetClass) constraintWidgetClass) {
437444c061aSmrg	_XtDependencies(&(wc->constraint_class.resources),
438444c061aSmrg			&(wc->constraint_class.num_resources),
439444c061aSmrg			(XrmResourceList *)NULL, (unsigned)0, (unsigned)0);
440444c061aSmrg    } else {
441444c061aSmrg	sc = (ConstraintWidgetClass) wc->core_class.superclass;
442444c061aSmrg	_XtDependencies(&(wc->constraint_class.resources),
443444c061aSmrg			&(wc->constraint_class.num_resources),
444444c061aSmrg			(XrmResourceList *) sc->constraint_class.resources,
445444c061aSmrg			sc->constraint_class.num_resources,
446444c061aSmrg			sc->constraint_class.constraint_size);
447444c061aSmrg    }
448444c061aSmrg} /* _XtConstraintResDependencies */
449444c061aSmrg
450444c061aSmrg
451444c061aSmrg
4529e7bcd65Smrg
453444c061aSmrgXrmResourceList* _XtCreateIndirectionTable (
454444c061aSmrg    XtResourceList  resources,
455444c061aSmrg    Cardinal	    num_resources)
456444c061aSmrg{
457444c061aSmrg    register Cardinal idx;
458444c061aSmrg    XrmResourceList* table;
459444c061aSmrg
460444c061aSmrg    table = (XrmResourceList*)__XtMalloc(num_resources * sizeof(XrmResourceList));
461444c061aSmrg    for (idx = 0; idx < num_resources; idx++)
462444c061aSmrg        table[idx] = (XrmResourceList)(&(resources[idx]));
463444c061aSmrg    return table;
464444c061aSmrg}
465444c061aSmrg
466444c061aSmrgstatic XtCacheRef *GetResources(
467444c061aSmrg    Widget	    widget,	    /* Widget resources are associated with */
468444c061aSmrg    char*	    base,	    /* Base address of memory to write to   */
469444c061aSmrg    XrmNameList     names,	    /* Full inheritance name of widget      */
470444c061aSmrg    XrmClassList    classes,	    /* Full inheritance class of widget     */
471444c061aSmrg    XrmResourceList*  table,	    /* The list of resources required.      */
472444c061aSmrg    unsigned	    num_resources,  /* number of items in resource list     */
473444c061aSmrg    XrmQuarkList    quark_args,     /* Arg names quarkified		    */
474444c061aSmrg    ArgList	    args,	    /* ArgList to override resources	    */
475444c061aSmrg    unsigned	    num_args,       /* number of items in arg list	    */
476444c061aSmrg    XtTypedArgList  typed_args,	    /* Typed arg list to override resources */
477444c061aSmrg    Cardinal*	    pNumTypedArgs,  /* number of items in typed arg list    */
478444c061aSmrg    Boolean	    tm_hack)	    /* do baseTranslations		    */
479444c061aSmrg{
480444c061aSmrg/*
481444c061aSmrg * assert: *pNumTypedArgs == 0 if num_args > 0
482444c061aSmrg * assert: num_args == 0 if *pNumTypedArgs > 0
483444c061aSmrg */
484444c061aSmrg#define SEARCHLISTLEN 100
485444c061aSmrg#define MAXRESOURCES  400
486444c061aSmrg
487444c061aSmrg    XrmValue	    value;
488444c061aSmrg    XrmQuark	    rawType;
489444c061aSmrg    XrmValue	    convValue;
490444c061aSmrg    XrmHashTable    stackSearchList[SEARCHLISTLEN];
491444c061aSmrg    XrmHashTable    *searchList = stackSearchList;
492444c061aSmrg    unsigned int    searchListSize = SEARCHLISTLEN;
493444c061aSmrg    Boolean	    found[MAXRESOURCES];
494444c061aSmrg    int		    typed[MAXRESOURCES];
495444c061aSmrg    XtCacheRef	    cache_ref[MAXRESOURCES];
496444c061aSmrg    XtCacheRef      *cache_ptr, *cache_base;
497444c061aSmrg    Boolean	    persistent_resources = True;
498444c061aSmrg    Boolean	    found_persistence = False;
499444c061aSmrg    int		    num_typed_args = *pNumTypedArgs;
500444c061aSmrg    XrmDatabase     db;
501444c061aSmrg    Boolean	    do_tm_hack = False;
502444c061aSmrg
503444c061aSmrg    if ((args == NULL) && (num_args != 0)) {
504444c061aSmrg    	XtAppWarningMsg(XtWidgetToApplicationContext(widget),
505444c061aSmrg		"invalidArgCount","getResources",XtCXtToolkitError,
506444c061aSmrg                 "argument count > 0 on NULL argument list",
507444c061aSmrg                   (String *)NULL, (Cardinal *)NULL);
508444c061aSmrg	num_args = 0;
509444c061aSmrg    }
510444c061aSmrg    if (num_resources == 0) {
511444c061aSmrg	return NULL;
512444c061aSmrg    } else if (num_resources >= MAXRESOURCES) {
513444c061aSmrg    	XtAppWarningMsg(XtWidgetToApplicationContext(widget),
514444c061aSmrg		"invalidResourceCount","getResources",XtCXtToolkitError,
515444c061aSmrg              "too many resources",
516444c061aSmrg	      (String *)NULL, (Cardinal *)NULL);
517444c061aSmrg	return NULL;
518444c061aSmrg    } else if (table == NULL) {
519444c061aSmrg    	XtAppWarningMsg(XtWidgetToApplicationContext(widget),
520444c061aSmrg		"invalidResourceCount","getResources",XtCXtToolkitError,
521444c061aSmrg              "resource count > 0 on NULL resource list",
522444c061aSmrg	      (String *)NULL, (Cardinal *)NULL);
523444c061aSmrg	return NULL;
524444c061aSmrg    }
525444c061aSmrg
526444c061aSmrg    /* Mark each resource as not found on arg list */
527444c061aSmrg    bzero((char *) found, (int) (num_resources * sizeof(Boolean)));
528444c061aSmrg    bzero((char *) typed, (int) (num_resources * sizeof(int)));
529444c061aSmrg
530444c061aSmrg    /* Copy the args into the resources, mark each as found */
531444c061aSmrg    {
532444c061aSmrg	register ArgList	    arg;
533444c061aSmrg	register XtTypedArgList	    typed_arg;
534444c061aSmrg	register XrmName	    argName;
535444c061aSmrg	register Cardinal	    j;
536444c061aSmrg	register int	    i;
537444c061aSmrg	register XrmResourceList rx;
538444c061aSmrg	register XrmResourceList *res;
539444c061aSmrg	for (arg = args, i = 0; (Cardinal)i < num_args; i++, arg++) {
540444c061aSmrg	    argName = quark_args[i];
541444c061aSmrg	    if (argName == QinitialResourcesPersistent) {
542444c061aSmrg		persistent_resources = (Boolean)arg->value;
543444c061aSmrg		found_persistence = True;
544444c061aSmrg		continue;
545444c061aSmrg	    }
546444c061aSmrg	    for (j = 0, res = table; j < num_resources; j++, res++) {
547444c061aSmrg		rx = *res;
548444c061aSmrg		if (argName == rx->xrm_name) {
549444c061aSmrg		    _XtCopyFromArg(
550444c061aSmrg			arg->value,
551444c061aSmrg			base - rx->xrm_offset - 1,
552444c061aSmrg			rx->xrm_size);
553444c061aSmrg		    found[j] = TRUE;
554444c061aSmrg		    break;
555444c061aSmrg		}
556444c061aSmrg	    }
557444c061aSmrg	}
558444c061aSmrg	for (typed_arg = typed_args, i = 0; i < num_typed_args;
559444c061aSmrg	     i++, typed_arg++) {
560444c061aSmrg	    register XrmRepresentation argType;
561444c061aSmrg	    argName = quark_args[i];
5629e7bcd65Smrg	    argType = (typed_arg->type == NULL) ? NULLQUARK
563444c061aSmrg		: XrmStringToRepresentation(typed_arg->type);
564444c061aSmrg	    if (argName == QinitialResourcesPersistent) {
565444c061aSmrg		persistent_resources = (Boolean)typed_arg->value;
5669e7bcd65Smrg		found_persistence = True;
567444c061aSmrg		break;
568444c061aSmrg	    }
569444c061aSmrg	    for (j = 0, res = table; j < num_resources; j++, res++) {
570444c061aSmrg		rx = *res;
571444c061aSmrg		if (argName == rx->xrm_name) {
572444c061aSmrg		    if (argType != NULLQUARK && argType != rx->xrm_type) {
573444c061aSmrg			typed[j] = i + 1;
574444c061aSmrg		    } else {
575444c061aSmrg			_XtCopyFromArg(
576444c061aSmrg				       typed_arg->value,
577444c061aSmrg				       base - rx->xrm_offset - 1,
578444c061aSmrg				       rx->xrm_size);
579444c061aSmrg		    }
580444c061aSmrg		    found[j] = TRUE;
581444c061aSmrg		    break;
5829e7bcd65Smrg		}
583444c061aSmrg	    }
584444c061aSmrg	}
585444c061aSmrg    }
586444c061aSmrg
587444c061aSmrg    /* Ask resource manager for a list of database levels that we can
588444c061aSmrg       do a single-level search on each resource */
589444c061aSmrg
590444c061aSmrg    db = XtScreenDatabase(XtScreenOfObject(widget));
591444c061aSmrg    while (!XrmQGetSearchList(db, names, classes,
592444c061aSmrg			      searchList, searchListSize)) {
593444c061aSmrg	if (searchList == stackSearchList)
594444c061aSmrg	    searchList = NULL;
595444c061aSmrg	searchList = (XrmHashTable*)XtRealloc((char*)searchList,
596444c061aSmrg					      sizeof(XrmHashTable) *
597444c061aSmrg					      (searchListSize *= 2));
598444c061aSmrg    }
5999e7bcd65Smrg
600444c061aSmrg    if (persistent_resources)
601444c061aSmrg	cache_base = NULL;
602444c061aSmrg    else
603444c061aSmrg	cache_base = cache_ref;
604444c061aSmrg    /* geez, this is an ugly mess */
605444c061aSmrg    if (XtIsShell(widget)) {
606444c061aSmrg	register XrmResourceList  *res;
607444c061aSmrg	register Cardinal	  j;
608444c061aSmrg	Screen *oldscreen = widget->core.screen;
609444c061aSmrg
610444c061aSmrg	/* look up screen resource first, since real rdb depends on it */
611444c061aSmrg	for (res = table, j = 0; j < num_resources; j++, res++) {
612444c061aSmrg	    if ((*res)->xrm_name != Qscreen)
613444c061aSmrg		continue;
614444c061aSmrg	    if (typed[j]) {
615444c061aSmrg		register XtTypedArg* arg = typed_args + typed[j] - 1;
616444c061aSmrg		XrmQuark from_type;
617444c061aSmrg		XrmValue from_val, to_val;
618444c061aSmrg
619444c061aSmrg		from_type = StringToQuark(arg->type);
620444c061aSmrg		from_val.size = arg->size;
621444c061aSmrg		if ((from_type == QString) || ((unsigned) arg->size > sizeof(XtArgVal)))
622444c061aSmrg		    from_val.addr = (XPointer)arg->value;
623444c061aSmrg		else
624444c061aSmrg		    from_val.addr = (XPointer)&arg->value;
625444c061aSmrg		to_val.size = sizeof(Screen*);
626444c061aSmrg		to_val.addr = (XPointer)&widget->core.screen;
627444c061aSmrg		found[j] = _XtConvert(widget, from_type, &from_val,
628444c061aSmrg				      QScreen, &to_val, cache_base);
629444c061aSmrg		if (cache_base && *cache_base)
630444c061aSmrg		    cache_base++;
631444c061aSmrg	    }
632444c061aSmrg	    if (!found[j]) {
633444c061aSmrg		if (XrmQGetSearchResource(searchList, Qscreen, QScreen,
634444c061aSmrg				      &rawType, &value)) {
635444c061aSmrg		    if (rawType != QScreen) {
636444c061aSmrg			convValue.size = sizeof(Screen*);
637444c061aSmrg			convValue.addr = (XPointer)&widget->core.screen;
638444c061aSmrg			(void)_XtConvert(widget, rawType, &value,
639444c061aSmrg					 QScreen, &convValue, cache_base);
640444c061aSmrg			if (cache_base && *cache_base)
641444c061aSmrg			    cache_base++;
642444c061aSmrg		    } else {
643444c061aSmrg			widget->core.screen = *((Screen **)value.addr);
644444c061aSmrg		    }
645444c061aSmrg		}
646444c061aSmrg	    }
647444c061aSmrg	    break;
648444c061aSmrg	}
649444c061aSmrg	/* now get the database to use for the rest of the resources */
650444c061aSmrg	if (widget->core.screen != oldscreen) {
651444c061aSmrg	    db = XtScreenDatabase(widget->core.screen);
652444c061aSmrg	    while (!XrmQGetSearchList(db, names, classes,
653444c061aSmrg				      searchList, searchListSize)) {
654444c061aSmrg		if (searchList == stackSearchList)
655444c061aSmrg		    searchList = NULL;
656444c061aSmrg		searchList = (XrmHashTable*)XtRealloc((char*)searchList,
657444c061aSmrg						      sizeof(XrmHashTable) *
658444c061aSmrg						      (searchListSize *= 2));
659444c061aSmrg	    }
660444c061aSmrg	}
661444c061aSmrg    }
662444c061aSmrg
663444c061aSmrg    /* go to the resource manager for those resources not found yet */
664444c061aSmrg    /* if it's not in the resource database use the default value   */
665444c061aSmrg
666444c061aSmrg    {
667444c061aSmrg	register XrmResourceList  rx;
668444c061aSmrg	register XrmResourceList  *res;
669444c061aSmrg	register Cardinal	  j;
670444c061aSmrg	register XrmRepresentation xrm_type;
671444c061aSmrg	register XrmRepresentation xrm_default_type;
672444c061aSmrg	char	char_val;
673444c061aSmrg	short	short_val;
674444c061aSmrg	int	int_val;
675444c061aSmrg	long	long_val;
676444c061aSmrg	char*	char_ptr;
677444c061aSmrg
678444c061aSmrg	if (!found_persistence) {
679444c061aSmrg	    if (XrmQGetSearchResource(searchList, QinitialResourcesPersistent,
680444c061aSmrg			QInitialResourcesPersistent, &rawType, &value)) {
681444c061aSmrg		if (rawType != QBoolean) {
682444c061aSmrg		    convValue.size = sizeof(Boolean);
683444c061aSmrg		    convValue.addr = (XPointer)&persistent_resources;
684444c061aSmrg		    (void)_XtConvert(widget, rawType, &value, QBoolean,
685444c061aSmrg				     &convValue, NULL);
686444c061aSmrg		}
687444c061aSmrg		else
688444c061aSmrg		    persistent_resources = *(Boolean*)value.addr;
689444c061aSmrg	    }
690444c061aSmrg	}
691444c061aSmrg	if (persistent_resources)
692444c061aSmrg	    cache_ptr = NULL;
693444c061aSmrg	else if (cache_base)
694444c061aSmrg	    cache_ptr = cache_base;
695444c061aSmrg	else
696444c061aSmrg	    cache_ptr = cache_ref;
697444c061aSmrg
698444c061aSmrg	for (res = table, j = 0; j < num_resources; j++, res++) {
699444c061aSmrg	    rx = *res;
700444c061aSmrg	    xrm_type = rx->xrm_type;
701444c061aSmrg	    if (typed[j]) {
702444c061aSmrg		register XtTypedArg* arg = typed_args + typed[j] - 1;
703444c061aSmrg
704444c061aSmrg		/*
7059e7bcd65Smrg                 * This resource value has been specified as a typed arg and
7069e7bcd65Smrg		 * has to be converted. Typed arg conversions are done here
707444c061aSmrg		 * to correctly interpose them with normal resource conversions.
708444c061aSmrg                 */
709444c061aSmrg		XrmQuark	    from_type;
710444c061aSmrg		XrmValue            from_val, to_val;
711444c061aSmrg		Boolean		    converted;
7129e7bcd65Smrg
713444c061aSmrg		from_type = StringToQuark(arg->type);
714444c061aSmrg    		from_val.size = arg->size;
715444c061aSmrg		if ((from_type == QString) || ((unsigned) arg->size > sizeof(XtArgVal)))
716444c061aSmrg        	    from_val.addr = (XPointer)arg->value;
717444c061aSmrg	        else
718444c061aSmrg            	    from_val.addr = (XPointer)&arg->value;
719444c061aSmrg		to_val.size = rx->xrm_size;
720444c061aSmrg		to_val.addr = base - rx->xrm_offset - 1;
721444c061aSmrg		converted = _XtConvert(widget, from_type, &from_val,
722444c061aSmrg				       xrm_type, &to_val, cache_ptr);
723444c061aSmrg		if (converted) {
724444c061aSmrg
725444c061aSmrg		    /* Copy the converted value back into the typed argument.
726444c061aSmrg		     * normally the data should be <= sizeof(XtArgVal) and
727444c061aSmrg		     * is stored directly into the 'value' field .... BUT
728444c061aSmrg		     * if the resource size is greater than sizeof(XtArgVal)
729444c061aSmrg		     * then we dynamically alloc a block of store to hold the
730444c061aSmrg		     * data and zap a copy in there !!! .... freeing it later
731444c061aSmrg		     * the size field in the typed arg is negated to indicate
732444c061aSmrg		     * that the store pointed to by the value field is
733444c061aSmrg		     * dynamic .......
734444c061aSmrg		     * "freeing" happens in the case of _XtCreate after the
735444c061aSmrg		     * CallInitialize ..... other clients of GetResources
736444c061aSmrg		     * using typed args should be aware of the need to free
737444c061aSmrg		     * this store .....
738444c061aSmrg		     */
739444c061aSmrg
740444c061aSmrg		    if(rx->xrm_size > sizeof(XtArgVal)) {
741444c061aSmrg			arg->value = (XtArgVal) __XtMalloc(rx->xrm_size);
742444c061aSmrg			arg->size = -(arg->size);
743444c061aSmrg		    } else { /* will fit - copy directly into value field */
744444c061aSmrg			arg->value = (XtArgVal) NULL;
745444c061aSmrg		    }
746444c061aSmrg		    CopyToArg((char *)(base - rx->xrm_offset - 1),
747444c061aSmrg				 &arg->value, rx->xrm_size);
748444c061aSmrg
749444c061aSmrg		} else {
750444c061aSmrg		   /* Conversion failed. Get default value. */
751444c061aSmrg		   found[j] = False;
752444c061aSmrg		}
753444c061aSmrg
754444c061aSmrg		if (cache_ptr && *cache_ptr)
755444c061aSmrg		    cache_ptr++;
756444c061aSmrg	    }
757444c061aSmrg
758444c061aSmrg	    if (!found[j]) {
759444c061aSmrg		Boolean	already_copied = False;
760444c061aSmrg		Boolean have_value = False;
761444c061aSmrg
762444c061aSmrg		if (XrmQGetSearchResource(searchList,
763444c061aSmrg			rx->xrm_name, rx->xrm_class, &rawType, &value)) {
764444c061aSmrg		    if (rawType != xrm_type) {
765444c061aSmrg			convValue.size = rx->xrm_size;
766444c061aSmrg			convValue.addr = (XPointer)(base - rx->xrm_offset - 1);
767444c061aSmrg			already_copied = have_value =
768444c061aSmrg			    _XtConvert(widget, rawType, &value,
769444c061aSmrg				       xrm_type, &convValue, cache_ptr);
770444c061aSmrg			if (cache_ptr && *cache_ptr)
771444c061aSmrg			    cache_ptr++;
772444c061aSmrg		    } else have_value = True;
773444c061aSmrg		    if (have_value && rx->xrm_name == Qtranslations)
774444c061aSmrg			do_tm_hack = True;
775444c061aSmrg		}
776444c061aSmrg		LOCK_PROCESS;
777444c061aSmrg		if (!have_value
778444c061aSmrg		    && ((rx->xrm_default_type == QImmediate)
779444c061aSmrg			|| (rx->xrm_default_type == xrm_type)
780444c061aSmrg			|| (rx->xrm_default_addr != NULL))) {
781444c061aSmrg		    /* Convert default value to proper type */
782444c061aSmrg		    xrm_default_type = rx->xrm_default_type;
783444c061aSmrg		    if (xrm_default_type == QCallProc) {
784444c061aSmrg#ifdef CRAY
785444c061aSmrg 			if ( (int) Cjumpp != (int) Cjump)
786444c061aSmrg 			    (*(XtResourceDefaultProc)
787444c061aSmrg			      (((int)(rx->xrm_default_addr))<<2))(
788444c061aSmrg 				 widget,-(rx->xrm_offset+1), &value);
789444c061aSmrg			else
790444c061aSmrg#endif
791444c061aSmrg			(*(XtResourceDefaultProc)(rx->xrm_default_addr))(
792444c061aSmrg			      widget,-(rx->xrm_offset+1), &value);
793444c061aSmrg
794444c061aSmrg		    } else if (xrm_default_type == QImmediate) {
795444c061aSmrg			/* XtRImmediate == XtRString for type XtRString */
796444c061aSmrg			if (xrm_type == QString) {
797444c061aSmrg			    value.addr = rx->xrm_default_addr;
798444c061aSmrg			} else if (rx->xrm_size == sizeof(int)) {
799444c061aSmrg			    int_val = (int)(long)rx->xrm_default_addr;
800444c061aSmrg			    value.addr = (XPointer) &int_val;
801444c061aSmrg			} else if (rx->xrm_size == sizeof(short)) {
802444c061aSmrg			    short_val = (short)(long)rx->xrm_default_addr;
803444c061aSmrg			    value.addr = (XPointer) &short_val;
804444c061aSmrg			} else if (rx->xrm_size == sizeof(char)) {
805444c061aSmrg			    char_val = (char)(long)rx->xrm_default_addr;
806444c061aSmrg			    value.addr = (XPointer) &char_val;
807444c061aSmrg			} else if (rx->xrm_size == sizeof(long)) {
808444c061aSmrg			    long_val = (long)rx->xrm_default_addr;
809444c061aSmrg			    value.addr = (XPointer) &long_val;
810444c061aSmrg			} else if (rx->xrm_size == sizeof(char*)) {
811444c061aSmrg			    char_ptr = (char*)rx->xrm_default_addr;
812444c061aSmrg			    value.addr = (XPointer) &char_ptr;
813444c061aSmrg			} else {
814444c061aSmrg			    value.addr = (XPointer) &(rx->xrm_default_addr);
815444c061aSmrg			}
816444c061aSmrg		    } else if (xrm_default_type == xrm_type) {
817444c061aSmrg			value.addr = rx->xrm_default_addr;
818444c061aSmrg		    } else {
819444c061aSmrg			value.addr = rx->xrm_default_addr;
820444c061aSmrg			if (xrm_default_type == QString) {
821444c061aSmrg			    value.size = strlen((char *)value.addr) + 1;
822444c061aSmrg			} else {
823444c061aSmrg			    value.size = sizeof(XtPointer);
824444c061aSmrg			}
825444c061aSmrg			convValue.size = rx->xrm_size;
826444c061aSmrg			convValue.addr = (XPointer)(base - rx->xrm_offset - 1);
827444c061aSmrg			already_copied =
828444c061aSmrg			    _XtConvert(widget, xrm_default_type, &value,
829444c061aSmrg				       xrm_type, &convValue, cache_ptr);
830444c061aSmrg			if (!already_copied)
831444c061aSmrg			    value.addr = NULL;
832444c061aSmrg			if (cache_ptr && *cache_ptr)
833444c061aSmrg			    cache_ptr++;
834444c061aSmrg		    }
835444c061aSmrg		}
836444c061aSmrg		if (!already_copied) {
837444c061aSmrg		    if (xrm_type == QString) {
838444c061aSmrg			*((String*)(base - rx->xrm_offset - 1)) = value.addr;
839444c061aSmrg		    } else {
840444c061aSmrg			if (value.addr != NULL) {
841444c061aSmrg			    XtMemmove(base - rx->xrm_offset - 1,
842444c061aSmrg				      value.addr, rx->xrm_size);
843444c061aSmrg			} else {
844444c061aSmrg			    /* didn't get value, initialize to NULL... */
845444c061aSmrg			    XtBZero(base - rx->xrm_offset - 1, rx->xrm_size);
846444c061aSmrg			}
847444c061aSmrg		    }
848444c061aSmrg		}
849444c061aSmrg		UNLOCK_PROCESS;
8509e7bcd65Smrg	    }
8519e7bcd65Smrg	}
8529e7bcd65Smrg	for (res = table, j = 0; j < num_resources; j++, res++) {
8539e7bcd65Smrg	    if (!found[j] && typed[j]) {
8549e7bcd65Smrg		/*
8559e7bcd65Smrg		 * This resource value was specified as a typed arg.
8569e7bcd65Smrg		 * However, the default value is being used here since
8579e7bcd65Smrg		 * type type conversion failed, so we compress the list.
8589e7bcd65Smrg		 */
8599e7bcd65Smrg		register XtTypedArg* arg = typed_args + typed[j] - 1;
8609e7bcd65Smrg		register int i;
861444c061aSmrg
8629e7bcd65Smrg		for (i = num_typed_args - typed[j]; i > 0; i--, arg++) {
8639e7bcd65Smrg		    *arg = *(arg+1);
864444c061aSmrg		}
8659e7bcd65Smrg		num_typed_args--;
8669e7bcd65Smrg	    }
867444c061aSmrg	}
868444c061aSmrg	if (tm_hack)
869444c061aSmrg	    widget->core.tm.current_state = NULL;
870444c061aSmrg	if (tm_hack &&
871444c061aSmrg	    (!widget->core.tm.translations ||
872444c061aSmrg	     (do_tm_hack &&
873444c061aSmrg	      widget->core.tm.translations->operation != XtTableReplace)) &&
874444c061aSmrg	    XrmQGetSearchResource(searchList, QbaseTranslations,
875444c061aSmrg				  QTranslations, &rawType, &value)) {
876444c061aSmrg	    if (rawType != QTranslationTable) {
877444c061aSmrg		convValue.size = sizeof(XtTranslations);
878444c061aSmrg		convValue.addr = (XPointer)&widget->core.tm.current_state;
879444c061aSmrg		(void)_XtConvert(widget, rawType, &value,
880444c061aSmrg				 QTranslationTable, &convValue, cache_ptr);
881444c061aSmrg		if (cache_ptr && *cache_ptr)
882444c061aSmrg		    cache_ptr++;
883444c061aSmrg	    } else {
884bdf0f55dSmrg		/* value.addr can be NULL see: !already_copied */
885bdf0f55dSmrg		if (value.addr)
886bdf0f55dSmrg		    *((XtTranslations *)&widget->core.tm.current_state) =
887bdf0f55dSmrg			*((XtTranslations *)value.addr);
888444c061aSmrg	    }
889444c061aSmrg	}
890444c061aSmrg    }
891444c061aSmrg    if ((Cardinal)num_typed_args != *pNumTypedArgs) *pNumTypedArgs = num_typed_args;
892444c061aSmrg    if (searchList != stackSearchList) XtFree((char*)searchList);
893444c061aSmrg    if (!cache_ptr)
894444c061aSmrg	cache_ptr = cache_base;
895444c061aSmrg    if (cache_ptr && cache_ptr != cache_ref) {
896444c061aSmrg	int cache_ref_size = cache_ptr - cache_ref;
897444c061aSmrg	XtCacheRef *refs = (XtCacheRef*)
898444c061aSmrg	    __XtMalloc((unsigned)sizeof(XtCacheRef)*(cache_ref_size + 1));
899444c061aSmrg	(void) memmove(refs, cache_ref, sizeof(XtCacheRef)*cache_ref_size );
900444c061aSmrg	refs[cache_ref_size] = NULL;
901444c061aSmrg	return refs;
902444c061aSmrg    }
903444c061aSmrg    return (XtCacheRef*)NULL;
904444c061aSmrg}
905444c061aSmrg
906444c061aSmrg
907444c061aSmrg
908444c061aSmrgstatic void CacheArgs(
909444c061aSmrg    ArgList	    args,
910444c061aSmrg    Cardinal	    num_args,
911444c061aSmrg    XtTypedArgList  typed_args,
912444c061aSmrg    Cardinal	    num_typed_args,
913444c061aSmrg    XrmQuarkList    quark_cache,
914444c061aSmrg    Cardinal	    num_quarks,
915444c061aSmrg    XrmQuarkList    *pQuarks)       /* RETURN */
916444c061aSmrg{
917444c061aSmrg    register XrmQuarkList   quarks;
918444c061aSmrg    register Cardinal       i;
919444c061aSmrg    register Cardinal       count;
920444c061aSmrg
921444c061aSmrg    count = (args != NULL) ? num_args : num_typed_args;
922444c061aSmrg
923444c061aSmrg    if (num_quarks < count) {
924444c061aSmrg	quarks = (XrmQuarkList) __XtMalloc(count * sizeof(XrmQuark));
925444c061aSmrg    } else {
926444c061aSmrg	quarks = quark_cache;
927444c061aSmrg    }
928444c061aSmrg    *pQuarks = quarks;
929444c061aSmrg
930444c061aSmrg    if (args != NULL) {
931444c061aSmrg	for (i = count; i; i--)
932444c061aSmrg	    *quarks++ = StringToQuark((args++)->name);
933444c061aSmrg    }
934444c061aSmrg    else {
935444c061aSmrg	for (i = count; i; i--)
936444c061aSmrg	    *quarks++ = StringToQuark((typed_args++)->name);
937444c061aSmrg    }
938444c061aSmrg}
939444c061aSmrg
940444c061aSmrg#define FreeCache(cache, pointer) \
941444c061aSmrg	  if (cache != pointer) XtFree((char *)pointer)
942444c061aSmrg
943444c061aSmrg
944444c061aSmrgXtCacheRef *_XtGetResources(
945444c061aSmrg    register 	Widget	  	w,
946444c061aSmrg    		ArgList	  	args,
947444c061aSmrg    		Cardinal  	num_args,
948444c061aSmrg		XtTypedArgList	typed_args,
949444c061aSmrg		Cardinal*	num_typed_args)
950444c061aSmrg{
951444c061aSmrg    XrmName	    *names, names_s[50];
952444c061aSmrg    XrmClass	    *classes, classes_s[50];
953444c061aSmrg    XrmQuark	    quark_cache[100];
954444c061aSmrg    XrmQuarkList    quark_args;
955444c061aSmrg    WidgetClass     wc;
956444c061aSmrg    ConstraintWidgetClass   cwc;
957444c061aSmrg    XtCacheRef	    *cache_refs, *cache_refs_core;
958444c061aSmrg    Cardinal	    count;
959444c061aSmrg
960444c061aSmrg    wc = XtClass(w);
961444c061aSmrg
962444c061aSmrg    count = CountTreeDepth(w);
963444c061aSmrg    names = (XrmName*) XtStackAlloc (count * sizeof(XrmName), names_s);
964444c061aSmrg    classes = (XrmClass*) XtStackAlloc (count * sizeof(XrmClass), classes_s);
965444c061aSmrg    if (names == NULL || classes == NULL) _XtAllocError(NULL);
966444c061aSmrg
967444c061aSmrg    /* Get names, classes for widget and ancestors */
968444c061aSmrg    GetNamesAndClasses(w, names, classes);
9699e7bcd65Smrg
970444c061aSmrg    /* Compile arg list into quarks */
971444c061aSmrg    CacheArgs(args, num_args, typed_args, *num_typed_args, quark_cache,
972444c061aSmrg	      XtNumber(quark_cache), &quark_args);
973444c061aSmrg
974444c061aSmrg    /* Get normal resources */
975444c061aSmrg    LOCK_PROCESS;
976444c061aSmrg    cache_refs = GetResources(w, (char*)w, names, classes,
977444c061aSmrg	(XrmResourceList *) wc->core_class.resources,
978444c061aSmrg	wc->core_class.num_resources, quark_args, args, num_args,
979444c061aSmrg	typed_args, num_typed_args, XtIsWidget(w));
980444c061aSmrg
981444c061aSmrg    if (w->core.constraints != NULL) {
982444c061aSmrg	cwc = (ConstraintWidgetClass) XtClass(w->core.parent);
983444c061aSmrg	cache_refs_core =
984444c061aSmrg	    GetResources(w, (char*)w->core.constraints, names, classes,
985444c061aSmrg	    (XrmResourceList *) cwc->constraint_class.resources,
986444c061aSmrg	    cwc->constraint_class.num_resources,
987444c061aSmrg	    quark_args, args, num_args, typed_args, num_typed_args, False);
988444c061aSmrg	if (cache_refs_core) {
989444c061aSmrg	    XtFree((char *)cache_refs_core);
990444c061aSmrg	}
991444c061aSmrg    }
992444c061aSmrg    FreeCache(quark_cache, quark_args);
993444c061aSmrg    UNLOCK_PROCESS;
994444c061aSmrg    XtStackFree((XtPointer)names, names_s);
995444c061aSmrg    XtStackFree((XtPointer)classes, classes_s);
996444c061aSmrg    return cache_refs;
997444c061aSmrg} /* _XtGetResources */
998444c061aSmrg
999444c061aSmrg
1000444c061aSmrgvoid _XtGetSubresources (
1001444c061aSmrg    Widget	  w,			/* Widget "parent" of subobject   */
1002444c061aSmrg    XtPointer	  base,			/* Base address to write to       */
1003444c061aSmrg    const char*   name,			/* name of subobject		    */
1004444c061aSmrg    const char*   class,		/* class of subobject		    */
1005444c061aSmrg    XtResourceList resources,		/* resource list for subobject    */
10069e7bcd65Smrg    Cardinal	  num_resources,
1007444c061aSmrg    ArgList	  args,			/* arg list to override resources */
1008444c061aSmrg    Cardinal	  num_args,
1009444c061aSmrg    XtTypedArgList typed_args,
1010444c061aSmrg    Cardinal      num_typed_args)
1011444c061aSmrg{
1012444c061aSmrg    XrmName	  *names, names_s[50];
1013444c061aSmrg    XrmClass	  *classes, classes_s[50];
1014444c061aSmrg    XrmQuark	  quark_cache[100];
1015444c061aSmrg    XrmQuarkList  quark_args;
1016444c061aSmrg    XrmResourceList* table;
1017444c061aSmrg    Cardinal	  count, ntyped_args = num_typed_args;
1018444c061aSmrg    XtCacheRef    *Resrc = NULL;
1019444c061aSmrg    WIDGET_TO_APPCON(w);
1020444c061aSmrg
1021444c061aSmrg    if (num_resources == 0) return;
1022444c061aSmrg
1023444c061aSmrg    LOCK_APP(app);
1024444c061aSmrg    count = CountTreeDepth(w);
1025444c061aSmrg    count++;	/* make sure there's enough room for name and class */
1026444c061aSmrg    names = (XrmName*) XtStackAlloc(count * sizeof(XrmName), names_s);
1027444c061aSmrg    classes = (XrmClass*) XtStackAlloc(count * sizeof(XrmClass), classes_s);
1028444c061aSmrg    if (names == NULL || classes == NULL) _XtAllocError(NULL);
1029444c061aSmrg
1030444c061aSmrg    /* Get full name, class of subobject */
1031444c061aSmrg    GetNamesAndClasses(w, names, classes);
1032444c061aSmrg    count -= 2;
1033444c061aSmrg    names[count] = StringToName(name);
1034444c061aSmrg    classes[count] = StringToClass(class);
1035444c061aSmrg    count++;
1036444c061aSmrg    names[count] = NULLQUARK;
1037444c061aSmrg    classes[count] = NULLQUARK;
1038444c061aSmrg
1039444c061aSmrg    /* Compile arg list into quarks */
1040444c061aSmrg    CacheArgs(args, num_args, typed_args, num_typed_args,
1041444c061aSmrg	      quark_cache, XtNumber(quark_cache), &quark_args);
1042444c061aSmrg
1043444c061aSmrg    /* Compile resource list if needed */
1044444c061aSmrg    if (((int) resources->resource_offset) >= 0) {
1045444c061aSmrg	XrmCompileResourceListEphem(resources, num_resources);
1046444c061aSmrg    }
10479e7bcd65Smrg    table = _XtCreateIndirectionTable(resources, num_resources);
1048444c061aSmrg    Resrc = GetResources(w, (char*)base, names, classes, table, num_resources,
1049444c061aSmrg			quark_args, args, num_args,
1050444c061aSmrg			typed_args, &ntyped_args, False);
1051444c061aSmrg    FreeCache(quark_cache, quark_args);
1052444c061aSmrg    XtFree((char *)table);
1053444c061aSmrg    XtFree((char *)Resrc);
1054444c061aSmrg    XtStackFree((XtPointer)names, names_s);
1055444c061aSmrg    XtStackFree((XtPointer)classes, classes_s);
1056444c061aSmrg    UNLOCK_APP(app);
1057444c061aSmrg}
1058444c061aSmrg
1059444c061aSmrgvoid XtGetSubresources (
1060444c061aSmrg    Widget	  w,			/* Widget "parent" of subobject   */
1061444c061aSmrg    XtPointer	  base,			/* Base address to write to       */
1062444c061aSmrg    _Xconst char* name,			/* name of subobject		    */
1063444c061aSmrg    _Xconst char* class,		/* class of subobject		    */
1064444c061aSmrg    XtResourceList resources,		/* resource list for subobject    */
10659e7bcd65Smrg    Cardinal	  num_resources,
1066444c061aSmrg    ArgList	  args,			/* arg list to override resources */
1067444c061aSmrg    Cardinal	  num_args)
1068444c061aSmrg{
1069444c061aSmrg    _XtGetSubresources (w, base, name, class, resources, num_resources, args, num_args, NULL, 0);
1070444c061aSmrg}
1071444c061aSmrg
1072444c061aSmrg
1073444c061aSmrgvoid _XtGetApplicationResources (
1074444c061aSmrg    Widget	    w,		  /* Application shell widget       */
1075444c061aSmrg    XtPointer	    base,	  /* Base address to write to       */
1076444c061aSmrg    XtResourceList  resources,	  /* resource list for subobject    */
1077444c061aSmrg    Cardinal	    num_resources,
1078444c061aSmrg    ArgList	    args,	  /* arg list to override resources */
1079444c061aSmrg    Cardinal	    num_args,
1080444c061aSmrg    XtTypedArgList  typed_args,
1081444c061aSmrg    Cardinal	    num_typed_args)
1082444c061aSmrg{
1083444c061aSmrg    XrmName	    *names, names_s[50];
1084444c061aSmrg    XrmClass	    *classes, classes_s[50];
1085444c061aSmrg    XrmQuark	    quark_cache[100];
1086444c061aSmrg    XrmQuarkList    quark_args;
1087444c061aSmrg    XrmResourceList* table;
1088444c061aSmrg    Cardinal        count, ntyped_args = num_typed_args;
1089444c061aSmrg#ifdef XTHREADS
1090444c061aSmrg    XtAppContext    app;
1091444c061aSmrg#endif
1092444c061aSmrg    XtCacheRef	    *Resrc = NULL;
1093444c061aSmrg
1094444c061aSmrg    if (num_resources == 0) return;
1095444c061aSmrg
1096444c061aSmrg#ifdef XTHREADS
1097444c061aSmrg    if (w == NULL) app = _XtDefaultAppContext();
1098444c061aSmrg    else app = XtWidgetToApplicationContext(w);
1099444c061aSmrg#endif
1100444c061aSmrg
1101444c061aSmrg    LOCK_APP(app);
1102444c061aSmrg    /* Get full name, class of application */
1103444c061aSmrg    if (w == NULL) {
1104444c061aSmrg	/* hack for R2 compatibility */
1105444c061aSmrg	XtPerDisplay pd = _XtGetPerDisplay(_XtDefaultAppContext()->list[0]);
1106444c061aSmrg	names = (XrmName*) XtStackAlloc (2 * sizeof(XrmName), names_s);
1107444c061aSmrg	classes = (XrmClass*) XtStackAlloc (2 * sizeof(XrmClass), classes_s);
1108444c061aSmrg	names[0] = pd->name;
1109444c061aSmrg	names[1] = NULLQUARK;
1110444c061aSmrg	classes[0] = pd->class;
1111444c061aSmrg	classes[1] = NULLQUARK;
1112444c061aSmrg    }
1113444c061aSmrg    else {
1114444c061aSmrg	count = CountTreeDepth(w);
1115444c061aSmrg        names = (XrmName*) XtStackAlloc(count * sizeof(XrmName), names_s);
1116444c061aSmrg        classes = (XrmClass*) XtStackAlloc(count * sizeof(XrmClass), classes_s);
1117444c061aSmrg	if (names == NULL || classes == NULL) _XtAllocError(NULL);
1118444c061aSmrg	GetNamesAndClasses(w, names, classes);
1119444c061aSmrg    }
1120444c061aSmrg
1121444c061aSmrg    /* Compile arg list into quarks */
11229e7bcd65Smrg    CacheArgs(args, num_args, typed_args, num_typed_args,  quark_cache,
1123444c061aSmrg	XtNumber(quark_cache), &quark_args);
1124444c061aSmrg    /* Compile resource list if needed */
1125444c061aSmrg    if (((int) resources->resource_offset) >= 0) {
1126444c061aSmrg#ifdef	CRAY2
1127444c061aSmrg 	if (base == 0) {	/* this client is non-portable, but... */
1128444c061aSmrg 	    int count;
1129444c061aSmrg	    XtResourceList  res = resources;
1130444c061aSmrg	    for (count = 0; count < num_resources; res++, count++) {
1131444c061aSmrg 		res->resource_offset *= sizeof(long);
1132444c061aSmrg 	    }
1133444c061aSmrg 	}
1134444c061aSmrg#endif	/* CRAY2 */
1135444c061aSmrg	XrmCompileResourceListEphem(resources, num_resources);
1136444c061aSmrg    }
1137444c061aSmrg    table = _XtCreateIndirectionTable(resources,num_resources);
1138444c061aSmrg
1139444c061aSmrg    Resrc = GetResources(w, (char*)base, names, classes, table, num_resources,
1140444c061aSmrg			quark_args, args, num_args,
1141444c061aSmrg			typed_args, &ntyped_args, False);
1142444c061aSmrg    FreeCache(quark_cache, quark_args);
1143444c061aSmrg    XtFree((char *)table);
1144444c061aSmrg    XtFree((char *)Resrc);
1145444c061aSmrg    if (w != NULL) {
1146444c061aSmrg	XtStackFree((XtPointer)names, names_s);
1147444c061aSmrg	XtStackFree((XtPointer)classes, classes_s);
1148444c061aSmrg    }
1149444c061aSmrg    UNLOCK_APP(app);
1150444c061aSmrg}
1151444c061aSmrg
1152444c061aSmrgvoid XtGetApplicationResources (
1153444c061aSmrg    Widget	    w,		  /* Application shell widget       */
1154444c061aSmrg    XtPointer	    base,	  /* Base address to write to       */
1155444c061aSmrg    XtResourceList  resources,	  /* resource list for subobject    */
1156444c061aSmrg    Cardinal	    num_resources,
1157444c061aSmrg    ArgList	    args,	  /* arg list to override resources */
1158444c061aSmrg    Cardinal	    num_args)
1159444c061aSmrg{
1160444c061aSmrg    _XtGetApplicationResources(w, base, resources, num_resources, args, num_args, NULL, 0);
1161444c061aSmrg}
1162444c061aSmrg
1163444c061aSmrgstatic Boolean initialized = FALSE;
1164444c061aSmrg
1165444c061aSmrgvoid _XtResourceListInitialize(void)
1166444c061aSmrg{
1167444c061aSmrg    LOCK_PROCESS;
1168444c061aSmrg    if (initialized) {
1169444c061aSmrg	XtWarningMsg("initializationError","xtInitialize",XtCXtToolkitError,
1170444c061aSmrg                  "Initializing Resource Lists twice",
1171444c061aSmrg		  (String *)NULL, (Cardinal *)NULL);
1172444c061aSmrg	UNLOCK_PROCESS;
1173444c061aSmrg    	return;
1174444c061aSmrg    }
1175444c061aSmrg    initialized = TRUE;
1176444c061aSmrg    UNLOCK_PROCESS;
1177444c061aSmrg
1178444c061aSmrg    QBoolean = XrmPermStringToQuark(XtCBoolean);
1179444c061aSmrg    QString = XrmPermStringToQuark(XtCString);
1180444c061aSmrg    QCallProc = XrmPermStringToQuark(XtRCallProc);
1181444c061aSmrg    QImmediate = XrmPermStringToQuark(XtRImmediate);
1182444c061aSmrg    QinitialResourcesPersistent = XrmPermStringToQuark(XtNinitialResourcesPersistent);
1183444c061aSmrg    QInitialResourcesPersistent = XrmPermStringToQuark(XtCInitialResourcesPersistent);
1184444c061aSmrg    Qtranslations = XrmPermStringToQuark(XtNtranslations);
1185444c061aSmrg    QbaseTranslations = XrmPermStringToQuark("baseTranslations");
1186444c061aSmrg    QTranslations = XrmPermStringToQuark(XtCTranslations);
1187444c061aSmrg    QTranslationTable = XrmPermStringToQuark(XtRTranslationTable);
1188444c061aSmrg    Qscreen = XrmPermStringToQuark(XtNscreen);
1189444c061aSmrg    QScreen = XrmPermStringToQuark(XtCScreen);
1190444c061aSmrg}
1191