Initialize.c revision 1477040f
1444c061aSmrg/* $Xorg: Initialize.c,v 1.8 2001/02/09 02:03:55 xorgcvs Exp $ */
2444c061aSmrg
3444c061aSmrg/***********************************************************
41477040fSmrgCopyright 1993 Sun Microsystems, Inc.  All rights reserved.
51477040fSmrg
61477040fSmrgPermission is hereby granted, free of charge, to any person obtaining a
71477040fSmrgcopy of this software and associated documentation files (the "Software"),
81477040fSmrgto deal in the Software without restriction, including without limitation
91477040fSmrgthe rights to use, copy, modify, merge, publish, distribute, sublicense,
101477040fSmrgand/or sell copies of the Software, and to permit persons to whom the
111477040fSmrgSoftware is furnished to do so, subject to the following conditions:
121477040fSmrg
131477040fSmrgThe above copyright notice and this permission notice (including the next
141477040fSmrgparagraph) shall be included in all copies or substantial portions of the
151477040fSmrgSoftware.
161477040fSmrg
171477040fSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
181477040fSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
191477040fSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
201477040fSmrgTHE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
211477040fSmrgLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
221477040fSmrgFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
231477040fSmrgDEALINGS IN THE SOFTWARE.
241477040fSmrg
251477040fSmrgCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
26444c061aSmrg
27444c061aSmrg                        All Rights Reserved
28444c061aSmrg
29444c061aSmrgPermission to use, copy, modify, and distribute this software and its
30444c061aSmrgdocumentation for any purpose and without fee is hereby granted,
31444c061aSmrgprovided that the above copyright notice appear in all copies and that
32444c061aSmrgboth that copyright notice and this permission notice appear in
331477040fSmrgsupporting documentation, and that the name of Digital not be
34444c061aSmrgused in advertising or publicity pertaining to distribution of the
35444c061aSmrgsoftware without specific, written prior permission.
36444c061aSmrg
37444c061aSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
38444c061aSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39444c061aSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
40444c061aSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
41444c061aSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
42444c061aSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43444c061aSmrgSOFTWARE.
44444c061aSmrg
45444c061aSmrg******************************************************************/
46444c061aSmrg/* $XFree86: xc/lib/Xt/Initialize.c,v 3.21 2003/04/21 16:34:27 herrb Exp $ */
47444c061aSmrg
48444c061aSmrg/*
49444c061aSmrg
50444c061aSmrgCopyright 1987, 1988, 1994, 1998  The Open Group
51444c061aSmrg
52444c061aSmrgPermission to use, copy, modify, distribute, and sell this software and its
53444c061aSmrgdocumentation for any purpose is hereby granted without fee, provided that
54444c061aSmrgthe above copyright notice appear in all copies and that both that
55444c061aSmrgcopyright notice and this permission notice appear in supporting
56444c061aSmrgdocumentation.
57444c061aSmrg
58444c061aSmrgThe above copyright notice and this permission notice shall be included in
59444c061aSmrgall copies or substantial portions of the Software.
60444c061aSmrg
61444c061aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
62444c061aSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
63444c061aSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
64444c061aSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
65444c061aSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
66444c061aSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
67444c061aSmrg
68444c061aSmrgExcept as contained in this notice, the name of The Open Group shall not be
69444c061aSmrgused in advertising or otherwise to promote the sale, use or other dealings
70444c061aSmrgin this Software without prior written authorization from The Open Group.
71444c061aSmrg
72444c061aSmrg*/
73444c061aSmrg
74444c061aSmrg/* Make sure all wm properties can make it out of the resource manager */
75444c061aSmrg
76444c061aSmrg#ifdef HAVE_CONFIG_H
77444c061aSmrg#include <config.h>
78444c061aSmrg#endif
79444c061aSmrg#include "IntrinsicI.h"
80444c061aSmrg#include "StringDefs.h"
81444c061aSmrg#include "CoreP.h"
82444c061aSmrg#include "ShellP.h"
83444c061aSmrg#include <stdio.h>
84444c061aSmrg#include <X11/Xlocale.h>
85444c061aSmrg#ifdef XTHREADS
86444c061aSmrg#include <X11/Xthreads.h>
87444c061aSmrg#endif
88444c061aSmrg#ifndef WIN32
89444c061aSmrg#define X_INCLUDE_PWD_H
90444c061aSmrg#define XOS_USE_XT_LOCKING
91444c061aSmrg#include <X11/Xos_r.h>
92444c061aSmrg#endif
93444c061aSmrg
94444c061aSmrg#include <stdlib.h>
95444c061aSmrg
96444c061aSmrg#if (defined(SUNSHLIB) || defined(AIXSHLIB)) && defined(SHAREDCODE)
97444c061aSmrg/*
98444c061aSmrg * If used as a shared library, generate code under a different name so that
99444c061aSmrg * the stub routines in sharedlib.c get loaded into the application binary.
100444c061aSmrg */
101444c061aSmrg#define XtToolkitInitialize _XtToolkitInitialize
102444c061aSmrg#define XtOpenApplication _XtOpenApplication
103444c061aSmrg#define XtAppInitialize _XtAppInitialize
104444c061aSmrg#define XtInitialize _XtInitialize
105444c061aSmrg#endif /* (SUNSHLIB || AIXSHLIB) && SHAREDCODE */
106444c061aSmrg
107444c061aSmrg/*
108444c061aSmrg * hpux
109444c061aSmrg * Hand-patched versions of HP-UX prior to version 7.0 can usefully add
110444c061aSmrg * -DUSE_UNAME in the appropriate config file to get long hostnames.
111444c061aSmrg */
112444c061aSmrg
113444c061aSmrg#ifdef USG
114444c061aSmrg#define USE_UNAME
115444c061aSmrg#endif
116444c061aSmrg
117444c061aSmrg#ifdef USE_UNAME
118444c061aSmrg#include <sys/utsname.h>
119444c061aSmrg#endif
120444c061aSmrg
121444c061aSmrg/* some unspecified magic number of expected search levels for Xrm */
122444c061aSmrg#define SEARCH_LIST_SIZE 1000
123444c061aSmrg
124444c061aSmrg/*
125444c061aSmrg This is a set of default records describing the command line arguments that
126444c061aSmrg Xlib will parse and set into the resource data base.
127444c061aSmrg
128444c061aSmrg This list is applied before the users list to enforce these defaults.  This is
129444c061aSmrg policy, which the toolkit avoids but I hate differing programs at this level.
130444c061aSmrg*/
131444c061aSmrg
132444c061aSmrgstatic XrmOptionDescRec const opTable[] = {
133444c061aSmrg{"+rv",		"*reverseVideo", XrmoptionNoArg,	(XtPointer) "off"},
134444c061aSmrg{"+synchronous","*synchronous",	XrmoptionNoArg,		(XtPointer) "off"},
135444c061aSmrg{"-background",	"*background",	XrmoptionSepArg,	(XtPointer) NULL},
136444c061aSmrg{"-bd",		"*borderColor",	XrmoptionSepArg,	(XtPointer) NULL},
137444c061aSmrg{"-bg",		"*background",	XrmoptionSepArg,	(XtPointer) NULL},
138444c061aSmrg{"-bordercolor","*borderColor",	XrmoptionSepArg,	(XtPointer) NULL},
139444c061aSmrg{"-borderwidth",".borderWidth",	XrmoptionSepArg,	(XtPointer) NULL},
140444c061aSmrg{"-bw",		".borderWidth",	XrmoptionSepArg,	(XtPointer) NULL},
141444c061aSmrg{"-display",	".display",     XrmoptionSepArg,	(XtPointer) NULL},
142444c061aSmrg{"-fg",		"*foreground",	XrmoptionSepArg,	(XtPointer) NULL},
143444c061aSmrg{"-fn",		"*font",	XrmoptionSepArg,	(XtPointer) NULL},
144444c061aSmrg{"-font",	"*font",	XrmoptionSepArg,	(XtPointer) NULL},
145444c061aSmrg{"-foreground",	"*foreground",	XrmoptionSepArg,	(XtPointer) NULL},
146444c061aSmrg{"-geometry",	".geometry",	XrmoptionSepArg,	(XtPointer) NULL},
147444c061aSmrg{"-iconic",	".iconic",	XrmoptionNoArg,		(XtPointer) "on"},
148444c061aSmrg{"-name",	".name",	XrmoptionSepArg,	(XtPointer) NULL},
149444c061aSmrg{"-reverse",	"*reverseVideo", XrmoptionNoArg,	(XtPointer) "on"},
150444c061aSmrg{"-rv",		"*reverseVideo", XrmoptionNoArg,	(XtPointer) "on"},
151444c061aSmrg{"-selectionTimeout",
152444c061aSmrg		".selectionTimeout", XrmoptionSepArg,	(XtPointer) NULL},
153444c061aSmrg{"-synchronous","*synchronous",	XrmoptionNoArg,		(XtPointer) "on"},
154444c061aSmrg{"-title",	".title",	XrmoptionSepArg,	(XtPointer) NULL},
155444c061aSmrg{"-xnllanguage",".xnlLanguage",	XrmoptionSepArg,	(XtPointer) NULL},
156444c061aSmrg{"-xrm",	NULL,		XrmoptionResArg,	(XtPointer) NULL},
157444c061aSmrg{"-xtsessionID",".sessionID",	XrmoptionSepArg,	(XtPointer) NULL},
158444c061aSmrg};
159444c061aSmrg
160444c061aSmrg
161444c061aSmrg/*
162444c061aSmrg * GetHostname - emulates gethostname() on non-bsd systems.
163444c061aSmrg */
164444c061aSmrg
165444c061aSmrgstatic void GetHostname (
166444c061aSmrg    char *buf,
167444c061aSmrg    int maxlen)
168444c061aSmrg{
169444c061aSmrg#ifdef USE_UNAME
170444c061aSmrg    int len;
171444c061aSmrg    struct utsname name;
172444c061aSmrg
173444c061aSmrg    if (maxlen <= 0 || buf == NULL)
174444c061aSmrg	return;
175444c061aSmrg
176444c061aSmrg    uname (&name);
177444c061aSmrg    len = strlen (name.nodename);
178444c061aSmrg    if (len >= maxlen) len = maxlen;
179444c061aSmrg    (void) strncpy (buf, name.nodename, len-1);
180444c061aSmrg    buf[len-1] = '\0';
181444c061aSmrg#else
182444c061aSmrg    if (maxlen <= 0 || buf == NULL)
183444c061aSmrg	return;
184444c061aSmrg
185444c061aSmrg    buf[0] = '\0';
186444c061aSmrg    (void) gethostname (buf, maxlen);
187444c061aSmrg    buf [maxlen - 1] = '\0';
188444c061aSmrg#endif
189444c061aSmrg}
190444c061aSmrg
191444c061aSmrg
192444c061aSmrg#ifdef SUNSHLIB
193444c061aSmrgvoid _XtInherit(void)
194444c061aSmrg{
195444c061aSmrg    extern void __XtInherit();
196444c061aSmrg    __XtInherit();
197444c061aSmrg}
198444c061aSmrg#define _XtInherit __XtInherit
199444c061aSmrg#endif
200444c061aSmrg
201444c061aSmrg
2022265a131Smrg#if defined (WIN32) || defined(__CYGWIN__)
203444c061aSmrg/*
204444c061aSmrg * The Symbol _XtInherit is used in two different manners.
205444c061aSmrg * First it could be used as a generic function and second
206444c061aSmrg * as an absolute address reference, which will be used to
207444c061aSmrg * check the initialisation process of several other libraries.
208444c061aSmrg * Because of this the symbol must be accessable by all
209444c061aSmrg * client dll's and applications.  In unix environments
210444c061aSmrg * this is no problem, because the used shared libraries
211444c061aSmrg * format (elf) supports this immediatly.  Under Windows
212444c061aSmrg * this isn't true, because a functions address in a dll
213444c061aSmrg * is different from the same function in another dll or
214444c061aSmrg * applications, because the used Portable Executable
215444c061aSmrg * File adds a code stub to each client to provide the
216444c061aSmrg * exported symbol name.  This stub uses an indirect
217444c061aSmrg * pointer to get the original symbol address, which is
218444c061aSmrg * then jumped to, like in this example:
219444c061aSmrg *
220444c061aSmrg * --- client ---                                     --- dll ----
221444c061aSmrg *  ...
222444c061aSmrg *  call foo
223444c061aSmrg *
224444c061aSmrg * foo: jmp (*_imp_foo)               ---->           foo: ....
225444c061aSmrg *      nop
226444c061aSmrg *      nop
227444c061aSmrg *
228444c061aSmrg * _imp_foo: .long <index of foo in dll export table, is
229444c061aSmrg *		    set to the real address by the runtime linker>
230444c061aSmrg *
231444c061aSmrg * Now it is clear why the clients symbol foo isn't the same
232444c061aSmrg * as in the dll and we can think about how to deal which
233444c061aSmrg * this two above mentioned requirements, to export this
234444c061aSmrg * symbol to all clients and to allow calling this symbol
235444c061aSmrg * as a function.  The solution I've used exports the
236444c061aSmrg * symbol _XtInherit as data symbol, because global data
237444c061aSmrg * symbols are exported to all clients.  But how to deal
238444c061aSmrg * with the second requirement, that this symbol should
239444c061aSmrg * be used as function.  The Trick is to build a little
240444c061aSmrg * code stub in the data section in the exact manner as
241444c061aSmrg * above explained.  This is done with the assembler code
242444c061aSmrg * below.
243444c061aSmrg *
244444c061aSmrg * Ralf Habacker
245444c061aSmrg *
246444c061aSmrg * References:
247444c061aSmrg * msdn          http://msdn.microsoft.com/msdnmag/issues/02/02/PE/PE.asp
248444c061aSmrg * cygwin-xfree: http://www.cygwin.com/ml/cygwin-xfree/2003-10/msg00000.html
249444c061aSmrg */
250444c061aSmrg
251444c061aSmrgasm (".data\n\
252444c061aSmrg .globl __XtInherit        \n\
253444c061aSmrg __XtInherit:      jmp *_y \n\
254444c061aSmrg  _y: .long ___XtInherit   \n\
255444c061aSmrg    .text                 \n");
256444c061aSmrg
257444c061aSmrg#define _XtInherit __XtInherit
258444c061aSmrg#endif
259444c061aSmrg
260444c061aSmrg
261444c061aSmrgvoid _XtInherit(void)
262444c061aSmrg{
263444c061aSmrg    XtErrorMsg("invalidProcedure","inheritanceProc",XtCXtToolkitError,
264444c061aSmrg            "Unresolved inheritance operation",
265444c061aSmrg              (String *)NULL, (Cardinal *)NULL);
266444c061aSmrg}
267444c061aSmrg
268444c061aSmrg
269444c061aSmrgvoid XtToolkitInitialize(void)
270444c061aSmrg{
271444c061aSmrg    static Boolean initialized = False;
272444c061aSmrg
273444c061aSmrg    LOCK_PROCESS;
274444c061aSmrg    if (initialized) {
275444c061aSmrg	UNLOCK_PROCESS;
276444c061aSmrg	return;
277444c061aSmrg    }
278444c061aSmrg    initialized = True;
279444c061aSmrg    UNLOCK_PROCESS;
280444c061aSmrg    /* Resource management initialization */
281444c061aSmrg    XrmInitialize();
282444c061aSmrg    _XtResourceListInitialize();
283444c061aSmrg
284444c061aSmrg    /* Other intrinsic intialization */
285444c061aSmrg    _XtConvertInitialize();
286444c061aSmrg    _XtEventInitialize();
287444c061aSmrg    _XtTranslateInitialize();
288444c061aSmrg
289444c061aSmrg    /* Some apps rely on old (broken) XtAppPeekEvent behavior */
290444c061aSmrg    if(getenv("XTAPPPEEKEVENT_SKIPTIMER"))
291444c061aSmrg	XtAppPeekEvent_SkipTimer = True;
292444c061aSmrg    else
293444c061aSmrg	XtAppPeekEvent_SkipTimer = False;
294444c061aSmrg}
295444c061aSmrg
296444c061aSmrg
297444c061aSmrgString _XtGetUserName(
298444c061aSmrg    String dest,
299444c061aSmrg    int len)
300444c061aSmrg{
301444c061aSmrg#ifdef WIN32
302444c061aSmrg    String ptr = NULL;
303444c061aSmrg
304444c061aSmrg    if ((ptr = getenv("USERNAME"))) {
305444c061aSmrg	(void) strncpy (dest, ptr, len-1);
306444c061aSmrg	dest[len-1] = '\0';
307444c061aSmrg    } else
308444c061aSmrg	*dest = '\0';
309444c061aSmrg#else
310444c061aSmrg#ifdef X_NEEDS_PWPARAMS
311444c061aSmrg    _Xgetpwparams pwparams;
312444c061aSmrg#endif
313444c061aSmrg    struct passwd *pw;
314444c061aSmrg    char* ptr;
315444c061aSmrg
316444c061aSmrg    if ((ptr = getenv("USER"))) {
317444c061aSmrg	(void) strncpy (dest, ptr, len-1);
318444c061aSmrg	dest[len-1] = '\0';
319444c061aSmrg    } else {
320444c061aSmrg	if ((pw = _XGetpwuid(getuid(),pwparams)) != NULL) {
321444c061aSmrg	    (void) strncpy (dest, pw->pw_name, len-1);
322444c061aSmrg	    dest[len-1] = '\0';
323444c061aSmrg	} else
324444c061aSmrg	    *dest = '\0';
325444c061aSmrg    }
326444c061aSmrg#endif
327444c061aSmrg    return dest;
328444c061aSmrg}
329444c061aSmrg
330444c061aSmrg
331444c061aSmrgstatic String GetRootDirName(
332444c061aSmrg    String dest,
333444c061aSmrg    int len)
334444c061aSmrg{
335444c061aSmrg#ifdef WIN32
336444c061aSmrg    register char *ptr1;
337444c061aSmrg    register char *ptr2 = NULL;
338444c061aSmrg    int len1 = 0, len2 = 0;
339444c061aSmrg
340444c061aSmrg    if (ptr1 = getenv("HOME")) {	/* old, deprecated */
341444c061aSmrg	len1 = strlen (ptr1);
342444c061aSmrg    } else if ((ptr1 = getenv("HOMEDRIVE")) && (ptr2 = getenv("HOMEDIR"))) {
343444c061aSmrg	len1 = strlen (ptr1);
344444c061aSmrg	len2 = strlen (ptr2);
345444c061aSmrg    } else if (ptr2 = getenv("USERNAME")) {
346444c061aSmrg	len1 = strlen (ptr1 = "/users/");
347444c061aSmrg	len2 = strlen (ptr2);
348444c061aSmrg    }
349444c061aSmrg    if ((len1 + len2 + 1) < len)
350444c061aSmrg	sprintf (dest, "%s%s", ptr1, (ptr2) ? ptr2 : "");
351444c061aSmrg    else
352444c061aSmrg	*dest = '\0';
353444c061aSmrg#else
354444c061aSmrg#ifdef X_NEEDS_PWPARAMS
355444c061aSmrg    _Xgetpwparams pwparams;
356444c061aSmrg#endif
357444c061aSmrg    struct passwd *pw;
358444c061aSmrg    static char *ptr;
359444c061aSmrg
360444c061aSmrg    if (len <= 0 || dest == NULL)
361444c061aSmrg	return NULL;
362444c061aSmrg
363444c061aSmrg    if ((ptr = getenv("HOME"))) {
364444c061aSmrg	(void) strncpy (dest, ptr, len-1);
365444c061aSmrg	dest[len-1] = '\0';
366444c061aSmrg    } else {
367444c061aSmrg	if ((ptr = getenv("USER")))
368444c061aSmrg	    pw = _XGetpwnam(ptr,pwparams);
369444c061aSmrg	else
370444c061aSmrg 	    pw = _XGetpwuid(getuid(),pwparams);
371444c061aSmrg	if (pw != NULL) {
372444c061aSmrg	    (void) strncpy (dest, pw->pw_dir, len-1);
373444c061aSmrg	    dest[len-1] = '\0';
374444c061aSmrg	} else
375444c061aSmrg	    *dest = '\0';
376444c061aSmrg    }
377444c061aSmrg#endif
378444c061aSmrg    return dest;
379444c061aSmrg}
380444c061aSmrg
381444c061aSmrgstatic void CombineAppUserDefaults(
382444c061aSmrg    Display *dpy,
383444c061aSmrg    XrmDatabase *pdb)
384444c061aSmrg{
385444c061aSmrg    char* filename;
386444c061aSmrg    char* path;
387444c061aSmrg    Boolean deallocate = False;
388444c061aSmrg
389444c061aSmrg    if (!(path = getenv("XUSERFILESEARCHPATH"))) {
3902265a131Smrg#if !defined(WIN32) || !defined(__MINGW32__)
391444c061aSmrg	char *old_path;
392444c061aSmrg	char homedir[PATH_MAX];
393444c061aSmrg	GetRootDirName(homedir, PATH_MAX);
394444c061aSmrg	if (!(old_path = getenv("XAPPLRESDIR"))) {
395444c061aSmrg	    char *path_default = "%s/%%L/%%N%%C:%s/%%l/%%N%%C:%s/%%N%%C:%s/%%L/%%N:%s/%%l/%%N:%s/%%N";
396444c061aSmrg	    if (!(path =
397444c061aSmrg		  ALLOCATE_LOCAL(6*strlen(homedir) + strlen(path_default))))
398444c061aSmrg		_XtAllocError(NULL);
399444c061aSmrg	    sprintf( path, path_default,
400444c061aSmrg		    homedir, homedir, homedir, homedir, homedir, homedir );
401444c061aSmrg	} else {
402444c061aSmrg	    char *path_default = "%s/%%L/%%N%%C:%s/%%l/%%N%%C:%s/%%N%%C:%s/%%N%%C:%s/%%L/%%N:%s/%%l/%%N:%s/%%N:%s/%%N";
403444c061aSmrg	    if (!(path =
404444c061aSmrg		  ALLOCATE_LOCAL( 6*strlen(old_path) + 2*strlen(homedir)
405444c061aSmrg				 + strlen(path_default))))
406444c061aSmrg		_XtAllocError(NULL);
407444c061aSmrg	    sprintf(path, path_default, old_path, old_path, old_path, homedir,
408444c061aSmrg		    old_path, old_path, old_path, homedir );
409444c061aSmrg	}
410444c061aSmrg	deallocate = True;
4112265a131Smrg#endif
412444c061aSmrg    }
413444c061aSmrg
414444c061aSmrg    filename = XtResolvePathname(dpy, NULL, NULL, NULL, path, NULL, 0, NULL);
415444c061aSmrg    if (filename) {
416444c061aSmrg	(void)XrmCombineFileDatabase(filename, pdb, False);
417444c061aSmrg	XtFree(filename);
418444c061aSmrg    }
419444c061aSmrg
420444c061aSmrg    if (deallocate) DEALLOCATE_LOCAL(path);
421444c061aSmrg}
422444c061aSmrg
423444c061aSmrgstatic void CombineUserDefaults(
424444c061aSmrg    Display *dpy,
425444c061aSmrg    XrmDatabase *pdb)
426444c061aSmrg{
4272265a131Smrg#ifdef __MINGW32__
4282265a131Smrg    char *slashDotXdefaults = "/Xdefaults";
4292265a131Smrg#else
430444c061aSmrg    char *slashDotXdefaults = "/.Xdefaults";
4312265a131Smrg#endif
432444c061aSmrg    char *dpy_defaults = XResourceManagerString(dpy);
433444c061aSmrg
434444c061aSmrg    if (dpy_defaults) {
435444c061aSmrg	XrmCombineDatabase(XrmGetStringDatabase(dpy_defaults), pdb, False);
436444c061aSmrg    } else {
437444c061aSmrg	char filename[PATH_MAX];
438444c061aSmrg	(void) GetRootDirName(filename,
439444c061aSmrg			PATH_MAX - strlen (slashDotXdefaults) - 1);
440444c061aSmrg	(void) strcat(filename, slashDotXdefaults);
441444c061aSmrg	(void)XrmCombineFileDatabase(filename, pdb, False);
442444c061aSmrg    }
443444c061aSmrg}
444444c061aSmrg
445444c061aSmrg/*ARGSUSED*/
446444c061aSmrgstatic Bool StoreDBEntry(
447444c061aSmrg    XrmDatabase		*db,
448444c061aSmrg    XrmBindingList      bindings,
449444c061aSmrg    XrmQuarkList	quarks,
450444c061aSmrg    XrmRepresentation   *type,
451444c061aSmrg    XrmValuePtr		value,
452444c061aSmrg    XPointer		data)
453444c061aSmrg{
454444c061aSmrg    XrmQPutResource((XrmDatabase *)data, bindings, quarks, *type, value);
455444c061aSmrg    return False;
456444c061aSmrg}
457444c061aSmrg
458444c061aSmrgstatic XrmDatabase CopyDB(XrmDatabase db)
459444c061aSmrg{
460444c061aSmrg    XrmDatabase copy = NULL;
461444c061aSmrg    XrmQuark empty = NULLQUARK;
462444c061aSmrg
463444c061aSmrg    XrmEnumerateDatabase(db, &empty, &empty, XrmEnumAllLevels,
464444c061aSmrg			 StoreDBEntry, (XPointer)&copy);
465444c061aSmrg    return copy;
466444c061aSmrg}
467444c061aSmrg
468444c061aSmrg/*ARGSUSED*/
469444c061aSmrgstatic String _XtDefaultLanguageProc(
470444c061aSmrg    Display   *dpy,	/* unused */
471444c061aSmrg    String     xnl,
472444c061aSmrg    XtPointer  closure)	/* unused */
473444c061aSmrg{
474444c061aSmrg    if (! setlocale(LC_ALL, xnl))
475444c061aSmrg	XtWarning("locale not supported by C library, locale unchanged");
476444c061aSmrg
477444c061aSmrg    if (! XSupportsLocale()) {
478444c061aSmrg	XtWarning("locale not supported by Xlib, locale set to C");
479444c061aSmrg	setlocale(LC_ALL, "C");
480444c061aSmrg    }
481444c061aSmrg    if (! XSetLocaleModifiers(""))
482444c061aSmrg	XtWarning("X locale modifiers not supported, using default");
483444c061aSmrg
484444c061aSmrg    return setlocale(LC_ALL, NULL); /* re-query in case overwritten */
485444c061aSmrg}
486444c061aSmrg
487444c061aSmrgXtLanguageProc XtSetLanguageProc(
488444c061aSmrg    XtAppContext      app,
489444c061aSmrg    XtLanguageProc    proc,
490444c061aSmrg    XtPointer         closure)
491444c061aSmrg{
492444c061aSmrg    XtLanguageProc    old;
493444c061aSmrg
494444c061aSmrg    if (!proc) {
495444c061aSmrg	proc = _XtDefaultLanguageProc;
496444c061aSmrg	closure = NULL;
497444c061aSmrg    }
498444c061aSmrg
499444c061aSmrg    if (app) {
500444c061aSmrg	LOCK_APP(app);
501444c061aSmrg	LOCK_PROCESS;
502444c061aSmrg	/* set langProcRec only for this application context */
503444c061aSmrg        old = app->langProcRec.proc;
504444c061aSmrg        app->langProcRec.proc = proc;
505444c061aSmrg        app->langProcRec.closure = closure;
506444c061aSmrg	UNLOCK_PROCESS;
507444c061aSmrg	UNLOCK_APP(app);
508444c061aSmrg    } else {
509444c061aSmrg	/* set langProcRec for all application contexts */
510444c061aSmrg        ProcessContext process;
511444c061aSmrg
512444c061aSmrg	LOCK_PROCESS;
513444c061aSmrg        process = _XtGetProcessContext();
514444c061aSmrg        old = process->globalLangProcRec.proc;
515444c061aSmrg	process->globalLangProcRec.proc = proc;
516444c061aSmrg	process->globalLangProcRec.closure = closure;
517444c061aSmrg        app = process->appContextList;
518444c061aSmrg        while (app) {
519444c061aSmrg            app->langProcRec.proc = proc;
520444c061aSmrg            app->langProcRec.closure = closure;
521444c061aSmrg	    app = app->next;
522444c061aSmrg        }
523444c061aSmrg	UNLOCK_PROCESS;
524444c061aSmrg    }
525444c061aSmrg    return (old ? old : _XtDefaultLanguageProc);
526444c061aSmrg}
527444c061aSmrg
528444c061aSmrgXrmDatabase XtScreenDatabase(
529444c061aSmrg    Screen *screen)
530444c061aSmrg{
531444c061aSmrg    int scrno;
532444c061aSmrg    Bool doing_def;
533444c061aSmrg    XrmDatabase db, olddb;
534444c061aSmrg    XtPerDisplay pd;
535444c061aSmrg    Status do_fallback;
536444c061aSmrg    char *scr_resources;
537444c061aSmrg    Display *dpy = DisplayOfScreen(screen);
538444c061aSmrg    DPY_TO_APPCON(dpy);
539444c061aSmrg
540444c061aSmrg    LOCK_APP(app);
541444c061aSmrg    LOCK_PROCESS;
542444c061aSmrg    if (screen == DefaultScreenOfDisplay(dpy)) {
543444c061aSmrg	scrno = DefaultScreen(dpy);
544444c061aSmrg	doing_def = True;
545444c061aSmrg    } else {
546444c061aSmrg	scrno = XScreenNumberOfScreen(screen);
547444c061aSmrg	doing_def = False;
548444c061aSmrg    }
549444c061aSmrg    pd = _XtGetPerDisplay(dpy);
550444c061aSmrg    if ((db = pd->per_screen_db[scrno])) {
551444c061aSmrg	UNLOCK_PROCESS;
552444c061aSmrg	UNLOCK_APP(app);
553444c061aSmrg	return (doing_def ? XrmGetDatabase(dpy) : db);
554444c061aSmrg    }
555444c061aSmrg    scr_resources = XScreenResourceString(screen);
556444c061aSmrg
557444c061aSmrg    if (ScreenCount(dpy) == 1) {
558444c061aSmrg	db = pd->cmd_db;
559444c061aSmrg	pd->cmd_db = NULL;
560444c061aSmrg    } else {
561444c061aSmrg	db = CopyDB(pd->cmd_db);
562444c061aSmrg    }
563444c061aSmrg    {   /* Environment defaults */
564444c061aSmrg	char	filenamebuf[PATH_MAX];
565444c061aSmrg	char	*filename;
566444c061aSmrg
567444c061aSmrg	if (!(filename = getenv("XENVIRONMENT"))) {
568444c061aSmrg	    int len;
5692265a131Smrg#ifdef __MINGW32__
5702265a131Smrg	    char *slashDotXdefaultsDash = "/Xdefaults-";
5712265a131Smrg#else
572444c061aSmrg	    char *slashDotXdefaultsDash = "/.Xdefaults-";
5732265a131Smrg#endif
574444c061aSmrg
575444c061aSmrg	    (void) GetRootDirName(filename = filenamebuf,
576444c061aSmrg			PATH_MAX - strlen (slashDotXdefaultsDash) - 1);
577444c061aSmrg	    (void) strcat(filename, slashDotXdefaultsDash);
578444c061aSmrg	    len = strlen(filename);
579444c061aSmrg	    GetHostname (filename+len, PATH_MAX-len);
580444c061aSmrg	}
581444c061aSmrg	(void)XrmCombineFileDatabase(filename, &db, False);
582444c061aSmrg    }
583444c061aSmrg    if (scr_resources)
584444c061aSmrg    {   /* Screen defaults */
585444c061aSmrg	XrmCombineDatabase(XrmGetStringDatabase(scr_resources), &db, False);
586444c061aSmrg	XFree(scr_resources);
587444c061aSmrg    }
588444c061aSmrg    /* Server or host defaults */
589444c061aSmrg    if (!pd->server_db)
590444c061aSmrg	CombineUserDefaults(dpy, &db);
591444c061aSmrg    else {
592444c061aSmrg	(void) XrmCombineDatabase(pd->server_db, &db, False);
593444c061aSmrg	pd->server_db = NULL;
594444c061aSmrg    }
595444c061aSmrg
596444c061aSmrg    if (!db)
597444c061aSmrg	db = XrmGetStringDatabase("");
598444c061aSmrg    pd->per_screen_db[scrno] = db;
599444c061aSmrg    olddb = XrmGetDatabase(dpy);
600444c061aSmrg    /* set database now, for XtResolvePathname to use */
601444c061aSmrg    XrmSetDatabase(dpy, db);
602444c061aSmrg    CombineAppUserDefaults(dpy, &db);
603444c061aSmrg    do_fallback = 1;
604444c061aSmrg    {   /* System app-defaults */
605444c061aSmrg	char	*filename;
606444c061aSmrg
607444c061aSmrg	if ((filename = XtResolvePathname(dpy, "app-defaults",
608444c061aSmrg					 NULL, NULL, NULL, NULL, 0, NULL))) {
609444c061aSmrg	    do_fallback = !XrmCombineFileDatabase(filename, &db, False);
610444c061aSmrg	    XtFree(filename);
611444c061aSmrg	}
612444c061aSmrg    }
613444c061aSmrg    /* now restore old database, if need be */
614444c061aSmrg    if (!doing_def)
615444c061aSmrg	XrmSetDatabase(dpy, olddb);
616444c061aSmrg    if (do_fallback && pd->appContext->fallback_resources)
617444c061aSmrg    {   /* Fallback defaults */
618444c061aSmrg        XrmDatabase fdb = NULL;
619444c061aSmrg	String *res;
620444c061aSmrg
621444c061aSmrg	for (res = pd->appContext->fallback_resources; *res; res++)
622444c061aSmrg	    XrmPutLineResource(&fdb, *res);
623444c061aSmrg	(void)XrmCombineDatabase(fdb, &db, False);
624444c061aSmrg    }
625444c061aSmrg    UNLOCK_PROCESS;
626444c061aSmrg    UNLOCK_APP(app);
627444c061aSmrg    return db;
628444c061aSmrg}
629444c061aSmrg
630444c061aSmrg/*
631444c061aSmrg * Merge two option tables, allowing the second to over-ride the first,
632444c061aSmrg * so that ambiguous abbreviations can be noticed.  The merge attempts
633444c061aSmrg * to make the resulting table lexicographically sorted, but succeeds
634444c061aSmrg * only if the first source table is sorted.  Though it _is_ recommended
635444c061aSmrg * (for optimizations later in XrmParseCommand), it is not required
636444c061aSmrg * that either source table be sorted.
637444c061aSmrg *
638444c061aSmrg * Caller is responsible for freeing the returned option table.
639444c061aSmrg */
640444c061aSmrg
641444c061aSmrgstatic void _MergeOptionTables(
642444c061aSmrg    const XrmOptionDescRec *src1,
643444c061aSmrg    Cardinal num_src1,
644444c061aSmrg    const XrmOptionDescRec *src2,
645444c061aSmrg    Cardinal num_src2,
646444c061aSmrg    XrmOptionDescRec **dst,
647444c061aSmrg    Cardinal *num_dst)
648444c061aSmrg{
649444c061aSmrg    XrmOptionDescRec *table, *endP;
650444c061aSmrg    register XrmOptionDescRec *opt1, *whereP, *dstP;
651444c061aSmrg    register const XrmOptionDescRec *opt2;
652444c061aSmrg    int i1;
653444c061aSmrg    Cardinal i2;
654444c061aSmrg    int dst_len, order;
655444c061aSmrg    Boolean found;
656444c061aSmrg    enum {Check, NotSorted, IsSorted} sort_order = Check;
657444c061aSmrg
658444c061aSmrg    *dst = table = (XrmOptionDescRec*)
659444c061aSmrg	__XtMalloc( sizeof(XrmOptionDescRec) * (num_src1 + num_src2) );
660444c061aSmrg
661444c061aSmrg    (void) memmove(table, src1, sizeof(XrmOptionDescRec) * num_src1 );
662444c061aSmrg    if (num_src2 == 0) {
663444c061aSmrg	*num_dst = num_src1;
664444c061aSmrg	return;
665444c061aSmrg    }
666444c061aSmrg    endP = &table[dst_len = num_src1];
667444c061aSmrg    for (opt2 = src2, i2= 0; i2 < num_src2; opt2++, i2++) {
668444c061aSmrg	found = False;
669444c061aSmrg	whereP = endP-1;	/* assume new option goes at the end */
670444c061aSmrg	for (opt1 = table, i1 = 0; i1 < dst_len; opt1++, i1++) {
671444c061aSmrg	    /* have to walk the entire new table so new list is ordered
672444c061aSmrg	       (if src1 was ordered) */
673444c061aSmrg	    if (sort_order == Check && i1 > 0
674444c061aSmrg		&& strcmp(opt1->option, (opt1-1)->option) < 0)
675444c061aSmrg		sort_order = NotSorted;
676444c061aSmrg	    if ((order = strcmp(opt1->option, opt2->option)) == 0) {
677444c061aSmrg		/* same option names; just overwrite opt1 with opt2 */
678444c061aSmrg		*opt1 = *opt2;
679444c061aSmrg		found = True;
680444c061aSmrg		break;
681444c061aSmrg		}
682444c061aSmrg	    /* else */
683444c061aSmrg	    if (sort_order == IsSorted && order > 0) {
684444c061aSmrg		/* insert before opt1 to preserve order */
685444c061aSmrg		/* shift rest of table forward to make room for new entry */
686444c061aSmrg		for (dstP = endP++; dstP > opt1; dstP--)
687444c061aSmrg		    *dstP = *(dstP-1);
688444c061aSmrg		*opt1 = *opt2;
689444c061aSmrg		dst_len++;
690444c061aSmrg		found = True;
691444c061aSmrg		break;
692444c061aSmrg	    }
693444c061aSmrg	    /* else */
694444c061aSmrg	    if (order < 0)
695444c061aSmrg		/* opt2 sorts after opt1, so remember this position */
696444c061aSmrg		whereP = opt1;
697444c061aSmrg	}
698444c061aSmrg	if (sort_order == Check && i1 == dst_len)
699444c061aSmrg	    sort_order = IsSorted;
700444c061aSmrg	if (!found) {
701444c061aSmrg	   /* when we get here, whereP points to the last entry in the
702444c061aSmrg	      destination that sorts before "opt2".  Shift rest of table
703444c061aSmrg	      forward and insert "opt2" after whereP. */
704444c061aSmrg	    whereP++;
705444c061aSmrg	    for (dstP = endP++; dstP > whereP; dstP--)
706444c061aSmrg		*dstP = *(dstP-1);
707444c061aSmrg	    *whereP = *opt2;
708444c061aSmrg	    dst_len++;
709444c061aSmrg	}
710444c061aSmrg    }
711444c061aSmrg    *num_dst = dst_len;
712444c061aSmrg}
713444c061aSmrg
714444c061aSmrg
715444c061aSmrg/* NOTE: name, class, and type must be permanent strings */
716444c061aSmrgstatic Boolean _GetResource(
717444c061aSmrg    Display *dpy,
718444c061aSmrg    XrmSearchList list,
719444c061aSmrg    String name,
720444c061aSmrg    String class,
721444c061aSmrg    String type,
722444c061aSmrg    XrmValue* value)
723444c061aSmrg{
724444c061aSmrg    XrmRepresentation db_type;
725444c061aSmrg    XrmValue db_value;
726444c061aSmrg    XrmName Qname = XrmPermStringToQuark(name);
727444c061aSmrg    XrmClass Qclass = XrmPermStringToQuark(class);
728444c061aSmrg    XrmRepresentation Qtype = XrmPermStringToQuark(type);
729444c061aSmrg
730444c061aSmrg    if (XrmQGetSearchResource(list, Qname, Qclass, &db_type, &db_value)) {
731444c061aSmrg	if (db_type == Qtype) {
732444c061aSmrg	    if (Qtype == _XtQString)
733444c061aSmrg		*(String*)value->addr = db_value.addr;
734444c061aSmrg	    else
735444c061aSmrg		(void) memmove(value->addr, db_value.addr, value->size );
736444c061aSmrg	    return True;
737444c061aSmrg	} else {
738444c061aSmrg	    WidgetRec widget; /* hack, hack */
739444c061aSmrg	    bzero( &widget, sizeof(widget) );
740444c061aSmrg	    widget.core.self = &widget;
741444c061aSmrg	    widget.core.widget_class = coreWidgetClass;
742444c061aSmrg	    widget.core.screen = (Screen*)DefaultScreenOfDisplay(dpy);
743444c061aSmrg	    XtInitializeWidgetClass(coreWidgetClass);
744444c061aSmrg	    if (_XtConvert(&widget,db_type,&db_value,Qtype,value,NULL)) {
745444c061aSmrg		return True;
746444c061aSmrg	    }
747444c061aSmrg	}
748444c061aSmrg    }
749444c061aSmrg    return False;
750444c061aSmrg}
751444c061aSmrg
752444c061aSmrgXrmDatabase _XtPreparseCommandLine(
753444c061aSmrg    XrmOptionDescRec *urlist,
754444c061aSmrg    Cardinal num_urs,
755444c061aSmrg    int argc,
756444c061aSmrg    String *argv,
757444c061aSmrg    /* return */
758444c061aSmrg    String *applName,
759444c061aSmrg    String *displayName,
760444c061aSmrg    String *language)
761444c061aSmrg{
7622265a131Smrg    XrmDatabase db = NULL;
763444c061aSmrg    XrmOptionDescRec *options;
764444c061aSmrg    Cardinal num_options;
765444c061aSmrg    XrmName name_list[3];
766444c061aSmrg    XrmName class_list[3];
767444c061aSmrg    XrmRepresentation type;
768444c061aSmrg    XrmValue val;
769444c061aSmrg    String *targv;
770444c061aSmrg    int targc = argc;
771444c061aSmrg
772444c061aSmrg    targv = (String *) __XtMalloc(sizeof(char *) * argc);
773444c061aSmrg    (void) memmove(targv, argv, sizeof(char *) * argc);
774444c061aSmrg    _MergeOptionTables(opTable, XtNumber(opTable), urlist, num_urs,
775444c061aSmrg		       &options, &num_options);
776444c061aSmrg    name_list[0] = class_list[0] = XrmPermStringToQuark(".");
777444c061aSmrg    name_list[2] = class_list[2] = NULLQUARK;
778444c061aSmrg    XrmParseCommand(&db, options, num_options, ".", &targc, targv);
779444c061aSmrg    if (applName) {
780444c061aSmrg	name_list[1] = XrmPermStringToQuark("name");
781444c061aSmrg	if (XrmQGetResource(db, name_list, name_list, &type, &val) &&
782444c061aSmrg	    type == _XtQString)
783444c061aSmrg	    *applName = val.addr;
784444c061aSmrg    }
785444c061aSmrg    if (displayName) {
786444c061aSmrg	name_list[1] = XrmPermStringToQuark("display");
787444c061aSmrg	if (XrmQGetResource(db, name_list, name_list, &type, &val) &&
788444c061aSmrg	    type == _XtQString)
789444c061aSmrg	    *displayName = val.addr;
790444c061aSmrg    }
791444c061aSmrg    if (language) {
792444c061aSmrg	name_list[1] = XrmPermStringToQuark("xnlLanguage");
793444c061aSmrg	class_list[1] = XrmPermStringToQuark("XnlLanguage");
794444c061aSmrg	if (XrmQGetResource(db, name_list, class_list, &type, &val) &&
795444c061aSmrg	    type == _XtQString)
796444c061aSmrg	    *language = val.addr;
797444c061aSmrg    }
798444c061aSmrg
799444c061aSmrg    XtFree((char *)targv);
800444c061aSmrg    XtFree((char *)options);
801444c061aSmrg    return db;
802444c061aSmrg}
803444c061aSmrg
804444c061aSmrg
805444c061aSmrgstatic void GetLanguage(
806444c061aSmrg    Display *dpy,
807444c061aSmrg    XtPerDisplay pd)
808444c061aSmrg{
809444c061aSmrg    XrmRepresentation type;
810444c061aSmrg    XrmValue value;
811444c061aSmrg    XrmName name_list[3];
812444c061aSmrg    XrmName class_list[3];
813444c061aSmrg
814444c061aSmrg    LOCK_PROCESS;
815444c061aSmrg    if (! pd->language) {
816444c061aSmrg	name_list[0] = pd->name;
817444c061aSmrg	name_list[1] = XrmPermStringToQuark("xnlLanguage");
818444c061aSmrg	class_list[0] = pd->class;
819444c061aSmrg	class_list[1] = XrmPermStringToQuark("XnlLanguage");
820444c061aSmrg	name_list[2] = class_list[2] = NULLQUARK;
821444c061aSmrg	if (!pd->server_db)
822444c061aSmrg	    CombineUserDefaults(dpy, &pd->server_db);
823444c061aSmrg	if (pd->server_db &&
824444c061aSmrg	    XrmQGetResource(pd->server_db,name_list,class_list, &type, &value)
825444c061aSmrg	    && type == _XtQString)
826444c061aSmrg	    pd->language = (char *) value.addr;
827444c061aSmrg    }
828444c061aSmrg
829444c061aSmrg    if (pd->appContext->langProcRec.proc) {
830444c061aSmrg	if (! pd->language) pd->language = "";
831444c061aSmrg	pd->language = (*pd->appContext->langProcRec.proc)
832444c061aSmrg	    (dpy, pd->language, pd->appContext->langProcRec.closure);
833444c061aSmrg    }
834444c061aSmrg    else if (! pd->language || pd->language[0] == '\0') /* R4 compatibility */
835444c061aSmrg	pd->language = getenv("LANG");
836444c061aSmrg
837444c061aSmrg    if (pd->language) pd->language = XtNewString(pd->language);
838444c061aSmrg    UNLOCK_PROCESS;
839444c061aSmrg}
840444c061aSmrg
841444c061aSmrgstatic void ProcessInternalConnection (
842444c061aSmrg    XtPointer client_data,
843444c061aSmrg    int* fd,
844444c061aSmrg    XtInputId* id)
845444c061aSmrg{
846444c061aSmrg    XProcessInternalConnection ((Display *) client_data, *fd);
847444c061aSmrg}
848444c061aSmrg
849444c061aSmrgstatic void ConnectionWatch (
850444c061aSmrg    Display* dpy,
851444c061aSmrg    XPointer client_data,
852444c061aSmrg    int fd,
853444c061aSmrg    Bool opening,
854444c061aSmrg    XPointer* watch_data)
855444c061aSmrg{
856444c061aSmrg    XtInputId* iptr;
857444c061aSmrg    XtAppContext app = XtDisplayToApplicationContext(dpy);
858444c061aSmrg
859444c061aSmrg    if (opening) {
860444c061aSmrg	iptr = (XtInputId *) __XtMalloc(sizeof(XtInputId));
861444c061aSmrg	*iptr = XtAppAddInput(app, fd, (XtPointer) XtInputReadMask,
862444c061aSmrg			      ProcessInternalConnection, client_data);
863444c061aSmrg	*watch_data = (XPointer) iptr;
864444c061aSmrg    } else {
865444c061aSmrg	iptr = (XtInputId *) *watch_data;
866444c061aSmrg	XtRemoveInput(*iptr);
867444c061aSmrg        (void) XtFree(*watch_data);
868444c061aSmrg    }
869444c061aSmrg}
870444c061aSmrg
871444c061aSmrgvoid _XtDisplayInitialize(
872444c061aSmrg	Display *dpy,
873444c061aSmrg        XtPerDisplay pd,
874444c061aSmrg	_Xconst char* name,
875444c061aSmrg	XrmOptionDescRec *urlist,
876444c061aSmrg	Cardinal num_urs,
877444c061aSmrg	int *argc,
878444c061aSmrg	char **argv)
879444c061aSmrg{
880444c061aSmrg	Boolean tmp_bool;
881444c061aSmrg	XrmValue value;
882444c061aSmrg	XrmOptionDescRec *options;
883444c061aSmrg	Cardinal num_options;
884444c061aSmrg	XrmDatabase db;
885444c061aSmrg	XrmName name_list[2];
886444c061aSmrg	XrmClass class_list[2];
887444c061aSmrg	XrmHashTable* search_list;
888444c061aSmrg	int search_list_size = SEARCH_LIST_SIZE;
889444c061aSmrg
890444c061aSmrg	GetLanguage(dpy, pd);
891444c061aSmrg
892444c061aSmrg	/* Parse the command line and remove Xt arguments from argv */
893444c061aSmrg	_MergeOptionTables( opTable, XtNumber(opTable), urlist, num_urs,
894444c061aSmrg			    &options, &num_options );
895444c061aSmrg	XrmParseCommand(&pd->cmd_db, options, num_options, name, argc, argv);
896444c061aSmrg
897444c061aSmrg	db = XtScreenDatabase(DefaultScreenOfDisplay(dpy));
898444c061aSmrg
899444c061aSmrg	if (!(search_list = (XrmHashTable*)
900444c061aSmrg		       ALLOCATE_LOCAL( SEARCH_LIST_SIZE*sizeof(XrmHashTable))))
901444c061aSmrg	    _XtAllocError(NULL);
902444c061aSmrg	name_list[0] = pd->name;
903444c061aSmrg	class_list[0] = pd->class;
904444c061aSmrg	name_list[1] = NULLQUARK;
905444c061aSmrg	class_list[1] = NULLQUARK;
906444c061aSmrg
907444c061aSmrg	while (!XrmQGetSearchList(db, name_list, class_list,
908444c061aSmrg				  search_list, search_list_size)) {
909444c061aSmrg	    XrmHashTable* old = search_list;
910444c061aSmrg	    Cardinal size = (search_list_size*=2)*sizeof(XrmHashTable);
911444c061aSmrg	    if (!(search_list = (XrmHashTable*)ALLOCATE_LOCAL(size)))
912444c061aSmrg		_XtAllocError(NULL);
913444c061aSmrg	    (void) memmove((char*)search_list, (char*)old, (size>>1) );
914444c061aSmrg	    DEALLOCATE_LOCAL(old);
915444c061aSmrg	}
916444c061aSmrg
917444c061aSmrg	value.size = sizeof(tmp_bool);
918444c061aSmrg	value.addr = (XtPointer)&tmp_bool;
919444c061aSmrg	if (_GetResource(dpy, search_list, "synchronous", "Synchronous",
920444c061aSmrg			 XtRBoolean, &value)) {
921444c061aSmrg	    int i;
922444c061aSmrg	    Display **dpyP = pd->appContext->list;
923444c061aSmrg	    pd->appContext->sync = tmp_bool;
924444c061aSmrg	    for (i = pd->appContext->count; i; dpyP++, i--) {
925444c061aSmrg		(void) XSynchronize(*dpyP, (Bool)tmp_bool);
926444c061aSmrg	    }
927444c061aSmrg	} else {
928444c061aSmrg	    (void) XSynchronize(dpy, (Bool)pd->appContext->sync);
929444c061aSmrg	}
930444c061aSmrg
931444c061aSmrg	if (_GetResource(dpy, search_list, "reverseVideo", "ReverseVideo",
932444c061aSmrg			 XtRBoolean, &value)
933444c061aSmrg	        && tmp_bool) {
934444c061aSmrg	    pd->rv = True;
935444c061aSmrg	}
936444c061aSmrg
937444c061aSmrg	value.size = sizeof(pd->multi_click_time);
938444c061aSmrg	value.addr = (XtPointer)&pd->multi_click_time;
939444c061aSmrg	if (!_GetResource(dpy, search_list,
940444c061aSmrg			  "multiClickTime", "MultiClickTime",
941444c061aSmrg			  XtRInt, &value)) {
942444c061aSmrg	    pd->multi_click_time = 200;
943444c061aSmrg	}
944444c061aSmrg
945444c061aSmrg	value.size = sizeof(pd->appContext->selectionTimeout);
946444c061aSmrg	value.addr = (XtPointer)&pd->appContext->selectionTimeout;
947444c061aSmrg	(void)_GetResource(dpy, search_list,
948444c061aSmrg			   "selectionTimeout", "SelectionTimeout",
949444c061aSmrg			   XtRInt, &value);
950444c061aSmrg
951444c061aSmrg#ifndef NO_IDENTIFY_WINDOWS
952444c061aSmrg	value.size = sizeof(pd->appContext->identify_windows);
953444c061aSmrg	value.addr = (XtPointer)&pd->appContext->identify_windows;
954444c061aSmrg	(void)_GetResource(dpy, search_list,
955444c061aSmrg			   "xtIdentifyWindows", "XtDebug",
956444c061aSmrg			   XtRBoolean, &value);
957444c061aSmrg#endif
958444c061aSmrg
959444c061aSmrg	XAddConnectionWatch(dpy, ConnectionWatch, (XPointer) dpy);
960444c061aSmrg
961444c061aSmrg	XtFree( (XtPointer)options );
962444c061aSmrg	DEALLOCATE_LOCAL( search_list );
963444c061aSmrg}
964444c061aSmrg
965444c061aSmrg/*	Function Name: XtAppSetFallbackResources
966444c061aSmrg *	Description: Sets the fallback resource list that will be loaded
967444c061aSmrg *                   at display initialization time.
968444c061aSmrg *	Arguments: app_context - the app context.
969444c061aSmrg *                 specification_list - the resource specification list.
970444c061aSmrg *	Returns: none.
971444c061aSmrg */
972444c061aSmrg
973444c061aSmrgvoid
974444c061aSmrgXtAppSetFallbackResources(
975444c061aSmrg    XtAppContext app_context,
976444c061aSmrg    String *specification_list)
977444c061aSmrg{
978444c061aSmrg    LOCK_APP(app_context);
979444c061aSmrg    app_context->fallback_resources = specification_list;
980444c061aSmrg    UNLOCK_APP(app_context);
981444c061aSmrg}
982444c061aSmrg
983444c061aSmrg
984444c061aSmrgWidget XtOpenApplication(XtAppContext *app_context_return,
985444c061aSmrg			 _Xconst char *application_class,
986444c061aSmrg			 XrmOptionDescRec *options, Cardinal num_options,
987444c061aSmrg			 int *argc_in_out, String *argv_in_out,
988444c061aSmrg			 String *fallback_resources, WidgetClass widget_class,
989444c061aSmrg			 ArgList args_in, Cardinal num_args_in)
990444c061aSmrg{
991444c061aSmrg    XtAppContext app_con;
992444c061aSmrg    Display * dpy;
993444c061aSmrg    register int saved_argc = *argc_in_out;
994444c061aSmrg    Widget root;
995444c061aSmrg    Arg args[3], *merged_args;
996444c061aSmrg    Cardinal num = 0;
997444c061aSmrg
998444c061aSmrg    XtToolkitInitialize(); /* cannot be moved into _XtAppInit */
999444c061aSmrg
1000444c061aSmrg    dpy = _XtAppInit(&app_con, (String)application_class, options, num_options,
1001444c061aSmrg		     argc_in_out, &argv_in_out, fallback_resources);
1002444c061aSmrg
1003444c061aSmrg    LOCK_APP(app_con);
1004444c061aSmrg    XtSetArg(args[num], XtNscreen, DefaultScreenOfDisplay(dpy)); num++;
1005444c061aSmrg    XtSetArg(args[num], XtNargc, saved_argc);	                 num++;
1006444c061aSmrg    XtSetArg(args[num], XtNargv, argv_in_out);	                 num++;
1007444c061aSmrg
1008444c061aSmrg    merged_args = XtMergeArgLists(args_in, num_args_in, args, num);
1009444c061aSmrg    num += num_args_in;
1010444c061aSmrg
1011444c061aSmrg    root = XtAppCreateShell(NULL, application_class, widget_class, dpy,
1012444c061aSmrg			    merged_args, num);
1013444c061aSmrg
1014444c061aSmrg    if (app_context_return)
1015444c061aSmrg	*app_context_return = app_con;
1016444c061aSmrg
1017444c061aSmrg    XtFree((XtPointer)merged_args);
1018444c061aSmrg    XtFree((XtPointer)argv_in_out);
1019444c061aSmrg    UNLOCK_APP(app_con);
1020444c061aSmrg    return root;
1021444c061aSmrg}
1022444c061aSmrg
1023444c061aSmrg
1024444c061aSmrgWidget
1025444c061aSmrgXtAppInitialize(
1026444c061aSmrg    XtAppContext * app_context_return,
1027444c061aSmrg    _Xconst char* application_class,
1028444c061aSmrg    XrmOptionDescRec *options,
1029444c061aSmrg    Cardinal num_options,
1030444c061aSmrg    int *argc_in_out,
1031444c061aSmrg    String *argv_in_out,
1032444c061aSmrg    String *fallback_resources,
1033444c061aSmrg    ArgList args_in,
1034444c061aSmrg    Cardinal num_args_in)
1035444c061aSmrg{
1036444c061aSmrg    return XtOpenApplication(app_context_return, application_class,
1037444c061aSmrg			     options, num_options,
1038444c061aSmrg			     argc_in_out, argv_in_out, fallback_resources,
1039444c061aSmrg			     applicationShellWidgetClass,
1040444c061aSmrg			     args_in, num_args_in);
1041444c061aSmrg}
1042444c061aSmrg
1043444c061aSmrg
1044444c061aSmrg/*ARGSUSED*/
1045444c061aSmrgWidget
1046444c061aSmrgXtInitialize(
1047444c061aSmrg    _Xconst char* name,
1048444c061aSmrg    _Xconst char* classname,
1049444c061aSmrg    XrmOptionDescRec *options,
1050444c061aSmrg    Cardinal num_options,
1051444c061aSmrg    int *argc,
1052444c061aSmrg    String *argv)
1053444c061aSmrg{
1054444c061aSmrg    Widget root;
1055444c061aSmrg    XtAppContext app_con;
1056444c061aSmrg    register ProcessContext process = _XtGetProcessContext();
1057444c061aSmrg
1058444c061aSmrg    root = XtAppInitialize(&app_con, classname, options, num_options,
1059444c061aSmrg			   argc, argv, NULL, NULL, (Cardinal) 0);
1060444c061aSmrg
1061444c061aSmrg    LOCK_PROCESS;
1062444c061aSmrg    process->defaultAppContext = app_con;
1063444c061aSmrg    UNLOCK_PROCESS;
1064444c061aSmrg    return root;
1065444c061aSmrg}
1066