Resources.c revision 0568f49b
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
90444c061aSmrgvoid _XtCopyFromParent(
91444c061aSmrg    Widget      widget,
92444c061aSmrg    int		offset,
93444c061aSmrg    XrmValue    *value)
94444c061aSmrg{
95444c061aSmrg    if (widget->core.parent == NULL) {
96444c061aSmrg	XtAppWarningMsg(XtWidgetToApplicationContext(widget),
97444c061aSmrg		"invalidParent","xtCopyFromParent",XtCXtToolkitError,
98444c061aSmrg                  "CopyFromParent must have non-NULL parent",
990568f49bSmrg		  NULL, NULL);
100444c061aSmrg        value->addr = NULL;
101444c061aSmrg        return;
102444c061aSmrg    }
103444c061aSmrg    value->addr = (XPointer)(((char *)widget->core.parent) + offset);
104444c061aSmrg} /* _XtCopyFromParent */
105444c061aSmrg
106444c061aSmrg
107444c061aSmrgvoid _XtCopyFromArg(
108444c061aSmrg    XtArgVal src,
109444c061aSmrg    char* dst,
110444c061aSmrg    register unsigned int size)
111444c061aSmrg{
112444c061aSmrg    if (size > sizeof(XtArgVal))
1130568f49bSmrg	(void) memmove((char *) dst, (char *)  src, (size_t) size);
114444c061aSmrg    else {
115444c061aSmrg	union {
116444c061aSmrg	    long	longval;
117444c061aSmrg#ifdef LONG64
118444c061aSmrg	    int		intval;
119444c061aSmrg#endif
120444c061aSmrg	    short	shortval;
121444c061aSmrg	    char	charval;
122444c061aSmrg	    char*	charptr;
123444c061aSmrg	    XtPointer	ptr;
124444c061aSmrg	} u;
125444c061aSmrg	char *p = (char*)&u;
126444c061aSmrg	if	(size == sizeof(long))	    u.longval = (long)src;
127444c061aSmrg#ifdef LONG64
128444c061aSmrg	else if (size == sizeof(int))	    u.intval = (int)src;
129444c061aSmrg#endif
130444c061aSmrg	else if (size == sizeof(short))	    u.shortval = (short)src;
131444c061aSmrg	else if (size == sizeof(char))	    u.charval = (char)src;
132444c061aSmrg	else if (size == sizeof(XtPointer)) u.ptr = (XtPointer)src;
133444c061aSmrg	else if (size == sizeof(char*))	    u.charptr = (char*)src;
134444c061aSmrg	else				    p = (char*)&src;
135444c061aSmrg
1360568f49bSmrg	(void) memmove(dst, p, (size_t) size);
137444c061aSmrg    }
138444c061aSmrg} /* _XtCopyFromArg */
139444c061aSmrg
140444c061aSmrgvoid _XtCopyToArg(
141444c061aSmrg    char* src,
142444c061aSmrg    XtArgVal *dst,
143444c061aSmrg    register unsigned int size)
144444c061aSmrg{
145444c061aSmrg    if (!*dst) {
146444c061aSmrg#ifdef GETVALUES_BUG
147444c061aSmrg	/* old GetValues semantics (storing directly into arglists) are bad,
148444c061aSmrg	 * but preserve for compatibility as long as arglist contains NULL.
149444c061aSmrg	 */
150444c061aSmrg	union {
151444c061aSmrg	    long	longval;
152444c061aSmrg#ifdef LONG64
153444c061aSmrg	    int		intval;
154444c061aSmrg#endif
155444c061aSmrg	    short	shortval;
156444c061aSmrg	    char	charval;
157444c061aSmrg	    char*	charptr;
158444c061aSmrg	    XtPointer	ptr;
159444c061aSmrg	} u;
160444c061aSmrg	if (size <= sizeof(XtArgVal)) {
1610568f49bSmrg	    (void) memmove((char*)&u, (char*)src, (size_t)size );
162444c061aSmrg	    if	    (size == sizeof(long)) 	*dst = (XtArgVal)u.longval;
163444c061aSmrg#ifdef LONG64
164444c061aSmrg	    else if (size == sizeof(int))	*dst = (XtArgVal)u.intval;
165444c061aSmrg#endif
166444c061aSmrg	    else if (size == sizeof(short))	*dst = (XtArgVal)u.shortval;
167444c061aSmrg	    else if (size == sizeof(char))	*dst = (XtArgVal)u.charval;
168444c061aSmrg	    else if (size == sizeof(char*))	*dst = (XtArgVal)u.charptr;
169444c061aSmrg	    else if (size == sizeof(XtPointer))	*dst = (XtArgVal)u.ptr;
1700568f49bSmrg	    else (void) memmove((char*)dst, (char*)src, (size_t)size );
171444c061aSmrg	}
172444c061aSmrg	else
1730568f49bSmrg	    (void) memmove((char*)dst, (char*)src, (size_t)size );
174444c061aSmrg#else
175444c061aSmrg	XtErrorMsg("invalidGetValues", "xtGetValues", XtCXtToolkitError,
1760568f49bSmrg	    "NULL ArgVal in XtGetValues", NULL, NULL);
177444c061aSmrg#endif
178444c061aSmrg    }
179444c061aSmrg    else {
180444c061aSmrg	/* proper GetValues semantics: argval is pointer to destination */
1810568f49bSmrg	(void) memmove((char*)*dst, (char*)src, (size_t)size );
182444c061aSmrg    }
183444c061aSmrg} /* _XtCopyToArg */
184444c061aSmrg
185444c061aSmrgstatic void CopyToArg(
186444c061aSmrg    char* src,
187444c061aSmrg    XtArgVal *dst,
188444c061aSmrg    register unsigned int size)
189444c061aSmrg{
190444c061aSmrg    if (!*dst) {
191444c061aSmrg	/* old GetValues semantics (storing directly into arglists) are bad,
192444c061aSmrg	 * but preserve for compatibility as long as arglist contains NULL.
193444c061aSmrg	 */
194444c061aSmrg	union {
195444c061aSmrg	    long	longval;
196444c061aSmrg#ifdef LONG64
197444c061aSmrg	    int		intval;
198444c061aSmrg#endif
199444c061aSmrg	    short	shortval;
200444c061aSmrg	    char	charval;
201444c061aSmrg	    char*	charptr;
202444c061aSmrg	    XtPointer	ptr;
203444c061aSmrg	} u;
204444c061aSmrg	if (size <= sizeof(XtArgVal)) {
2050568f49bSmrg	    (void) memmove((char*)&u, (char*)src, (size_t)size );
206444c061aSmrg	    if	    (size == sizeof(long)) 	*dst = (XtArgVal)u.longval;
207444c061aSmrg#ifdef LONG64
208444c061aSmrg	    else if (size == sizeof(int))	*dst = (XtArgVal)u.intval;
209444c061aSmrg#endif
210444c061aSmrg	    else if (size == sizeof(short))	*dst = (XtArgVal)u.shortval;
211444c061aSmrg	    else if (size == sizeof(char))	*dst = (XtArgVal)u.charval;
212444c061aSmrg	    else if (size == sizeof(char*))	*dst = (XtArgVal)u.charptr;
213444c061aSmrg	    else if (size == sizeof(XtPointer))	*dst = (XtArgVal)u.ptr;
2140568f49bSmrg	    else (void) memmove((char*)dst, (char*)src, (size_t)size );
215444c061aSmrg	}
216444c061aSmrg	else
2170568f49bSmrg	    (void) memmove((char*)dst, (char*)src, (size_t)size );
218444c061aSmrg    }
219444c061aSmrg    else {
220444c061aSmrg	/* proper GetValues semantics: argval is pointer to destination */
2210568f49bSmrg	(void) memmove((char*)*dst, (char*)src, (size_t)size );
222444c061aSmrg    }
223444c061aSmrg} /* CopyToArg */
224444c061aSmrg
225444c061aSmrg
226444c061aSmrgstatic Cardinal CountTreeDepth(
227444c061aSmrg    Widget w)
228444c061aSmrg{
229444c061aSmrg    Cardinal count;
230444c061aSmrg
2319e7bcd65Smrg    for (count = 1; w != NULL; w = (Widget) w->core.parent)
232444c061aSmrg	count++;
233444c061aSmrg
234444c061aSmrg    return count;
235444c061aSmrg}
236444c061aSmrg
237444c061aSmrgstatic void GetNamesAndClasses(
238444c061aSmrg    register Widget	  w,
239444c061aSmrg    register XrmNameList  names,
240444c061aSmrg    register XrmClassList classes)
241444c061aSmrg{
242444c061aSmrg    register Cardinal length, j;
243444c061aSmrg    register XrmQuark t;
244444c061aSmrg    WidgetClass class;
245444c061aSmrg
246444c061aSmrg    /* Return null-terminated quark arrays, with length the number of
247444c061aSmrg       quarks (not including NULL) */
248444c061aSmrg
249444c061aSmrg    LOCK_PROCESS;
250444c061aSmrg    for (length = 0; w != NULL; w = (Widget) w->core.parent) {
251444c061aSmrg	names[length] = w->core.xrm_name;
252444c061aSmrg	class = XtClass(w);
253444c061aSmrg	/* KLUDGE KLUDGE KLUDGE KLUDGE */
254444c061aSmrg	if (w->core.parent == NULL && XtIsApplicationShell(w)) {
255444c061aSmrg	    classes[length] =
256444c061aSmrg		((ApplicationShellWidget) w)->application.xrm_class;
257444c061aSmrg	} else classes[length] = class->core_class.xrm_class;
258444c061aSmrg	length++;
259444c061aSmrg     }
260444c061aSmrg    UNLOCK_PROCESS;
261444c061aSmrg    /* They're in backwards order, flop them around */
262444c061aSmrg    for (j = 0; j < length/2; j++) {
263444c061aSmrg	t = names[j];
264444c061aSmrg	names[j] = names[length-j-1];
265444c061aSmrg	names[length-j-1] = t;
266444c061aSmrg        t = classes[j];
267444c061aSmrg	classes[j] = classes[length-j-1];
268444c061aSmrg	classes[length-j-1] = t;
269444c061aSmrg    }
270444c061aSmrg    names[length] = NULLQUARK;
271444c061aSmrg    classes[length] = NULLQUARK;
272444c061aSmrg} /* GetNamesAndClasses */
273444c061aSmrg
274444c061aSmrg
275444c061aSmrg/* Spiffy fast compiled form of resource list.				*/
276444c061aSmrg/* XtResourceLists are compiled in-place into XrmResourceLists		*/
277444c061aSmrg/* All atoms are replaced by quarks, and offsets are -offset-1 to	*/
278444c061aSmrg/* indicate that this list has been compiled already			*/
279444c061aSmrg
280444c061aSmrgvoid _XtCompileResourceList(
281444c061aSmrg    register XtResourceList resources,
282444c061aSmrg    	     Cardinal       num_resources)
283444c061aSmrg{
284444c061aSmrg    register Cardinal count;
285444c061aSmrg
286444c061aSmrg#define xrmres  ((XrmResourceList) resources)
287444c061aSmrg#define PSToQ   XrmPermStringToQuark
288444c061aSmrg
289444c061aSmrg    for (count = 0; count < num_resources; resources++, count++) {
290444c061aSmrg    	xrmres->xrm_name	 = PSToQ(resources->resource_name);
291444c061aSmrg    	xrmres->xrm_class	 = PSToQ(resources->resource_class);
292444c061aSmrg    	xrmres->xrm_type	 = PSToQ(resources->resource_type);
2930568f49bSmrg        xrmres->xrm_offset	 = (int)
294444c061aSmrg		(-(int)resources->resource_offset - 1);
295444c061aSmrg    	xrmres->xrm_default_type = PSToQ(resources->default_type);
296444c061aSmrg    }
297444c061aSmrg#undef PSToQ
298444c061aSmrg#undef xrmres
299444c061aSmrg} /* _XtCompileResourceList */
300444c061aSmrg
301444c061aSmrg/* Like _XtCompileResourceList, but strings are not permanent */
302444c061aSmrgstatic void  XrmCompileResourceListEphem(
303444c061aSmrg    register XtResourceList resources,
304444c061aSmrg    	     Cardinal       num_resources)
305444c061aSmrg{
306444c061aSmrg    register Cardinal count;
307444c061aSmrg
308444c061aSmrg#define xrmres  ((XrmResourceList) resources)
309444c061aSmrg
310444c061aSmrg    for (count = 0; count < num_resources; resources++, count++) {
311444c061aSmrg    	xrmres->xrm_name	 = StringToName(resources->resource_name);
312444c061aSmrg    	xrmres->xrm_class	 = StringToClass(resources->resource_class);
313444c061aSmrg    	xrmres->xrm_type	 = StringToQuark(resources->resource_type);
3140568f49bSmrg        xrmres->xrm_offset	 = (int)
315444c061aSmrg		(-(int)resources->resource_offset - 1);
316444c061aSmrg    	xrmres->xrm_default_type = StringToQuark(resources->default_type);
317444c061aSmrg    }
318444c061aSmrg#undef xrmres
319444c061aSmrg} /* XrmCompileResourceListEphem */
320444c061aSmrg
321444c061aSmrgstatic void BadSize(
322444c061aSmrg    Cardinal size,
323444c061aSmrg    XrmQuark name)
324444c061aSmrg{
325444c061aSmrg    String params[2];
326444c061aSmrg    Cardinal num_params = 2;
327444c061aSmrg
328444c061aSmrg    params[0] = (String)(long) size;
329444c061aSmrg    params[1] = XrmQuarkToString(name);
330444c061aSmrg    XtWarningMsg("invalidSizeOverride", "xtDependencies", XtCXtToolkitError,
331444c061aSmrg	"Representation size %d must match superclass's to override %s",
332444c061aSmrg	params, &num_params);
333444c061aSmrg} /* BadType */
334444c061aSmrg
335444c061aSmrg/*
336444c061aSmrg * Create a new resource list, with the class resources following the
337444c061aSmrg * superclass's resources.  If a resource in the class list overrides
338444c061aSmrg * a superclass resource, then just replace the superclass entry in place.
339444c061aSmrg *
340444c061aSmrg * At the same time, add a level of indirection to the XtResourceList to
341444c061aSmrg * create and XrmResourceList.
342444c061aSmrg */
343444c061aSmrgvoid _XtDependencies(
344444c061aSmrg    XtResourceList  *class_resp,	/* VAR */
345444c061aSmrg    Cardinal	    *class_num_resp,    /* VAR */
346444c061aSmrg    XrmResourceList *super_res,
347444c061aSmrg    Cardinal	    super_num_res,
348444c061aSmrg    Cardinal	    super_widget_size)
349444c061aSmrg{
350444c061aSmrg    register XrmResourceList *new_res;
351444c061aSmrg	     Cardinal	     new_num_res;
352444c061aSmrg	     XrmResourceList class_res = (XrmResourceList) *class_resp;
353444c061aSmrg	     Cardinal        class_num_res = *class_num_resp;
354444c061aSmrg    register Cardinal	     i, j;
355444c061aSmrg	     Cardinal        new_next;
356444c061aSmrg
357444c061aSmrg    if (class_num_res == 0) {
358444c061aSmrg	/* Just point to superclass resource list */
359444c061aSmrg	*class_resp = (XtResourceList) super_res;
360444c061aSmrg	*class_num_resp = super_num_res;
361444c061aSmrg	return;
362444c061aSmrg    }
363444c061aSmrg
364444c061aSmrg    /* Allocate and initialize new_res with superclass resource pointers */
365444c061aSmrg    new_num_res = super_num_res + class_num_res;
3660568f49bSmrg    new_res = (XrmResourceList *) __XtMalloc((Cardinal)(new_num_res*sizeof(XrmResourceList)));
367444c061aSmrg    if (super_num_res > 0)
368444c061aSmrg	XtMemmove(new_res, super_res, super_num_res * sizeof(XrmResourceList));
3699e7bcd65Smrg
370444c061aSmrg    /* Put pointers to class resource entries into new_res */
371444c061aSmrg    new_next = super_num_res;
372444c061aSmrg    for (i = 0; i < class_num_res; i++) {
373444c061aSmrg	if ((Cardinal)(-class_res[i].xrm_offset-1) < super_widget_size) {
374444c061aSmrg	    /* Probably an override of superclass resources--look for overlap */
375444c061aSmrg	    for (j = 0; j < super_num_res; j++) {
376444c061aSmrg		if (class_res[i].xrm_offset == new_res[j]->xrm_offset) {
377444c061aSmrg		    /* Spec is silent on what fields subclass can override.
378444c061aSmrg		     * The only two of real concern are type & size.
379444c061aSmrg		     * Although allowing type to be over-ridden introduces
380444c061aSmrg		     * the possibility of errors, it's at present the only
381444c061aSmrg		     * reasonable way to allow a subclass to force a private
382444c061aSmrg		     * converter to be invoked for a subset of fields.
383444c061aSmrg		     */
384444c061aSmrg		    /* We do insist that size be identical to superclass */
385444c061aSmrg		    if (class_res[i].xrm_size != new_res[j]->xrm_size) {
386444c061aSmrg			BadSize(class_res[i].xrm_size,
387444c061aSmrg				(XrmQuark) class_res[i].xrm_name);
388444c061aSmrg			class_res[i].xrm_size = new_res[j]->xrm_size;
389444c061aSmrg		    }
390444c061aSmrg		    new_res[j] = &(class_res[i]);
391444c061aSmrg		    new_num_res--;
392444c061aSmrg		    goto NextResource;
393444c061aSmrg		}
394444c061aSmrg	    } /* for j */
395444c061aSmrg	}
396444c061aSmrg	/* Not an overlap, add an entry to new_res */
397444c061aSmrg	new_res[new_next++] = &(class_res[i]);
398444c061aSmrgNextResource:;
399444c061aSmrg    } /* for i */
400444c061aSmrg
401444c061aSmrg    /* Okay, stuff new resources back into class record */
402444c061aSmrg    *class_resp = (XtResourceList) new_res;
403444c061aSmrg    *class_num_resp = new_num_res;
404444c061aSmrg} /* _XtDependencies */
405444c061aSmrg
406444c061aSmrg
407444c061aSmrgvoid _XtResourceDependencies(
408444c061aSmrg    WidgetClass wc)
409444c061aSmrg{
410444c061aSmrg    WidgetClass sc;
411444c061aSmrg
412444c061aSmrg    sc = wc->core_class.superclass;
413444c061aSmrg    if (sc == NULL) {
414444c061aSmrg	_XtDependencies(&(wc->core_class.resources),
415444c061aSmrg			&(wc->core_class.num_resources),
416444c061aSmrg			(XrmResourceList *) NULL, (unsigned)0, (unsigned)0);
417444c061aSmrg    } else {
418444c061aSmrg	_XtDependencies(&(wc->core_class.resources),
419444c061aSmrg			&(wc->core_class.num_resources),
420444c061aSmrg			(XrmResourceList *) sc->core_class.resources,
421444c061aSmrg			sc->core_class.num_resources,
422444c061aSmrg			sc->core_class.widget_size);
423444c061aSmrg    }
424444c061aSmrg} /* _XtResourceDependencies */
425444c061aSmrg
426444c061aSmrgvoid _XtConstraintResDependencies(
427444c061aSmrg    ConstraintWidgetClass wc)
428444c061aSmrg{
429444c061aSmrg    if (wc == (ConstraintWidgetClass) constraintWidgetClass) {
430444c061aSmrg	_XtDependencies(&(wc->constraint_class.resources),
431444c061aSmrg			&(wc->constraint_class.num_resources),
432444c061aSmrg			(XrmResourceList *)NULL, (unsigned)0, (unsigned)0);
433444c061aSmrg    } else {
4340568f49bSmrg	ConstraintWidgetClass sc;
4350568f49bSmrg
436444c061aSmrg	sc = (ConstraintWidgetClass) wc->core_class.superclass;
437444c061aSmrg	_XtDependencies(&(wc->constraint_class.resources),
438444c061aSmrg			&(wc->constraint_class.num_resources),
439444c061aSmrg			(XrmResourceList *) sc->constraint_class.resources,
440444c061aSmrg			sc->constraint_class.num_resources,
441444c061aSmrg			sc->constraint_class.constraint_size);
442444c061aSmrg    }
443444c061aSmrg} /* _XtConstraintResDependencies */
444444c061aSmrg
445444c061aSmrg
446444c061aSmrg
4479e7bcd65Smrg
448444c061aSmrgXrmResourceList* _XtCreateIndirectionTable (
449444c061aSmrg    XtResourceList  resources,
450444c061aSmrg    Cardinal	    num_resources)
451444c061aSmrg{
452444c061aSmrg    register Cardinal idx;
453444c061aSmrg    XrmResourceList* table;
454444c061aSmrg
4550568f49bSmrg    table = (XrmResourceList*)__XtMalloc((Cardinal)(num_resources * sizeof(XrmResourceList)));
456444c061aSmrg    for (idx = 0; idx < num_resources; idx++)
457444c061aSmrg        table[idx] = (XrmResourceList)(&(resources[idx]));
458444c061aSmrg    return table;
459444c061aSmrg}
460444c061aSmrg
461444c061aSmrgstatic XtCacheRef *GetResources(
462444c061aSmrg    Widget	    widget,	    /* Widget resources are associated with */
463444c061aSmrg    char*	    base,	    /* Base address of memory to write to   */
464444c061aSmrg    XrmNameList     names,	    /* Full inheritance name of widget      */
465444c061aSmrg    XrmClassList    classes,	    /* Full inheritance class of widget     */
466444c061aSmrg    XrmResourceList*  table,	    /* The list of resources required.      */
467444c061aSmrg    unsigned	    num_resources,  /* number of items in resource list     */
468444c061aSmrg    XrmQuarkList    quark_args,     /* Arg names quarkified		    */
469444c061aSmrg    ArgList	    args,	    /* ArgList to override resources	    */
470444c061aSmrg    unsigned	    num_args,       /* number of items in arg list	    */
471444c061aSmrg    XtTypedArgList  typed_args,	    /* Typed arg list to override resources */
472444c061aSmrg    Cardinal*	    pNumTypedArgs,  /* number of items in typed arg list    */
473444c061aSmrg    Boolean	    tm_hack)	    /* do baseTranslations		    */
474444c061aSmrg{
475444c061aSmrg/*
476444c061aSmrg * assert: *pNumTypedArgs == 0 if num_args > 0
477444c061aSmrg * assert: num_args == 0 if *pNumTypedArgs > 0
478444c061aSmrg */
479444c061aSmrg#define SEARCHLISTLEN 100
480444c061aSmrg#define MAXRESOURCES  400
481444c061aSmrg
482444c061aSmrg    XrmValue	    value;
483444c061aSmrg    XrmQuark	    rawType;
484444c061aSmrg    XrmValue	    convValue;
485444c061aSmrg    XrmHashTable    stackSearchList[SEARCHLISTLEN];
486444c061aSmrg    XrmHashTable    *searchList = stackSearchList;
487444c061aSmrg    unsigned int    searchListSize = SEARCHLISTLEN;
488444c061aSmrg    Boolean	    found[MAXRESOURCES];
489444c061aSmrg    int		    typed[MAXRESOURCES];
490444c061aSmrg    XtCacheRef	    cache_ref[MAXRESOURCES];
491444c061aSmrg    XtCacheRef      *cache_ptr, *cache_base;
492444c061aSmrg    Boolean	    persistent_resources = True;
493444c061aSmrg    Boolean	    found_persistence = False;
4940568f49bSmrg    int		    num_typed_args = (int) *pNumTypedArgs;
495444c061aSmrg    XrmDatabase     db;
496444c061aSmrg    Boolean	    do_tm_hack = False;
497444c061aSmrg
498444c061aSmrg    if ((args == NULL) && (num_args != 0)) {
499444c061aSmrg    	XtAppWarningMsg(XtWidgetToApplicationContext(widget),
500444c061aSmrg		"invalidArgCount","getResources",XtCXtToolkitError,
501444c061aSmrg                 "argument count > 0 on NULL argument list",
5020568f49bSmrg                   NULL, NULL);
503444c061aSmrg	num_args = 0;
504444c061aSmrg    }
505444c061aSmrg    if (num_resources == 0) {
506444c061aSmrg	return NULL;
507444c061aSmrg    } else if (num_resources >= MAXRESOURCES) {
508444c061aSmrg    	XtAppWarningMsg(XtWidgetToApplicationContext(widget),
509444c061aSmrg		"invalidResourceCount","getResources",XtCXtToolkitError,
510444c061aSmrg              "too many resources",
5110568f49bSmrg	      NULL, NULL);
512444c061aSmrg	return NULL;
513444c061aSmrg    } else if (table == NULL) {
514444c061aSmrg    	XtAppWarningMsg(XtWidgetToApplicationContext(widget),
515444c061aSmrg		"invalidResourceCount","getResources",XtCXtToolkitError,
516444c061aSmrg              "resource count > 0 on NULL resource list",
5170568f49bSmrg	      NULL, NULL);
518444c061aSmrg	return NULL;
519444c061aSmrg    }
520444c061aSmrg
521444c061aSmrg    /* Mark each resource as not found on arg list */
5220568f49bSmrg    memset((void *) found, 0, (size_t) (num_resources * sizeof(Boolean)));
5230568f49bSmrg    memset((void *) typed, 0, (size_t) (num_resources * sizeof(int)));
524444c061aSmrg
525444c061aSmrg    /* Copy the args into the resources, mark each as found */
526444c061aSmrg    {
527444c061aSmrg	register ArgList	    arg;
528444c061aSmrg	register XtTypedArgList	    typed_arg;
529444c061aSmrg	register XrmName	    argName;
530444c061aSmrg	register Cardinal	    j;
531444c061aSmrg	register int	    i;
532444c061aSmrg	register XrmResourceList rx;
533444c061aSmrg	register XrmResourceList *res;
534444c061aSmrg	for (arg = args, i = 0; (Cardinal)i < num_args; i++, arg++) {
535444c061aSmrg	    argName = quark_args[i];
536444c061aSmrg	    if (argName == QinitialResourcesPersistent) {
537444c061aSmrg		persistent_resources = (Boolean)arg->value;
538444c061aSmrg		found_persistence = True;
539444c061aSmrg		continue;
540444c061aSmrg	    }
541444c061aSmrg	    for (j = 0, res = table; j < num_resources; j++, res++) {
542444c061aSmrg		rx = *res;
543444c061aSmrg		if (argName == rx->xrm_name) {
544444c061aSmrg		    _XtCopyFromArg(
545444c061aSmrg			arg->value,
546444c061aSmrg			base - rx->xrm_offset - 1,
547444c061aSmrg			rx->xrm_size);
548444c061aSmrg		    found[j] = TRUE;
549444c061aSmrg		    break;
550444c061aSmrg		}
551444c061aSmrg	    }
552444c061aSmrg	}
553444c061aSmrg	for (typed_arg = typed_args, i = 0; i < num_typed_args;
554444c061aSmrg	     i++, typed_arg++) {
555444c061aSmrg	    register XrmRepresentation argType;
556444c061aSmrg	    argName = quark_args[i];
5579e7bcd65Smrg	    argType = (typed_arg->type == NULL) ? NULLQUARK
558444c061aSmrg		: XrmStringToRepresentation(typed_arg->type);
559444c061aSmrg	    if (argName == QinitialResourcesPersistent) {
560444c061aSmrg		persistent_resources = (Boolean)typed_arg->value;
5619e7bcd65Smrg		found_persistence = True;
562444c061aSmrg		break;
563444c061aSmrg	    }
564444c061aSmrg	    for (j = 0, res = table; j < num_resources; j++, res++) {
565444c061aSmrg		rx = *res;
566444c061aSmrg		if (argName == rx->xrm_name) {
567444c061aSmrg		    if (argType != NULLQUARK && argType != rx->xrm_type) {
568444c061aSmrg			typed[j] = i + 1;
569444c061aSmrg		    } else {
570444c061aSmrg			_XtCopyFromArg(
571444c061aSmrg				       typed_arg->value,
572444c061aSmrg				       base - rx->xrm_offset - 1,
573444c061aSmrg				       rx->xrm_size);
574444c061aSmrg		    }
575444c061aSmrg		    found[j] = TRUE;
576444c061aSmrg		    break;
5779e7bcd65Smrg		}
578444c061aSmrg	    }
579444c061aSmrg	}
580444c061aSmrg    }
581444c061aSmrg
582444c061aSmrg    /* Ask resource manager for a list of database levels that we can
583444c061aSmrg       do a single-level search on each resource */
584444c061aSmrg
585444c061aSmrg    db = XtScreenDatabase(XtScreenOfObject(widget));
586444c061aSmrg    while (!XrmQGetSearchList(db, names, classes,
5870568f49bSmrg			      searchList, (int) searchListSize)) {
588444c061aSmrg	if (searchList == stackSearchList)
589444c061aSmrg	    searchList = NULL;
590444c061aSmrg	searchList = (XrmHashTable*)XtRealloc((char*)searchList,
5910568f49bSmrg					      (Cardinal) (sizeof(XrmHashTable) *
5920568f49bSmrg					      (searchListSize *= 2)));
593444c061aSmrg    }
5949e7bcd65Smrg
595444c061aSmrg    if (persistent_resources)
596444c061aSmrg	cache_base = NULL;
597444c061aSmrg    else
598444c061aSmrg	cache_base = cache_ref;
599444c061aSmrg    /* geez, this is an ugly mess */
600444c061aSmrg    if (XtIsShell(widget)) {
601444c061aSmrg	register XrmResourceList  *res;
602444c061aSmrg	register Cardinal	  j;
603444c061aSmrg	Screen *oldscreen = widget->core.screen;
604444c061aSmrg
605444c061aSmrg	/* look up screen resource first, since real rdb depends on it */
606444c061aSmrg	for (res = table, j = 0; j < num_resources; j++, res++) {
607444c061aSmrg	    if ((*res)->xrm_name != Qscreen)
608444c061aSmrg		continue;
609444c061aSmrg	    if (typed[j]) {
610444c061aSmrg		register XtTypedArg* arg = typed_args + typed[j] - 1;
611444c061aSmrg		XrmQuark from_type;
612444c061aSmrg		XrmValue from_val, to_val;
613444c061aSmrg
614444c061aSmrg		from_type = StringToQuark(arg->type);
6150568f49bSmrg		from_val.size = (Cardinal) arg->size;
616444c061aSmrg		if ((from_type == QString) || ((unsigned) arg->size > sizeof(XtArgVal)))
617444c061aSmrg		    from_val.addr = (XPointer)arg->value;
618444c061aSmrg		else
619444c061aSmrg		    from_val.addr = (XPointer)&arg->value;
620444c061aSmrg		to_val.size = sizeof(Screen*);
621444c061aSmrg		to_val.addr = (XPointer)&widget->core.screen;
622444c061aSmrg		found[j] = _XtConvert(widget, from_type, &from_val,
623444c061aSmrg				      QScreen, &to_val, cache_base);
624444c061aSmrg		if (cache_base && *cache_base)
625444c061aSmrg		    cache_base++;
626444c061aSmrg	    }
627444c061aSmrg	    if (!found[j]) {
628444c061aSmrg		if (XrmQGetSearchResource(searchList, Qscreen, QScreen,
629444c061aSmrg				      &rawType, &value)) {
630444c061aSmrg		    if (rawType != QScreen) {
631444c061aSmrg			convValue.size = sizeof(Screen*);
632444c061aSmrg			convValue.addr = (XPointer)&widget->core.screen;
633444c061aSmrg			(void)_XtConvert(widget, rawType, &value,
634444c061aSmrg					 QScreen, &convValue, cache_base);
635444c061aSmrg			if (cache_base && *cache_base)
636444c061aSmrg			    cache_base++;
637444c061aSmrg		    } else {
638444c061aSmrg			widget->core.screen = *((Screen **)value.addr);
639444c061aSmrg		    }
640444c061aSmrg		}
641444c061aSmrg	    }
642444c061aSmrg	    break;
643444c061aSmrg	}
644444c061aSmrg	/* now get the database to use for the rest of the resources */
645444c061aSmrg	if (widget->core.screen != oldscreen) {
646444c061aSmrg	    db = XtScreenDatabase(widget->core.screen);
647444c061aSmrg	    while (!XrmQGetSearchList(db, names, classes,
6480568f49bSmrg				      searchList, (int) searchListSize)) {
649444c061aSmrg		if (searchList == stackSearchList)
650444c061aSmrg		    searchList = NULL;
651444c061aSmrg		searchList = (XrmHashTable*)XtRealloc((char*)searchList,
6520568f49bSmrg						      (Cardinal)(sizeof(XrmHashTable) *
6530568f49bSmrg						      (searchListSize *= 2)));
654444c061aSmrg	    }
655444c061aSmrg	}
656444c061aSmrg    }
657444c061aSmrg
658444c061aSmrg    /* go to the resource manager for those resources not found yet */
659444c061aSmrg    /* if it's not in the resource database use the default value   */
660444c061aSmrg
661444c061aSmrg    {
662444c061aSmrg	register XrmResourceList  rx;
663444c061aSmrg	register XrmResourceList  *res;
664444c061aSmrg	register Cardinal	  j;
665444c061aSmrg	register XrmRepresentation xrm_type;
666444c061aSmrg	register XrmRepresentation xrm_default_type;
667444c061aSmrg	char	char_val;
668444c061aSmrg	short	short_val;
669444c061aSmrg	int	int_val;
670444c061aSmrg	long	long_val;
671444c061aSmrg	char*	char_ptr;
672444c061aSmrg
673444c061aSmrg	if (!found_persistence) {
674444c061aSmrg	    if (XrmQGetSearchResource(searchList, QinitialResourcesPersistent,
675444c061aSmrg			QInitialResourcesPersistent, &rawType, &value)) {
676444c061aSmrg		if (rawType != QBoolean) {
677444c061aSmrg		    convValue.size = sizeof(Boolean);
678444c061aSmrg		    convValue.addr = (XPointer)&persistent_resources;
679444c061aSmrg		    (void)_XtConvert(widget, rawType, &value, QBoolean,
680444c061aSmrg				     &convValue, NULL);
681444c061aSmrg		}
682444c061aSmrg		else
683444c061aSmrg		    persistent_resources = *(Boolean*)value.addr;
684444c061aSmrg	    }
685444c061aSmrg	}
686444c061aSmrg	if (persistent_resources)
687444c061aSmrg	    cache_ptr = NULL;
688444c061aSmrg	else if (cache_base)
689444c061aSmrg	    cache_ptr = cache_base;
690444c061aSmrg	else
691444c061aSmrg	    cache_ptr = cache_ref;
692444c061aSmrg
693444c061aSmrg	for (res = table, j = 0; j < num_resources; j++, res++) {
694444c061aSmrg	    rx = *res;
6950568f49bSmrg	    xrm_type = (XrmRepresentation) rx->xrm_type;
696444c061aSmrg	    if (typed[j]) {
697444c061aSmrg		register XtTypedArg* arg = typed_args + typed[j] - 1;
698444c061aSmrg
699444c061aSmrg		/*
7009e7bcd65Smrg                 * This resource value has been specified as a typed arg and
7019e7bcd65Smrg		 * has to be converted. Typed arg conversions are done here
702444c061aSmrg		 * to correctly interpose them with normal resource conversions.
703444c061aSmrg                 */
704444c061aSmrg		XrmQuark	    from_type;
705444c061aSmrg		XrmValue            from_val, to_val;
706444c061aSmrg		Boolean		    converted;
7079e7bcd65Smrg
708444c061aSmrg		from_type = StringToQuark(arg->type);
7090568f49bSmrg    		from_val.size = (Cardinal) arg->size;
710444c061aSmrg		if ((from_type == QString) || ((unsigned) arg->size > sizeof(XtArgVal)))
711444c061aSmrg        	    from_val.addr = (XPointer)arg->value;
712444c061aSmrg	        else
713444c061aSmrg            	    from_val.addr = (XPointer)&arg->value;
714444c061aSmrg		to_val.size = rx->xrm_size;
715444c061aSmrg		to_val.addr = base - rx->xrm_offset - 1;
716444c061aSmrg		converted = _XtConvert(widget, from_type, &from_val,
717444c061aSmrg				       xrm_type, &to_val, cache_ptr);
718444c061aSmrg		if (converted) {
719444c061aSmrg
720444c061aSmrg		    /* Copy the converted value back into the typed argument.
721444c061aSmrg		     * normally the data should be <= sizeof(XtArgVal) and
722444c061aSmrg		     * is stored directly into the 'value' field .... BUT
723444c061aSmrg		     * if the resource size is greater than sizeof(XtArgVal)
724444c061aSmrg		     * then we dynamically alloc a block of store to hold the
725444c061aSmrg		     * data and zap a copy in there !!! .... freeing it later
726444c061aSmrg		     * the size field in the typed arg is negated to indicate
727444c061aSmrg		     * that the store pointed to by the value field is
728444c061aSmrg		     * dynamic .......
729444c061aSmrg		     * "freeing" happens in the case of _XtCreate after the
730444c061aSmrg		     * CallInitialize ..... other clients of GetResources
731444c061aSmrg		     * using typed args should be aware of the need to free
732444c061aSmrg		     * this store .....
733444c061aSmrg		     */
734444c061aSmrg
735444c061aSmrg		    if(rx->xrm_size > sizeof(XtArgVal)) {
7360568f49bSmrg			arg->value = (XtArgVal) (void *) __XtMalloc(rx->xrm_size);
737444c061aSmrg			arg->size = -(arg->size);
738444c061aSmrg		    } else { /* will fit - copy directly into value field */
739444c061aSmrg			arg->value = (XtArgVal) NULL;
740444c061aSmrg		    }
741444c061aSmrg		    CopyToArg((char *)(base - rx->xrm_offset - 1),
742444c061aSmrg				 &arg->value, rx->xrm_size);
743444c061aSmrg
744444c061aSmrg		} else {
745444c061aSmrg		   /* Conversion failed. Get default value. */
746444c061aSmrg		   found[j] = False;
747444c061aSmrg		}
748444c061aSmrg
749444c061aSmrg		if (cache_ptr && *cache_ptr)
750444c061aSmrg		    cache_ptr++;
751444c061aSmrg	    }
752444c061aSmrg
753444c061aSmrg	    if (!found[j]) {
754444c061aSmrg		Boolean	already_copied = False;
755444c061aSmrg		Boolean have_value = False;
756444c061aSmrg
757444c061aSmrg		if (XrmQGetSearchResource(searchList,
7580568f49bSmrg			(XrmName) rx->xrm_name, (XrmClass) rx->xrm_class, &rawType, &value)) {
759444c061aSmrg		    if (rawType != xrm_type) {
760444c061aSmrg			convValue.size = rx->xrm_size;
761444c061aSmrg			convValue.addr = (XPointer)(base - rx->xrm_offset - 1);
762444c061aSmrg			already_copied = have_value =
763444c061aSmrg			    _XtConvert(widget, rawType, &value,
764444c061aSmrg				       xrm_type, &convValue, cache_ptr);
765444c061aSmrg			if (cache_ptr && *cache_ptr)
766444c061aSmrg			    cache_ptr++;
767444c061aSmrg		    } else have_value = True;
768444c061aSmrg		    if (have_value && rx->xrm_name == Qtranslations)
769444c061aSmrg			do_tm_hack = True;
770444c061aSmrg		}
771444c061aSmrg		LOCK_PROCESS;
772444c061aSmrg		if (!have_value
773444c061aSmrg		    && ((rx->xrm_default_type == QImmediate)
774444c061aSmrg			|| (rx->xrm_default_type == xrm_type)
775444c061aSmrg			|| (rx->xrm_default_addr != NULL))) {
776444c061aSmrg		    /* Convert default value to proper type */
7770568f49bSmrg		    xrm_default_type = (XrmRepresentation) rx->xrm_default_type;
778444c061aSmrg		    if (xrm_default_type == QCallProc) {
779444c061aSmrg			(*(XtResourceDefaultProc)(rx->xrm_default_addr))(
780444c061aSmrg			      widget,-(rx->xrm_offset+1), &value);
781444c061aSmrg
782444c061aSmrg		    } else if (xrm_default_type == QImmediate) {
783444c061aSmrg			/* XtRImmediate == XtRString for type XtRString */
784444c061aSmrg			if (xrm_type == QString) {
785444c061aSmrg			    value.addr = rx->xrm_default_addr;
786444c061aSmrg			} else if (rx->xrm_size == sizeof(int)) {
787444c061aSmrg			    int_val = (int)(long)rx->xrm_default_addr;
788444c061aSmrg			    value.addr = (XPointer) &int_val;
789444c061aSmrg			} else if (rx->xrm_size == sizeof(short)) {
790444c061aSmrg			    short_val = (short)(long)rx->xrm_default_addr;
791444c061aSmrg			    value.addr = (XPointer) &short_val;
792444c061aSmrg			} else if (rx->xrm_size == sizeof(char)) {
793444c061aSmrg			    char_val = (char)(long)rx->xrm_default_addr;
794444c061aSmrg			    value.addr = (XPointer) &char_val;
795444c061aSmrg			} else if (rx->xrm_size == sizeof(long)) {
796444c061aSmrg			    long_val = (long)rx->xrm_default_addr;
797444c061aSmrg			    value.addr = (XPointer) &long_val;
798444c061aSmrg			} else if (rx->xrm_size == sizeof(char*)) {
799444c061aSmrg			    char_ptr = (char*)rx->xrm_default_addr;
800444c061aSmrg			    value.addr = (XPointer) &char_ptr;
801444c061aSmrg			} else {
802444c061aSmrg			    value.addr = (XPointer) &(rx->xrm_default_addr);
803444c061aSmrg			}
804444c061aSmrg		    } else if (xrm_default_type == xrm_type) {
805444c061aSmrg			value.addr = rx->xrm_default_addr;
806444c061aSmrg		    } else {
807444c061aSmrg			value.addr = rx->xrm_default_addr;
808444c061aSmrg			if (xrm_default_type == QString) {
8090568f49bSmrg			    value.size = (unsigned) strlen((char *)value.addr) + 1;
810444c061aSmrg			} else {
811444c061aSmrg			    value.size = sizeof(XtPointer);
812444c061aSmrg			}
813444c061aSmrg			convValue.size = rx->xrm_size;
814444c061aSmrg			convValue.addr = (XPointer)(base - rx->xrm_offset - 1);
815444c061aSmrg			already_copied =
816444c061aSmrg			    _XtConvert(widget, xrm_default_type, &value,
817444c061aSmrg				       xrm_type, &convValue, cache_ptr);
818444c061aSmrg			if (!already_copied)
819444c061aSmrg			    value.addr = NULL;
820444c061aSmrg			if (cache_ptr && *cache_ptr)
821444c061aSmrg			    cache_ptr++;
822444c061aSmrg		    }
823444c061aSmrg		}
824444c061aSmrg		if (!already_copied) {
825444c061aSmrg		    if (xrm_type == QString) {
826444c061aSmrg			*((String*)(base - rx->xrm_offset - 1)) = value.addr;
827444c061aSmrg		    } else {
828444c061aSmrg			if (value.addr != NULL) {
829444c061aSmrg			    XtMemmove(base - rx->xrm_offset - 1,
830444c061aSmrg				      value.addr, rx->xrm_size);
831444c061aSmrg			} else {
832444c061aSmrg			    /* didn't get value, initialize to NULL... */
833444c061aSmrg			    XtBZero(base - rx->xrm_offset - 1, rx->xrm_size);
834444c061aSmrg			}
835444c061aSmrg		    }
836444c061aSmrg		}
837444c061aSmrg		UNLOCK_PROCESS;
8389e7bcd65Smrg	    }
8399e7bcd65Smrg	}
8409e7bcd65Smrg	for (res = table, j = 0; j < num_resources; j++, res++) {
8419e7bcd65Smrg	    if (!found[j] && typed[j]) {
8429e7bcd65Smrg		/*
8439e7bcd65Smrg		 * This resource value was specified as a typed arg.
8449e7bcd65Smrg		 * However, the default value is being used here since
8459e7bcd65Smrg		 * type type conversion failed, so we compress the list.
8469e7bcd65Smrg		 */
8479e7bcd65Smrg		register XtTypedArg* arg = typed_args + typed[j] - 1;
8489e7bcd65Smrg		register int i;
849444c061aSmrg
8509e7bcd65Smrg		for (i = num_typed_args - typed[j]; i > 0; i--, arg++) {
8519e7bcd65Smrg		    *arg = *(arg+1);
852444c061aSmrg		}
8539e7bcd65Smrg		num_typed_args--;
8549e7bcd65Smrg	    }
855444c061aSmrg	}
856444c061aSmrg	if (tm_hack)
857444c061aSmrg	    widget->core.tm.current_state = NULL;
858444c061aSmrg	if (tm_hack &&
859444c061aSmrg	    (!widget->core.tm.translations ||
860444c061aSmrg	     (do_tm_hack &&
861444c061aSmrg	      widget->core.tm.translations->operation != XtTableReplace)) &&
862444c061aSmrg	    XrmQGetSearchResource(searchList, QbaseTranslations,
863444c061aSmrg				  QTranslations, &rawType, &value)) {
864444c061aSmrg	    if (rawType != QTranslationTable) {
865444c061aSmrg		convValue.size = sizeof(XtTranslations);
866444c061aSmrg		convValue.addr = (XPointer)&widget->core.tm.current_state;
867444c061aSmrg		(void)_XtConvert(widget, rawType, &value,
868444c061aSmrg				 QTranslationTable, &convValue, cache_ptr);
869444c061aSmrg		if (cache_ptr && *cache_ptr)
870444c061aSmrg		    cache_ptr++;
871444c061aSmrg	    } else {
872bdf0f55dSmrg		/* value.addr can be NULL see: !already_copied */
873bdf0f55dSmrg		if (value.addr)
874bdf0f55dSmrg		    *((XtTranslations *)&widget->core.tm.current_state) =
875bdf0f55dSmrg			*((XtTranslations *)value.addr);
876444c061aSmrg	    }
877444c061aSmrg	}
878444c061aSmrg    }
8790568f49bSmrg    if ((Cardinal)num_typed_args != *pNumTypedArgs) *pNumTypedArgs = (Cardinal) num_typed_args;
880444c061aSmrg    if (searchList != stackSearchList) XtFree((char*)searchList);
881444c061aSmrg    if (!cache_ptr)
882444c061aSmrg	cache_ptr = cache_base;
883444c061aSmrg    if (cache_ptr && cache_ptr != cache_ref) {
8840568f49bSmrg	int cache_ref_size = (int) (cache_ptr - cache_ref);
885444c061aSmrg	XtCacheRef *refs = (XtCacheRef*)
8860568f49bSmrg	    __XtMalloc((Cardinal)(sizeof(XtCacheRef) * (size_t)(cache_ref_size + 1)));
8870568f49bSmrg	(void) memmove(refs, cache_ref, sizeof(XtCacheRef)*(size_t)cache_ref_size );
888444c061aSmrg	refs[cache_ref_size] = NULL;
889444c061aSmrg	return refs;
890444c061aSmrg    }
891444c061aSmrg    return (XtCacheRef*)NULL;
892444c061aSmrg}
893444c061aSmrg
894444c061aSmrg
895444c061aSmrg
896444c061aSmrgstatic void CacheArgs(
897444c061aSmrg    ArgList	    args,
898444c061aSmrg    Cardinal	    num_args,
899444c061aSmrg    XtTypedArgList  typed_args,
900444c061aSmrg    Cardinal	    num_typed_args,
901444c061aSmrg    XrmQuarkList    quark_cache,
902444c061aSmrg    Cardinal	    num_quarks,
903444c061aSmrg    XrmQuarkList    *pQuarks)       /* RETURN */
904444c061aSmrg{
905444c061aSmrg    register XrmQuarkList   quarks;
906444c061aSmrg    register Cardinal       i;
907444c061aSmrg    register Cardinal       count;
908444c061aSmrg
909444c061aSmrg    count = (args != NULL) ? num_args : num_typed_args;
910444c061aSmrg
911444c061aSmrg    if (num_quarks < count) {
9120568f49bSmrg	quarks = (XrmQuarkList) __XtMalloc((Cardinal)(count * sizeof(XrmQuark)));
913444c061aSmrg    } else {
914444c061aSmrg	quarks = quark_cache;
915444c061aSmrg    }
916444c061aSmrg    *pQuarks = quarks;
917444c061aSmrg
918444c061aSmrg    if (args != NULL) {
919444c061aSmrg	for (i = count; i; i--)
920444c061aSmrg	    *quarks++ = StringToQuark((args++)->name);
921444c061aSmrg    }
922444c061aSmrg    else {
923444c061aSmrg	for (i = count; i; i--)
924444c061aSmrg	    *quarks++ = StringToQuark((typed_args++)->name);
925444c061aSmrg    }
926444c061aSmrg}
927444c061aSmrg
928444c061aSmrg#define FreeCache(cache, pointer) \
929444c061aSmrg	  if (cache != pointer) XtFree((char *)pointer)
930444c061aSmrg
931444c061aSmrg
932444c061aSmrgXtCacheRef *_XtGetResources(
933444c061aSmrg    register 	Widget	  	w,
934444c061aSmrg    		ArgList	  	args,
935444c061aSmrg    		Cardinal  	num_args,
936444c061aSmrg		XtTypedArgList	typed_args,
937444c061aSmrg		Cardinal*	num_typed_args)
938444c061aSmrg{
939444c061aSmrg    XrmName	    *names, names_s[50];
940444c061aSmrg    XrmClass	    *classes, classes_s[50];
941444c061aSmrg    XrmQuark	    quark_cache[100];
942444c061aSmrg    XrmQuarkList    quark_args;
943444c061aSmrg    WidgetClass     wc;
9440568f49bSmrg    XtCacheRef	    *cache_refs = NULL;
945444c061aSmrg    Cardinal	    count;
946444c061aSmrg
947444c061aSmrg    wc = XtClass(w);
948444c061aSmrg
949444c061aSmrg    count = CountTreeDepth(w);
950444c061aSmrg    names = (XrmName*) XtStackAlloc (count * sizeof(XrmName), names_s);
951444c061aSmrg    classes = (XrmClass*) XtStackAlloc (count * sizeof(XrmClass), classes_s);
9520568f49bSmrg    if (names == NULL || classes == NULL) {
9530568f49bSmrg	_XtAllocError(NULL);
9540568f49bSmrg    } else {
9559e7bcd65Smrg
9560568f49bSmrg	/* Get names, classes for widget and ancestors */
9570568f49bSmrg	GetNamesAndClasses(w, names, classes);
958444c061aSmrg
9590568f49bSmrg	/* Compile arg list into quarks */
9600568f49bSmrg	CacheArgs(args, num_args, typed_args, *num_typed_args, quark_cache,
9610568f49bSmrg		  XtNumber(quark_cache), &quark_args);
9620568f49bSmrg
9630568f49bSmrg	/* Get normal resources */
9640568f49bSmrg	LOCK_PROCESS;
9650568f49bSmrg	cache_refs = GetResources(w, (char*)w, names, classes,
9660568f49bSmrg	    (XrmResourceList *) wc->core_class.resources,
9670568f49bSmrg	    wc->core_class.num_resources, quark_args, args, num_args,
9680568f49bSmrg	    typed_args, num_typed_args, XtIsWidget(w));
9690568f49bSmrg
9700568f49bSmrg	if (w->core.constraints != NULL) {
9710568f49bSmrg	    ConstraintWidgetClass cwc;
9720568f49bSmrg	    XtCacheRef *cache_refs_core;
9730568f49bSmrg
9740568f49bSmrg	    cwc = (ConstraintWidgetClass) XtClass(w->core.parent);
9750568f49bSmrg	    cache_refs_core =
9760568f49bSmrg		GetResources(w, (char*)w->core.constraints, names, classes,
9770568f49bSmrg		(XrmResourceList *) cwc->constraint_class.resources,
9780568f49bSmrg		cwc->constraint_class.num_resources,
9790568f49bSmrg		quark_args, args, num_args, typed_args, num_typed_args, False);
9800568f49bSmrg	     XtFree((char *)cache_refs_core);
981444c061aSmrg	}
9820568f49bSmrg	FreeCache(quark_cache, quark_args);
9830568f49bSmrg	UNLOCK_PROCESS;
9840568f49bSmrg	XtStackFree((XtPointer)names, names_s);
9850568f49bSmrg	XtStackFree((XtPointer)classes, classes_s);
986444c061aSmrg    }
987444c061aSmrg    return cache_refs;
988444c061aSmrg} /* _XtGetResources */
989444c061aSmrg
990444c061aSmrg
991444c061aSmrgvoid _XtGetSubresources (
992444c061aSmrg    Widget	  w,			/* Widget "parent" of subobject   */
993444c061aSmrg    XtPointer	  base,			/* Base address to write to       */
994444c061aSmrg    const char*   name,			/* name of subobject		    */
995444c061aSmrg    const char*   class,		/* class of subobject		    */
996444c061aSmrg    XtResourceList resources,		/* resource list for subobject    */
9979e7bcd65Smrg    Cardinal	  num_resources,
998444c061aSmrg    ArgList	  args,			/* arg list to override resources */
999444c061aSmrg    Cardinal	  num_args,
1000444c061aSmrg    XtTypedArgList typed_args,
1001444c061aSmrg    Cardinal      num_typed_args)
1002444c061aSmrg{
1003444c061aSmrg    XrmName	  *names, names_s[50];
1004444c061aSmrg    XrmClass	  *classes, classes_s[50];
1005444c061aSmrg    XrmQuark	  quark_cache[100];
1006444c061aSmrg    XrmQuarkList  quark_args;
1007444c061aSmrg    XrmResourceList* table;
1008444c061aSmrg    Cardinal	  count, ntyped_args = num_typed_args;
1009444c061aSmrg    XtCacheRef    *Resrc = NULL;
1010444c061aSmrg    WIDGET_TO_APPCON(w);
1011444c061aSmrg
1012444c061aSmrg    if (num_resources == 0) return;
1013444c061aSmrg
1014444c061aSmrg    LOCK_APP(app);
1015444c061aSmrg    count = CountTreeDepth(w);
1016444c061aSmrg    count++;	/* make sure there's enough room for name and class */
1017444c061aSmrg    names = (XrmName*) XtStackAlloc(count * sizeof(XrmName), names_s);
1018444c061aSmrg    classes = (XrmClass*) XtStackAlloc(count * sizeof(XrmClass), classes_s);
10190568f49bSmrg    if (names == NULL || classes == NULL) {
10200568f49bSmrg	_XtAllocError(NULL);
10210568f49bSmrg    } else {
10220568f49bSmrg	/* Get full name, class of subobject */
10230568f49bSmrg	GetNamesAndClasses(w, names, classes);
10240568f49bSmrg	count -= 2;
10250568f49bSmrg	names[count] = StringToName(name);
10260568f49bSmrg	classes[count] = StringToClass(class);
10270568f49bSmrg	count++;
10280568f49bSmrg	names[count] = NULLQUARK;
10290568f49bSmrg	classes[count] = NULLQUARK;
1030444c061aSmrg
10310568f49bSmrg	/* Compile arg list into quarks */
10320568f49bSmrg	CacheArgs(args, num_args, typed_args, num_typed_args,
10330568f49bSmrg		  quark_cache, XtNumber(quark_cache), &quark_args);
1034444c061aSmrg
10350568f49bSmrg	/* Compile resource list if needed */
10360568f49bSmrg	if (((int) resources->resource_offset) >= 0) {
10370568f49bSmrg	    XrmCompileResourceListEphem(resources, num_resources);
10380568f49bSmrg	}
10390568f49bSmrg	table = _XtCreateIndirectionTable(resources, num_resources);
10400568f49bSmrg	Resrc = GetResources(w, (char*)base, names, classes, table, num_resources,
10410568f49bSmrg			    quark_args, args, num_args,
10420568f49bSmrg			    typed_args, &ntyped_args, False);
10430568f49bSmrg	FreeCache(quark_cache, quark_args);
10440568f49bSmrg	XtFree((char *)table);
10450568f49bSmrg	XtFree((char *)Resrc);
10460568f49bSmrg	XtStackFree((XtPointer)names, names_s);
10470568f49bSmrg	XtStackFree((XtPointer)classes, classes_s);
10480568f49bSmrg	UNLOCK_APP(app);
1049444c061aSmrg    }
1050444c061aSmrg}
1051444c061aSmrg
1052444c061aSmrgvoid XtGetSubresources (
1053444c061aSmrg    Widget	  w,			/* Widget "parent" of subobject   */
1054444c061aSmrg    XtPointer	  base,			/* Base address to write to       */
1055444c061aSmrg    _Xconst char* name,			/* name of subobject		    */
1056444c061aSmrg    _Xconst char* class,		/* class of subobject		    */
1057444c061aSmrg    XtResourceList resources,		/* resource list for subobject    */
10589e7bcd65Smrg    Cardinal	  num_resources,
1059444c061aSmrg    ArgList	  args,			/* arg list to override resources */
1060444c061aSmrg    Cardinal	  num_args)
1061444c061aSmrg{
1062444c061aSmrg    _XtGetSubresources (w, base, name, class, resources, num_resources, args, num_args, NULL, 0);
1063444c061aSmrg}
1064444c061aSmrg
1065444c061aSmrg
1066444c061aSmrgvoid _XtGetApplicationResources (
1067444c061aSmrg    Widget	    w,		  /* Application shell widget       */
1068444c061aSmrg    XtPointer	    base,	  /* Base address to write to       */
1069444c061aSmrg    XtResourceList  resources,	  /* resource list for subobject    */
1070444c061aSmrg    Cardinal	    num_resources,
1071444c061aSmrg    ArgList	    args,	  /* arg list to override resources */
1072444c061aSmrg    Cardinal	    num_args,
1073444c061aSmrg    XtTypedArgList  typed_args,
1074444c061aSmrg    Cardinal	    num_typed_args)
1075444c061aSmrg{
1076444c061aSmrg    XrmName	    *names, names_s[50];
1077444c061aSmrg    XrmClass	    *classes, classes_s[50];
1078444c061aSmrg    XrmQuark	    quark_cache[100];
1079444c061aSmrg    XrmQuarkList    quark_args;
1080444c061aSmrg    XrmResourceList* table;
10810568f49bSmrg    Cardinal        ntyped_args = num_typed_args;
1082444c061aSmrg#ifdef XTHREADS
1083444c061aSmrg    XtAppContext    app;
1084444c061aSmrg#endif
1085444c061aSmrg    XtCacheRef	    *Resrc = NULL;
1086444c061aSmrg
1087444c061aSmrg    if (num_resources == 0) return;
1088444c061aSmrg
1089444c061aSmrg#ifdef XTHREADS
1090444c061aSmrg    if (w == NULL) app = _XtDefaultAppContext();
1091444c061aSmrg    else app = XtWidgetToApplicationContext(w);
1092444c061aSmrg#endif
1093444c061aSmrg
1094444c061aSmrg    LOCK_APP(app);
1095444c061aSmrg    /* Get full name, class of application */
1096444c061aSmrg    if (w == NULL) {
1097444c061aSmrg	/* hack for R2 compatibility */
1098444c061aSmrg	XtPerDisplay pd = _XtGetPerDisplay(_XtDefaultAppContext()->list[0]);
1099444c061aSmrg	names = (XrmName*) XtStackAlloc (2 * sizeof(XrmName), names_s);
1100444c061aSmrg	classes = (XrmClass*) XtStackAlloc (2 * sizeof(XrmClass), classes_s);
11010568f49bSmrg	if (names == NULL || classes == NULL) {
11020568f49bSmrg	    _XtAllocError(NULL);
11030568f49bSmrg	} else {
11040568f49bSmrg	    names[0] = pd->name;
11050568f49bSmrg	    names[1] = NULLQUARK;
11060568f49bSmrg	    classes[0] = pd->class;
11070568f49bSmrg	    classes[1] = NULLQUARK;
11080568f49bSmrg	}
1109444c061aSmrg    }
1110444c061aSmrg    else {
11110568f49bSmrg	Cardinal count = CountTreeDepth(w);
1112444c061aSmrg        names = (XrmName*) XtStackAlloc(count * sizeof(XrmName), names_s);
1113444c061aSmrg        classes = (XrmClass*) XtStackAlloc(count * sizeof(XrmClass), classes_s);
11140568f49bSmrg	if (names == NULL || classes == NULL) {
11150568f49bSmrg	    _XtAllocError(NULL);
11160568f49bSmrg	} else {
11170568f49bSmrg	    GetNamesAndClasses(w, names, classes);
11180568f49bSmrg	}
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	XrmCompileResourceListEphem(resources, num_resources);
1127444c061aSmrg    }
1128444c061aSmrg    table = _XtCreateIndirectionTable(resources,num_resources);
1129444c061aSmrg
1130444c061aSmrg    Resrc = GetResources(w, (char*)base, names, classes, table, num_resources,
1131444c061aSmrg			quark_args, args, num_args,
1132444c061aSmrg			typed_args, &ntyped_args, False);
1133444c061aSmrg    FreeCache(quark_cache, quark_args);
1134444c061aSmrg    XtFree((char *)table);
1135444c061aSmrg    XtFree((char *)Resrc);
1136444c061aSmrg    if (w != NULL) {
1137444c061aSmrg	XtStackFree((XtPointer)names, names_s);
1138444c061aSmrg	XtStackFree((XtPointer)classes, classes_s);
1139444c061aSmrg    }
1140444c061aSmrg    UNLOCK_APP(app);
1141444c061aSmrg}
1142444c061aSmrg
1143444c061aSmrgvoid XtGetApplicationResources (
1144444c061aSmrg    Widget	    w,		  /* Application shell widget       */
1145444c061aSmrg    XtPointer	    base,	  /* Base address to write to       */
1146444c061aSmrg    XtResourceList  resources,	  /* resource list for subobject    */
1147444c061aSmrg    Cardinal	    num_resources,
1148444c061aSmrg    ArgList	    args,	  /* arg list to override resources */
1149444c061aSmrg    Cardinal	    num_args)
1150444c061aSmrg{
1151444c061aSmrg    _XtGetApplicationResources(w, base, resources, num_resources, args, num_args, NULL, 0);
1152444c061aSmrg}
1153444c061aSmrg
1154444c061aSmrgstatic Boolean initialized = FALSE;
1155444c061aSmrg
1156444c061aSmrgvoid _XtResourceListInitialize(void)
1157444c061aSmrg{
1158444c061aSmrg    LOCK_PROCESS;
1159444c061aSmrg    if (initialized) {
1160444c061aSmrg	XtWarningMsg("initializationError","xtInitialize",XtCXtToolkitError,
1161444c061aSmrg                  "Initializing Resource Lists twice",
11620568f49bSmrg		  NULL, NULL);
1163444c061aSmrg	UNLOCK_PROCESS;
1164444c061aSmrg    	return;
1165444c061aSmrg    }
1166444c061aSmrg    initialized = TRUE;
1167444c061aSmrg    UNLOCK_PROCESS;
1168444c061aSmrg
1169444c061aSmrg    QBoolean = XrmPermStringToQuark(XtCBoolean);
1170444c061aSmrg    QString = XrmPermStringToQuark(XtCString);
1171444c061aSmrg    QCallProc = XrmPermStringToQuark(XtRCallProc);
1172444c061aSmrg    QImmediate = XrmPermStringToQuark(XtRImmediate);
1173444c061aSmrg    QinitialResourcesPersistent = XrmPermStringToQuark(XtNinitialResourcesPersistent);
1174444c061aSmrg    QInitialResourcesPersistent = XrmPermStringToQuark(XtCInitialResourcesPersistent);
1175444c061aSmrg    Qtranslations = XrmPermStringToQuark(XtNtranslations);
1176444c061aSmrg    QbaseTranslations = XrmPermStringToQuark("baseTranslations");
1177444c061aSmrg    QTranslations = XrmPermStringToQuark(XtCTranslations);
1178444c061aSmrg    QTranslationTable = XrmPermStringToQuark(XtRTranslationTable);
1179444c061aSmrg    Qscreen = XrmPermStringToQuark(XtNscreen);
1180444c061aSmrg    QScreen = XrmPermStringToQuark(XtCScreen);
1181444c061aSmrg}
1182