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) ©); 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