Display.c revision 0568f49b
1444c061aSmrg/***********************************************************
2249c3046SmrgCopyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
31477040fSmrg
41477040fSmrgPermission is hereby granted, free of charge, to any person obtaining a
51477040fSmrgcopy of this software and associated documentation files (the "Software"),
61477040fSmrgto deal in the Software without restriction, including without limitation
71477040fSmrgthe rights to use, copy, modify, merge, publish, distribute, sublicense,
81477040fSmrgand/or sell copies of the Software, and to permit persons to whom the
91477040fSmrgSoftware is furnished to do so, subject to the following conditions:
101477040fSmrg
111477040fSmrgThe above copyright notice and this permission notice (including the next
121477040fSmrgparagraph) shall be included in all copies or substantial portions of the
131477040fSmrgSoftware.
141477040fSmrg
151477040fSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
161477040fSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171477040fSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
181477040fSmrgTHE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
191477040fSmrgLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
201477040fSmrgFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
211477040fSmrgDEALINGS IN THE SOFTWARE.
221477040fSmrg
231477040fSmrgCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
24444c061aSmrg
25444c061aSmrg                        All Rights Reserved
26444c061aSmrg
27444c061aSmrgPermission to use, copy, modify, and distribute this software and its
28444c061aSmrgdocumentation for any purpose and without fee is hereby granted,
29444c061aSmrgprovided that the above copyright notice appear in all copies and that
30444c061aSmrgboth that copyright notice and this permission notice appear in
311477040fSmrgsupporting documentation, and that the name of Digital not be
32444c061aSmrgused in advertising or publicity pertaining to distribution of the
33444c061aSmrgsoftware without specific, written prior permission.
34444c061aSmrg
35444c061aSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
36444c061aSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
37444c061aSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
38444c061aSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
39444c061aSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
40444c061aSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
41444c061aSmrgSOFTWARE.
42444c061aSmrg
43444c061aSmrg******************************************************************/
44444c061aSmrg
45444c061aSmrg/*
46444c061aSmrg
47444c061aSmrgCopyright 1987, 1988, 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#ifdef HAVE_CONFIG_H
72444c061aSmrg#include <config.h>
73444c061aSmrg#endif
74444c061aSmrg#include "IntrinsicI.h"
75444c061aSmrg#ifndef X_NO_RESOURCE_CONFIGURATION_MANAGEMENT
76444c061aSmrg#include "ResConfigP.h"
77444c061aSmrg#endif
78444c061aSmrg
79444c061aSmrg#include <stdlib.h>
80444c061aSmrg
81444c061aSmrg#ifdef XTHREADS
82444c061aSmrgvoid (*_XtProcessLock)(void) = NULL;
83444c061aSmrgvoid (*_XtProcessUnlock)(void) = NULL;
84444c061aSmrgvoid (*_XtInitAppLock)(XtAppContext) = NULL;
85444c061aSmrg#endif
86444c061aSmrg
870568f49bSmrgstatic _Xconst _XtString XtNnoPerDisplay = "noPerDisplay";
88444c061aSmrg
89444c061aSmrgProcessContext _XtGetProcessContext(void)
90444c061aSmrg{
91444c061aSmrg    static ProcessContextRec processContextRec = {
92444c061aSmrg	(XtAppContext)NULL,
93444c061aSmrg	(XtAppContext)NULL,
94444c061aSmrg	(ConverterTable)NULL,
95444c061aSmrg	{(XtLanguageProc)NULL, (XtPointer)NULL}
96444c061aSmrg    };
97444c061aSmrg
98444c061aSmrg    return &processContextRec;
99444c061aSmrg}
100444c061aSmrg
101444c061aSmrg
102444c061aSmrgXtAppContext _XtDefaultAppContext(void)
103444c061aSmrg{
104444c061aSmrg    ProcessContext process = _XtGetProcessContext();
105444c061aSmrg    XtAppContext app;
106444c061aSmrg
107444c061aSmrg    LOCK_PROCESS;
108444c061aSmrg    if (process->defaultAppContext == NULL) {
109444c061aSmrg	process->defaultAppContext = XtCreateApplicationContext();
110444c061aSmrg    }
111444c061aSmrg    app = process->defaultAppContext;
112444c061aSmrg    UNLOCK_PROCESS;
113444c061aSmrg    return app;
114444c061aSmrg}
115444c061aSmrg
116444c061aSmrgstatic void AddToAppContext(
117444c061aSmrg	Display *d,
118444c061aSmrg	XtAppContext app)
119444c061aSmrg{
120444c061aSmrg#define DISPLAYS_TO_ADD 4
121444c061aSmrg
122444c061aSmrg	if (app->count >= app->max) {
1230568f49bSmrg	    app->max = (short) (app->max + DISPLAYS_TO_ADD);
124444c061aSmrg	    app->list = (Display **) XtRealloc((char *)app->list,
1250568f49bSmrg		    (Cardinal) (((size_t) app->max) * sizeof(Display *)));
126444c061aSmrg	}
127444c061aSmrg
128444c061aSmrg	app->list[app->count++] = d;
129444c061aSmrg	app->rebuild_fdlist = TRUE;
1300568f49bSmrg#ifdef USE_POLL
1310568f49bSmrg	app->fds.nfds++;
1320568f49bSmrg#else
133444c061aSmrg	if (ConnectionNumber(d) + 1 > app->fds.nfds) {
134444c061aSmrg	    app->fds.nfds = ConnectionNumber(d) + 1;
135444c061aSmrg	}
136444c061aSmrg#endif
137444c061aSmrg#undef DISPLAYS_TO_ADD
138444c061aSmrg}
139444c061aSmrg
140444c061aSmrgstatic void XtDeleteFromAppContext(
141444c061aSmrg	Display *d,
142444c061aSmrg	register XtAppContext app)
143444c061aSmrg{
144444c061aSmrg	register int i;
145444c061aSmrg
146444c061aSmrg	for (i = 0; i < app->count; i++) if (app->list[i] == d) break;
147444c061aSmrg
148444c061aSmrg	if (i < app->count) {
149444c061aSmrg	    if (i <= app->last && app->last > 0) app->last--;
150444c061aSmrg	    for (i++; i < app->count; i++) app->list[i-1] = app->list[i];
151444c061aSmrg	    app->count--;
152444c061aSmrg	}
153444c061aSmrg	app->rebuild_fdlist = TRUE;
1540568f49bSmrg#ifdef USE_POLL
1550568f49bSmrg	app->fds.nfds--;
1560568f49bSmrg#else
157444c061aSmrg	if ((ConnectionNumber(d) + 1) == app->fds.nfds)
158444c061aSmrg	    app->fds.nfds--;
159444c061aSmrg	else			/* Unnecessary, just to be fool-proof */
160444c061aSmrg	    FD_CLR(ConnectionNumber(d), &app->fds.rmask);
161444c061aSmrg#endif
162444c061aSmrg}
163444c061aSmrg
164444c061aSmrgstatic XtPerDisplay NewPerDisplay(
165444c061aSmrg	Display *dpy)
166444c061aSmrg{
167444c061aSmrg	PerDisplayTablePtr pd;
168444c061aSmrg
169444c061aSmrg	pd = XtNew(PerDisplayTable);
170444c061aSmrg	LOCK_PROCESS;
171444c061aSmrg	pd->dpy = dpy;
172444c061aSmrg	pd->next = _XtperDisplayList;
173444c061aSmrg	_XtperDisplayList = pd;
174444c061aSmrg	UNLOCK_PROCESS;
175444c061aSmrg	return &(pd->perDpy);
176444c061aSmrg}
177444c061aSmrg
178444c061aSmrgstatic XtPerDisplay InitPerDisplay(
179444c061aSmrg    Display *dpy,
180444c061aSmrg    XtAppContext app,
181444c061aSmrg    _Xconst char * name,
182444c061aSmrg    _Xconst char * classname)
183444c061aSmrg{
184444c061aSmrg    XtPerDisplay pd;
185444c061aSmrg
186444c061aSmrg    AddToAppContext(dpy, app);
187444c061aSmrg
188444c061aSmrg    pd = NewPerDisplay(dpy);
189444c061aSmrg    _XtHeapInit(&pd->heap);
190444c061aSmrg    pd->destroy_callbacks = NULL;
191444c061aSmrg    pd->region = XCreateRegion();
192444c061aSmrg    pd->case_cvt = NULL;
193444c061aSmrg    pd->defaultKeycodeTranslator = XtTranslateKey;
194444c061aSmrg    pd->keysyms_serial = 0;
195444c061aSmrg    pd->keysyms = NULL;
196444c061aSmrg    XDisplayKeycodes(dpy, &pd->min_keycode, &pd->max_keycode);
197444c061aSmrg    pd->modKeysyms = NULL;
198444c061aSmrg    pd->modsToKeysyms = NULL;
199444c061aSmrg    pd->appContext = app;
200444c061aSmrg    pd->name = XrmStringToName(name);
201444c061aSmrg    pd->class = XrmStringToClass(classname);
202444c061aSmrg    pd->being_destroyed = False;
203444c061aSmrg    pd->GClist = NULL;
204444c061aSmrg    pd->pixmap_tab = NULL;
205444c061aSmrg    pd->language = NULL;
206444c061aSmrg    pd->rv = False;
207444c061aSmrg    pd->last_event.xany.serial = 0;
208444c061aSmrg    pd->last_timestamp = 0;
209444c061aSmrg    _XtAllocTMContext(pd);
210444c061aSmrg    pd->mapping_callbacks = NULL;
211444c061aSmrg
212444c061aSmrg    pd->pdi.grabList = NULL;
213444c061aSmrg    pd->pdi.trace = NULL;
214444c061aSmrg    pd->pdi.traceDepth = 0;
215444c061aSmrg    pd->pdi.traceMax = 0;
216444c061aSmrg    pd->pdi.focusWidget = NULL;
217444c061aSmrg    pd->pdi.activatingKey = 0;
218444c061aSmrg    pd->pdi.keyboard.grabType = XtNoServerGrab;
219444c061aSmrg    pd->pdi.pointer.grabType  = XtNoServerGrab;
220444c061aSmrg    _XtAllocWWTable(pd);
2210568f49bSmrg    pd->per_screen_db = (XrmDatabase *)__XtCalloc((Cardinal)ScreenCount(dpy),
2220568f49bSmrg						(Cardinal)sizeof(XrmDatabase));
223444c061aSmrg    pd->cmd_db = (XrmDatabase)NULL;
224444c061aSmrg    pd->server_db = (XrmDatabase)NULL;
225444c061aSmrg    pd->dispatcher_list = NULL;
226444c061aSmrg    pd->ext_select_list = NULL;
227444c061aSmrg    pd->ext_select_count = 0;
228444c061aSmrg    pd->hook_object = NULL;
229444c061aSmrg#if 0
230444c061aSmrg    pd->hook_object = _XtCreate("hooks", "Hooks", hookObjectClass,
231444c061aSmrg	(Widget)NULL, (Screen*)DefaultScreenOfDisplay(dpy),
232444c061aSmrg	(ArgList)NULL, 0, (XtTypedArgList)NULL, 0,
233444c061aSmrg	(ConstraintWidgetClass)NULL);
234444c061aSmrg#endif
235444c061aSmrg
236444c061aSmrg#ifndef X_NO_RESOURCE_CONFIGURATION_MANAGEMENT
237444c061aSmrg    pd->rcm_init = XInternAtom (dpy, RCM_INIT, 0);
238444c061aSmrg    pd->rcm_data = XInternAtom (dpy, RCM_DATA, 0);
239444c061aSmrg#endif
240444c061aSmrg
241444c061aSmrg    return pd;
242444c061aSmrg}
243444c061aSmrg
244444c061aSmrgDisplay *XtOpenDisplay(
245444c061aSmrg	XtAppContext app,
2460568f49bSmrg	_Xconst _XtString displayName,
2470568f49bSmrg	_Xconst _XtString applName,
2480568f49bSmrg	_Xconst _XtString className,
249444c061aSmrg	XrmOptionDescRec *urlist,
250444c061aSmrg	Cardinal num_urs,
251444c061aSmrg	int *argc,
2520568f49bSmrg	_XtString *argv)
253444c061aSmrg{
254444c061aSmrg	Display *d;
2552265a131Smrg	XrmDatabase db = NULL;
256444c061aSmrg	String language = NULL;
257444c061aSmrg
258444c061aSmrg	LOCK_APP(app);
259444c061aSmrg	LOCK_PROCESS;
260444c061aSmrg	/* parse the command line for name, display, and/or language */
261444c061aSmrg	db = _XtPreparseCommandLine(urlist, num_urs, *argc, argv,
262444c061aSmrg				(String *)&applName,
263444c061aSmrg				(String *)(displayName ? NULL : &displayName),
264444c061aSmrg				(app->process->globalLangProcRec.proc ?
265444c061aSmrg				&language : NULL));
266444c061aSmrg	UNLOCK_PROCESS;
267444c061aSmrg	d = XOpenDisplay(displayName);
268444c061aSmrg
269444c061aSmrg	if (! applName && !(applName = getenv("RESOURCE_NAME"))) {
270444c061aSmrg	    if (*argc > 0 && argv[0] && *argv[0]) {
271444c061aSmrg#ifdef WIN32
272444c061aSmrg		char *ptr = strrchr(argv[0], '\\');
273444c061aSmrg#else
274444c061aSmrg		char *ptr = strrchr(argv[0], '/');
275444c061aSmrg#endif
276444c061aSmrg
277444c061aSmrg		if (ptr) applName = ++ptr;
278444c061aSmrg		else applName = argv[0];
279444c061aSmrg	    } else
280444c061aSmrg		applName = "main";
281444c061aSmrg	}
282444c061aSmrg
283444c061aSmrg	if (d) {
2840568f49bSmrg	    XtPerDisplay pd;
285444c061aSmrg	    pd = InitPerDisplay(d, app, applName, className);
286444c061aSmrg	    pd->language = language;
287444c061aSmrg	    _XtDisplayInitialize(d, pd, applName, urlist, num_urs, argc, argv);
288444c061aSmrg	} else {
289444c061aSmrg	    int len;
290444c061aSmrg	    displayName = XDisplayName(displayName);
2910568f49bSmrg	    len = (int) strlen (displayName);
2920568f49bSmrg	    app->display_name_tried = (_XtString) __XtMalloc ((Cardinal)(len + 1));
2930568f49bSmrg	    strncpy ((char*) app->display_name_tried, displayName, (size_t) (len + 1));
294444c061aSmrg	    app->display_name_tried[len] = '\0';
295444c061aSmrg	}
296444c061aSmrg	if (db) XrmDestroyDatabase(db);
297444c061aSmrg	UNLOCK_APP(app);
298444c061aSmrg	return d;
299444c061aSmrg}
300444c061aSmrg
301444c061aSmrgDisplay *
302444c061aSmrg_XtAppInit(
303444c061aSmrg	XtAppContext * app_context_return,
304444c061aSmrg	String application_class,
305444c061aSmrg	XrmOptionDescRec *options,
306444c061aSmrg	Cardinal num_options,
307444c061aSmrg	int *argc_in_out,
3080568f49bSmrg	_XtString **argv_in_out,
309444c061aSmrg	String * fallback_resources)
310444c061aSmrg{
3110568f49bSmrg    _XtString *saved_argv;
312444c061aSmrg    int i;
313444c061aSmrg    Display *dpy;
314444c061aSmrg
315444c061aSmrg/*
316444c061aSmrg * Save away argv and argc so we can set the properties later
317444c061aSmrg */
318444c061aSmrg
3190568f49bSmrg    saved_argv = (_XtString *)
3200568f49bSmrg	__XtMalloc( (Cardinal)((size_t)(*argc_in_out + 1) * sizeof(_XtString)) );
321444c061aSmrg
322444c061aSmrg    for (i = 0 ; i < *argc_in_out ; i++) saved_argv[i] = (*argv_in_out)[i];
323444c061aSmrg    saved_argv[i] = NULL;	/* NULL terminate that sucker. */
324444c061aSmrg
325444c061aSmrg
326444c061aSmrg    *app_context_return = XtCreateApplicationContext();
327444c061aSmrg
328444c061aSmrg    LOCK_APP((*app_context_return));
329444c061aSmrg    if (fallback_resources) /* save a procedure call */
330444c061aSmrg	XtAppSetFallbackResources(*app_context_return, fallback_resources);
331444c061aSmrg
3320568f49bSmrg    dpy = XtOpenDisplay(*app_context_return, NULL, NULL,
333444c061aSmrg			application_class,
334444c061aSmrg			options, num_options, argc_in_out, *argv_in_out);
335444c061aSmrg
336444c061aSmrg    if (!dpy) {
337444c061aSmrg	String param = (*app_context_return)->display_name_tried;
338444c061aSmrg	Cardinal param_count = 1;
339444c061aSmrg	XtErrorMsg("invalidDisplay","xtInitialize",XtCXtToolkitError,
340444c061aSmrg                   "Can't open display: %s", &param, &param_count);
341444c061aSmrg	XtFree((char *) (*app_context_return)->display_name_tried);
342444c061aSmrg    }
343444c061aSmrg    *argv_in_out = saved_argv;
344444c061aSmrg    UNLOCK_APP((*app_context_return));
345444c061aSmrg    return dpy;
346444c061aSmrg}
347444c061aSmrg
348444c061aSmrgvoid
349444c061aSmrgXtDisplayInitialize(
350444c061aSmrg	XtAppContext app,
351444c061aSmrg	Display *dpy,
3520568f49bSmrg	_Xconst _XtString name,
3530568f49bSmrg	_Xconst _XtString classname,
354444c061aSmrg	XrmOptionDescRec *urlist,
355444c061aSmrg	Cardinal num_urs,
356444c061aSmrg	int *argc,
3570568f49bSmrg	_XtString *argv
358444c061aSmrg	)
359444c061aSmrg{
360444c061aSmrg    XtPerDisplay pd;
3612265a131Smrg    XrmDatabase db = NULL;
362444c061aSmrg
363444c061aSmrg    LOCK_APP(app);
364444c061aSmrg    pd = InitPerDisplay(dpy, app, name, classname);
365444c061aSmrg    LOCK_PROCESS;
366444c061aSmrg    if (app->process->globalLangProcRec.proc)
367444c061aSmrg	/* pre-parse the command line for the language resource */
368444c061aSmrg	db = _XtPreparseCommandLine(urlist, num_urs, *argc, argv, NULL, NULL,
369444c061aSmrg				    &pd->language);
370444c061aSmrg    UNLOCK_PROCESS;
371444c061aSmrg    _XtDisplayInitialize(dpy, pd, name, urlist, num_urs, argc, argv);
372444c061aSmrg    if (db) XrmDestroyDatabase(db);
373444c061aSmrg    UNLOCK_APP(app);
374444c061aSmrg}
375444c061aSmrg
376444c061aSmrgXtAppContext XtCreateApplicationContext(void)
377444c061aSmrg{
378444c061aSmrg	XtAppContext app = XtNew(XtAppStruct);
379444c061aSmrg#ifdef XTHREADS
380444c061aSmrg	app->lock_info = NULL;
381444c061aSmrg	app->lock = NULL;
382444c061aSmrg	app->unlock = NULL;
383444c061aSmrg	app->yield_lock = NULL;
384444c061aSmrg	app->restore_lock = NULL;
385444c061aSmrg	app->free_lock = NULL;
386444c061aSmrg#endif
387444c061aSmrg	INIT_APP_LOCK(app);
388444c061aSmrg	LOCK_APP(app);
389444c061aSmrg	LOCK_PROCESS;
390444c061aSmrg	app->process = _XtGetProcessContext();
391444c061aSmrg	app->next = app->process->appContextList;
392444c061aSmrg	app->process->appContextList = app;
393444c061aSmrg	app->langProcRec.proc = app->process->globalLangProcRec.proc;
394444c061aSmrg	app->langProcRec.closure = app->process->globalLangProcRec.closure;
395444c061aSmrg	app->destroy_callbacks = NULL;
396444c061aSmrg	app->list = NULL;
397444c061aSmrg	app->count = app->max = app->last = 0;
398444c061aSmrg	app->timerQueue = NULL;
399444c061aSmrg	app->workQueue = NULL;
400444c061aSmrg	app->signalQueue = NULL;
401444c061aSmrg	app->input_list = NULL;
402444c061aSmrg	app->outstandingQueue = NULL;
403444c061aSmrg	app->errorDB = NULL;
404444c061aSmrg	_XtSetDefaultErrorHandlers(&app->errorMsgHandler,
405444c061aSmrg		&app->warningMsgHandler, &app->errorHandler,
406444c061aSmrg		&app->warningHandler);
407444c061aSmrg	app->action_table = NULL;
408444c061aSmrg	_XtSetDefaultSelectionTimeout(&app->selectionTimeout);
409444c061aSmrg	_XtSetDefaultConverterTable(&app->converterTable);
410444c061aSmrg	app->sync = app->being_destroyed = app->error_inited = FALSE;
411444c061aSmrg	app->in_phase2_destroy = NULL;
412444c061aSmrg#ifndef USE_POLL
413444c061aSmrg	FD_ZERO(&app->fds.rmask);
414444c061aSmrg	FD_ZERO(&app->fds.wmask);
415444c061aSmrg	FD_ZERO(&app->fds.emask);
416444c061aSmrg#endif
417444c061aSmrg	app->fds.nfds = 0;
418444c061aSmrg	app->input_count = app->input_max = 0;
419444c061aSmrg	_XtHeapInit(&app->heap);
420444c061aSmrg	app->fallback_resources = NULL;
421444c061aSmrg	_XtPopupInitialize(app);
422444c061aSmrg	app->action_hook_list = NULL;
423444c061aSmrg	app->block_hook_list = NULL;
424444c061aSmrg	app->destroy_list_size = app->destroy_count = app->dispatch_level = 0;
425444c061aSmrg	app->destroy_list = NULL;
426444c061aSmrg#ifndef NO_IDENTIFY_WINDOWS
427444c061aSmrg	app->identify_windows = False;
428444c061aSmrg#endif
429444c061aSmrg	app->free_bindings = NULL;
430444c061aSmrg	app->display_name_tried = NULL;
431444c061aSmrg	app->dpy_destroy_count = 0;
432444c061aSmrg	app->dpy_destroy_list = NULL;
433444c061aSmrg	app->exit_flag = FALSE;
434444c061aSmrg	app->rebuild_fdlist = TRUE;
435444c061aSmrg	UNLOCK_PROCESS;
436444c061aSmrg	UNLOCK_APP(app);
437444c061aSmrg	return app;
438444c061aSmrg}
439444c061aSmrg
440444c061aSmrgvoid XtAppSetExitFlag (
441444c061aSmrg    XtAppContext app)
442444c061aSmrg{
443444c061aSmrg    LOCK_APP(app);
444444c061aSmrg    app->exit_flag = TRUE;
445444c061aSmrg    UNLOCK_APP(app);
446444c061aSmrg}
447444c061aSmrg
448444c061aSmrgBoolean XtAppGetExitFlag (
449444c061aSmrg    XtAppContext app)
450444c061aSmrg{
451444c061aSmrg    Boolean retval;
452444c061aSmrg    LOCK_APP(app);
453444c061aSmrg    retval = app->exit_flag;
454444c061aSmrg    UNLOCK_APP(app);
455444c061aSmrg    return retval;
456444c061aSmrg}
457444c061aSmrg
458444c061aSmrgstatic void DestroyAppContext(XtAppContext app)
459444c061aSmrg{
460444c061aSmrg	XtAppContext* prev_app;
461444c061aSmrg
462444c061aSmrg	prev_app = &app->process->appContextList;
463444c061aSmrg	while (app->count-- > 0) XtCloseDisplay(app->list[app->count]);
464444c061aSmrg	if (app->list != NULL) XtFree((char *)app->list);
465444c061aSmrg	_XtFreeConverterTable(app->converterTable);
466444c061aSmrg	_XtCacheFlushTag(app, (XtPointer)&app->heap);
467444c061aSmrg	_XtFreeActions(app->action_table);
468444c061aSmrg	if (app->destroy_callbacks != NULL) {
469444c061aSmrg	    XtCallCallbackList((Widget) NULL,
470444c061aSmrg			       (XtCallbackList)app->destroy_callbacks,
471444c061aSmrg			       (XtPointer)app);
472444c061aSmrg	    _XtRemoveAllCallbacks(&app->destroy_callbacks);
473444c061aSmrg	}
474444c061aSmrg	while (app->timerQueue) XtRemoveTimeOut((XtIntervalId)app->timerQueue);
475444c061aSmrg	while (app->workQueue) XtRemoveWorkProc((XtWorkProcId)app->workQueue);
476444c061aSmrg	while (app->signalQueue) XtRemoveSignal((XtSignalId)app->signalQueue);
477444c061aSmrg	if (app->input_list) _XtRemoveAllInputs(app);
478444c061aSmrg	XtFree((char*)app->destroy_list);
479444c061aSmrg	_XtHeapFree(&app->heap);
480444c061aSmrg	while (*prev_app != app) prev_app = &(*prev_app)->next;
481444c061aSmrg	*prev_app = app->next;
482444c061aSmrg	if (app->process->defaultAppContext == app)
483444c061aSmrg	    app->process->defaultAppContext = NULL;
484444c061aSmrg	if (app->free_bindings) _XtDoFreeBindings (app);
485444c061aSmrg	FREE_APP_LOCK(app);
486444c061aSmrg	XtFree((char *)app);
487444c061aSmrg}
488444c061aSmrg
489444c061aSmrgstatic XtAppContext* appDestroyList = NULL;
490444c061aSmrgint _XtAppDestroyCount = 0;
491444c061aSmrg
492444c061aSmrgvoid XtDestroyApplicationContext(XtAppContext app)
493444c061aSmrg{
494444c061aSmrg	LOCK_APP(app);
495444c061aSmrg	if (app->being_destroyed) {
496444c061aSmrg	    UNLOCK_APP(app);
497444c061aSmrg	    return;
498444c061aSmrg	}
499444c061aSmrg
500444c061aSmrg	if (_XtSafeToDestroy(app)) {
501444c061aSmrg	    LOCK_PROCESS;
502444c061aSmrg	    DestroyAppContext(app);
503444c061aSmrg	    UNLOCK_PROCESS;
504444c061aSmrg	} else {
505444c061aSmrg	    app->being_destroyed = TRUE;
506444c061aSmrg	    LOCK_PROCESS;
507444c061aSmrg	    _XtAppDestroyCount++;
508444c061aSmrg	    appDestroyList =
509444c061aSmrg		    (XtAppContext *) XtRealloc((char *) appDestroyList,
5100568f49bSmrg		    (unsigned) ((size_t)_XtAppDestroyCount * sizeof(XtAppContext)));
511444c061aSmrg	    appDestroyList[_XtAppDestroyCount-1] = app;
512444c061aSmrg	    UNLOCK_PROCESS;
513444c061aSmrg	    UNLOCK_APP(app);
514444c061aSmrg	}
515444c061aSmrg}
516444c061aSmrg
517444c061aSmrgvoid _XtDestroyAppContexts(void)
518444c061aSmrg{
519444c061aSmrg	int i,ii;
520444c061aSmrg	XtAppContext apps[8];
521444c061aSmrg	XtAppContext* pApps;
522444c061aSmrg
5230568f49bSmrg	pApps = XtStackAlloc (sizeof (XtAppContext) * (size_t)_XtAppDestroyCount, apps);
524444c061aSmrg
525444c061aSmrg	for (i = ii = 0; i < _XtAppDestroyCount; i++) {
526444c061aSmrg	    if (_XtSafeToDestroy(appDestroyList[i]))
527444c061aSmrg		DestroyAppContext(appDestroyList[i]);
528444c061aSmrg	    else
529444c061aSmrg		pApps[ii++] = appDestroyList[i];
530444c061aSmrg	}
531444c061aSmrg	_XtAppDestroyCount = ii;
532444c061aSmrg	if (_XtAppDestroyCount == 0) {
533444c061aSmrg	    XtFree((char *) appDestroyList);
534444c061aSmrg	    appDestroyList = NULL;
535444c061aSmrg	} else {
536444c061aSmrg	    for (i = 0; i < ii; i++)
537444c061aSmrg		appDestroyList[i] = pApps[i];
538444c061aSmrg	}
539444c061aSmrg	XtStackFree ((XtPointer) pApps, apps);
540444c061aSmrg}
541444c061aSmrg
542444c061aSmrgXrmDatabase XtDatabase(Display *dpy)
543444c061aSmrg{
544444c061aSmrg    XrmDatabase retval;
545444c061aSmrg    DPY_TO_APPCON(dpy);
546444c061aSmrg
547444c061aSmrg    LOCK_APP(app);
548444c061aSmrg    retval = XrmGetDatabase(dpy);
549444c061aSmrg    UNLOCK_APP(app);
550444c061aSmrg    return retval;
551444c061aSmrg}
552444c061aSmrg
553444c061aSmrgPerDisplayTablePtr _XtperDisplayList = NULL;
554444c061aSmrg
555444c061aSmrgXtPerDisplay _XtSortPerDisplayList(Display *dpy)
556444c061aSmrg{
557444c061aSmrg	register PerDisplayTablePtr pd, opd = NULL;
5580568f49bSmrg	XtPerDisplay result = NULL;
559444c061aSmrg
560444c061aSmrg	LOCK_PROCESS;
561444c061aSmrg	for (pd = _XtperDisplayList;
562444c061aSmrg	     pd != NULL && pd->dpy != dpy;
563444c061aSmrg	     pd = pd->next) {
564444c061aSmrg	    opd = pd;
565444c061aSmrg	}
566444c061aSmrg
567444c061aSmrg	if (pd == NULL) {
568444c061aSmrg	    XtErrorMsg(XtNnoPerDisplay, "getPerDisplay", XtCXtToolkitError,
569444c061aSmrg		    "Couldn't find per display information",
5700568f49bSmrg		    NULL, NULL);
5710568f49bSmrg	} else {
5720568f49bSmrg	    if (pd != _XtperDisplayList) {	/* move it to the front */
5730568f49bSmrg		/* opd points to the previous one... */
574444c061aSmrg
5750568f49bSmrg		opd->next = pd->next;
5760568f49bSmrg		pd->next = _XtperDisplayList;
5770568f49bSmrg		_XtperDisplayList = pd;
5780568f49bSmrg	    }
5790568f49bSmrg	    result = &(pd->perDpy);
580444c061aSmrg	}
581444c061aSmrg	UNLOCK_PROCESS;
5820568f49bSmrg	return result;
583444c061aSmrg}
584444c061aSmrg
585444c061aSmrgXtAppContext XtDisplayToApplicationContext(Display *dpy)
586444c061aSmrg{
587444c061aSmrg	XtAppContext retval;
588444c061aSmrg
589444c061aSmrg	retval = _XtGetPerDisplay(dpy)->appContext;
590444c061aSmrg	return retval;
591444c061aSmrg}
592444c061aSmrg
593444c061aSmrgstatic void CloseDisplay(Display *dpy)
594444c061aSmrg{
5950568f49bSmrg        register XtPerDisplay xtpd = NULL;
596444c061aSmrg	register PerDisplayTablePtr pd, opd = NULL;
597444c061aSmrg	XrmDatabase db;
598444c061aSmrg
599444c061aSmrg	XtDestroyWidget(XtHooksOfDisplay(dpy));
600444c061aSmrg
601444c061aSmrg	LOCK_PROCESS;
602444c061aSmrg	for (pd = _XtperDisplayList;
603444c061aSmrg	     pd != NULL && pd->dpy != dpy;
604444c061aSmrg	     pd = pd->next){
605444c061aSmrg	    opd = pd;
606444c061aSmrg	}
607444c061aSmrg
608444c061aSmrg	if (pd == NULL) {
609444c061aSmrg	    XtErrorMsg(XtNnoPerDisplay, "closeDisplay", XtCXtToolkitError,
610444c061aSmrg		    "Couldn't find per display information",
6110568f49bSmrg		    NULL, NULL);
6120568f49bSmrg	} else {
613444c061aSmrg
6140568f49bSmrg	    if (pd == _XtperDisplayList) _XtperDisplayList = pd->next;
6150568f49bSmrg	    else opd->next = pd->next;
616444c061aSmrg
6170568f49bSmrg	    xtpd = &(pd->perDpy);
6180568f49bSmrg	}
619444c061aSmrg
620444c061aSmrg        if (xtpd != NULL) {
6210568f49bSmrg	    int i;
6220568f49bSmrg
623444c061aSmrg	    if (xtpd->destroy_callbacks != NULL) {
624444c061aSmrg		XtCallCallbackList((Widget) NULL,
625444c061aSmrg				   (XtCallbackList)xtpd->destroy_callbacks,
626444c061aSmrg				   (XtPointer)xtpd);
627444c061aSmrg		_XtRemoveAllCallbacks(&xtpd->destroy_callbacks);
628444c061aSmrg	    }
629444c061aSmrg	    if (xtpd->mapping_callbacks != NULL)
630444c061aSmrg		_XtRemoveAllCallbacks(&xtpd->mapping_callbacks);
631444c061aSmrg	    XtDeleteFromAppContext(dpy, xtpd->appContext);
632444c061aSmrg	    if (xtpd->keysyms)
633444c061aSmrg		XFree((char *) xtpd->keysyms);
634444c061aSmrg            XtFree((char *) xtpd->modKeysyms);
635444c061aSmrg            XtFree((char *) xtpd->modsToKeysyms);
636444c061aSmrg            xtpd->keysyms_per_keycode = 0;
637444c061aSmrg            xtpd->being_destroyed = FALSE;
638444c061aSmrg            xtpd->keysyms = NULL;
639444c061aSmrg            xtpd->modKeysyms = NULL;
640444c061aSmrg            xtpd->modsToKeysyms = NULL;
641444c061aSmrg	    XDestroyRegion(xtpd->region);
642444c061aSmrg	    _XtCacheFlushTag(xtpd->appContext, (XtPointer)&xtpd->heap);
643444c061aSmrg	    _XtGClistFree(dpy, xtpd);
644444c061aSmrg	    XtFree((char*)xtpd->pdi.trace);
645444c061aSmrg	    _XtHeapFree(&xtpd->heap);
646444c061aSmrg	    _XtFreeWWTable(xtpd);
647444c061aSmrg	    xtpd->per_screen_db[DefaultScreen(dpy)] = (XrmDatabase)NULL;
648444c061aSmrg	    for (i = ScreenCount(dpy); --i >= 0; ) {
649444c061aSmrg		db = xtpd->per_screen_db[i];
650444c061aSmrg		if (db)
651444c061aSmrg		    XrmDestroyDatabase(db);
652444c061aSmrg	    }
653444c061aSmrg	    XtFree((char *)xtpd->per_screen_db);
654444c061aSmrg	    if ((db = XrmGetDatabase(dpy)))
655444c061aSmrg		XrmDestroyDatabase(db);
656444c061aSmrg	    if (xtpd->cmd_db)
657444c061aSmrg		XrmDestroyDatabase(xtpd->cmd_db);
658444c061aSmrg	    if (xtpd->server_db)
659444c061aSmrg		XrmDestroyDatabase(xtpd->server_db);
6600568f49bSmrg	    XtFree((_XtString)xtpd->language);
661444c061aSmrg	    if (xtpd->dispatcher_list != NULL)
662444c061aSmrg		XtFree((char *) xtpd->dispatcher_list);
663444c061aSmrg	    if (xtpd->ext_select_list != NULL)
664444c061aSmrg		XtFree((char *) xtpd->ext_select_list);
665444c061aSmrg        }
666444c061aSmrg	XtFree((char*)pd);
667444c061aSmrg	XrmSetDatabase(dpy, (XrmDatabase)NULL);
668444c061aSmrg	XCloseDisplay(dpy);
669444c061aSmrg	UNLOCK_PROCESS;
670444c061aSmrg}
671444c061aSmrg
672444c061aSmrgvoid XtCloseDisplay(Display *dpy)
673444c061aSmrg{
674444c061aSmrg	XtPerDisplay pd;
675444c061aSmrg	XtAppContext app = XtDisplayToApplicationContext(dpy);
676444c061aSmrg
677444c061aSmrg	LOCK_APP(app);
678444c061aSmrg	pd = _XtGetPerDisplay(dpy);
679444c061aSmrg	if (pd->being_destroyed) {
680444c061aSmrg	    UNLOCK_APP(app);
681444c061aSmrg	    return;
682444c061aSmrg	}
683444c061aSmrg
684444c061aSmrg	if (_XtSafeToDestroy(app)) CloseDisplay(dpy);
685444c061aSmrg	else {
686444c061aSmrg	    pd->being_destroyed = TRUE;
687444c061aSmrg	    app->dpy_destroy_count++;
688444c061aSmrg	    app->dpy_destroy_list = (Display **)
689444c061aSmrg		XtRealloc((char *) app->dpy_destroy_list,
6900568f49bSmrg		    (Cardinal) ((size_t)app->dpy_destroy_count * sizeof(Display *)));
691444c061aSmrg	    app->dpy_destroy_list[app->dpy_destroy_count-1] = dpy;
692444c061aSmrg	}
693444c061aSmrg	UNLOCK_APP(app);
694444c061aSmrg}
695444c061aSmrg
696444c061aSmrgvoid _XtCloseDisplays(XtAppContext app)
697444c061aSmrg{
698444c061aSmrg	int i;
699444c061aSmrg
700444c061aSmrg	LOCK_APP(app);
701444c061aSmrg	for (i = 0; i < app->dpy_destroy_count; i++) {
702444c061aSmrg	    CloseDisplay(app->dpy_destroy_list[i]);
703444c061aSmrg	}
704444c061aSmrg	app->dpy_destroy_count = 0;
705444c061aSmrg	XtFree((char *) app->dpy_destroy_list);
706444c061aSmrg	app->dpy_destroy_list = NULL;
707444c061aSmrg	UNLOCK_APP(app);
708444c061aSmrg}
709444c061aSmrg
710444c061aSmrgXtAppContext XtWidgetToApplicationContext(Widget w)
711444c061aSmrg{
712444c061aSmrg	XtAppContext retval;
713444c061aSmrg
714444c061aSmrg	retval = _XtGetPerDisplay(XtDisplayOfObject(w))->appContext;
715444c061aSmrg	return retval;
716444c061aSmrg}
717444c061aSmrg
718444c061aSmrg
719444c061aSmrgvoid XtGetApplicationNameAndClass(
720444c061aSmrg    Display *dpy,
721444c061aSmrg    String *name_return,
722444c061aSmrg    String *class_return)
723444c061aSmrg{
724444c061aSmrg    XtPerDisplay pd;
725444c061aSmrg
726444c061aSmrg    pd = _XtGetPerDisplay(dpy);
727444c061aSmrg    *name_return = XrmQuarkToString(pd->name);
728444c061aSmrg    *class_return = XrmQuarkToString(pd->class);
729444c061aSmrg}
730444c061aSmrg
731444c061aSmrgXtPerDisplay _XtGetPerDisplay (Display* display)
732444c061aSmrg{
733444c061aSmrg    XtPerDisplay retval;
734444c061aSmrg
735444c061aSmrg    LOCK_PROCESS;
736444c061aSmrg    retval = ((_XtperDisplayList != NULL &&
737444c061aSmrg	      _XtperDisplayList->dpy == display)
738444c061aSmrg	      ? &_XtperDisplayList->perDpy
739444c061aSmrg	      : _XtSortPerDisplayList(display));
740444c061aSmrg    UNLOCK_PROCESS;
741444c061aSmrg    return retval;
742444c061aSmrg}
743444c061aSmrg
744444c061aSmrgXtPerDisplayInputRec* _XtGetPerDisplayInput(Display* display)
745444c061aSmrg{
746444c061aSmrg    XtPerDisplayInputRec* retval;
747444c061aSmrg    LOCK_PROCESS;
748444c061aSmrg    retval = ((_XtperDisplayList != NULL &&
749444c061aSmrg	      _XtperDisplayList->dpy == display)
750444c061aSmrg	      ? &_XtperDisplayList->perDpy.pdi
751444c061aSmrg	      : &_XtSortPerDisplayList(display)->pdi);
752444c061aSmrg    UNLOCK_PROCESS;
753444c061aSmrg    return retval;
754444c061aSmrg}
755444c061aSmrg
756444c061aSmrgvoid XtGetDisplays(
757444c061aSmrg    XtAppContext app_context,
758444c061aSmrg    Display*** dpy_return,
759444c061aSmrg    Cardinal* num_dpy_return)
760444c061aSmrg{
761444c061aSmrg    int ii;
762444c061aSmrg    LOCK_APP(app_context);
7630568f49bSmrg    *num_dpy_return = (Cardinal)app_context->count;
7640568f49bSmrg    *dpy_return = (Display**)__XtMalloc((Cardinal)((size_t)app_context->count * sizeof(Display*)));
765444c061aSmrg    for (ii = 0; ii < app_context->count; ii++)
766444c061aSmrg	(*dpy_return)[ii] = app_context->list[ii];
767444c061aSmrg    UNLOCK_APP(app_context);
768444c061aSmrg}
769