Initialize.c revision a3bd7f05
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
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.
206444c061aSmrg * Because of this the symbol must be accessable by all
207444c061aSmrg * client dll's and applications.  In unix environments
208444c061aSmrg * this is no problem, because the used shared libraries
209444c061aSmrg * format (elf) supports this immediatly.  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
290444c061aSmrg    /* Other intrinsic intialization */
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
671a3bd7f05Smrg    *dst = table = (XrmOptionDescRec *)
672a3bd7f05Smrg        __XtMalloc((Cardinal)
673a3bd7f05Smrg                   (sizeof(XrmOptionDescRec) * (num_src1 + num_src2)));
674444c061aSmrg
675a3bd7f05Smrg    (void) memmove(table, src1, sizeof(XrmOptionDescRec) * num_src1);
676444c061aSmrg    if (num_src2 == 0) {
677a3bd7f05Smrg        *num_dst = num_src1;
678a3bd7f05Smrg        return;
679444c061aSmrg    }
680a3bd7f05Smrg    endP = &table[dst_len = (int) num_src1];
681a3bd7f05Smrg    for (opt2 = src2, i2 = 0; i2 < num_src2; opt2++, i2++) {
6820568f49bSmrg        XrmOptionDescRec *whereP;
6830568f49bSmrg        Boolean found;
6840568f49bSmrg
685a3bd7f05Smrg        found = False;
686a3bd7f05Smrg        whereP = endP - 1;      /* assume new option goes at the end */
687a3bd7f05Smrg        for (opt1 = table, i1 = 0; i1 < dst_len; opt1++, i1++) {
688a3bd7f05Smrg            /* have to walk the entire new table so new list is ordered
689a3bd7f05Smrg               (if src1 was ordered) */
690a3bd7f05Smrg            if (sort_order == Check && i1 > 0
691a3bd7f05Smrg                && strcmp(opt1->option, (opt1 - 1)->option) < 0)
692a3bd7f05Smrg                sort_order = NotSorted;
693a3bd7f05Smrg            if ((order = strcmp(opt1->option, opt2->option)) == 0) {
694a3bd7f05Smrg                /* same option names; just overwrite opt1 with opt2 */
695a3bd7f05Smrg                *opt1 = *opt2;
696a3bd7f05Smrg                found = True;
697a3bd7f05Smrg                break;
698a3bd7f05Smrg            }
699a3bd7f05Smrg            /* else */
700a3bd7f05Smrg            if (sort_order == IsSorted && order > 0) {
701a3bd7f05Smrg                /* insert before opt1 to preserve order */
702a3bd7f05Smrg                /* shift rest of table forward to make room for new entry */
703a3bd7f05Smrg                for (dstP = endP++; dstP > opt1; dstP--)
704a3bd7f05Smrg                    *dstP = *(dstP - 1);
705a3bd7f05Smrg                *opt1 = *opt2;
706a3bd7f05Smrg                dst_len++;
707a3bd7f05Smrg                found = True;
708a3bd7f05Smrg                break;
709a3bd7f05Smrg            }
710a3bd7f05Smrg            /* else */
711a3bd7f05Smrg            if (order < 0)
712a3bd7f05Smrg                /* opt2 sorts after opt1, so remember this position */
713a3bd7f05Smrg                whereP = opt1;
714a3bd7f05Smrg        }
715a3bd7f05Smrg        if (sort_order == Check && i1 == dst_len)
716a3bd7f05Smrg            sort_order = IsSorted;
717a3bd7f05Smrg        if (!found) {
718a3bd7f05Smrg            /* when we get here, whereP points to the last entry in the
719a3bd7f05Smrg               destination that sorts before "opt2".  Shift rest of table
720a3bd7f05Smrg               forward and insert "opt2" after whereP. */
721a3bd7f05Smrg            whereP++;
722a3bd7f05Smrg            for (dstP = endP++; dstP > whereP; dstP--)
723a3bd7f05Smrg                *dstP = *(dstP - 1);
724a3bd7f05Smrg            *whereP = *opt2;
725a3bd7f05Smrg            dst_len++;
726a3bd7f05Smrg        }
727444c061aSmrg    }
728a3bd7f05Smrg    *num_dst = (Cardinal) dst_len;
729444c061aSmrg}
730444c061aSmrg
731444c061aSmrg/* NOTE: name, class, and type must be permanent strings */
732a3bd7f05Smrgstatic Boolean
733a3bd7f05Smrg_GetResource(Display *dpy,
734a3bd7f05Smrg             XrmSearchList list,
735a3bd7f05Smrg             String name,
736a3bd7f05Smrg             String class,
737a3bd7f05Smrg             String type,
738a3bd7f05Smrg             XrmValue *value)
739444c061aSmrg{
740444c061aSmrg    XrmRepresentation db_type;
741444c061aSmrg    XrmValue db_value;
742444c061aSmrg    XrmName Qname = XrmPermStringToQuark(name);
743444c061aSmrg    XrmClass Qclass = XrmPermStringToQuark(class);
744444c061aSmrg    XrmRepresentation Qtype = XrmPermStringToQuark(type);
745444c061aSmrg
746444c061aSmrg    if (XrmQGetSearchResource(list, Qname, Qclass, &db_type, &db_value)) {
747a3bd7f05Smrg        if (db_type == Qtype) {
748a3bd7f05Smrg            if (Qtype == _XtQString)
749a3bd7f05Smrg                *(String *) value->addr = db_value.addr;
750a3bd7f05Smrg            else
751a3bd7f05Smrg                (void) memmove(value->addr, db_value.addr, value->size);
752a3bd7f05Smrg            return True;
753a3bd7f05Smrg        }
754a3bd7f05Smrg        else {
755a3bd7f05Smrg            WidgetRec widget;   /* hack, hack */
756a3bd7f05Smrg
757a3bd7f05Smrg            memset(&widget, 0, sizeof(widget));
758a3bd7f05Smrg            widget.core.self = &widget;
759a3bd7f05Smrg            widget.core.widget_class = coreWidgetClass;
760a3bd7f05Smrg            widget.core.screen = (Screen *) DefaultScreenOfDisplay(dpy);
761a3bd7f05Smrg            XtInitializeWidgetClass(coreWidgetClass);
762a3bd7f05Smrg            if (_XtConvert(&widget, db_type, &db_value, Qtype, value, NULL)) {
763a3bd7f05Smrg                return True;
764a3bd7f05Smrg            }
765a3bd7f05Smrg        }
766444c061aSmrg    }
767444c061aSmrg    return False;
768444c061aSmrg}
769444c061aSmrg
770a3bd7f05SmrgXrmDatabase
771a3bd7f05Smrg_XtPreparseCommandLine(XrmOptionDescRec *urlist,
772a3bd7f05Smrg                       Cardinal num_urs,
773a3bd7f05Smrg                       int argc,
774a3bd7f05Smrg                       _XtString *argv, /* return */
775a3bd7f05Smrg                       String *applName,
776a3bd7f05Smrg                       String *displayName,
777a3bd7f05Smrg                       String *language)
778444c061aSmrg{
7792265a131Smrg    XrmDatabase db = NULL;
780444c061aSmrg    XrmOptionDescRec *options;
781444c061aSmrg    Cardinal num_options;
782444c061aSmrg    XrmName name_list[3];
783444c061aSmrg    XrmName class_list[3];
784444c061aSmrg    XrmRepresentation type;
785444c061aSmrg    XrmValue val;
7860568f49bSmrg    _XtString *targv;
787444c061aSmrg    int targc = argc;
788444c061aSmrg
789a3bd7f05Smrg    targv = (_XtString *)
790a3bd7f05Smrg        __XtMalloc((Cardinal) (sizeof(_XtString *) * (size_t) argc));
7910568f49bSmrg    (void) memmove(targv, argv, sizeof(char *) * (size_t) argc);
792444c061aSmrg    _MergeOptionTables(opTable, XtNumber(opTable), urlist, num_urs,
793a3bd7f05Smrg                       &options, &num_options);
794444c061aSmrg    name_list[0] = class_list[0] = XrmPermStringToQuark(".");
795444c061aSmrg    name_list[2] = class_list[2] = NULLQUARK;
7960568f49bSmrg    XrmParseCommand(&db, options, (int) num_options, ".", &targc, targv);
797444c061aSmrg    if (applName) {
798a3bd7f05Smrg        name_list[1] = XrmPermStringToQuark("name");
799a3bd7f05Smrg        if (XrmQGetResource(db, name_list, name_list, &type, &val) &&
800a3bd7f05Smrg            type == _XtQString)
801a3bd7f05Smrg            *applName = val.addr;
802444c061aSmrg    }
803444c061aSmrg    if (displayName) {
804a3bd7f05Smrg        name_list[1] = XrmPermStringToQuark("display");
805a3bd7f05Smrg        if (XrmQGetResource(db, name_list, name_list, &type, &val) &&
806a3bd7f05Smrg            type == _XtQString)
807a3bd7f05Smrg            *displayName = val.addr;
808444c061aSmrg    }
809444c061aSmrg    if (language) {
810a3bd7f05Smrg        name_list[1] = XrmPermStringToQuark("xnlLanguage");
811a3bd7f05Smrg        class_list[1] = XrmPermStringToQuark("XnlLanguage");
812a3bd7f05Smrg        if (XrmQGetResource(db, name_list, class_list, &type, &val) &&
813a3bd7f05Smrg            type == _XtQString)
814a3bd7f05Smrg            *language = val.addr;
815444c061aSmrg    }
816444c061aSmrg
817a3bd7f05Smrg    XtFree((char *) targv);
818a3bd7f05Smrg    XtFree((char *) options);
819444c061aSmrg    return db;
820444c061aSmrg}
821444c061aSmrg
822a3bd7f05Smrgstatic void
823a3bd7f05SmrgGetLanguage(Display *dpy, XtPerDisplay pd)
824444c061aSmrg{
825444c061aSmrg    XrmRepresentation type;
826444c061aSmrg    XrmValue value;
827444c061aSmrg    XrmName name_list[3];
828444c061aSmrg    XrmName class_list[3];
829444c061aSmrg
830444c061aSmrg    LOCK_PROCESS;
831a3bd7f05Smrg    if (!pd->language) {
832a3bd7f05Smrg        name_list[0] = pd->name;
833a3bd7f05Smrg        name_list[1] = XrmPermStringToQuark("xnlLanguage");
834a3bd7f05Smrg        class_list[0] = pd->class;
835a3bd7f05Smrg        class_list[1] = XrmPermStringToQuark("XnlLanguage");
836a3bd7f05Smrg        name_list[2] = class_list[2] = NULLQUARK;
837a3bd7f05Smrg        if (!pd->server_db)
838a3bd7f05Smrg            CombineUserDefaults(dpy, &pd->server_db);
839a3bd7f05Smrg        if (pd->server_db &&
840a3bd7f05Smrg            XrmQGetResource(pd->server_db, name_list, class_list, &type, &value)
841a3bd7f05Smrg            && type == _XtQString)
842a3bd7f05Smrg            pd->language = (char *) value.addr;
843444c061aSmrg    }
844444c061aSmrg
845444c061aSmrg    if (pd->appContext->langProcRec.proc) {
846a3bd7f05Smrg        if (!pd->language)
847a3bd7f05Smrg            pd->language = "";
848a3bd7f05Smrg        pd->language = (*pd->appContext->langProcRec.proc)
849a3bd7f05Smrg            (dpy, pd->language, pd->appContext->langProcRec.closure);
850444c061aSmrg    }
851a3bd7f05Smrg    else if (!pd->language || pd->language[0] == '\0')  /* R4 compatibility */
852a3bd7f05Smrg        pd->language = getenv("LANG");
853444c061aSmrg
854a3bd7f05Smrg    if (pd->language)
855a3bd7f05Smrg        pd->language = XtNewString(pd->language);
856444c061aSmrg    UNLOCK_PROCESS;
857444c061aSmrg}
858444c061aSmrg
859a3bd7f05Smrgstatic void
860a3bd7f05SmrgProcessInternalConnection(XtPointer client_data,
861a3bd7f05Smrg                          int *fd,
862a3bd7f05Smrg                          XtInputId *id _X_UNUSED)
863444c061aSmrg{
864a3bd7f05Smrg    XProcessInternalConnection((Display *) client_data, *fd);
865444c061aSmrg}
866444c061aSmrg
867a3bd7f05Smrgstatic void
868a3bd7f05SmrgConnectionWatch(Display *dpy,
869a3bd7f05Smrg                XPointer client_data,
870a3bd7f05Smrg                int fd,
871a3bd7f05Smrg                Bool opening,
872a3bd7f05Smrg                XPointer *watch_data)
873444c061aSmrg{
874a3bd7f05Smrg    XtInputId *iptr;
875444c061aSmrg    XtAppContext app = XtDisplayToApplicationContext(dpy);
876444c061aSmrg
877444c061aSmrg    if (opening) {
878a3bd7f05Smrg        iptr = (XtInputId *) __XtMalloc(sizeof(XtInputId));
879a3bd7f05Smrg        *iptr = XtAppAddInput(app, fd, (XtPointer) XtInputReadMask,
880a3bd7f05Smrg                              ProcessInternalConnection, client_data);
881a3bd7f05Smrg        *watch_data = (XPointer) iptr;
882a3bd7f05Smrg    }
883a3bd7f05Smrg    else {
884a3bd7f05Smrg        iptr = (XtInputId *) *watch_data;
885a3bd7f05Smrg        XtRemoveInput(*iptr);
886444c061aSmrg        (void) XtFree(*watch_data);
887444c061aSmrg    }
888444c061aSmrg}
889444c061aSmrg
890a3bd7f05Smrgvoid
891a3bd7f05Smrg_XtDisplayInitialize(Display *dpy,
892a3bd7f05Smrg                     XtPerDisplay pd,
893a3bd7f05Smrg                     _Xconst char *name,
894a3bd7f05Smrg                     XrmOptionDescRec *urlist,
895a3bd7f05Smrg                     Cardinal num_urs,
896a3bd7f05Smrg                     int *argc,
897a3bd7f05Smrg                     char **argv)
898444c061aSmrg{
899a3bd7f05Smrg    Boolean tmp_bool;
900a3bd7f05Smrg    XrmValue value;
901a3bd7f05Smrg    XrmOptionDescRec *options;
902a3bd7f05Smrg    Cardinal num_options;
903a3bd7f05Smrg    XrmDatabase db;
904a3bd7f05Smrg    XrmName name_list[2];
905a3bd7f05Smrg    XrmClass class_list[2];
906a3bd7f05Smrg    XrmHashTable *search_list;
907a3bd7f05Smrg    int search_list_size = SEARCH_LIST_SIZE;
908a3bd7f05Smrg
909a3bd7f05Smrg    GetLanguage(dpy, pd);
910a3bd7f05Smrg
911a3bd7f05Smrg    /* Parse the command line and remove Xt arguments from argv */
912a3bd7f05Smrg    _MergeOptionTables(opTable, XtNumber(opTable), urlist, num_urs,
913a3bd7f05Smrg                       &options, &num_options);
914a3bd7f05Smrg    XrmParseCommand(&pd->cmd_db, options, (int) num_options, name, argc, argv);
915a3bd7f05Smrg
916a3bd7f05Smrg    db = XtScreenDatabase(DefaultScreenOfDisplay(dpy));
917a3bd7f05Smrg
918a3bd7f05Smrg    if (!(search_list = (XrmHashTable *)
919a3bd7f05Smrg          ALLOCATE_LOCAL(SEARCH_LIST_SIZE * sizeof(XrmHashTable))))
920a3bd7f05Smrg        _XtAllocError(NULL);
921a3bd7f05Smrg    name_list[0] = pd->name;
922a3bd7f05Smrg    class_list[0] = pd->class;
923a3bd7f05Smrg    name_list[1] = NULLQUARK;
924a3bd7f05Smrg    class_list[1] = NULLQUARK;
925a3bd7f05Smrg
926a3bd7f05Smrg    while (!XrmQGetSearchList(db, name_list, class_list,
927a3bd7f05Smrg                              search_list, search_list_size)) {
928a3bd7f05Smrg        XrmHashTable *old = search_list;
929a3bd7f05Smrg        Cardinal size =
930a3bd7f05Smrg            (Cardinal) ((size_t) (search_list_size *= 2) *
931a3bd7f05Smrg                        sizeof(XrmHashTable));
932a3bd7f05Smrg        if (!(search_list = (XrmHashTable *) ALLOCATE_LOCAL(size)))
933a3bd7f05Smrg            _XtAllocError(NULL);
934a3bd7f05Smrg        (void) memmove((char *) search_list, (char *) old, (size >> 1));
935a3bd7f05Smrg        DEALLOCATE_LOCAL(old);
936a3bd7f05Smrg    }
937a3bd7f05Smrg
938a3bd7f05Smrg    value.size = sizeof(tmp_bool);
939a3bd7f05Smrg    value.addr = (XtPointer) &tmp_bool;
940a3bd7f05Smrg    if (_GetResource(dpy, search_list, "synchronous", "Synchronous",
941a3bd7f05Smrg                     XtRBoolean, &value)) {
942a3bd7f05Smrg        int i;
943a3bd7f05Smrg        Display **dpyP = pd->appContext->list;
944a3bd7f05Smrg
945a3bd7f05Smrg        pd->appContext->sync = tmp_bool;
946a3bd7f05Smrg        for (i = pd->appContext->count; i; dpyP++, i--) {
947a3bd7f05Smrg            (void) XSynchronize(*dpyP, (Bool) tmp_bool);
948a3bd7f05Smrg        }
949a3bd7f05Smrg    }
950a3bd7f05Smrg    else {
951a3bd7f05Smrg        (void) XSynchronize(dpy, (Bool) pd->appContext->sync);
952a3bd7f05Smrg    }
953a3bd7f05Smrg
954a3bd7f05Smrg    if (_GetResource(dpy, search_list, "reverseVideo", "ReverseVideo",
955a3bd7f05Smrg                     XtRBoolean, &value)
956a3bd7f05Smrg        && tmp_bool) {
957a3bd7f05Smrg        pd->rv = True;
958a3bd7f05Smrg    }
959a3bd7f05Smrg
960a3bd7f05Smrg    value.size = sizeof(pd->multi_click_time);
961a3bd7f05Smrg    value.addr = (XtPointer) &pd->multi_click_time;
962a3bd7f05Smrg    if (!_GetResource(dpy, search_list,
963a3bd7f05Smrg                      "multiClickTime", "MultiClickTime", XtRInt, &value)) {
964a3bd7f05Smrg        pd->multi_click_time = 200;
965a3bd7f05Smrg    }
966a3bd7f05Smrg
967a3bd7f05Smrg    value.size = sizeof(pd->appContext->selectionTimeout);
968a3bd7f05Smrg    value.addr = (XtPointer) &pd->appContext->selectionTimeout;
969a3bd7f05Smrg    (void) _GetResource(dpy, search_list,
970a3bd7f05Smrg                        "selectionTimeout", "SelectionTimeout", XtRInt, &value);
971444c061aSmrg
972444c061aSmrg#ifndef NO_IDENTIFY_WINDOWS
973a3bd7f05Smrg    value.size = sizeof(pd->appContext->identify_windows);
974a3bd7f05Smrg    value.addr = (XtPointer) &pd->appContext->identify_windows;
975a3bd7f05Smrg    (void) _GetResource(dpy, search_list,
976a3bd7f05Smrg                        "xtIdentifyWindows", "XtDebug", XtRBoolean, &value);
977444c061aSmrg#endif
978444c061aSmrg
979a3bd7f05Smrg    XAddConnectionWatch(dpy, ConnectionWatch, (XPointer) dpy);
980444c061aSmrg
981a3bd7f05Smrg    XtFree((XtPointer) options);
982a3bd7f05Smrg    DEALLOCATE_LOCAL(search_list);
983444c061aSmrg}
984444c061aSmrg
985a3bd7f05Smrg/*      Function Name: XtAppSetFallbackResources
986a3bd7f05Smrg *      Description: Sets the fallback resource list that will be loaded
987444c061aSmrg *                   at display initialization time.
988a3bd7f05Smrg *      Arguments: app_context - the app context.
989444c061aSmrg *                 specification_list - the resource specification list.
990a3bd7f05Smrg *      Returns: none.
991444c061aSmrg */
992444c061aSmrg
993444c061aSmrgvoid
994a3bd7f05SmrgXtAppSetFallbackResources(XtAppContext app_context, String *specification_list)
995444c061aSmrg{
996444c061aSmrg    LOCK_APP(app_context);
997444c061aSmrg    app_context->fallback_resources = specification_list;
998444c061aSmrg    UNLOCK_APP(app_context);
999444c061aSmrg}
1000444c061aSmrg
1001a3bd7f05SmrgWidget
1002a3bd7f05SmrgXtOpenApplication(XtAppContext *app_context_return,
1003a3bd7f05Smrg                  _Xconst char *application_class,
1004a3bd7f05Smrg                  XrmOptionDescRec *options,
1005a3bd7f05Smrg                  Cardinal num_options,
1006a3bd7f05Smrg                  int *argc_in_out,
1007a3bd7f05Smrg                  _XtString *argv_in_out,
1008a3bd7f05Smrg                  String *fallback_resources,
1009a3bd7f05Smrg                  WidgetClass widget_class,
1010a3bd7f05Smrg                  ArgList args_in,
1011a3bd7f05Smrg                  Cardinal num_args_in)
1012444c061aSmrg{
1013444c061aSmrg    XtAppContext app_con;
1014a3bd7f05Smrg    Display *dpy;
1015444c061aSmrg    register int saved_argc = *argc_in_out;
1016444c061aSmrg    Widget root;
1017444c061aSmrg    Arg args[3], *merged_args;
1018444c061aSmrg    Cardinal num = 0;
1019444c061aSmrg
1020a3bd7f05Smrg    XtToolkitInitialize();      /* cannot be moved into _XtAppInit */
1021444c061aSmrg
1022a3bd7f05Smrg    dpy = _XtAppInit(&app_con, (String) application_class, options, num_options,
1023a3bd7f05Smrg                     argc_in_out, &argv_in_out, fallback_resources);
1024444c061aSmrg
1025444c061aSmrg    LOCK_APP(app_con);
1026a3bd7f05Smrg    XtSetArg(args[num], XtNscreen, DefaultScreenOfDisplay(dpy));
1027a3bd7f05Smrg    num++;
1028a3bd7f05Smrg    XtSetArg(args[num], XtNargc, saved_argc);
1029a3bd7f05Smrg    num++;
1030a3bd7f05Smrg    XtSetArg(args[num], XtNargv, argv_in_out);
1031a3bd7f05Smrg    num++;
1032444c061aSmrg
1033444c061aSmrg    merged_args = XtMergeArgLists(args_in, num_args_in, args, num);
1034444c061aSmrg    num += num_args_in;
1035444c061aSmrg
1036444c061aSmrg    root = XtAppCreateShell(NULL, application_class, widget_class, dpy,
1037a3bd7f05Smrg                            merged_args, num);
1038444c061aSmrg
1039444c061aSmrg    if (app_context_return)
1040a3bd7f05Smrg        *app_context_return = app_con;
1041444c061aSmrg
1042a3bd7f05Smrg    XtFree((XtPointer) merged_args);
1043a3bd7f05Smrg    XtFree((XtPointer) argv_in_out);
1044444c061aSmrg    UNLOCK_APP(app_con);
1045444c061aSmrg    return root;
1046444c061aSmrg}
1047444c061aSmrg
1048444c061aSmrgWidget
1049a3bd7f05SmrgXtAppInitialize(XtAppContext *app_context_return,
1050a3bd7f05Smrg                _Xconst char *application_class,
1051a3bd7f05Smrg                XrmOptionDescRec *options,
1052a3bd7f05Smrg                Cardinal num_options,
1053a3bd7f05Smrg                int *argc_in_out,
1054a3bd7f05Smrg                _XtString *argv_in_out,
1055a3bd7f05Smrg                String *fallback_resources,
1056a3bd7f05Smrg                ArgList args_in,
1057a3bd7f05Smrg                Cardinal num_args_in)
1058444c061aSmrg{
1059444c061aSmrg    return XtOpenApplication(app_context_return, application_class,
1060a3bd7f05Smrg                             options, num_options,
1061a3bd7f05Smrg                             argc_in_out, argv_in_out, fallback_resources,
1062a3bd7f05Smrg                             applicationShellWidgetClass, args_in, num_args_in);
1063444c061aSmrg}
1064444c061aSmrg
1065444c061aSmrgWidget
1066a3bd7f05SmrgXtInitialize(_Xconst _XtString name _X_UNUSED,
1067a3bd7f05Smrg             _Xconst _XtString classname,
1068a3bd7f05Smrg             XrmOptionDescRec *options,
1069a3bd7f05Smrg             Cardinal num_options,
1070a3bd7f05Smrg             int *argc,
1071a3bd7f05Smrg             _XtString *argv)
1072444c061aSmrg{
1073444c061aSmrg    Widget root;
1074444c061aSmrg    XtAppContext app_con;
1075444c061aSmrg    register ProcessContext process = _XtGetProcessContext();
1076444c061aSmrg
1077444c061aSmrg    root = XtAppInitialize(&app_con, classname, options, num_options,
1078a3bd7f05Smrg                           argc, argv, NULL, NULL, (Cardinal) 0);
1079444c061aSmrg
1080444c061aSmrg    LOCK_PROCESS;
1081444c061aSmrg    process->defaultAppContext = app_con;
1082444c061aSmrg    UNLOCK_PROCESS;
1083444c061aSmrg    return root;
1084444c061aSmrg}
1085