1444c061aSmrg/*********************************************************** 2fdf6a26fSmrgCopyright (c) 1993, Oracle and/or its affiliates. 31477040fSmrg 41477040fSmrgPermission is hereby granted, free of charge, to any person obtaining a 51477040fSmrgcopy of this software and associated documentation files (the "Software"), 61477040fSmrgto deal in the Software without restriction, including without limitation 71477040fSmrgthe rights to use, copy, modify, merge, publish, distribute, sublicense, 81477040fSmrgand/or sell copies of the Software, and to permit persons to whom the 91477040fSmrgSoftware is furnished to do so, subject to the following conditions: 101477040fSmrg 111477040fSmrgThe above copyright notice and this permission notice (including the next 121477040fSmrgparagraph) shall be included in all copies or substantial portions of the 131477040fSmrgSoftware. 141477040fSmrg 151477040fSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 161477040fSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 171477040fSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 181477040fSmrgTHE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 191477040fSmrgLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 201477040fSmrgFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 211477040fSmrgDEALINGS IN THE SOFTWARE. 221477040fSmrg 231477040fSmrgCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. 24444c061aSmrg 25444c061aSmrg All Rights Reserved 26444c061aSmrg 27444c061aSmrgPermission to use, copy, modify, and distribute this software and its 28444c061aSmrgdocumentation for any purpose and without fee is hereby granted, 29444c061aSmrgprovided that the above copyright notice appear in all copies and that 30444c061aSmrgboth that copyright notice and this permission notice appear in 311477040fSmrgsupporting documentation, and that the name of Digital not be 32444c061aSmrgused in advertising or publicity pertaining to distribution of the 33444c061aSmrgsoftware without specific, written prior permission. 34444c061aSmrg 35444c061aSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 36444c061aSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 37444c061aSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 38444c061aSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 39444c061aSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 40444c061aSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 41444c061aSmrgSOFTWARE. 42444c061aSmrg 43444c061aSmrg******************************************************************/ 44444c061aSmrg 45444c061aSmrg/* 46444c061aSmrg 47444c061aSmrgCopyright 1987, 1988, 1994, 1998 The Open Group 48444c061aSmrg 49444c061aSmrgPermission to use, copy, modify, distribute, and sell this software and its 50444c061aSmrgdocumentation for any purpose is hereby granted without fee, provided that 51444c061aSmrgthe above copyright notice appear in all copies and that both that 52444c061aSmrgcopyright notice and this permission notice appear in supporting 53444c061aSmrgdocumentation. 54444c061aSmrg 55444c061aSmrgThe above copyright notice and this permission notice shall be included in 56444c061aSmrgall copies or substantial portions of the Software. 57444c061aSmrg 58444c061aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 59444c061aSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 60444c061aSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 61444c061aSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 62444c061aSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 63444c061aSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 64444c061aSmrg 65444c061aSmrgExcept as contained in this notice, the name of The Open Group shall not be 66444c061aSmrgused in advertising or otherwise to promote the sale, use or other dealings 67444c061aSmrgin this Software without prior written authorization from The Open Group. 68444c061aSmrg 69444c061aSmrg*/ 70444c061aSmrg 71444c061aSmrg/* Make sure all wm properties can make it out of the resource manager */ 72444c061aSmrg 73444c061aSmrg#ifdef HAVE_CONFIG_H 74444c061aSmrg#include <config.h> 75444c061aSmrg#endif 76444c061aSmrg#include "IntrinsicI.h" 77444c061aSmrg#include "StringDefs.h" 78444c061aSmrg#include "CoreP.h" 79444c061aSmrg#include "ShellP.h" 80444c061aSmrg#include <stdio.h> 81444c061aSmrg#include <X11/Xlocale.h> 82444c061aSmrg#ifdef XTHREADS 83444c061aSmrg#include <X11/Xthreads.h> 84444c061aSmrg#endif 85444c061aSmrg#ifndef WIN32 86444c061aSmrg#define X_INCLUDE_PWD_H 87444c061aSmrg#define XOS_USE_XT_LOCKING 88444c061aSmrg#include <X11/Xos_r.h> 89444c061aSmrg#endif 90444c061aSmrg 91444c061aSmrg#include <stdlib.h> 92444c061aSmrg 93444c061aSmrg/* some unspecified magic number of expected search levels for Xrm */ 94444c061aSmrg#define SEARCH_LIST_SIZE 1000 95444c061aSmrg 96444c061aSmrg/* 97444c061aSmrg This is a set of default records describing the command line arguments that 98444c061aSmrg Xlib will parse and set into the resource data base. 99444c061aSmrg 100444c061aSmrg This list is applied before the users list to enforce these defaults. This is 101444c061aSmrg policy, which the toolkit avoids but I hate differing programs at this level. 102444c061aSmrg*/ 103444c061aSmrg 104a3bd7f05Smrg/* *INDENT-OFF* */ 105444c061aSmrgstatic XrmOptionDescRec const opTable[] = { 106a3bd7f05Smrg{"+rv", "*reverseVideo", XrmoptionNoArg, (XtPointer) "off"}, 107a3bd7f05Smrg{"+synchronous", "*synchronous", XrmoptionNoArg, (XtPointer) "off"}, 108a3bd7f05Smrg{"-background", "*background", XrmoptionSepArg, (XtPointer) NULL}, 109a3bd7f05Smrg{"-bd", "*borderColor", XrmoptionSepArg, (XtPointer) NULL}, 110a3bd7f05Smrg{"-bg", "*background", XrmoptionSepArg, (XtPointer) NULL}, 111a3bd7f05Smrg{"-bordercolor", "*borderColor", XrmoptionSepArg, (XtPointer) NULL}, 112a3bd7f05Smrg{"-borderwidth", ".borderWidth", XrmoptionSepArg, (XtPointer) NULL}, 113a3bd7f05Smrg{"-bw", ".borderWidth", XrmoptionSepArg, (XtPointer) NULL}, 114a3bd7f05Smrg{"-display", ".display", XrmoptionSepArg, (XtPointer) NULL}, 115a3bd7f05Smrg{"-fg", "*foreground", XrmoptionSepArg, (XtPointer) NULL}, 116a3bd7f05Smrg{"-fn", "*font", XrmoptionSepArg, (XtPointer) NULL}, 117a3bd7f05Smrg{"-font", "*font", XrmoptionSepArg, (XtPointer) NULL}, 118a3bd7f05Smrg{"-foreground", "*foreground", XrmoptionSepArg, (XtPointer) NULL}, 119a3bd7f05Smrg{"-geometry", ".geometry", XrmoptionSepArg, (XtPointer) NULL}, 120a3bd7f05Smrg{"-iconic", ".iconic", XrmoptionNoArg, (XtPointer) "on"}, 121a3bd7f05Smrg{"-name", ".name", XrmoptionSepArg, (XtPointer) NULL}, 122a3bd7f05Smrg{"-reverse", "*reverseVideo", XrmoptionNoArg, (XtPointer) "on"}, 123a3bd7f05Smrg{"-rv", "*reverseVideo", XrmoptionNoArg, (XtPointer) "on"}, 124a3bd7f05Smrg{"-selectionTimeout", ".selectionTimeout", XrmoptionSepArg, (XtPointer) NULL}, 125a3bd7f05Smrg{"-synchronous", "*synchronous", XrmoptionNoArg, (XtPointer) "on"}, 126a3bd7f05Smrg{"-title", ".title", XrmoptionSepArg, (XtPointer) NULL}, 127a3bd7f05Smrg{"-xnllanguage", ".xnlLanguage", XrmoptionSepArg, (XtPointer) NULL}, 128a3bd7f05Smrg{"-xrm", NULL, XrmoptionResArg, (XtPointer) NULL}, 129a3bd7f05Smrg{"-xtsessionID", ".sessionID", XrmoptionSepArg, (XtPointer) NULL}, 130444c061aSmrg}; 131a3bd7f05Smrg/* *INDENT-ON* */ 132444c061aSmrg 133444c061aSmrg/* 134444c061aSmrg * GetHostname - emulates gethostname() on non-bsd systems. 135444c061aSmrg */ 136444c061aSmrg 137a3bd7f05Smrgstatic void 138a3bd7f05SmrgGetHostname(char *buf, int maxlen) 139444c061aSmrg{ 140444c061aSmrg if (maxlen <= 0 || buf == NULL) 141a3bd7f05Smrg return; 142444c061aSmrg 143444c061aSmrg buf[0] = '\0'; 144a3bd7f05Smrg (void) gethostname(buf, (size_t) maxlen); 145a3bd7f05Smrg buf[maxlen - 1] = '\0'; 146444c061aSmrg} 147444c061aSmrg 148444c061aSmrg 1492265a131Smrg#if defined (WIN32) || defined(__CYGWIN__) 150444c061aSmrg/* 151444c061aSmrg * The Symbol _XtInherit is used in two different manners. 152444c061aSmrg * First it could be used as a generic function and second 153444c061aSmrg * as an absolute address reference, which will be used to 154444c061aSmrg * check the initialisation process of several other libraries. 155fdf6a26fSmrg * Because of this the symbol must be accessible by all 156444c061aSmrg * client dll's and applications. In unix environments 157444c061aSmrg * this is no problem, because the used shared libraries 158fdf6a26fSmrg * format (elf) supports this immediately. Under Windows 159444c061aSmrg * this isn't true, because a functions address in a dll 160444c061aSmrg * is different from the same function in another dll or 161444c061aSmrg * applications, because the used Portable Executable 162444c061aSmrg * File adds a code stub to each client to provide the 163444c061aSmrg * exported symbol name. This stub uses an indirect 164444c061aSmrg * pointer to get the original symbol address, which is 165444c061aSmrg * then jumped to, like in this example: 166444c061aSmrg * 167444c061aSmrg * --- client --- --- dll ---- 168444c061aSmrg * ... 169444c061aSmrg * call foo 170444c061aSmrg * 171444c061aSmrg * foo: jmp (*_imp_foo) ----> foo: .... 172444c061aSmrg * nop 173444c061aSmrg * nop 174444c061aSmrg * 175444c061aSmrg * _imp_foo: .long <index of foo in dll export table, is 176a3bd7f05Smrg * set to the real address by the runtime linker> 177444c061aSmrg * 178444c061aSmrg * Now it is clear why the clients symbol foo isn't the same 179444c061aSmrg * as in the dll and we can think about how to deal which 180444c061aSmrg * this two above mentioned requirements, to export this 181444c061aSmrg * symbol to all clients and to allow calling this symbol 182444c061aSmrg * as a function. The solution I've used exports the 183444c061aSmrg * symbol _XtInherit as data symbol, because global data 184444c061aSmrg * symbols are exported to all clients. But how to deal 185444c061aSmrg * with the second requirement, that this symbol should 186444c061aSmrg * be used as function. The Trick is to build a little 187444c061aSmrg * code stub in the data section in the exact manner as 188444c061aSmrg * above explained. This is done with the assembler code 189444c061aSmrg * below. 190444c061aSmrg * 191444c061aSmrg * Ralf Habacker 192444c061aSmrg * 193444c061aSmrg * References: 194444c061aSmrg * msdn http://msdn.microsoft.com/msdnmag/issues/02/02/PE/PE.asp 195444c061aSmrg * cygwin-xfree: http://www.cygwin.com/ml/cygwin-xfree/2003-10/msg00000.html 196444c061aSmrg */ 197444c061aSmrg 198339a7c43Smrg#ifdef __x86_64__ 199a3bd7f05Smrgasm(".section .trampoline, \"dwx\" \n\ 200339a7c43Smrg .globl _XtInherit \n\ 201339a7c43Smrg _XtInherit: \n\ 202339a7c43Smrg jmp *_y(%rip) \n\ 203339a7c43Smrg_y: .quad __XtInherit \n\ 204339a7c43Smrg .text \n"); 205339a7c43Smrg#else 206a3bd7f05Smrgasm(".data\n\ 207444c061aSmrg .globl __XtInherit \n\ 208444c061aSmrg __XtInherit: jmp *_y \n\ 209444c061aSmrg _y: .long ___XtInherit \n\ 210444c061aSmrg .text \n"); 211339a7c43Smrg#endif 212444c061aSmrg 213444c061aSmrg#define _XtInherit __XtInherit 214444c061aSmrg#endif 215444c061aSmrg 216a3bd7f05Smrgvoid 217a3bd7f05Smrg_XtInherit(void) 218444c061aSmrg{ 219a3bd7f05Smrg XtErrorMsg("invalidProcedure", "inheritanceProc", XtCXtToolkitError, 220a3bd7f05Smrg "Unresolved inheritance operation", NULL, NULL); 221444c061aSmrg} 222444c061aSmrg 223a3bd7f05Smrgvoid 224a3bd7f05SmrgXtToolkitInitialize(void) 225444c061aSmrg{ 226444c061aSmrg static Boolean initialized = False; 227444c061aSmrg 228444c061aSmrg LOCK_PROCESS; 229444c061aSmrg if (initialized) { 230a3bd7f05Smrg UNLOCK_PROCESS; 231a3bd7f05Smrg return; 232444c061aSmrg } 233444c061aSmrg initialized = True; 234444c061aSmrg UNLOCK_PROCESS; 235444c061aSmrg /* Resource management initialization */ 236444c061aSmrg XrmInitialize(); 237444c061aSmrg _XtResourceListInitialize(); 238444c061aSmrg 239fdf6a26fSmrg /* Other intrinsic initialization */ 240444c061aSmrg _XtConvertInitialize(); 241444c061aSmrg _XtEventInitialize(); 242444c061aSmrg _XtTranslateInitialize(); 243444c061aSmrg 244444c061aSmrg /* Some apps rely on old (broken) XtAppPeekEvent behavior */ 245a3bd7f05Smrg if (getenv("XTAPPPEEKEVENT_SKIPTIMER")) 246a3bd7f05Smrg XtAppPeekEvent_SkipTimer = True; 247444c061aSmrg else 248a3bd7f05Smrg XtAppPeekEvent_SkipTimer = False; 249444c061aSmrg} 250444c061aSmrg 251a3bd7f05SmrgString 252a3bd7f05Smrg_XtGetUserName(_XtString dest, int len) 253444c061aSmrg{ 254444c061aSmrg#ifdef WIN32 255444c061aSmrg String ptr = NULL; 256444c061aSmrg 257444c061aSmrg if ((ptr = getenv("USERNAME"))) { 258a3bd7f05Smrg (void) strncpy(dest, ptr, len - 1); 259a3bd7f05Smrg dest[len - 1] = '\0'; 260a3bd7f05Smrg } 261a3bd7f05Smrg else 262a3bd7f05Smrg *dest = '\0'; 263444c061aSmrg#else 264444c061aSmrg#ifdef X_NEEDS_PWPARAMS 265444c061aSmrg _Xgetpwparams pwparams; 266444c061aSmrg#endif 267444c061aSmrg struct passwd *pw; 268a3bd7f05Smrg char *ptr; 269444c061aSmrg 270444c061aSmrg if ((ptr = getenv("USER"))) { 271a3bd7f05Smrg (void) strncpy(dest, ptr, (size_t) (len - 1)); 272a3bd7f05Smrg dest[len - 1] = '\0'; 273a3bd7f05Smrg } 274a3bd7f05Smrg else { 275a3bd7f05Smrg if ((pw = _XGetpwuid(getuid(), pwparams)) != NULL) { 276a3bd7f05Smrg (void) strncpy(dest, pw->pw_name, (size_t) (len - 1)); 277a3bd7f05Smrg dest[len - 1] = '\0'; 278a3bd7f05Smrg } 279a3bd7f05Smrg else 280a3bd7f05Smrg *dest = '\0'; 281444c061aSmrg } 282444c061aSmrg#endif 283444c061aSmrg return dest; 284444c061aSmrg} 285444c061aSmrg 286a3bd7f05Smrgstatic String 287a3bd7f05SmrgGetRootDirName(_XtString dest, int len) 288444c061aSmrg{ 289444c061aSmrg#ifdef WIN32 290444c061aSmrg register char *ptr1; 291444c061aSmrg register char *ptr2 = NULL; 292444c061aSmrg int len1 = 0, len2 = 0; 293444c061aSmrg 294a3bd7f05Smrg if (ptr1 = getenv("HOME")) { /* old, deprecated */ 295a3bd7f05Smrg len1 = strlen(ptr1); 296a3bd7f05Smrg } 297a3bd7f05Smrg else if ((ptr1 = getenv("HOMEDRIVE")) && (ptr2 = getenv("HOMEDIR"))) { 298a3bd7f05Smrg len1 = strlen(ptr1); 299a3bd7f05Smrg len2 = strlen(ptr2); 300a3bd7f05Smrg } 301a3bd7f05Smrg else if (ptr2 = getenv("USERNAME")) { 302a3bd7f05Smrg len1 = strlen(ptr1 = "/users/"); 303a3bd7f05Smrg len2 = strlen(ptr2); 304444c061aSmrg } 305444c061aSmrg if ((len1 + len2 + 1) < len) 306a3bd7f05Smrg sprintf(dest, "%s%s", ptr1, (ptr2) ? ptr2 : ""); 307444c061aSmrg else 308a3bd7f05Smrg *dest = '\0'; 309444c061aSmrg#else 310444c061aSmrg#ifdef X_NEEDS_PWPARAMS 311444c061aSmrg _Xgetpwparams pwparams; 312444c061aSmrg#endif 313444c061aSmrg static char *ptr; 314444c061aSmrg 315444c061aSmrg if (len <= 0 || dest == NULL) 316a3bd7f05Smrg return NULL; 317444c061aSmrg 318444c061aSmrg if ((ptr = getenv("HOME"))) { 319a3bd7f05Smrg (void) strncpy(dest, ptr, (size_t) (len - 1)); 320a3bd7f05Smrg dest[len - 1] = '\0'; 321a3bd7f05Smrg } 322a3bd7f05Smrg else { 3230568f49bSmrg struct passwd *pw; 324a3bd7f05Smrg 325a3bd7f05Smrg if ((ptr = getenv("USER"))) 326a3bd7f05Smrg pw = _XGetpwnam(ptr, pwparams); 327a3bd7f05Smrg else 328a3bd7f05Smrg pw = _XGetpwuid(getuid(), pwparams); 329a3bd7f05Smrg if (pw != NULL) { 330a3bd7f05Smrg (void) strncpy(dest, pw->pw_dir, (size_t) (len - 1)); 331a3bd7f05Smrg dest[len - 1] = '\0'; 332a3bd7f05Smrg } 333a3bd7f05Smrg else 334a3bd7f05Smrg *dest = '\0'; 335444c061aSmrg } 336444c061aSmrg#endif 337444c061aSmrg return dest; 338444c061aSmrg} 339444c061aSmrg 340a3bd7f05Smrgstatic void 341a3bd7f05SmrgCombineAppUserDefaults(Display *dpy, XrmDatabase *pdb) 342444c061aSmrg{ 343a3bd7f05Smrg char *filename; 344a3bd7f05Smrg char *path = NULL; 345444c061aSmrg Boolean deallocate = False; 346444c061aSmrg 347444c061aSmrg if (!(path = getenv("XUSERFILESEARCHPATH"))) { 3482265a131Smrg#if !defined(WIN32) || !defined(__MINGW32__) 349a3bd7f05Smrg char *old_path; 350a3bd7f05Smrg char homedir[PATH_MAX]; 351a3bd7f05Smrg 352a3bd7f05Smrg GetRootDirName(homedir, PATH_MAX); 353a3bd7f05Smrg if (!(old_path = getenv("XAPPLRESDIR"))) { 354a3bd7f05Smrg XtAsprintf(&path, 355a3bd7f05Smrg "%s/%%L/%%N%%C:%s/%%l/%%N%%C:%s/%%N%%C:%s/%%L/%%N:%s/%%l/%%N:%s/%%N", 356a3bd7f05Smrg homedir, homedir, homedir, homedir, homedir, homedir); 357a3bd7f05Smrg } 358a3bd7f05Smrg else { 359a3bd7f05Smrg XtAsprintf(&path, 360a3bd7f05Smrg "%s/%%L/%%N%%C:%s/%%l/%%N%%C:%s/%%N%%C:%s/%%N%%C:%s/%%L/%%N:%s/%%l/%%N:%s/%%N:%s/%%N", 361a3bd7f05Smrg old_path, old_path, old_path, homedir, 362a3bd7f05Smrg old_path, old_path, old_path, homedir); 363a3bd7f05Smrg } 364a3bd7f05Smrg deallocate = True; 3652265a131Smrg#endif 366444c061aSmrg } 367444c061aSmrg 368444c061aSmrg filename = XtResolvePathname(dpy, NULL, NULL, NULL, path, NULL, 0, NULL); 369444c061aSmrg if (filename) { 370a3bd7f05Smrg (void) XrmCombineFileDatabase(filename, pdb, False); 371a3bd7f05Smrg XtFree(filename); 372444c061aSmrg } 373444c061aSmrg 374bdf0f55dSmrg if (deallocate) 375a3bd7f05Smrg XtFree(path); 376444c061aSmrg} 377444c061aSmrg 378a3bd7f05Smrgstatic void 379a3bd7f05SmrgCombineUserDefaults(Display *dpy, XrmDatabase *pdb) 380444c061aSmrg{ 381444c061aSmrg char *dpy_defaults = XResourceManagerString(dpy); 382444c061aSmrg 383444c061aSmrg if (dpy_defaults) { 384a3bd7f05Smrg XrmCombineDatabase(XrmGetStringDatabase(dpy_defaults), pdb, False); 385a3bd7f05Smrg } 386a3bd7f05Smrg else { 3870568f49bSmrg#ifdef __MINGW32__ 388a3bd7f05Smrg const char *slashDotXdefaults = "/Xdefaults"; 3890568f49bSmrg#else 390a3bd7f05Smrg const char *slashDotXdefaults = "/.Xdefaults"; 3910568f49bSmrg#endif 392a3bd7f05Smrg char filename[PATH_MAX]; 393a3bd7f05Smrg 394a3bd7f05Smrg (void) GetRootDirName(filename, 395a3bd7f05Smrg PATH_MAX - (int) strlen(slashDotXdefaults) - 1); 396a3bd7f05Smrg (void) strcat(filename, slashDotXdefaults); 397a3bd7f05Smrg (void) XrmCombineFileDatabase(filename, pdb, False); 398444c061aSmrg } 399444c061aSmrg} 400444c061aSmrg 401a3bd7f05Smrgstatic Bool 402a3bd7f05SmrgStoreDBEntry(XrmDatabase *db _X_UNUSED, 403a3bd7f05Smrg XrmBindingList bindings, 404a3bd7f05Smrg XrmQuarkList quarks, 405a3bd7f05Smrg XrmRepresentation *type, 406a3bd7f05Smrg XrmValuePtr value, 407a3bd7f05Smrg XPointer data) 408444c061aSmrg{ 409a3bd7f05Smrg XrmQPutResource((XrmDatabase *) data, bindings, quarks, *type, value); 410444c061aSmrg return False; 411444c061aSmrg} 412444c061aSmrg 413a3bd7f05Smrgstatic XrmDatabase 414a3bd7f05SmrgCopyDB(XrmDatabase db) 415444c061aSmrg{ 416444c061aSmrg XrmDatabase copy = NULL; 417444c061aSmrg XrmQuark empty = NULLQUARK; 418444c061aSmrg 419444c061aSmrg XrmEnumerateDatabase(db, &empty, &empty, XrmEnumAllLevels, 420a3bd7f05Smrg StoreDBEntry, (XPointer) ©); 421444c061aSmrg return copy; 422444c061aSmrg} 423444c061aSmrg 424a3bd7f05Smrgstatic String 425a3bd7f05Smrg_XtDefaultLanguageProc(Display *dpy _X_UNUSED, 426a3bd7f05Smrg String xnl, 427a3bd7f05Smrg XtPointer closure _X_UNUSED) 428444c061aSmrg{ 429a3bd7f05Smrg if (!setlocale(LC_ALL, xnl)) 430a3bd7f05Smrg XtWarning("locale not supported by C library, locale unchanged"); 431444c061aSmrg 432a3bd7f05Smrg if (!XSupportsLocale()) { 433a3bd7f05Smrg XtWarning("locale not supported by Xlib, locale set to C"); 434a3bd7f05Smrg setlocale(LC_ALL, "C"); 435444c061aSmrg } 436a3bd7f05Smrg if (!XSetLocaleModifiers("")) 437a3bd7f05Smrg XtWarning("X locale modifiers not supported, using default"); 438444c061aSmrg 439a3bd7f05Smrg return setlocale(LC_ALL, NULL); /* re-query in case overwritten */ 440444c061aSmrg} 441444c061aSmrg 442a3bd7f05SmrgXtLanguageProc 443a3bd7f05SmrgXtSetLanguageProc(XtAppContext app, XtLanguageProc proc, XtPointer closure) 444444c061aSmrg{ 445a3bd7f05Smrg XtLanguageProc old; 446444c061aSmrg 447444c061aSmrg if (!proc) { 448a3bd7f05Smrg proc = _XtDefaultLanguageProc; 449a3bd7f05Smrg closure = NULL; 450444c061aSmrg } 451444c061aSmrg 452444c061aSmrg if (app) { 453a3bd7f05Smrg LOCK_APP(app); 454a3bd7f05Smrg LOCK_PROCESS; 455a3bd7f05Smrg /* set langProcRec only for this application context */ 456444c061aSmrg old = app->langProcRec.proc; 457444c061aSmrg app->langProcRec.proc = proc; 458444c061aSmrg app->langProcRec.closure = closure; 459a3bd7f05Smrg UNLOCK_PROCESS; 460a3bd7f05Smrg UNLOCK_APP(app); 461a3bd7f05Smrg } 462a3bd7f05Smrg else { 463a3bd7f05Smrg /* set langProcRec for all application contexts */ 464444c061aSmrg ProcessContext process; 465444c061aSmrg 466a3bd7f05Smrg LOCK_PROCESS; 467444c061aSmrg process = _XtGetProcessContext(); 468444c061aSmrg old = process->globalLangProcRec.proc; 469a3bd7f05Smrg process->globalLangProcRec.proc = proc; 470a3bd7f05Smrg process->globalLangProcRec.closure = closure; 471444c061aSmrg app = process->appContextList; 472444c061aSmrg while (app) { 473444c061aSmrg app->langProcRec.proc = proc; 474444c061aSmrg app->langProcRec.closure = closure; 475a3bd7f05Smrg app = app->next; 476444c061aSmrg } 477a3bd7f05Smrg UNLOCK_PROCESS; 478444c061aSmrg } 479444c061aSmrg return (old ? old : _XtDefaultLanguageProc); 480444c061aSmrg} 481444c061aSmrg 482a3bd7f05SmrgXrmDatabase 483a3bd7f05SmrgXtScreenDatabase(Screen *screen) 484444c061aSmrg{ 485444c061aSmrg int scrno; 486444c061aSmrg Bool doing_def; 487444c061aSmrg XrmDatabase db, olddb; 488444c061aSmrg XtPerDisplay pd; 489444c061aSmrg Status do_fallback; 490444c061aSmrg char *scr_resources; 491444c061aSmrg Display *dpy = DisplayOfScreen(screen); 492a3bd7f05Smrg 493444c061aSmrg DPY_TO_APPCON(dpy); 494a3bd7f05Smrg if (dpy == NULL) { 495a3bd7f05Smrg XtErrorMsg("nullDisplay", 496a3bd7f05Smrg "XtScreenDatabase", XtCXtToolkitError, 497a3bd7f05Smrg "XtScreenDatabase requires a non-NULL display", 498a3bd7f05Smrg NULL, NULL); 499a3bd7f05Smrg } 500444c061aSmrg 501444c061aSmrg LOCK_APP(app); 502444c061aSmrg LOCK_PROCESS; 503444c061aSmrg if (screen == DefaultScreenOfDisplay(dpy)) { 504a3bd7f05Smrg scrno = DefaultScreen(dpy); 505a3bd7f05Smrg doing_def = True; 506a3bd7f05Smrg } 507a3bd7f05Smrg else { 508a3bd7f05Smrg scrno = XScreenNumberOfScreen(screen); 509a3bd7f05Smrg doing_def = False; 510444c061aSmrg } 511444c061aSmrg pd = _XtGetPerDisplay(dpy); 512444c061aSmrg if ((db = pd->per_screen_db[scrno])) { 513a3bd7f05Smrg UNLOCK_PROCESS; 514a3bd7f05Smrg UNLOCK_APP(app); 515a3bd7f05Smrg return (doing_def ? XrmGetDatabase(dpy) : db); 516444c061aSmrg } 517444c061aSmrg scr_resources = XScreenResourceString(screen); 518444c061aSmrg 519444c061aSmrg if (ScreenCount(dpy) == 1) { 520a3bd7f05Smrg db = pd->cmd_db; 521a3bd7f05Smrg pd->cmd_db = NULL; 522a3bd7f05Smrg } 523a3bd7f05Smrg else { 524a3bd7f05Smrg db = CopyDB(pd->cmd_db); 525444c061aSmrg } 526a3bd7f05Smrg { /* Environment defaults */ 527a3bd7f05Smrg char filenamebuf[PATH_MAX]; 528a3bd7f05Smrg char *filename; 529a3bd7f05Smrg 530a3bd7f05Smrg if (!(filename = getenv("XENVIRONMENT"))) { 531a3bd7f05Smrg int len; 532444c061aSmrg 5332265a131Smrg#ifdef __MINGW32__ 534a3bd7f05Smrg const char *slashDotXdefaultsDash = "/Xdefaults-"; 5352265a131Smrg#else 536a3bd7f05Smrg const char *slashDotXdefaultsDash = "/.Xdefaults-"; 5372265a131Smrg#endif 538444c061aSmrg 539a3bd7f05Smrg (void) GetRootDirName(filename = filenamebuf, 540a3bd7f05Smrg PATH_MAX - 541a3bd7f05Smrg (int) strlen(slashDotXdefaultsDash) - 1); 542a3bd7f05Smrg (void) strcat(filename, slashDotXdefaultsDash); 543a3bd7f05Smrg len = (int) strlen(filename); 544a3bd7f05Smrg GetHostname(filename + len, PATH_MAX - len); 545a3bd7f05Smrg } 546a3bd7f05Smrg (void) XrmCombineFileDatabase(filename, &db, False); 547444c061aSmrg } 548a3bd7f05Smrg if (scr_resources) { /* Screen defaults */ 549a3bd7f05Smrg XrmCombineDatabase(XrmGetStringDatabase(scr_resources), &db, False); 550a3bd7f05Smrg XFree(scr_resources); 551444c061aSmrg } 552444c061aSmrg /* Server or host defaults */ 553444c061aSmrg if (!pd->server_db) 554a3bd7f05Smrg CombineUserDefaults(dpy, &db); 555444c061aSmrg else { 556a3bd7f05Smrg (void) XrmCombineDatabase(pd->server_db, &db, False); 557a3bd7f05Smrg pd->server_db = NULL; 558444c061aSmrg } 559444c061aSmrg 560444c061aSmrg if (!db) 561a3bd7f05Smrg db = XrmGetStringDatabase(""); 562444c061aSmrg pd->per_screen_db[scrno] = db; 563444c061aSmrg olddb = XrmGetDatabase(dpy); 564444c061aSmrg /* set database now, for XtResolvePathname to use */ 565444c061aSmrg XrmSetDatabase(dpy, db); 566444c061aSmrg CombineAppUserDefaults(dpy, &db); 567444c061aSmrg do_fallback = 1; 568a3bd7f05Smrg { /* System app-defaults */ 569a3bd7f05Smrg char *filename; 570a3bd7f05Smrg 571a3bd7f05Smrg if ((filename = XtResolvePathname(dpy, "app-defaults", 572a3bd7f05Smrg NULL, NULL, NULL, NULL, 0, NULL))) { 573a3bd7f05Smrg do_fallback = !XrmCombineFileDatabase(filename, &db, False); 574a3bd7f05Smrg XtFree(filename); 575a3bd7f05Smrg } 576444c061aSmrg } 577444c061aSmrg /* now restore old database, if need be */ 578444c061aSmrg if (!doing_def) 579a3bd7f05Smrg XrmSetDatabase(dpy, olddb); 580a3bd7f05Smrg if (do_fallback && pd->appContext->fallback_resources) { /* Fallback defaults */ 581444c061aSmrg XrmDatabase fdb = NULL; 582a3bd7f05Smrg String *res; 583444c061aSmrg 584a3bd7f05Smrg for (res = pd->appContext->fallback_resources; *res; res++) 585a3bd7f05Smrg XrmPutLineResource(&fdb, *res); 586a3bd7f05Smrg (void) XrmCombineDatabase(fdb, &db, False); 587444c061aSmrg } 588444c061aSmrg UNLOCK_PROCESS; 589444c061aSmrg UNLOCK_APP(app); 590444c061aSmrg return db; 591444c061aSmrg} 592444c061aSmrg 593444c061aSmrg/* 594444c061aSmrg * Merge two option tables, allowing the second to over-ride the first, 595444c061aSmrg * so that ambiguous abbreviations can be noticed. The merge attempts 596444c061aSmrg * to make the resulting table lexicographically sorted, but succeeds 597444c061aSmrg * only if the first source table is sorted. Though it _is_ recommended 598444c061aSmrg * (for optimizations later in XrmParseCommand), it is not required 599444c061aSmrg * that either source table be sorted. 600444c061aSmrg * 601444c061aSmrg * Caller is responsible for freeing the returned option table. 602444c061aSmrg */ 603444c061aSmrg 604a3bd7f05Smrgstatic void 605a3bd7f05Smrg_MergeOptionTables(const XrmOptionDescRec *src1, 606a3bd7f05Smrg Cardinal num_src1, 607a3bd7f05Smrg const XrmOptionDescRec *src2, 608a3bd7f05Smrg Cardinal num_src2, 609a3bd7f05Smrg XrmOptionDescRec **dst, 610a3bd7f05Smrg Cardinal *num_dst) 611444c061aSmrg{ 612444c061aSmrg XrmOptionDescRec *table, *endP; 6130568f49bSmrg XrmOptionDescRec *opt1, *dstP; 6140568f49bSmrg const XrmOptionDescRec *opt2; 615444c061aSmrg int i1; 616444c061aSmrg Cardinal i2; 617444c061aSmrg int dst_len, order; 618a3bd7f05Smrg enum { Check, NotSorted, IsSorted } sort_order = Check; 619444c061aSmrg 620fdf6a26fSmrg *dst = table = XtMallocArray(num_src1 + num_src2, 621fdf6a26fSmrg (Cardinal) sizeof(XrmOptionDescRec)); 622444c061aSmrg 623fdf6a26fSmrg (void) memcpy(table, src1, sizeof(XrmOptionDescRec) * num_src1); 624444c061aSmrg if (num_src2 == 0) { 625a3bd7f05Smrg *num_dst = num_src1; 626a3bd7f05Smrg return; 627444c061aSmrg } 628a3bd7f05Smrg endP = &table[dst_len = (int) num_src1]; 629a3bd7f05Smrg for (opt2 = src2, i2 = 0; i2 < num_src2; opt2++, i2++) { 6300568f49bSmrg XrmOptionDescRec *whereP; 6310568f49bSmrg Boolean found; 6320568f49bSmrg 633a3bd7f05Smrg found = False; 634a3bd7f05Smrg whereP = endP - 1; /* assume new option goes at the end */ 635a3bd7f05Smrg for (opt1 = table, i1 = 0; i1 < dst_len; opt1++, i1++) { 636a3bd7f05Smrg /* have to walk the entire new table so new list is ordered 637a3bd7f05Smrg (if src1 was ordered) */ 638a3bd7f05Smrg if (sort_order == Check && i1 > 0 639a3bd7f05Smrg && strcmp(opt1->option, (opt1 - 1)->option) < 0) 640a3bd7f05Smrg sort_order = NotSorted; 641a3bd7f05Smrg if ((order = strcmp(opt1->option, opt2->option)) == 0) { 642a3bd7f05Smrg /* same option names; just overwrite opt1 with opt2 */ 643a3bd7f05Smrg *opt1 = *opt2; 644a3bd7f05Smrg found = True; 645a3bd7f05Smrg break; 646a3bd7f05Smrg } 647a3bd7f05Smrg /* else */ 648a3bd7f05Smrg if (sort_order == IsSorted && order > 0) { 649a3bd7f05Smrg /* insert before opt1 to preserve order */ 650a3bd7f05Smrg /* shift rest of table forward to make room for new entry */ 651a3bd7f05Smrg for (dstP = endP++; dstP > opt1; dstP--) 652a3bd7f05Smrg *dstP = *(dstP - 1); 653a3bd7f05Smrg *opt1 = *opt2; 654a3bd7f05Smrg dst_len++; 655a3bd7f05Smrg found = True; 656a3bd7f05Smrg break; 657a3bd7f05Smrg } 658a3bd7f05Smrg /* else */ 659a3bd7f05Smrg if (order < 0) 660a3bd7f05Smrg /* opt2 sorts after opt1, so remember this position */ 661a3bd7f05Smrg whereP = opt1; 662a3bd7f05Smrg } 663a3bd7f05Smrg if (sort_order == Check && i1 == dst_len) 664a3bd7f05Smrg sort_order = IsSorted; 665a3bd7f05Smrg if (!found) { 666a3bd7f05Smrg /* when we get here, whereP points to the last entry in the 667a3bd7f05Smrg destination that sorts before "opt2". Shift rest of table 668a3bd7f05Smrg forward and insert "opt2" after whereP. */ 669a3bd7f05Smrg whereP++; 670a3bd7f05Smrg for (dstP = endP++; dstP > whereP; dstP--) 671a3bd7f05Smrg *dstP = *(dstP - 1); 672a3bd7f05Smrg *whereP = *opt2; 673a3bd7f05Smrg dst_len++; 674a3bd7f05Smrg } 675444c061aSmrg } 676a3bd7f05Smrg *num_dst = (Cardinal) dst_len; 677444c061aSmrg} 678444c061aSmrg 679444c061aSmrg/* NOTE: name, class, and type must be permanent strings */ 680a3bd7f05Smrgstatic Boolean 681a3bd7f05Smrg_GetResource(Display *dpy, 682a3bd7f05Smrg XrmSearchList list, 683a3bd7f05Smrg String name, 684a3bd7f05Smrg String class, 685a3bd7f05Smrg String type, 686a3bd7f05Smrg XrmValue *value) 687444c061aSmrg{ 688444c061aSmrg XrmRepresentation db_type; 689444c061aSmrg XrmValue db_value; 690444c061aSmrg XrmName Qname = XrmPermStringToQuark(name); 691444c061aSmrg XrmClass Qclass = XrmPermStringToQuark(class); 692444c061aSmrg XrmRepresentation Qtype = XrmPermStringToQuark(type); 693444c061aSmrg 694444c061aSmrg if (XrmQGetSearchResource(list, Qname, Qclass, &db_type, &db_value)) { 695a3bd7f05Smrg if (db_type == Qtype) { 696a3bd7f05Smrg if (Qtype == _XtQString) 697a3bd7f05Smrg *(String *) value->addr = db_value.addr; 698a3bd7f05Smrg else 699fdf6a26fSmrg (void) memcpy(value->addr, db_value.addr, value->size); 700a3bd7f05Smrg return True; 701a3bd7f05Smrg } 702a3bd7f05Smrg else { 703a3bd7f05Smrg WidgetRec widget; /* hack, hack */ 704a3bd7f05Smrg 705a3bd7f05Smrg memset(&widget, 0, sizeof(widget)); 706a3bd7f05Smrg widget.core.self = &widget; 707a3bd7f05Smrg widget.core.widget_class = coreWidgetClass; 708a3bd7f05Smrg widget.core.screen = (Screen *) DefaultScreenOfDisplay(dpy); 709a3bd7f05Smrg XtInitializeWidgetClass(coreWidgetClass); 710a3bd7f05Smrg if (_XtConvert(&widget, db_type, &db_value, Qtype, value, NULL)) { 711a3bd7f05Smrg return True; 712a3bd7f05Smrg } 713a3bd7f05Smrg } 714444c061aSmrg } 715444c061aSmrg return False; 716444c061aSmrg} 717444c061aSmrg 718a3bd7f05SmrgXrmDatabase 719a3bd7f05Smrg_XtPreparseCommandLine(XrmOptionDescRec *urlist, 720a3bd7f05Smrg Cardinal num_urs, 721a3bd7f05Smrg int argc, 722a3bd7f05Smrg _XtString *argv, /* return */ 723a3bd7f05Smrg String *applName, 724a3bd7f05Smrg String *displayName, 725a3bd7f05Smrg String *language) 726444c061aSmrg{ 7272265a131Smrg XrmDatabase db = NULL; 728444c061aSmrg XrmOptionDescRec *options; 729444c061aSmrg Cardinal num_options; 730444c061aSmrg XrmName name_list[3]; 731444c061aSmrg XrmName class_list[3]; 732444c061aSmrg XrmRepresentation type; 733444c061aSmrg XrmValue val; 7340568f49bSmrg _XtString *targv; 735444c061aSmrg int targc = argc; 736444c061aSmrg 737fdf6a26fSmrg targv = XtMallocArray((Cardinal) argc, (Cardinal) sizeof(_XtString *)); 738fdf6a26fSmrg (void) memcpy(targv, argv, sizeof(char *) * (size_t) argc); 739444c061aSmrg _MergeOptionTables(opTable, XtNumber(opTable), urlist, num_urs, 740a3bd7f05Smrg &options, &num_options); 741444c061aSmrg name_list[0] = class_list[0] = XrmPermStringToQuark("."); 742444c061aSmrg name_list[2] = class_list[2] = NULLQUARK; 7430568f49bSmrg XrmParseCommand(&db, options, (int) num_options, ".", &targc, targv); 744444c061aSmrg if (applName) { 745a3bd7f05Smrg name_list[1] = XrmPermStringToQuark("name"); 746a3bd7f05Smrg if (XrmQGetResource(db, name_list, name_list, &type, &val) && 747a3bd7f05Smrg type == _XtQString) 748a3bd7f05Smrg *applName = val.addr; 749444c061aSmrg } 750444c061aSmrg if (displayName) { 751a3bd7f05Smrg name_list[1] = XrmPermStringToQuark("display"); 752a3bd7f05Smrg if (XrmQGetResource(db, name_list, name_list, &type, &val) && 753a3bd7f05Smrg type == _XtQString) 754a3bd7f05Smrg *displayName = val.addr; 755444c061aSmrg } 756444c061aSmrg if (language) { 757a3bd7f05Smrg name_list[1] = XrmPermStringToQuark("xnlLanguage"); 758a3bd7f05Smrg class_list[1] = XrmPermStringToQuark("XnlLanguage"); 759a3bd7f05Smrg if (XrmQGetResource(db, name_list, class_list, &type, &val) && 760a3bd7f05Smrg type == _XtQString) 761a3bd7f05Smrg *language = val.addr; 762444c061aSmrg } 763444c061aSmrg 764a3bd7f05Smrg XtFree((char *) targv); 765a3bd7f05Smrg XtFree((char *) options); 766444c061aSmrg return db; 767444c061aSmrg} 768444c061aSmrg 769a3bd7f05Smrgstatic void 770a3bd7f05SmrgGetLanguage(Display *dpy, XtPerDisplay pd) 771444c061aSmrg{ 772444c061aSmrg XrmRepresentation type; 773444c061aSmrg XrmValue value; 774444c061aSmrg XrmName name_list[3]; 775444c061aSmrg XrmName class_list[3]; 776444c061aSmrg 777444c061aSmrg LOCK_PROCESS; 778a3bd7f05Smrg if (!pd->language) { 779a3bd7f05Smrg name_list[0] = pd->name; 780a3bd7f05Smrg name_list[1] = XrmPermStringToQuark("xnlLanguage"); 781a3bd7f05Smrg class_list[0] = pd->class; 782a3bd7f05Smrg class_list[1] = XrmPermStringToQuark("XnlLanguage"); 783a3bd7f05Smrg name_list[2] = class_list[2] = NULLQUARK; 784a3bd7f05Smrg if (!pd->server_db) 785a3bd7f05Smrg CombineUserDefaults(dpy, &pd->server_db); 786a3bd7f05Smrg if (pd->server_db && 787a3bd7f05Smrg XrmQGetResource(pd->server_db, name_list, class_list, &type, &value) 788a3bd7f05Smrg && type == _XtQString) 789a3bd7f05Smrg pd->language = (char *) value.addr; 790444c061aSmrg } 791444c061aSmrg 792444c061aSmrg if (pd->appContext->langProcRec.proc) { 793a3bd7f05Smrg if (!pd->language) 794a3bd7f05Smrg pd->language = ""; 795a3bd7f05Smrg pd->language = (*pd->appContext->langProcRec.proc) 796a3bd7f05Smrg (dpy, pd->language, pd->appContext->langProcRec.closure); 797444c061aSmrg } 798a3bd7f05Smrg else if (!pd->language || pd->language[0] == '\0') /* R4 compatibility */ 799a3bd7f05Smrg pd->language = getenv("LANG"); 800444c061aSmrg 801a3bd7f05Smrg if (pd->language) 802a3bd7f05Smrg pd->language = XtNewString(pd->language); 803444c061aSmrg UNLOCK_PROCESS; 804444c061aSmrg} 805444c061aSmrg 806a3bd7f05Smrgstatic void 807a3bd7f05SmrgProcessInternalConnection(XtPointer client_data, 808a3bd7f05Smrg int *fd, 809a3bd7f05Smrg XtInputId *id _X_UNUSED) 810444c061aSmrg{ 811a3bd7f05Smrg XProcessInternalConnection((Display *) client_data, *fd); 812444c061aSmrg} 813444c061aSmrg 814a3bd7f05Smrgstatic void 815a3bd7f05SmrgConnectionWatch(Display *dpy, 816a3bd7f05Smrg XPointer client_data, 817a3bd7f05Smrg int fd, 818a3bd7f05Smrg Bool opening, 819a3bd7f05Smrg XPointer *watch_data) 820444c061aSmrg{ 821a3bd7f05Smrg XtInputId *iptr; 822444c061aSmrg XtAppContext app = XtDisplayToApplicationContext(dpy); 823444c061aSmrg 824444c061aSmrg if (opening) { 825a3bd7f05Smrg iptr = (XtInputId *) __XtMalloc(sizeof(XtInputId)); 826a3bd7f05Smrg *iptr = XtAppAddInput(app, fd, (XtPointer) XtInputReadMask, 827a3bd7f05Smrg ProcessInternalConnection, client_data); 828a3bd7f05Smrg *watch_data = (XPointer) iptr; 829a3bd7f05Smrg } 830a3bd7f05Smrg else { 831a3bd7f05Smrg iptr = (XtInputId *) *watch_data; 832a3bd7f05Smrg XtRemoveInput(*iptr); 833444c061aSmrg (void) XtFree(*watch_data); 834444c061aSmrg } 835444c061aSmrg} 836444c061aSmrg 837a3bd7f05Smrgvoid 838a3bd7f05Smrg_XtDisplayInitialize(Display *dpy, 839a3bd7f05Smrg XtPerDisplay pd, 840a3bd7f05Smrg _Xconst char *name, 841a3bd7f05Smrg XrmOptionDescRec *urlist, 842a3bd7f05Smrg Cardinal num_urs, 843a3bd7f05Smrg int *argc, 844a3bd7f05Smrg char **argv) 845444c061aSmrg{ 846a3bd7f05Smrg Boolean tmp_bool; 847a3bd7f05Smrg XrmValue value; 848a3bd7f05Smrg XrmOptionDescRec *options; 849a3bd7f05Smrg Cardinal num_options; 850a3bd7f05Smrg XrmDatabase db; 851a3bd7f05Smrg XrmName name_list[2]; 852a3bd7f05Smrg XrmClass class_list[2]; 853a3bd7f05Smrg XrmHashTable *search_list; 854a3bd7f05Smrg int search_list_size = SEARCH_LIST_SIZE; 855a3bd7f05Smrg 856a3bd7f05Smrg GetLanguage(dpy, pd); 857a3bd7f05Smrg 858a3bd7f05Smrg /* Parse the command line and remove Xt arguments from argv */ 859a3bd7f05Smrg _MergeOptionTables(opTable, XtNumber(opTable), urlist, num_urs, 860a3bd7f05Smrg &options, &num_options); 861a3bd7f05Smrg XrmParseCommand(&pd->cmd_db, options, (int) num_options, name, argc, argv); 862a3bd7f05Smrg 863a3bd7f05Smrg db = XtScreenDatabase(DefaultScreenOfDisplay(dpy)); 864a3bd7f05Smrg 865a3bd7f05Smrg if (!(search_list = (XrmHashTable *) 866a3bd7f05Smrg ALLOCATE_LOCAL(SEARCH_LIST_SIZE * sizeof(XrmHashTable)))) 867a3bd7f05Smrg _XtAllocError(NULL); 868a3bd7f05Smrg name_list[0] = pd->name; 869a3bd7f05Smrg class_list[0] = pd->class; 870a3bd7f05Smrg name_list[1] = NULLQUARK; 871a3bd7f05Smrg class_list[1] = NULLQUARK; 872a3bd7f05Smrg 873a3bd7f05Smrg while (!XrmQGetSearchList(db, name_list, class_list, 874a3bd7f05Smrg search_list, search_list_size)) { 875a3bd7f05Smrg XrmHashTable *old = search_list; 876a3bd7f05Smrg Cardinal size = 877a3bd7f05Smrg (Cardinal) ((size_t) (search_list_size *= 2) * 878a3bd7f05Smrg sizeof(XrmHashTable)); 879a3bd7f05Smrg if (!(search_list = (XrmHashTable *) ALLOCATE_LOCAL(size))) 880a3bd7f05Smrg _XtAllocError(NULL); 881fdf6a26fSmrg (void) memcpy(search_list, old, (size >> 1)); 882a3bd7f05Smrg DEALLOCATE_LOCAL(old); 883a3bd7f05Smrg } 884a3bd7f05Smrg 885a3bd7f05Smrg value.size = sizeof(tmp_bool); 886a3bd7f05Smrg value.addr = (XtPointer) &tmp_bool; 887a3bd7f05Smrg if (_GetResource(dpy, search_list, "synchronous", "Synchronous", 888a3bd7f05Smrg XtRBoolean, &value)) { 889a3bd7f05Smrg int i; 890a3bd7f05Smrg Display **dpyP = pd->appContext->list; 891a3bd7f05Smrg 892a3bd7f05Smrg pd->appContext->sync = tmp_bool; 893a3bd7f05Smrg for (i = pd->appContext->count; i; dpyP++, i--) { 894a3bd7f05Smrg (void) XSynchronize(*dpyP, (Bool) tmp_bool); 895a3bd7f05Smrg } 896a3bd7f05Smrg } 897a3bd7f05Smrg else { 898a3bd7f05Smrg (void) XSynchronize(dpy, (Bool) pd->appContext->sync); 899a3bd7f05Smrg } 900a3bd7f05Smrg 901a3bd7f05Smrg if (_GetResource(dpy, search_list, "reverseVideo", "ReverseVideo", 902a3bd7f05Smrg XtRBoolean, &value) 903a3bd7f05Smrg && tmp_bool) { 904a3bd7f05Smrg pd->rv = True; 905a3bd7f05Smrg } 906a3bd7f05Smrg 907a3bd7f05Smrg value.size = sizeof(pd->multi_click_time); 908a3bd7f05Smrg value.addr = (XtPointer) &pd->multi_click_time; 909a3bd7f05Smrg if (!_GetResource(dpy, search_list, 910a3bd7f05Smrg "multiClickTime", "MultiClickTime", XtRInt, &value)) { 911a3bd7f05Smrg pd->multi_click_time = 200; 912a3bd7f05Smrg } 913a3bd7f05Smrg 914a3bd7f05Smrg value.size = sizeof(pd->appContext->selectionTimeout); 915a3bd7f05Smrg value.addr = (XtPointer) &pd->appContext->selectionTimeout; 916a3bd7f05Smrg (void) _GetResource(dpy, search_list, 917a3bd7f05Smrg "selectionTimeout", "SelectionTimeout", XtRInt, &value); 918444c061aSmrg 919444c061aSmrg#ifndef NO_IDENTIFY_WINDOWS 920a3bd7f05Smrg value.size = sizeof(pd->appContext->identify_windows); 921a3bd7f05Smrg value.addr = (XtPointer) &pd->appContext->identify_windows; 922a3bd7f05Smrg (void) _GetResource(dpy, search_list, 923a3bd7f05Smrg "xtIdentifyWindows", "XtDebug", XtRBoolean, &value); 924444c061aSmrg#endif 925444c061aSmrg 926a3bd7f05Smrg XAddConnectionWatch(dpy, ConnectionWatch, (XPointer) dpy); 927444c061aSmrg 928a3bd7f05Smrg XtFree((XtPointer) options); 929a3bd7f05Smrg DEALLOCATE_LOCAL(search_list); 930444c061aSmrg} 931444c061aSmrg 932a3bd7f05Smrg/* Function Name: XtAppSetFallbackResources 933a3bd7f05Smrg * Description: Sets the fallback resource list that will be loaded 934444c061aSmrg * at display initialization time. 935a3bd7f05Smrg * Arguments: app_context - the app context. 936444c061aSmrg * specification_list - the resource specification list. 937a3bd7f05Smrg * Returns: none. 938444c061aSmrg */ 939444c061aSmrg 940444c061aSmrgvoid 941a3bd7f05SmrgXtAppSetFallbackResources(XtAppContext app_context, String *specification_list) 942444c061aSmrg{ 943444c061aSmrg LOCK_APP(app_context); 944444c061aSmrg app_context->fallback_resources = specification_list; 945444c061aSmrg UNLOCK_APP(app_context); 946444c061aSmrg} 947444c061aSmrg 948a3bd7f05SmrgWidget 949a3bd7f05SmrgXtOpenApplication(XtAppContext *app_context_return, 950a3bd7f05Smrg _Xconst char *application_class, 951a3bd7f05Smrg XrmOptionDescRec *options, 952a3bd7f05Smrg Cardinal num_options, 953a3bd7f05Smrg int *argc_in_out, 954a3bd7f05Smrg _XtString *argv_in_out, 955a3bd7f05Smrg String *fallback_resources, 956a3bd7f05Smrg WidgetClass widget_class, 957a3bd7f05Smrg ArgList args_in, 958a3bd7f05Smrg Cardinal num_args_in) 959444c061aSmrg{ 960444c061aSmrg XtAppContext app_con; 961a3bd7f05Smrg Display *dpy; 962444c061aSmrg register int saved_argc = *argc_in_out; 963444c061aSmrg Widget root; 964444c061aSmrg Arg args[3], *merged_args; 965444c061aSmrg Cardinal num = 0; 966444c061aSmrg 967a3bd7f05Smrg XtToolkitInitialize(); /* cannot be moved into _XtAppInit */ 968444c061aSmrg 969a3bd7f05Smrg dpy = _XtAppInit(&app_con, (String) application_class, options, num_options, 970a3bd7f05Smrg argc_in_out, &argv_in_out, fallback_resources); 971444c061aSmrg 972444c061aSmrg LOCK_APP(app_con); 973a3bd7f05Smrg XtSetArg(args[num], XtNscreen, DefaultScreenOfDisplay(dpy)); 974a3bd7f05Smrg num++; 975a3bd7f05Smrg XtSetArg(args[num], XtNargc, saved_argc); 976a3bd7f05Smrg num++; 977a3bd7f05Smrg XtSetArg(args[num], XtNargv, argv_in_out); 978a3bd7f05Smrg num++; 979444c061aSmrg 980444c061aSmrg merged_args = XtMergeArgLists(args_in, num_args_in, args, num); 981444c061aSmrg num += num_args_in; 982444c061aSmrg 983444c061aSmrg root = XtAppCreateShell(NULL, application_class, widget_class, dpy, 984a3bd7f05Smrg merged_args, num); 985444c061aSmrg 986444c061aSmrg if (app_context_return) 987a3bd7f05Smrg *app_context_return = app_con; 988444c061aSmrg 989a3bd7f05Smrg XtFree((XtPointer) merged_args); 990a3bd7f05Smrg XtFree((XtPointer) argv_in_out); 991444c061aSmrg UNLOCK_APP(app_con); 992444c061aSmrg return root; 993444c061aSmrg} 994444c061aSmrg 995444c061aSmrgWidget 996a3bd7f05SmrgXtAppInitialize(XtAppContext *app_context_return, 997a3bd7f05Smrg _Xconst char *application_class, 998a3bd7f05Smrg XrmOptionDescRec *options, 999a3bd7f05Smrg Cardinal num_options, 1000a3bd7f05Smrg int *argc_in_out, 1001a3bd7f05Smrg _XtString *argv_in_out, 1002a3bd7f05Smrg String *fallback_resources, 1003a3bd7f05Smrg ArgList args_in, 1004a3bd7f05Smrg Cardinal num_args_in) 1005444c061aSmrg{ 1006444c061aSmrg return XtOpenApplication(app_context_return, application_class, 1007a3bd7f05Smrg options, num_options, 1008a3bd7f05Smrg argc_in_out, argv_in_out, fallback_resources, 1009a3bd7f05Smrg applicationShellWidgetClass, args_in, num_args_in); 1010444c061aSmrg} 1011444c061aSmrg 1012444c061aSmrgWidget 1013a3bd7f05SmrgXtInitialize(_Xconst _XtString name _X_UNUSED, 1014a3bd7f05Smrg _Xconst _XtString classname, 1015a3bd7f05Smrg XrmOptionDescRec *options, 1016a3bd7f05Smrg Cardinal num_options, 1017a3bd7f05Smrg int *argc, 1018a3bd7f05Smrg _XtString *argv) 1019444c061aSmrg{ 1020444c061aSmrg Widget root; 1021444c061aSmrg XtAppContext app_con; 1022444c061aSmrg register ProcessContext process = _XtGetProcessContext(); 1023444c061aSmrg 1024444c061aSmrg root = XtAppInitialize(&app_con, classname, options, num_options, 1025a3bd7f05Smrg argc, argv, NULL, NULL, (Cardinal) 0); 1026444c061aSmrg 1027444c061aSmrg LOCK_PROCESS; 1028444c061aSmrg process->defaultAppContext = app_con; 1029444c061aSmrg UNLOCK_PROCESS; 1030444c061aSmrg return root; 1031444c061aSmrg} 1032