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