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