Initialize.c revision fdf6a26f
1444c061aSmrg/***********************************************************
2fdf6a26fSmrgCopyright (c) 1993, Oracle and/or its affiliates.
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
102a3bd7f05Smrg#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
129a3bd7f05Smrg/* *INDENT-OFF* */
130444c061aSmrgstatic XrmOptionDescRec const opTable[] = {
131a3bd7f05Smrg{"+rv",               "*reverseVideo",     XrmoptionNoArg,   (XtPointer) "off"},
132a3bd7f05Smrg{"+synchronous",      "*synchronous",      XrmoptionNoArg,   (XtPointer) "off"},
133a3bd7f05Smrg{"-background",       "*background",       XrmoptionSepArg,  (XtPointer) NULL},
134a3bd7f05Smrg{"-bd",               "*borderColor",      XrmoptionSepArg,  (XtPointer) NULL},
135a3bd7f05Smrg{"-bg",               "*background",       XrmoptionSepArg,  (XtPointer) NULL},
136a3bd7f05Smrg{"-bordercolor",      "*borderColor",      XrmoptionSepArg,  (XtPointer) NULL},
137a3bd7f05Smrg{"-borderwidth",      ".borderWidth",      XrmoptionSepArg,  (XtPointer) NULL},
138a3bd7f05Smrg{"-bw",               ".borderWidth",      XrmoptionSepArg,  (XtPointer) NULL},
139a3bd7f05Smrg{"-display",          ".display",          XrmoptionSepArg,  (XtPointer) NULL},
140a3bd7f05Smrg{"-fg",               "*foreground",       XrmoptionSepArg,  (XtPointer) NULL},
141a3bd7f05Smrg{"-fn",               "*font",             XrmoptionSepArg,  (XtPointer) NULL},
142a3bd7f05Smrg{"-font",             "*font",             XrmoptionSepArg,  (XtPointer) NULL},
143a3bd7f05Smrg{"-foreground",       "*foreground",       XrmoptionSepArg,  (XtPointer) NULL},
144a3bd7f05Smrg{"-geometry",         ".geometry",         XrmoptionSepArg,  (XtPointer) NULL},
145a3bd7f05Smrg{"-iconic",           ".iconic",           XrmoptionNoArg,   (XtPointer) "on"},
146a3bd7f05Smrg{"-name",             ".name",             XrmoptionSepArg,  (XtPointer) NULL},
147a3bd7f05Smrg{"-reverse",          "*reverseVideo",     XrmoptionNoArg,   (XtPointer) "on"},
148a3bd7f05Smrg{"-rv",               "*reverseVideo",     XrmoptionNoArg,   (XtPointer) "on"},
149a3bd7f05Smrg{"-selectionTimeout", ".selectionTimeout", XrmoptionSepArg,  (XtPointer) NULL},
150a3bd7f05Smrg{"-synchronous",      "*synchronous",      XrmoptionNoArg,   (XtPointer) "on"},
151a3bd7f05Smrg{"-title",            ".title",            XrmoptionSepArg,  (XtPointer) NULL},
152a3bd7f05Smrg{"-xnllanguage",      ".xnlLanguage",      XrmoptionSepArg,  (XtPointer) NULL},
153a3bd7f05Smrg{"-xrm",              NULL,                XrmoptionResArg,  (XtPointer) NULL},
154a3bd7f05Smrg{"-xtsessionID",      ".sessionID",        XrmoptionSepArg,  (XtPointer) NULL},
155444c061aSmrg};
156a3bd7f05Smrg/* *INDENT-ON* */
157444c061aSmrg
158444c061aSmrg/*
159444c061aSmrg * GetHostname - emulates gethostname() on non-bsd systems.
160444c061aSmrg */
161444c061aSmrg
162a3bd7f05Smrgstatic void
163a3bd7f05SmrgGetHostname(char *buf, int maxlen)
164444c061aSmrg{
165444c061aSmrg#ifdef USE_UNAME
166444c061aSmrg    int len;
167444c061aSmrg    struct utsname name;
168444c061aSmrg
169444c061aSmrg    if (maxlen <= 0 || buf == NULL)
170a3bd7f05Smrg        return;
171a3bd7f05Smrg
172a3bd7f05Smrg    uname(&name);
173a3bd7f05Smrg    len = strlen(name.nodename);
174a3bd7f05Smrg    if (len >= maxlen)
175a3bd7f05Smrg        len = maxlen;
176a3bd7f05Smrg    (void) strncpy(buf, name.nodename, len - 1);
177a3bd7f05Smrg    buf[len - 1] = '\0';
178444c061aSmrg#else
179444c061aSmrg    if (maxlen <= 0 || buf == NULL)
180a3bd7f05Smrg        return;
181444c061aSmrg
182444c061aSmrg    buf[0] = '\0';
183a3bd7f05Smrg    (void) gethostname(buf, (size_t) maxlen);
184a3bd7f05Smrg    buf[maxlen - 1] = '\0';
185444c061aSmrg#endif
186444c061aSmrg}
187444c061aSmrg
188444c061aSmrg#ifdef SUNSHLIB
189a3bd7f05Smrgvoid
190a3bd7f05Smrg_XtInherit(void)
191444c061aSmrg{
192444c061aSmrg    extern void __XtInherit();
193a3bd7f05Smrg
194444c061aSmrg    __XtInherit();
195444c061aSmrg}
196a3bd7f05Smrg
197444c061aSmrg#define _XtInherit __XtInherit
198444c061aSmrg#endif
199444c061aSmrg
2002265a131Smrg#if defined (WIN32) || defined(__CYGWIN__)
201444c061aSmrg/*
202444c061aSmrg * The Symbol _XtInherit is used in two different manners.
203444c061aSmrg * First it could be used as a generic function and second
204444c061aSmrg * as an absolute address reference, which will be used to
205444c061aSmrg * check the initialisation process of several other libraries.
206fdf6a26fSmrg * Because of this the symbol must be accessible by all
207444c061aSmrg * client dll's and applications.  In unix environments
208444c061aSmrg * this is no problem, because the used shared libraries
209fdf6a26fSmrg * format (elf) supports this immediately.  Under Windows
210444c061aSmrg * this isn't true, because a functions address in a dll
211444c061aSmrg * is different from the same function in another dll or
212444c061aSmrg * applications, because the used Portable Executable
213444c061aSmrg * File adds a code stub to each client to provide the
214444c061aSmrg * exported symbol name.  This stub uses an indirect
215444c061aSmrg * pointer to get the original symbol address, which is
216444c061aSmrg * then jumped to, like in this example:
217444c061aSmrg *
218444c061aSmrg * --- client ---                                     --- dll ----
219444c061aSmrg *  ...
220444c061aSmrg *  call foo
221444c061aSmrg *
222444c061aSmrg * foo: jmp (*_imp_foo)               ---->           foo: ....
223444c061aSmrg *      nop
224444c061aSmrg *      nop
225444c061aSmrg *
226444c061aSmrg * _imp_foo: .long <index of foo in dll export table, is
227a3bd7f05Smrg *                  set to the real address by the runtime linker>
228444c061aSmrg *
229444c061aSmrg * Now it is clear why the clients symbol foo isn't the same
230444c061aSmrg * as in the dll and we can think about how to deal which
231444c061aSmrg * this two above mentioned requirements, to export this
232444c061aSmrg * symbol to all clients and to allow calling this symbol
233444c061aSmrg * as a function.  The solution I've used exports the
234444c061aSmrg * symbol _XtInherit as data symbol, because global data
235444c061aSmrg * symbols are exported to all clients.  But how to deal
236444c061aSmrg * with the second requirement, that this symbol should
237444c061aSmrg * be used as function.  The Trick is to build a little
238444c061aSmrg * code stub in the data section in the exact manner as
239444c061aSmrg * above explained.  This is done with the assembler code
240444c061aSmrg * below.
241444c061aSmrg *
242444c061aSmrg * Ralf Habacker
243444c061aSmrg *
244444c061aSmrg * References:
245444c061aSmrg * msdn          http://msdn.microsoft.com/msdnmag/issues/02/02/PE/PE.asp
246444c061aSmrg * cygwin-xfree: http://www.cygwin.com/ml/cygwin-xfree/2003-10/msg00000.html
247444c061aSmrg */
248444c061aSmrg
249339a7c43Smrg#ifdef __x86_64__
250a3bd7f05Smrgasm(".section .trampoline, \"dwx\" \n\
251339a7c43Smrg .globl _XtInherit        \n\
252339a7c43Smrg _XtInherit:              \n\
253339a7c43Smrg    jmp *_y(%rip)         \n\
254339a7c43Smrg_y: .quad __XtInherit     \n\
255339a7c43Smrg    .text                 \n");
256339a7c43Smrg#else
257a3bd7f05Smrgasm(".data\n\
258444c061aSmrg .globl __XtInherit        \n\
259444c061aSmrg __XtInherit:      jmp *_y \n\
260444c061aSmrg  _y: .long ___XtInherit   \n\
261444c061aSmrg    .text                 \n");
262339a7c43Smrg#endif
263444c061aSmrg
264444c061aSmrg#define _XtInherit __XtInherit
265444c061aSmrg#endif
266444c061aSmrg
267a3bd7f05Smrgvoid
268a3bd7f05Smrg_XtInherit(void)
269444c061aSmrg{
270a3bd7f05Smrg    XtErrorMsg("invalidProcedure", "inheritanceProc", XtCXtToolkitError,
271a3bd7f05Smrg               "Unresolved inheritance operation", NULL, NULL);
272444c061aSmrg}
273444c061aSmrg
274a3bd7f05Smrgvoid
275a3bd7f05SmrgXtToolkitInitialize(void)
276444c061aSmrg{
277444c061aSmrg    static Boolean initialized = False;
278444c061aSmrg
279444c061aSmrg    LOCK_PROCESS;
280444c061aSmrg    if (initialized) {
281a3bd7f05Smrg        UNLOCK_PROCESS;
282a3bd7f05Smrg        return;
283444c061aSmrg    }
284444c061aSmrg    initialized = True;
285444c061aSmrg    UNLOCK_PROCESS;
286444c061aSmrg    /* Resource management initialization */
287444c061aSmrg    XrmInitialize();
288444c061aSmrg    _XtResourceListInitialize();
289444c061aSmrg
290fdf6a26fSmrg    /* Other intrinsic initialization */
291444c061aSmrg    _XtConvertInitialize();
292444c061aSmrg    _XtEventInitialize();
293444c061aSmrg    _XtTranslateInitialize();
294444c061aSmrg
295444c061aSmrg    /* Some apps rely on old (broken) XtAppPeekEvent behavior */
296a3bd7f05Smrg    if (getenv("XTAPPPEEKEVENT_SKIPTIMER"))
297a3bd7f05Smrg        XtAppPeekEvent_SkipTimer = True;
298444c061aSmrg    else
299a3bd7f05Smrg        XtAppPeekEvent_SkipTimer = False;
300444c061aSmrg}
301444c061aSmrg
302a3bd7f05SmrgString
303a3bd7f05Smrg_XtGetUserName(_XtString dest, int len)
304444c061aSmrg{
305444c061aSmrg#ifdef WIN32
306444c061aSmrg    String ptr = NULL;
307444c061aSmrg
308444c061aSmrg    if ((ptr = getenv("USERNAME"))) {
309a3bd7f05Smrg        (void) strncpy(dest, ptr, len - 1);
310a3bd7f05Smrg        dest[len - 1] = '\0';
311a3bd7f05Smrg    }
312a3bd7f05Smrg    else
313a3bd7f05Smrg        *dest = '\0';
314444c061aSmrg#else
315444c061aSmrg#ifdef X_NEEDS_PWPARAMS
316444c061aSmrg    _Xgetpwparams pwparams;
317444c061aSmrg#endif
318444c061aSmrg    struct passwd *pw;
319a3bd7f05Smrg    char *ptr;
320444c061aSmrg
321444c061aSmrg    if ((ptr = getenv("USER"))) {
322a3bd7f05Smrg        (void) strncpy(dest, ptr, (size_t) (len - 1));
323a3bd7f05Smrg        dest[len - 1] = '\0';
324a3bd7f05Smrg    }
325a3bd7f05Smrg    else {
326a3bd7f05Smrg        if ((pw = _XGetpwuid(getuid(), pwparams)) != NULL) {
327a3bd7f05Smrg            (void) strncpy(dest, pw->pw_name, (size_t) (len - 1));
328a3bd7f05Smrg            dest[len - 1] = '\0';
329a3bd7f05Smrg        }
330a3bd7f05Smrg        else
331a3bd7f05Smrg            *dest = '\0';
332444c061aSmrg    }
333444c061aSmrg#endif
334444c061aSmrg    return dest;
335444c061aSmrg}
336444c061aSmrg
337a3bd7f05Smrgstatic String
338a3bd7f05SmrgGetRootDirName(_XtString dest, int len)
339444c061aSmrg{
340444c061aSmrg#ifdef WIN32
341444c061aSmrg    register char *ptr1;
342444c061aSmrg    register char *ptr2 = NULL;
343444c061aSmrg    int len1 = 0, len2 = 0;
344444c061aSmrg
345a3bd7f05Smrg    if (ptr1 = getenv("HOME")) {        /* old, deprecated */
346a3bd7f05Smrg        len1 = strlen(ptr1);
347a3bd7f05Smrg    }
348a3bd7f05Smrg    else if ((ptr1 = getenv("HOMEDRIVE")) && (ptr2 = getenv("HOMEDIR"))) {
349a3bd7f05Smrg        len1 = strlen(ptr1);
350a3bd7f05Smrg        len2 = strlen(ptr2);
351a3bd7f05Smrg    }
352a3bd7f05Smrg    else if (ptr2 = getenv("USERNAME")) {
353a3bd7f05Smrg        len1 = strlen(ptr1 = "/users/");
354a3bd7f05Smrg        len2 = strlen(ptr2);
355444c061aSmrg    }
356444c061aSmrg    if ((len1 + len2 + 1) < len)
357a3bd7f05Smrg        sprintf(dest, "%s%s", ptr1, (ptr2) ? ptr2 : "");
358444c061aSmrg    else
359a3bd7f05Smrg        *dest = '\0';
360444c061aSmrg#else
361444c061aSmrg#ifdef X_NEEDS_PWPARAMS
362444c061aSmrg    _Xgetpwparams pwparams;
363444c061aSmrg#endif
364444c061aSmrg    static char *ptr;
365444c061aSmrg
366444c061aSmrg    if (len <= 0 || dest == NULL)
367a3bd7f05Smrg        return NULL;
368444c061aSmrg
369444c061aSmrg    if ((ptr = getenv("HOME"))) {
370a3bd7f05Smrg        (void) strncpy(dest, ptr, (size_t) (len - 1));
371a3bd7f05Smrg        dest[len - 1] = '\0';
372a3bd7f05Smrg    }
373a3bd7f05Smrg    else {
3740568f49bSmrg        struct passwd *pw;
375a3bd7f05Smrg
376a3bd7f05Smrg        if ((ptr = getenv("USER")))
377a3bd7f05Smrg            pw = _XGetpwnam(ptr, pwparams);
378a3bd7f05Smrg        else
379a3bd7f05Smrg            pw = _XGetpwuid(getuid(), pwparams);
380a3bd7f05Smrg        if (pw != NULL) {
381a3bd7f05Smrg            (void) strncpy(dest, pw->pw_dir, (size_t) (len - 1));
382a3bd7f05Smrg            dest[len - 1] = '\0';
383a3bd7f05Smrg        }
384a3bd7f05Smrg        else
385a3bd7f05Smrg            *dest = '\0';
386444c061aSmrg    }
387444c061aSmrg#endif
388444c061aSmrg    return dest;
389444c061aSmrg}
390444c061aSmrg
391a3bd7f05Smrgstatic void
392a3bd7f05SmrgCombineAppUserDefaults(Display *dpy, XrmDatabase *pdb)
393444c061aSmrg{
394a3bd7f05Smrg    char *filename;
395a3bd7f05Smrg    char *path = NULL;
396444c061aSmrg    Boolean deallocate = False;
397444c061aSmrg
398444c061aSmrg    if (!(path = getenv("XUSERFILESEARCHPATH"))) {
3992265a131Smrg#if !defined(WIN32) || !defined(__MINGW32__)
400a3bd7f05Smrg        char *old_path;
401a3bd7f05Smrg        char homedir[PATH_MAX];
402a3bd7f05Smrg
403a3bd7f05Smrg        GetRootDirName(homedir, PATH_MAX);
404a3bd7f05Smrg        if (!(old_path = getenv("XAPPLRESDIR"))) {
405a3bd7f05Smrg            XtAsprintf(&path,
406a3bd7f05Smrg                       "%s/%%L/%%N%%C:%s/%%l/%%N%%C:%s/%%N%%C:%s/%%L/%%N:%s/%%l/%%N:%s/%%N",
407a3bd7f05Smrg                       homedir, homedir, homedir, homedir, homedir, homedir);
408a3bd7f05Smrg        }
409a3bd7f05Smrg        else {
410a3bd7f05Smrg            XtAsprintf(&path,
411a3bd7f05Smrg                       "%s/%%L/%%N%%C:%s/%%l/%%N%%C:%s/%%N%%C:%s/%%N%%C:%s/%%L/%%N:%s/%%l/%%N:%s/%%N:%s/%%N",
412a3bd7f05Smrg                       old_path, old_path, old_path, homedir,
413a3bd7f05Smrg                       old_path, old_path, old_path, homedir);
414a3bd7f05Smrg        }
415a3bd7f05Smrg        deallocate = True;
4162265a131Smrg#endif
417444c061aSmrg    }
418444c061aSmrg
419444c061aSmrg    filename = XtResolvePathname(dpy, NULL, NULL, NULL, path, NULL, 0, NULL);
420444c061aSmrg    if (filename) {
421a3bd7f05Smrg        (void) XrmCombineFileDatabase(filename, pdb, False);
422a3bd7f05Smrg        XtFree(filename);
423444c061aSmrg    }
424444c061aSmrg
425bdf0f55dSmrg    if (deallocate)
426a3bd7f05Smrg        XtFree(path);
427444c061aSmrg}
428444c061aSmrg
429a3bd7f05Smrgstatic void
430a3bd7f05SmrgCombineUserDefaults(Display *dpy, XrmDatabase *pdb)
431444c061aSmrg{
432444c061aSmrg    char *dpy_defaults = XResourceManagerString(dpy);
433444c061aSmrg
434444c061aSmrg    if (dpy_defaults) {
435a3bd7f05Smrg        XrmCombineDatabase(XrmGetStringDatabase(dpy_defaults), pdb, False);
436a3bd7f05Smrg    }
437a3bd7f05Smrg    else {
4380568f49bSmrg#ifdef __MINGW32__
439a3bd7f05Smrg        const char *slashDotXdefaults = "/Xdefaults";
4400568f49bSmrg#else
441a3bd7f05Smrg        const char *slashDotXdefaults = "/.Xdefaults";
4420568f49bSmrg#endif
443a3bd7f05Smrg        char filename[PATH_MAX];
444a3bd7f05Smrg
445a3bd7f05Smrg        (void) GetRootDirName(filename,
446a3bd7f05Smrg                              PATH_MAX - (int) strlen(slashDotXdefaults) - 1);
447a3bd7f05Smrg        (void) strcat(filename, slashDotXdefaults);
448a3bd7f05Smrg        (void) XrmCombineFileDatabase(filename, pdb, False);
449444c061aSmrg    }
450444c061aSmrg}
451444c061aSmrg
452a3bd7f05Smrgstatic Bool
453a3bd7f05SmrgStoreDBEntry(XrmDatabase *db _X_UNUSED,
454a3bd7f05Smrg             XrmBindingList bindings,
455a3bd7f05Smrg             XrmQuarkList quarks,
456a3bd7f05Smrg             XrmRepresentation *type,
457a3bd7f05Smrg             XrmValuePtr value,
458a3bd7f05Smrg             XPointer data)
459444c061aSmrg{
460a3bd7f05Smrg    XrmQPutResource((XrmDatabase *) data, bindings, quarks, *type, value);
461444c061aSmrg    return False;
462444c061aSmrg}
463444c061aSmrg
464a3bd7f05Smrgstatic XrmDatabase
465a3bd7f05SmrgCopyDB(XrmDatabase db)
466444c061aSmrg{
467444c061aSmrg    XrmDatabase copy = NULL;
468444c061aSmrg    XrmQuark empty = NULLQUARK;
469444c061aSmrg
470444c061aSmrg    XrmEnumerateDatabase(db, &empty, &empty, XrmEnumAllLevels,
471a3bd7f05Smrg                         StoreDBEntry, (XPointer) &copy);
472444c061aSmrg    return copy;
473444c061aSmrg}
474444c061aSmrg
475a3bd7f05Smrgstatic String
476a3bd7f05Smrg_XtDefaultLanguageProc(Display *dpy _X_UNUSED,
477a3bd7f05Smrg                       String xnl,
478a3bd7f05Smrg                       XtPointer closure _X_UNUSED)
479444c061aSmrg{
480a3bd7f05Smrg    if (!setlocale(LC_ALL, xnl))
481a3bd7f05Smrg        XtWarning("locale not supported by C library, locale unchanged");
482444c061aSmrg
483a3bd7f05Smrg    if (!XSupportsLocale()) {
484a3bd7f05Smrg        XtWarning("locale not supported by Xlib, locale set to C");
485a3bd7f05Smrg        setlocale(LC_ALL, "C");
486444c061aSmrg    }
487a3bd7f05Smrg    if (!XSetLocaleModifiers(""))
488a3bd7f05Smrg        XtWarning("X locale modifiers not supported, using default");
489444c061aSmrg
490a3bd7f05Smrg    return setlocale(LC_ALL, NULL);     /* re-query in case overwritten */
491444c061aSmrg}
492444c061aSmrg
493a3bd7f05SmrgXtLanguageProc
494a3bd7f05SmrgXtSetLanguageProc(XtAppContext app, XtLanguageProc proc, XtPointer closure)
495444c061aSmrg{
496a3bd7f05Smrg    XtLanguageProc old;
497444c061aSmrg
498444c061aSmrg    if (!proc) {
499a3bd7f05Smrg        proc = _XtDefaultLanguageProc;
500a3bd7f05Smrg        closure = NULL;
501444c061aSmrg    }
502444c061aSmrg
503444c061aSmrg    if (app) {
504a3bd7f05Smrg        LOCK_APP(app);
505a3bd7f05Smrg        LOCK_PROCESS;
506a3bd7f05Smrg        /* set langProcRec only for this application context */
507444c061aSmrg        old = app->langProcRec.proc;
508444c061aSmrg        app->langProcRec.proc = proc;
509444c061aSmrg        app->langProcRec.closure = closure;
510a3bd7f05Smrg        UNLOCK_PROCESS;
511a3bd7f05Smrg        UNLOCK_APP(app);
512a3bd7f05Smrg    }
513a3bd7f05Smrg    else {
514a3bd7f05Smrg        /* set langProcRec for all application contexts */
515444c061aSmrg        ProcessContext process;
516444c061aSmrg
517a3bd7f05Smrg        LOCK_PROCESS;
518444c061aSmrg        process = _XtGetProcessContext();
519444c061aSmrg        old = process->globalLangProcRec.proc;
520a3bd7f05Smrg        process->globalLangProcRec.proc = proc;
521a3bd7f05Smrg        process->globalLangProcRec.closure = closure;
522444c061aSmrg        app = process->appContextList;
523444c061aSmrg        while (app) {
524444c061aSmrg            app->langProcRec.proc = proc;
525444c061aSmrg            app->langProcRec.closure = closure;
526a3bd7f05Smrg            app = app->next;
527444c061aSmrg        }
528a3bd7f05Smrg        UNLOCK_PROCESS;
529444c061aSmrg    }
530444c061aSmrg    return (old ? old : _XtDefaultLanguageProc);
531444c061aSmrg}
532444c061aSmrg
533a3bd7f05SmrgXrmDatabase
534a3bd7f05SmrgXtScreenDatabase(Screen *screen)
535444c061aSmrg{
536444c061aSmrg    int scrno;
537444c061aSmrg    Bool doing_def;
538444c061aSmrg    XrmDatabase db, olddb;
539444c061aSmrg    XtPerDisplay pd;
540444c061aSmrg    Status do_fallback;
541444c061aSmrg    char *scr_resources;
542444c061aSmrg    Display *dpy = DisplayOfScreen(screen);
543a3bd7f05Smrg
544444c061aSmrg    DPY_TO_APPCON(dpy);
545a3bd7f05Smrg    if (dpy == NULL) {
546a3bd7f05Smrg        XtErrorMsg("nullDisplay",
547a3bd7f05Smrg                   "XtScreenDatabase", XtCXtToolkitError,
548a3bd7f05Smrg                   "XtScreenDatabase requires a non-NULL display",
549a3bd7f05Smrg                   NULL, NULL);
550a3bd7f05Smrg    }
551444c061aSmrg
552444c061aSmrg    LOCK_APP(app);
553444c061aSmrg    LOCK_PROCESS;
554444c061aSmrg    if (screen == DefaultScreenOfDisplay(dpy)) {
555a3bd7f05Smrg        scrno = DefaultScreen(dpy);
556a3bd7f05Smrg        doing_def = True;
557a3bd7f05Smrg    }
558a3bd7f05Smrg    else {
559a3bd7f05Smrg        scrno = XScreenNumberOfScreen(screen);
560a3bd7f05Smrg        doing_def = False;
561444c061aSmrg    }
562444c061aSmrg    pd = _XtGetPerDisplay(dpy);
563444c061aSmrg    if ((db = pd->per_screen_db[scrno])) {
564a3bd7f05Smrg        UNLOCK_PROCESS;
565a3bd7f05Smrg        UNLOCK_APP(app);
566a3bd7f05Smrg        return (doing_def ? XrmGetDatabase(dpy) : db);
567444c061aSmrg    }
568444c061aSmrg    scr_resources = XScreenResourceString(screen);
569444c061aSmrg
570444c061aSmrg    if (ScreenCount(dpy) == 1) {
571a3bd7f05Smrg        db = pd->cmd_db;
572a3bd7f05Smrg        pd->cmd_db = NULL;
573a3bd7f05Smrg    }
574a3bd7f05Smrg    else {
575a3bd7f05Smrg        db = CopyDB(pd->cmd_db);
576444c061aSmrg    }
577a3bd7f05Smrg    {                           /* Environment defaults */
578a3bd7f05Smrg        char filenamebuf[PATH_MAX];
579a3bd7f05Smrg        char *filename;
580a3bd7f05Smrg
581a3bd7f05Smrg        if (!(filename = getenv("XENVIRONMENT"))) {
582a3bd7f05Smrg            int len;
583444c061aSmrg
5842265a131Smrg#ifdef __MINGW32__
585a3bd7f05Smrg            const char *slashDotXdefaultsDash = "/Xdefaults-";
5862265a131Smrg#else
587a3bd7f05Smrg            const char *slashDotXdefaultsDash = "/.Xdefaults-";
5882265a131Smrg#endif
589444c061aSmrg
590a3bd7f05Smrg            (void) GetRootDirName(filename = filenamebuf,
591a3bd7f05Smrg                                  PATH_MAX -
592a3bd7f05Smrg                                  (int) strlen(slashDotXdefaultsDash) - 1);
593a3bd7f05Smrg            (void) strcat(filename, slashDotXdefaultsDash);
594a3bd7f05Smrg            len = (int) strlen(filename);
595a3bd7f05Smrg            GetHostname(filename + len, PATH_MAX - len);
596a3bd7f05Smrg        }
597a3bd7f05Smrg        (void) XrmCombineFileDatabase(filename, &db, False);
598444c061aSmrg    }
599a3bd7f05Smrg    if (scr_resources) {        /* Screen defaults */
600a3bd7f05Smrg        XrmCombineDatabase(XrmGetStringDatabase(scr_resources), &db, False);
601a3bd7f05Smrg        XFree(scr_resources);
602444c061aSmrg    }
603444c061aSmrg    /* Server or host defaults */
604444c061aSmrg    if (!pd->server_db)
605a3bd7f05Smrg        CombineUserDefaults(dpy, &db);
606444c061aSmrg    else {
607a3bd7f05Smrg        (void) XrmCombineDatabase(pd->server_db, &db, False);
608a3bd7f05Smrg        pd->server_db = NULL;
609444c061aSmrg    }
610444c061aSmrg
611444c061aSmrg    if (!db)
612a3bd7f05Smrg        db = XrmGetStringDatabase("");
613444c061aSmrg    pd->per_screen_db[scrno] = db;
614444c061aSmrg    olddb = XrmGetDatabase(dpy);
615444c061aSmrg    /* set database now, for XtResolvePathname to use */
616444c061aSmrg    XrmSetDatabase(dpy, db);
617444c061aSmrg    CombineAppUserDefaults(dpy, &db);
618444c061aSmrg    do_fallback = 1;
619a3bd7f05Smrg    {                           /* System app-defaults */
620a3bd7f05Smrg        char *filename;
621a3bd7f05Smrg
622a3bd7f05Smrg        if ((filename = XtResolvePathname(dpy, "app-defaults",
623a3bd7f05Smrg                                          NULL, NULL, NULL, NULL, 0, NULL))) {
624a3bd7f05Smrg            do_fallback = !XrmCombineFileDatabase(filename, &db, False);
625a3bd7f05Smrg            XtFree(filename);
626a3bd7f05Smrg        }
627444c061aSmrg    }
628444c061aSmrg    /* now restore old database, if need be */
629444c061aSmrg    if (!doing_def)
630a3bd7f05Smrg        XrmSetDatabase(dpy, olddb);
631a3bd7f05Smrg    if (do_fallback && pd->appContext->fallback_resources) {    /* Fallback defaults */
632444c061aSmrg        XrmDatabase fdb = NULL;
633a3bd7f05Smrg        String *res;
634444c061aSmrg
635a3bd7f05Smrg        for (res = pd->appContext->fallback_resources; *res; res++)
636a3bd7f05Smrg            XrmPutLineResource(&fdb, *res);
637a3bd7f05Smrg        (void) XrmCombineDatabase(fdb, &db, False);
638444c061aSmrg    }
639444c061aSmrg    UNLOCK_PROCESS;
640444c061aSmrg    UNLOCK_APP(app);
641444c061aSmrg    return db;
642444c061aSmrg}
643444c061aSmrg
644444c061aSmrg/*
645444c061aSmrg * Merge two option tables, allowing the second to over-ride the first,
646444c061aSmrg * so that ambiguous abbreviations can be noticed.  The merge attempts
647444c061aSmrg * to make the resulting table lexicographically sorted, but succeeds
648444c061aSmrg * only if the first source table is sorted.  Though it _is_ recommended
649444c061aSmrg * (for optimizations later in XrmParseCommand), it is not required
650444c061aSmrg * that either source table be sorted.
651444c061aSmrg *
652444c061aSmrg * Caller is responsible for freeing the returned option table.
653444c061aSmrg */
654444c061aSmrg
655a3bd7f05Smrgstatic void
656a3bd7f05Smrg_MergeOptionTables(const XrmOptionDescRec *src1,
657a3bd7f05Smrg                   Cardinal num_src1,
658a3bd7f05Smrg                   const XrmOptionDescRec *src2,
659a3bd7f05Smrg                   Cardinal num_src2,
660a3bd7f05Smrg                   XrmOptionDescRec **dst,
661a3bd7f05Smrg                   Cardinal *num_dst)
662444c061aSmrg{
663444c061aSmrg    XrmOptionDescRec *table, *endP;
6640568f49bSmrg    XrmOptionDescRec *opt1, *dstP;
6650568f49bSmrg    const XrmOptionDescRec *opt2;
666444c061aSmrg    int i1;
667444c061aSmrg    Cardinal i2;
668444c061aSmrg    int dst_len, order;
669a3bd7f05Smrg    enum { Check, NotSorted, IsSorted } sort_order = Check;
670444c061aSmrg
671fdf6a26fSmrg    *dst = table = XtMallocArray(num_src1 + num_src2,
672fdf6a26fSmrg                                 (Cardinal) sizeof(XrmOptionDescRec));
673444c061aSmrg
674fdf6a26fSmrg    (void) memcpy(table, src1, sizeof(XrmOptionDescRec) * num_src1);
675444c061aSmrg    if (num_src2 == 0) {
676a3bd7f05Smrg        *num_dst = num_src1;
677a3bd7f05Smrg        return;
678444c061aSmrg    }
679a3bd7f05Smrg    endP = &table[dst_len = (int) num_src1];
680a3bd7f05Smrg    for (opt2 = src2, i2 = 0; i2 < num_src2; opt2++, i2++) {
6810568f49bSmrg        XrmOptionDescRec *whereP;
6820568f49bSmrg        Boolean found;
6830568f49bSmrg
684a3bd7f05Smrg        found = False;
685a3bd7f05Smrg        whereP = endP - 1;      /* assume new option goes at the end */
686a3bd7f05Smrg        for (opt1 = table, i1 = 0; i1 < dst_len; opt1++, i1++) {
687a3bd7f05Smrg            /* have to walk the entire new table so new list is ordered
688a3bd7f05Smrg               (if src1 was ordered) */
689a3bd7f05Smrg            if (sort_order == Check && i1 > 0
690a3bd7f05Smrg                && strcmp(opt1->option, (opt1 - 1)->option) < 0)
691a3bd7f05Smrg                sort_order = NotSorted;
692a3bd7f05Smrg            if ((order = strcmp(opt1->option, opt2->option)) == 0) {
693a3bd7f05Smrg                /* same option names; just overwrite opt1 with opt2 */
694a3bd7f05Smrg                *opt1 = *opt2;
695a3bd7f05Smrg                found = True;
696a3bd7f05Smrg                break;
697a3bd7f05Smrg            }
698a3bd7f05Smrg            /* else */
699a3bd7f05Smrg            if (sort_order == IsSorted && order > 0) {
700a3bd7f05Smrg                /* insert before opt1 to preserve order */
701a3bd7f05Smrg                /* shift rest of table forward to make room for new entry */
702a3bd7f05Smrg                for (dstP = endP++; dstP > opt1; dstP--)
703a3bd7f05Smrg                    *dstP = *(dstP - 1);
704a3bd7f05Smrg                *opt1 = *opt2;
705a3bd7f05Smrg                dst_len++;
706a3bd7f05Smrg                found = True;
707a3bd7f05Smrg                break;
708a3bd7f05Smrg            }
709a3bd7f05Smrg            /* else */
710a3bd7f05Smrg            if (order < 0)
711a3bd7f05Smrg                /* opt2 sorts after opt1, so remember this position */
712a3bd7f05Smrg                whereP = opt1;
713a3bd7f05Smrg        }
714a3bd7f05Smrg        if (sort_order == Check && i1 == dst_len)
715a3bd7f05Smrg            sort_order = IsSorted;
716a3bd7f05Smrg        if (!found) {
717a3bd7f05Smrg            /* when we get here, whereP points to the last entry in the
718a3bd7f05Smrg               destination that sorts before "opt2".  Shift rest of table
719a3bd7f05Smrg               forward and insert "opt2" after whereP. */
720a3bd7f05Smrg            whereP++;
721a3bd7f05Smrg            for (dstP = endP++; dstP > whereP; dstP--)
722a3bd7f05Smrg                *dstP = *(dstP - 1);
723a3bd7f05Smrg            *whereP = *opt2;
724a3bd7f05Smrg            dst_len++;
725a3bd7f05Smrg        }
726444c061aSmrg    }
727a3bd7f05Smrg    *num_dst = (Cardinal) dst_len;
728444c061aSmrg}
729444c061aSmrg
730444c061aSmrg/* NOTE: name, class, and type must be permanent strings */
731a3bd7f05Smrgstatic Boolean
732a3bd7f05Smrg_GetResource(Display *dpy,
733a3bd7f05Smrg             XrmSearchList list,
734a3bd7f05Smrg             String name,
735a3bd7f05Smrg             String class,
736a3bd7f05Smrg             String type,
737a3bd7f05Smrg             XrmValue *value)
738444c061aSmrg{
739444c061aSmrg    XrmRepresentation db_type;
740444c061aSmrg    XrmValue db_value;
741444c061aSmrg    XrmName Qname = XrmPermStringToQuark(name);
742444c061aSmrg    XrmClass Qclass = XrmPermStringToQuark(class);
743444c061aSmrg    XrmRepresentation Qtype = XrmPermStringToQuark(type);
744444c061aSmrg
745444c061aSmrg    if (XrmQGetSearchResource(list, Qname, Qclass, &db_type, &db_value)) {
746a3bd7f05Smrg        if (db_type == Qtype) {
747a3bd7f05Smrg            if (Qtype == _XtQString)
748a3bd7f05Smrg                *(String *) value->addr = db_value.addr;
749a3bd7f05Smrg            else
750fdf6a26fSmrg                (void) memcpy(value->addr, db_value.addr, value->size);
751a3bd7f05Smrg            return True;
752a3bd7f05Smrg        }
753a3bd7f05Smrg        else {
754a3bd7f05Smrg            WidgetRec widget;   /* hack, hack */
755a3bd7f05Smrg
756a3bd7f05Smrg            memset(&widget, 0, sizeof(widget));
757a3bd7f05Smrg            widget.core.self = &widget;
758a3bd7f05Smrg            widget.core.widget_class = coreWidgetClass;
759a3bd7f05Smrg            widget.core.screen = (Screen *) DefaultScreenOfDisplay(dpy);
760a3bd7f05Smrg            XtInitializeWidgetClass(coreWidgetClass);
761a3bd7f05Smrg            if (_XtConvert(&widget, db_type, &db_value, Qtype, value, NULL)) {
762a3bd7f05Smrg                return True;
763a3bd7f05Smrg            }
764a3bd7f05Smrg        }
765444c061aSmrg    }
766444c061aSmrg    return False;
767444c061aSmrg}
768444c061aSmrg
769a3bd7f05SmrgXrmDatabase
770a3bd7f05Smrg_XtPreparseCommandLine(XrmOptionDescRec *urlist,
771a3bd7f05Smrg                       Cardinal num_urs,
772a3bd7f05Smrg                       int argc,
773a3bd7f05Smrg                       _XtString *argv, /* return */
774a3bd7f05Smrg                       String *applName,
775a3bd7f05Smrg                       String *displayName,
776a3bd7f05Smrg                       String *language)
777444c061aSmrg{
7782265a131Smrg    XrmDatabase db = NULL;
779444c061aSmrg    XrmOptionDescRec *options;
780444c061aSmrg    Cardinal num_options;
781444c061aSmrg    XrmName name_list[3];
782444c061aSmrg    XrmName class_list[3];
783444c061aSmrg    XrmRepresentation type;
784444c061aSmrg    XrmValue val;
7850568f49bSmrg    _XtString *targv;
786444c061aSmrg    int targc = argc;
787444c061aSmrg
788fdf6a26fSmrg    targv = XtMallocArray((Cardinal) argc, (Cardinal) sizeof(_XtString *));
789fdf6a26fSmrg    (void) memcpy(targv, argv, sizeof(char *) * (size_t) argc);
790444c061aSmrg    _MergeOptionTables(opTable, XtNumber(opTable), urlist, num_urs,
791a3bd7f05Smrg                       &options, &num_options);
792444c061aSmrg    name_list[0] = class_list[0] = XrmPermStringToQuark(".");
793444c061aSmrg    name_list[2] = class_list[2] = NULLQUARK;
7940568f49bSmrg    XrmParseCommand(&db, options, (int) num_options, ".", &targc, targv);
795444c061aSmrg    if (applName) {
796a3bd7f05Smrg        name_list[1] = XrmPermStringToQuark("name");
797a3bd7f05Smrg        if (XrmQGetResource(db, name_list, name_list, &type, &val) &&
798a3bd7f05Smrg            type == _XtQString)
799a3bd7f05Smrg            *applName = val.addr;
800444c061aSmrg    }
801444c061aSmrg    if (displayName) {
802a3bd7f05Smrg        name_list[1] = XrmPermStringToQuark("display");
803a3bd7f05Smrg        if (XrmQGetResource(db, name_list, name_list, &type, &val) &&
804a3bd7f05Smrg            type == _XtQString)
805a3bd7f05Smrg            *displayName = val.addr;
806444c061aSmrg    }
807444c061aSmrg    if (language) {
808a3bd7f05Smrg        name_list[1] = XrmPermStringToQuark("xnlLanguage");
809a3bd7f05Smrg        class_list[1] = XrmPermStringToQuark("XnlLanguage");
810a3bd7f05Smrg        if (XrmQGetResource(db, name_list, class_list, &type, &val) &&
811a3bd7f05Smrg            type == _XtQString)
812a3bd7f05Smrg            *language = val.addr;
813444c061aSmrg    }
814444c061aSmrg
815a3bd7f05Smrg    XtFree((char *) targv);
816a3bd7f05Smrg    XtFree((char *) options);
817444c061aSmrg    return db;
818444c061aSmrg}
819444c061aSmrg
820a3bd7f05Smrgstatic void
821a3bd7f05SmrgGetLanguage(Display *dpy, XtPerDisplay pd)
822444c061aSmrg{
823444c061aSmrg    XrmRepresentation type;
824444c061aSmrg    XrmValue value;
825444c061aSmrg    XrmName name_list[3];
826444c061aSmrg    XrmName class_list[3];
827444c061aSmrg
828444c061aSmrg    LOCK_PROCESS;
829a3bd7f05Smrg    if (!pd->language) {
830a3bd7f05Smrg        name_list[0] = pd->name;
831a3bd7f05Smrg        name_list[1] = XrmPermStringToQuark("xnlLanguage");
832a3bd7f05Smrg        class_list[0] = pd->class;
833a3bd7f05Smrg        class_list[1] = XrmPermStringToQuark("XnlLanguage");
834a3bd7f05Smrg        name_list[2] = class_list[2] = NULLQUARK;
835a3bd7f05Smrg        if (!pd->server_db)
836a3bd7f05Smrg            CombineUserDefaults(dpy, &pd->server_db);
837a3bd7f05Smrg        if (pd->server_db &&
838a3bd7f05Smrg            XrmQGetResource(pd->server_db, name_list, class_list, &type, &value)
839a3bd7f05Smrg            && type == _XtQString)
840a3bd7f05Smrg            pd->language = (char *) value.addr;
841444c061aSmrg    }
842444c061aSmrg
843444c061aSmrg    if (pd->appContext->langProcRec.proc) {
844a3bd7f05Smrg        if (!pd->language)
845a3bd7f05Smrg            pd->language = "";
846a3bd7f05Smrg        pd->language = (*pd->appContext->langProcRec.proc)
847a3bd7f05Smrg            (dpy, pd->language, pd->appContext->langProcRec.closure);
848444c061aSmrg    }
849a3bd7f05Smrg    else if (!pd->language || pd->language[0] == '\0')  /* R4 compatibility */
850a3bd7f05Smrg        pd->language = getenv("LANG");
851444c061aSmrg
852a3bd7f05Smrg    if (pd->language)
853a3bd7f05Smrg        pd->language = XtNewString(pd->language);
854444c061aSmrg    UNLOCK_PROCESS;
855444c061aSmrg}
856444c061aSmrg
857a3bd7f05Smrgstatic void
858a3bd7f05SmrgProcessInternalConnection(XtPointer client_data,
859a3bd7f05Smrg                          int *fd,
860a3bd7f05Smrg                          XtInputId *id _X_UNUSED)
861444c061aSmrg{
862a3bd7f05Smrg    XProcessInternalConnection((Display *) client_data, *fd);
863444c061aSmrg}
864444c061aSmrg
865a3bd7f05Smrgstatic void
866a3bd7f05SmrgConnectionWatch(Display *dpy,
867a3bd7f05Smrg                XPointer client_data,
868a3bd7f05Smrg                int fd,
869a3bd7f05Smrg                Bool opening,
870a3bd7f05Smrg                XPointer *watch_data)
871444c061aSmrg{
872a3bd7f05Smrg    XtInputId *iptr;
873444c061aSmrg    XtAppContext app = XtDisplayToApplicationContext(dpy);
874444c061aSmrg
875444c061aSmrg    if (opening) {
876a3bd7f05Smrg        iptr = (XtInputId *) __XtMalloc(sizeof(XtInputId));
877a3bd7f05Smrg        *iptr = XtAppAddInput(app, fd, (XtPointer) XtInputReadMask,
878a3bd7f05Smrg                              ProcessInternalConnection, client_data);
879a3bd7f05Smrg        *watch_data = (XPointer) iptr;
880a3bd7f05Smrg    }
881a3bd7f05Smrg    else {
882a3bd7f05Smrg        iptr = (XtInputId *) *watch_data;
883a3bd7f05Smrg        XtRemoveInput(*iptr);
884444c061aSmrg        (void) XtFree(*watch_data);
885444c061aSmrg    }
886444c061aSmrg}
887444c061aSmrg
888a3bd7f05Smrgvoid
889a3bd7f05Smrg_XtDisplayInitialize(Display *dpy,
890a3bd7f05Smrg                     XtPerDisplay pd,
891a3bd7f05Smrg                     _Xconst char *name,
892a3bd7f05Smrg                     XrmOptionDescRec *urlist,
893a3bd7f05Smrg                     Cardinal num_urs,
894a3bd7f05Smrg                     int *argc,
895a3bd7f05Smrg                     char **argv)
896444c061aSmrg{
897a3bd7f05Smrg    Boolean tmp_bool;
898a3bd7f05Smrg    XrmValue value;
899a3bd7f05Smrg    XrmOptionDescRec *options;
900a3bd7f05Smrg    Cardinal num_options;
901a3bd7f05Smrg    XrmDatabase db;
902a3bd7f05Smrg    XrmName name_list[2];
903a3bd7f05Smrg    XrmClass class_list[2];
904a3bd7f05Smrg    XrmHashTable *search_list;
905a3bd7f05Smrg    int search_list_size = SEARCH_LIST_SIZE;
906a3bd7f05Smrg
907a3bd7f05Smrg    GetLanguage(dpy, pd);
908a3bd7f05Smrg
909a3bd7f05Smrg    /* Parse the command line and remove Xt arguments from argv */
910a3bd7f05Smrg    _MergeOptionTables(opTable, XtNumber(opTable), urlist, num_urs,
911a3bd7f05Smrg                       &options, &num_options);
912a3bd7f05Smrg    XrmParseCommand(&pd->cmd_db, options, (int) num_options, name, argc, argv);
913a3bd7f05Smrg
914a3bd7f05Smrg    db = XtScreenDatabase(DefaultScreenOfDisplay(dpy));
915a3bd7f05Smrg
916a3bd7f05Smrg    if (!(search_list = (XrmHashTable *)
917a3bd7f05Smrg          ALLOCATE_LOCAL(SEARCH_LIST_SIZE * sizeof(XrmHashTable))))
918a3bd7f05Smrg        _XtAllocError(NULL);
919a3bd7f05Smrg    name_list[0] = pd->name;
920a3bd7f05Smrg    class_list[0] = pd->class;
921a3bd7f05Smrg    name_list[1] = NULLQUARK;
922a3bd7f05Smrg    class_list[1] = NULLQUARK;
923a3bd7f05Smrg
924a3bd7f05Smrg    while (!XrmQGetSearchList(db, name_list, class_list,
925a3bd7f05Smrg                              search_list, search_list_size)) {
926a3bd7f05Smrg        XrmHashTable *old = search_list;
927a3bd7f05Smrg        Cardinal size =
928a3bd7f05Smrg            (Cardinal) ((size_t) (search_list_size *= 2) *
929a3bd7f05Smrg                        sizeof(XrmHashTable));
930a3bd7f05Smrg        if (!(search_list = (XrmHashTable *) ALLOCATE_LOCAL(size)))
931a3bd7f05Smrg            _XtAllocError(NULL);
932fdf6a26fSmrg        (void) memcpy(search_list, old, (size >> 1));
933a3bd7f05Smrg        DEALLOCATE_LOCAL(old);
934a3bd7f05Smrg    }
935a3bd7f05Smrg
936a3bd7f05Smrg    value.size = sizeof(tmp_bool);
937a3bd7f05Smrg    value.addr = (XtPointer) &tmp_bool;
938a3bd7f05Smrg    if (_GetResource(dpy, search_list, "synchronous", "Synchronous",
939a3bd7f05Smrg                     XtRBoolean, &value)) {
940a3bd7f05Smrg        int i;
941a3bd7f05Smrg        Display **dpyP = pd->appContext->list;
942a3bd7f05Smrg
943a3bd7f05Smrg        pd->appContext->sync = tmp_bool;
944a3bd7f05Smrg        for (i = pd->appContext->count; i; dpyP++, i--) {
945a3bd7f05Smrg            (void) XSynchronize(*dpyP, (Bool) tmp_bool);
946a3bd7f05Smrg        }
947a3bd7f05Smrg    }
948a3bd7f05Smrg    else {
949a3bd7f05Smrg        (void) XSynchronize(dpy, (Bool) pd->appContext->sync);
950a3bd7f05Smrg    }
951a3bd7f05Smrg
952a3bd7f05Smrg    if (_GetResource(dpy, search_list, "reverseVideo", "ReverseVideo",
953a3bd7f05Smrg                     XtRBoolean, &value)
954a3bd7f05Smrg        && tmp_bool) {
955a3bd7f05Smrg        pd->rv = True;
956a3bd7f05Smrg    }
957a3bd7f05Smrg
958a3bd7f05Smrg    value.size = sizeof(pd->multi_click_time);
959a3bd7f05Smrg    value.addr = (XtPointer) &pd->multi_click_time;
960a3bd7f05Smrg    if (!_GetResource(dpy, search_list,
961a3bd7f05Smrg                      "multiClickTime", "MultiClickTime", XtRInt, &value)) {
962a3bd7f05Smrg        pd->multi_click_time = 200;
963a3bd7f05Smrg    }
964a3bd7f05Smrg
965a3bd7f05Smrg    value.size = sizeof(pd->appContext->selectionTimeout);
966a3bd7f05Smrg    value.addr = (XtPointer) &pd->appContext->selectionTimeout;
967a3bd7f05Smrg    (void) _GetResource(dpy, search_list,
968a3bd7f05Smrg                        "selectionTimeout", "SelectionTimeout", XtRInt, &value);
969444c061aSmrg
970444c061aSmrg#ifndef NO_IDENTIFY_WINDOWS
971a3bd7f05Smrg    value.size = sizeof(pd->appContext->identify_windows);
972a3bd7f05Smrg    value.addr = (XtPointer) &pd->appContext->identify_windows;
973a3bd7f05Smrg    (void) _GetResource(dpy, search_list,
974a3bd7f05Smrg                        "xtIdentifyWindows", "XtDebug", XtRBoolean, &value);
975444c061aSmrg#endif
976444c061aSmrg
977a3bd7f05Smrg    XAddConnectionWatch(dpy, ConnectionWatch, (XPointer) dpy);
978444c061aSmrg
979a3bd7f05Smrg    XtFree((XtPointer) options);
980a3bd7f05Smrg    DEALLOCATE_LOCAL(search_list);
981444c061aSmrg}
982444c061aSmrg
983a3bd7f05Smrg/*      Function Name: XtAppSetFallbackResources
984a3bd7f05Smrg *      Description: Sets the fallback resource list that will be loaded
985444c061aSmrg *                   at display initialization time.
986a3bd7f05Smrg *      Arguments: app_context - the app context.
987444c061aSmrg *                 specification_list - the resource specification list.
988a3bd7f05Smrg *      Returns: none.
989444c061aSmrg */
990444c061aSmrg
991444c061aSmrgvoid
992a3bd7f05SmrgXtAppSetFallbackResources(XtAppContext app_context, String *specification_list)
993444c061aSmrg{
994444c061aSmrg    LOCK_APP(app_context);
995444c061aSmrg    app_context->fallback_resources = specification_list;
996444c061aSmrg    UNLOCK_APP(app_context);
997444c061aSmrg}
998444c061aSmrg
999a3bd7f05SmrgWidget
1000a3bd7f05SmrgXtOpenApplication(XtAppContext *app_context_return,
1001a3bd7f05Smrg                  _Xconst char *application_class,
1002a3bd7f05Smrg                  XrmOptionDescRec *options,
1003a3bd7f05Smrg                  Cardinal num_options,
1004a3bd7f05Smrg                  int *argc_in_out,
1005a3bd7f05Smrg                  _XtString *argv_in_out,
1006a3bd7f05Smrg                  String *fallback_resources,
1007a3bd7f05Smrg                  WidgetClass widget_class,
1008a3bd7f05Smrg                  ArgList args_in,
1009a3bd7f05Smrg                  Cardinal num_args_in)
1010444c061aSmrg{
1011444c061aSmrg    XtAppContext app_con;
1012a3bd7f05Smrg    Display *dpy;
1013444c061aSmrg    register int saved_argc = *argc_in_out;
1014444c061aSmrg    Widget root;
1015444c061aSmrg    Arg args[3], *merged_args;
1016444c061aSmrg    Cardinal num = 0;
1017444c061aSmrg
1018a3bd7f05Smrg    XtToolkitInitialize();      /* cannot be moved into _XtAppInit */
1019444c061aSmrg
1020a3bd7f05Smrg    dpy = _XtAppInit(&app_con, (String) application_class, options, num_options,
1021a3bd7f05Smrg                     argc_in_out, &argv_in_out, fallback_resources);
1022444c061aSmrg
1023444c061aSmrg    LOCK_APP(app_con);
1024a3bd7f05Smrg    XtSetArg(args[num], XtNscreen, DefaultScreenOfDisplay(dpy));
1025a3bd7f05Smrg    num++;
1026a3bd7f05Smrg    XtSetArg(args[num], XtNargc, saved_argc);
1027a3bd7f05Smrg    num++;
1028a3bd7f05Smrg    XtSetArg(args[num], XtNargv, argv_in_out);
1029a3bd7f05Smrg    num++;
1030444c061aSmrg
1031444c061aSmrg    merged_args = XtMergeArgLists(args_in, num_args_in, args, num);
1032444c061aSmrg    num += num_args_in;
1033444c061aSmrg
1034444c061aSmrg    root = XtAppCreateShell(NULL, application_class, widget_class, dpy,
1035a3bd7f05Smrg                            merged_args, num);
1036444c061aSmrg
1037444c061aSmrg    if (app_context_return)
1038a3bd7f05Smrg        *app_context_return = app_con;
1039444c061aSmrg
1040a3bd7f05Smrg    XtFree((XtPointer) merged_args);
1041a3bd7f05Smrg    XtFree((XtPointer) argv_in_out);
1042444c061aSmrg    UNLOCK_APP(app_con);
1043444c061aSmrg    return root;
1044444c061aSmrg}
1045444c061aSmrg
1046444c061aSmrgWidget
1047a3bd7f05SmrgXtAppInitialize(XtAppContext *app_context_return,
1048a3bd7f05Smrg                _Xconst char *application_class,
1049a3bd7f05Smrg                XrmOptionDescRec *options,
1050a3bd7f05Smrg                Cardinal num_options,
1051a3bd7f05Smrg                int *argc_in_out,
1052a3bd7f05Smrg                _XtString *argv_in_out,
1053a3bd7f05Smrg                String *fallback_resources,
1054a3bd7f05Smrg                ArgList args_in,
1055a3bd7f05Smrg                Cardinal num_args_in)
1056444c061aSmrg{
1057444c061aSmrg    return XtOpenApplication(app_context_return, application_class,
1058a3bd7f05Smrg                             options, num_options,
1059a3bd7f05Smrg                             argc_in_out, argv_in_out, fallback_resources,
1060a3bd7f05Smrg                             applicationShellWidgetClass, args_in, num_args_in);
1061444c061aSmrg}
1062444c061aSmrg
1063444c061aSmrgWidget
1064a3bd7f05SmrgXtInitialize(_Xconst _XtString name _X_UNUSED,
1065a3bd7f05Smrg             _Xconst _XtString classname,
1066a3bd7f05Smrg             XrmOptionDescRec *options,
1067a3bd7f05Smrg             Cardinal num_options,
1068a3bd7f05Smrg             int *argc,
1069a3bd7f05Smrg             _XtString *argv)
1070444c061aSmrg{
1071444c061aSmrg    Widget root;
1072444c061aSmrg    XtAppContext app_con;
1073444c061aSmrg    register ProcessContext process = _XtGetProcessContext();
1074444c061aSmrg
1075444c061aSmrg    root = XtAppInitialize(&app_con, classname, options, num_options,
1076a3bd7f05Smrg                           argc, argv, NULL, NULL, (Cardinal) 0);
1077444c061aSmrg
1078444c061aSmrg    LOCK_PROCESS;
1079444c061aSmrg    process->defaultAppContext = app_con;
1080444c061aSmrg    UNLOCK_PROCESS;
1081444c061aSmrg    return root;
1082444c061aSmrg}
1083