Display.c revision 444c061a
1444c061aSmrg/* $Xorg: Display.c,v 1.6 2001/02/09 02:03:54 xorgcvs Exp $ */
2444c061aSmrg
3444c061aSmrg/***********************************************************
4444c061aSmrgCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
5444c061aSmrgCopyright 1993 by Sun Microsystems, Inc. Mountain View, CA.
6444c061aSmrg
7444c061aSmrg                        All Rights Reserved
8444c061aSmrg
9444c061aSmrgPermission to use, copy, modify, and distribute this software and its
10444c061aSmrgdocumentation for any purpose and without fee is hereby granted,
11444c061aSmrgprovided that the above copyright notice appear in all copies and that
12444c061aSmrgboth that copyright notice and this permission notice appear in
13444c061aSmrgsupporting documentation, and that the names of Digital or Sun not be
14444c061aSmrgused in advertising or publicity pertaining to distribution of the
15444c061aSmrgsoftware without specific, written prior permission.
16444c061aSmrg
17444c061aSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
18444c061aSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
19444c061aSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
20444c061aSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21444c061aSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22444c061aSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
23444c061aSmrgSOFTWARE.
24444c061aSmrg
25444c061aSmrgSUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
26444c061aSmrgINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
27444c061aSmrgNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
28444c061aSmrgABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
29444c061aSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
30444c061aSmrgPROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
31444c061aSmrgOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
32444c061aSmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE.
33444c061aSmrg
34444c061aSmrg******************************************************************/
35444c061aSmrg/* $XFree86: xc/lib/Xt/Display.c,v 3.15 2002/09/18 01:25:01 dawes Exp $ */
36444c061aSmrg
37444c061aSmrg/*
38444c061aSmrg
39444c061aSmrgCopyright 1987, 1988, 1998  The Open Group
40444c061aSmrg
41444c061aSmrgPermission to use, copy, modify, distribute, and sell this software and its
42444c061aSmrgdocumentation for any purpose is hereby granted without fee, provided that
43444c061aSmrgthe above copyright notice appear in all copies and that both that
44444c061aSmrgcopyright notice and this permission notice appear in supporting
45444c061aSmrgdocumentation.
46444c061aSmrg
47444c061aSmrgThe above copyright notice and this permission notice shall be included in
48444c061aSmrgall copies or substantial portions of the Software.
49444c061aSmrg
50444c061aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
51444c061aSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
52444c061aSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
53444c061aSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
54444c061aSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
55444c061aSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
56444c061aSmrg
57444c061aSmrgExcept as contained in this notice, the name of The Open Group shall not be
58444c061aSmrgused in advertising or otherwise to promote the sale, use or other dealings
59444c061aSmrgin this Software without prior written authorization from The Open Group.
60444c061aSmrg
61444c061aSmrg*/
62444c061aSmrg
63444c061aSmrg#ifdef HAVE_CONFIG_H
64444c061aSmrg#include <config.h>
65444c061aSmrg#endif
66444c061aSmrg#include "IntrinsicI.h"
67444c061aSmrg#ifndef X_NO_RESOURCE_CONFIGURATION_MANAGEMENT
68444c061aSmrg#include "ResConfigP.h"
69444c061aSmrg#endif
70444c061aSmrg
71444c061aSmrg#include <stdlib.h>
72444c061aSmrg
73444c061aSmrg#ifdef XTHREADS
74444c061aSmrgvoid (*_XtProcessLock)(void) = NULL;
75444c061aSmrgvoid (*_XtProcessUnlock)(void) = NULL;
76444c061aSmrgvoid (*_XtInitAppLock)(XtAppContext) = NULL;
77444c061aSmrg#endif
78444c061aSmrg
79444c061aSmrgstatic String XtNnoPerDisplay = "noPerDisplay";
80444c061aSmrg
81444c061aSmrgProcessContext _XtGetProcessContext(void)
82444c061aSmrg{
83444c061aSmrg    static ProcessContextRec processContextRec = {
84444c061aSmrg	(XtAppContext)NULL,
85444c061aSmrg	(XtAppContext)NULL,
86444c061aSmrg	(ConverterTable)NULL,
87444c061aSmrg	{(XtLanguageProc)NULL, (XtPointer)NULL}
88444c061aSmrg    };
89444c061aSmrg
90444c061aSmrg    return &processContextRec;
91444c061aSmrg}
92444c061aSmrg
93444c061aSmrg
94444c061aSmrgXtAppContext _XtDefaultAppContext(void)
95444c061aSmrg{
96444c061aSmrg    ProcessContext process = _XtGetProcessContext();
97444c061aSmrg    XtAppContext app;
98444c061aSmrg
99444c061aSmrg    LOCK_PROCESS;
100444c061aSmrg    if (process->defaultAppContext == NULL) {
101444c061aSmrg	process->defaultAppContext = XtCreateApplicationContext();
102444c061aSmrg    }
103444c061aSmrg    app = process->defaultAppContext;
104444c061aSmrg    UNLOCK_PROCESS;
105444c061aSmrg    return app;
106444c061aSmrg}
107444c061aSmrg
108444c061aSmrgstatic void AddToAppContext(
109444c061aSmrg	Display *d,
110444c061aSmrg	XtAppContext app)
111444c061aSmrg{
112444c061aSmrg#define DISPLAYS_TO_ADD 4
113444c061aSmrg
114444c061aSmrg	if (app->count >= app->max) {
115444c061aSmrg	    app->max += DISPLAYS_TO_ADD;
116444c061aSmrg	    app->list = (Display **) XtRealloc((char *)app->list,
117444c061aSmrg		    (unsigned) app->max * sizeof(Display *));
118444c061aSmrg	}
119444c061aSmrg
120444c061aSmrg	app->list[app->count++] = d;
121444c061aSmrg	app->rebuild_fdlist = TRUE;
122444c061aSmrg#ifndef USE_POLL
123444c061aSmrg	if (ConnectionNumber(d) + 1 > app->fds.nfds) {
124444c061aSmrg	    app->fds.nfds = ConnectionNumber(d) + 1;
125444c061aSmrg	}
126444c061aSmrg#else
127444c061aSmrg	app->fds.nfds++;
128444c061aSmrg#endif
129444c061aSmrg#undef DISPLAYS_TO_ADD
130444c061aSmrg}
131444c061aSmrg
132444c061aSmrgstatic void XtDeleteFromAppContext(
133444c061aSmrg	Display *d,
134444c061aSmrg	register XtAppContext app)
135444c061aSmrg{
136444c061aSmrg	register int i;
137444c061aSmrg
138444c061aSmrg	for (i = 0; i < app->count; i++) if (app->list[i] == d) break;
139444c061aSmrg
140444c061aSmrg	if (i < app->count) {
141444c061aSmrg	    if (i <= app->last && app->last > 0) app->last--;
142444c061aSmrg	    for (i++; i < app->count; i++) app->list[i-1] = app->list[i];
143444c061aSmrg	    app->count--;
144444c061aSmrg	}
145444c061aSmrg	app->rebuild_fdlist = TRUE;
146444c061aSmrg#ifndef USE_POLL
147444c061aSmrg	if ((ConnectionNumber(d) + 1) == app->fds.nfds)
148444c061aSmrg	    app->fds.nfds--;
149444c061aSmrg	else			/* Unnecessary, just to be fool-proof */
150444c061aSmrg	    FD_CLR(ConnectionNumber(d), &app->fds.rmask);
151444c061aSmrg#else
152444c061aSmrg	app->fds.nfds--;
153444c061aSmrg#endif
154444c061aSmrg}
155444c061aSmrg
156444c061aSmrgstatic XtPerDisplay NewPerDisplay(
157444c061aSmrg	Display *dpy)
158444c061aSmrg{
159444c061aSmrg	PerDisplayTablePtr pd;
160444c061aSmrg
161444c061aSmrg	pd = XtNew(PerDisplayTable);
162444c061aSmrg	LOCK_PROCESS;
163444c061aSmrg	pd->dpy = dpy;
164444c061aSmrg	pd->next = _XtperDisplayList;
165444c061aSmrg	_XtperDisplayList = pd;
166444c061aSmrg	UNLOCK_PROCESS;
167444c061aSmrg	return &(pd->perDpy);
168444c061aSmrg}
169444c061aSmrg
170444c061aSmrgstatic XtPerDisplay InitPerDisplay(
171444c061aSmrg    Display *dpy,
172444c061aSmrg    XtAppContext app,
173444c061aSmrg    _Xconst char * name,
174444c061aSmrg    _Xconst char * classname)
175444c061aSmrg{
176444c061aSmrg    XtPerDisplay pd;
177444c061aSmrg
178444c061aSmrg    AddToAppContext(dpy, app);
179444c061aSmrg
180444c061aSmrg    pd = NewPerDisplay(dpy);
181444c061aSmrg    _XtHeapInit(&pd->heap);
182444c061aSmrg    pd->destroy_callbacks = NULL;
183444c061aSmrg    pd->region = XCreateRegion();
184444c061aSmrg    pd->case_cvt = NULL;
185444c061aSmrg    pd->defaultKeycodeTranslator = XtTranslateKey;
186444c061aSmrg    pd->keysyms_serial = 0;
187444c061aSmrg    pd->keysyms = NULL;
188444c061aSmrg    XDisplayKeycodes(dpy, &pd->min_keycode, &pd->max_keycode);
189444c061aSmrg    pd->modKeysyms = NULL;
190444c061aSmrg    pd->modsToKeysyms = NULL;
191444c061aSmrg    pd->appContext = app;
192444c061aSmrg    pd->name = XrmStringToName(name);
193444c061aSmrg    pd->class = XrmStringToClass(classname);
194444c061aSmrg    pd->being_destroyed = False;
195444c061aSmrg    pd->GClist = NULL;
196444c061aSmrg    pd->pixmap_tab = NULL;
197444c061aSmrg    pd->language = NULL;
198444c061aSmrg    pd->rv = False;
199444c061aSmrg    pd->last_event.xany.serial = 0;
200444c061aSmrg    pd->last_timestamp = 0;
201444c061aSmrg    _XtAllocTMContext(pd);
202444c061aSmrg    pd->mapping_callbacks = NULL;
203444c061aSmrg
204444c061aSmrg    pd->pdi.grabList = NULL;
205444c061aSmrg    pd->pdi.trace = NULL;
206444c061aSmrg    pd->pdi.traceDepth = 0;
207444c061aSmrg    pd->pdi.traceMax = 0;
208444c061aSmrg    pd->pdi.focusWidget = NULL;
209444c061aSmrg    pd->pdi.activatingKey = 0;
210444c061aSmrg    pd->pdi.keyboard.grabType = XtNoServerGrab;
211444c061aSmrg    pd->pdi.pointer.grabType  = XtNoServerGrab;
212444c061aSmrg    _XtAllocWWTable(pd);
213444c061aSmrg    pd->per_screen_db = (XrmDatabase *)__XtCalloc(ScreenCount(dpy),
214444c061aSmrg						sizeof(XrmDatabase));
215444c061aSmrg    pd->cmd_db = (XrmDatabase)NULL;
216444c061aSmrg    pd->server_db = (XrmDatabase)NULL;
217444c061aSmrg    pd->dispatcher_list = NULL;
218444c061aSmrg    pd->ext_select_list = NULL;
219444c061aSmrg    pd->ext_select_count = 0;
220444c061aSmrg    pd->hook_object = NULL;
221444c061aSmrg#if 0
222444c061aSmrg    pd->hook_object = _XtCreate("hooks", "Hooks", hookObjectClass,
223444c061aSmrg	(Widget)NULL, (Screen*)DefaultScreenOfDisplay(dpy),
224444c061aSmrg	(ArgList)NULL, 0, (XtTypedArgList)NULL, 0,
225444c061aSmrg	(ConstraintWidgetClass)NULL);
226444c061aSmrg#endif
227444c061aSmrg
228444c061aSmrg#ifndef X_NO_RESOURCE_CONFIGURATION_MANAGEMENT
229444c061aSmrg    pd->rcm_init = XInternAtom (dpy, RCM_INIT, 0);
230444c061aSmrg    pd->rcm_data = XInternAtom (dpy, RCM_DATA, 0);
231444c061aSmrg#endif
232444c061aSmrg
233444c061aSmrg    return pd;
234444c061aSmrg}
235444c061aSmrg
236444c061aSmrgDisplay *XtOpenDisplay(
237444c061aSmrg	XtAppContext app,
238444c061aSmrg	_Xconst char* displayName,
239444c061aSmrg	_Xconst char* applName,
240444c061aSmrg	_Xconst char* className,
241444c061aSmrg	XrmOptionDescRec *urlist,
242444c061aSmrg	Cardinal num_urs,
243444c061aSmrg	int *argc,
244444c061aSmrg	String *argv)
245444c061aSmrg{
246444c061aSmrg	Display *d;
247444c061aSmrg	XrmDatabase db = 0;
248444c061aSmrg	XtPerDisplay pd;
249444c061aSmrg	String language = NULL;
250444c061aSmrg
251444c061aSmrg	LOCK_APP(app);
252444c061aSmrg	LOCK_PROCESS;
253444c061aSmrg	/* parse the command line for name, display, and/or language */
254444c061aSmrg	db = _XtPreparseCommandLine(urlist, num_urs, *argc, argv,
255444c061aSmrg				(String *)&applName,
256444c061aSmrg				(String *)(displayName ? NULL : &displayName),
257444c061aSmrg				(app->process->globalLangProcRec.proc ?
258444c061aSmrg				&language : NULL));
259444c061aSmrg	UNLOCK_PROCESS;
260444c061aSmrg	d = XOpenDisplay(displayName);
261444c061aSmrg
262444c061aSmrg	if (! applName && !(applName = getenv("RESOURCE_NAME"))) {
263444c061aSmrg	    if (*argc > 0 && argv[0] && *argv[0]) {
264444c061aSmrg#ifdef WIN32
265444c061aSmrg		char *ptr = strrchr(argv[0], '\\');
266444c061aSmrg#else
267444c061aSmrg		char *ptr = strrchr(argv[0], '/');
268444c061aSmrg#endif
269444c061aSmrg#ifdef __UNIXOS2__
270444c061aSmrg		char *dot_ptr,*ptr2;
271444c061aSmrg		ptr2 = strrchr(argv[0],'\\');
272444c061aSmrg		if (ptr2 > ptr) ptr = ptr2;
273444c061aSmrg		dot_ptr = strrchr(argv[0],'.');
274444c061aSmrg		if (dot_ptr && (dot_ptr > ptr)) *dot_ptr='\0';
275444c061aSmrg#endif  /* This will remove the .exe suffix under OS/2 */
276444c061aSmrg
277444c061aSmrg		if (ptr) applName = ++ptr;
278444c061aSmrg		else applName = argv[0];
279444c061aSmrg	    } else
280444c061aSmrg		applName = "main";
281444c061aSmrg	}
282444c061aSmrg
283444c061aSmrg	if (d) {
284444c061aSmrg	    pd = InitPerDisplay(d, app, applName, className);
285444c061aSmrg	    pd->language = language;
286444c061aSmrg	    _XtDisplayInitialize(d, pd, applName, urlist, num_urs, argc, argv);
287444c061aSmrg	} else {
288444c061aSmrg	    int len;
289444c061aSmrg	    displayName = XDisplayName(displayName);
290444c061aSmrg	    len = strlen (displayName);
291444c061aSmrg	    app->display_name_tried = (String) __XtMalloc (len + 1);
292444c061aSmrg	    strncpy ((char*) app->display_name_tried, displayName, len + 1);
293444c061aSmrg	    app->display_name_tried[len] = '\0';
294444c061aSmrg	}
295444c061aSmrg	if (db) XrmDestroyDatabase(db);
296444c061aSmrg	UNLOCK_APP(app);
297444c061aSmrg	return d;
298444c061aSmrg}
299444c061aSmrg
300444c061aSmrgDisplay *
301444c061aSmrg_XtAppInit(
302444c061aSmrg	XtAppContext * app_context_return,
303444c061aSmrg	String application_class,
304444c061aSmrg	XrmOptionDescRec *options,
305444c061aSmrg	Cardinal num_options,
306444c061aSmrg	int *argc_in_out,
307444c061aSmrg	String **argv_in_out,
308444c061aSmrg	String * fallback_resources)
309444c061aSmrg{
310444c061aSmrg    String *saved_argv;
311444c061aSmrg    int i;
312444c061aSmrg    Display *dpy;
313444c061aSmrg
314444c061aSmrg/*
315444c061aSmrg * Save away argv and argc so we can set the properties later
316444c061aSmrg */
317444c061aSmrg
318444c061aSmrg    saved_argv = (String *)
319444c061aSmrg	__XtMalloc( (Cardinal)((*argc_in_out + 1) * sizeof(String)) );
320444c061aSmrg
321444c061aSmrg    for (i = 0 ; i < *argc_in_out ; i++) saved_argv[i] = (*argv_in_out)[i];
322444c061aSmrg    saved_argv[i] = NULL;	/* NULL terminate that sucker. */
323444c061aSmrg
324444c061aSmrg
325444c061aSmrg    *app_context_return = XtCreateApplicationContext();
326444c061aSmrg
327444c061aSmrg    LOCK_APP((*app_context_return));
328444c061aSmrg    if (fallback_resources) /* save a procedure call */
329444c061aSmrg	XtAppSetFallbackResources(*app_context_return, fallback_resources);
330444c061aSmrg
331444c061aSmrg    dpy = XtOpenDisplay(*app_context_return, (String) NULL, NULL,
332444c061aSmrg			application_class,
333444c061aSmrg			options, num_options, argc_in_out, *argv_in_out);
334444c061aSmrg
335444c061aSmrg    if (!dpy) {
336444c061aSmrg	String param = (*app_context_return)->display_name_tried;
337444c061aSmrg	Cardinal param_count = 1;
338444c061aSmrg	XtErrorMsg("invalidDisplay","xtInitialize",XtCXtToolkitError,
339444c061aSmrg                   "Can't open display: %s", &param, &param_count);
340444c061aSmrg	XtFree((char *) (*app_context_return)->display_name_tried);
341444c061aSmrg    }
342444c061aSmrg    *argv_in_out = saved_argv;
343444c061aSmrg    UNLOCK_APP((*app_context_return));
344444c061aSmrg    return dpy;
345444c061aSmrg}
346444c061aSmrg
347444c061aSmrgvoid
348444c061aSmrgXtDisplayInitialize(
349444c061aSmrg	XtAppContext app,
350444c061aSmrg	Display *dpy,
351444c061aSmrg	_Xconst char* name,
352444c061aSmrg	_Xconst char* classname,
353444c061aSmrg	XrmOptionDescRec *urlist,
354444c061aSmrg	Cardinal num_urs,
355444c061aSmrg	int *argc,
356444c061aSmrg	String *argv
357444c061aSmrg	)
358444c061aSmrg{
359444c061aSmrg    XtPerDisplay pd;
360444c061aSmrg    XrmDatabase db = 0;
361444c061aSmrg
362444c061aSmrg    LOCK_APP(app);
363444c061aSmrg    pd = InitPerDisplay(dpy, app, name, classname);
364444c061aSmrg    LOCK_PROCESS;
365444c061aSmrg    if (app->process->globalLangProcRec.proc)
366444c061aSmrg	/* pre-parse the command line for the language resource */
367444c061aSmrg	db = _XtPreparseCommandLine(urlist, num_urs, *argc, argv, NULL, NULL,
368444c061aSmrg				    &pd->language);
369444c061aSmrg    UNLOCK_PROCESS;
370444c061aSmrg    _XtDisplayInitialize(dpy, pd, name, urlist, num_urs, argc, argv);
371444c061aSmrg    if (db) XrmDestroyDatabase(db);
372444c061aSmrg    UNLOCK_APP(app);
373444c061aSmrg}
374444c061aSmrg
375444c061aSmrgXtAppContext XtCreateApplicationContext(void)
376444c061aSmrg{
377444c061aSmrg	XtAppContext app = XtNew(XtAppStruct);
378444c061aSmrg#ifdef XTHREADS
379444c061aSmrg	app->lock_info = NULL;
380444c061aSmrg	app->lock = NULL;
381444c061aSmrg	app->unlock = NULL;
382444c061aSmrg	app->yield_lock = NULL;
383444c061aSmrg	app->restore_lock = NULL;
384444c061aSmrg	app->free_lock = NULL;
385444c061aSmrg#endif
386444c061aSmrg	INIT_APP_LOCK(app);
387444c061aSmrg	LOCK_APP(app);
388444c061aSmrg	LOCK_PROCESS;
389444c061aSmrg	app->process = _XtGetProcessContext();
390444c061aSmrg	app->next = app->process->appContextList;
391444c061aSmrg	app->process->appContextList = app;
392444c061aSmrg	app->langProcRec.proc = app->process->globalLangProcRec.proc;
393444c061aSmrg	app->langProcRec.closure = app->process->globalLangProcRec.closure;
394444c061aSmrg	app->destroy_callbacks = NULL;
395444c061aSmrg	app->list = NULL;
396444c061aSmrg	app->count = app->max = app->last = 0;
397444c061aSmrg	app->timerQueue = NULL;
398444c061aSmrg	app->workQueue = NULL;
399444c061aSmrg	app->signalQueue = NULL;
400444c061aSmrg	app->input_list = NULL;
401444c061aSmrg	app->outstandingQueue = NULL;
402444c061aSmrg	app->errorDB = NULL;
403444c061aSmrg	_XtSetDefaultErrorHandlers(&app->errorMsgHandler,
404444c061aSmrg		&app->warningMsgHandler, &app->errorHandler,
405444c061aSmrg		&app->warningHandler);
406444c061aSmrg	app->action_table = NULL;
407444c061aSmrg	_XtSetDefaultSelectionTimeout(&app->selectionTimeout);
408444c061aSmrg	_XtSetDefaultConverterTable(&app->converterTable);
409444c061aSmrg	app->sync = app->being_destroyed = app->error_inited = FALSE;
410444c061aSmrg	app->in_phase2_destroy = NULL;
411444c061aSmrg#ifndef USE_POLL
412444c061aSmrg	FD_ZERO(&app->fds.rmask);
413444c061aSmrg	FD_ZERO(&app->fds.wmask);
414444c061aSmrg	FD_ZERO(&app->fds.emask);
415444c061aSmrg#endif
416444c061aSmrg	app->fds.nfds = 0;
417444c061aSmrg	app->input_count = app->input_max = 0;
418444c061aSmrg	_XtHeapInit(&app->heap);
419444c061aSmrg	app->fallback_resources = NULL;
420444c061aSmrg	_XtPopupInitialize(app);
421444c061aSmrg	app->action_hook_list = NULL;
422444c061aSmrg	app->block_hook_list = NULL;
423444c061aSmrg	app->destroy_list_size = app->destroy_count = app->dispatch_level = 0;
424444c061aSmrg	app->destroy_list = NULL;
425444c061aSmrg#ifndef NO_IDENTIFY_WINDOWS
426444c061aSmrg	app->identify_windows = False;
427444c061aSmrg#endif
428444c061aSmrg	app->free_bindings = NULL;
429444c061aSmrg	app->display_name_tried = NULL;
430444c061aSmrg	app->dpy_destroy_count = 0;
431444c061aSmrg	app->dpy_destroy_list = NULL;
432444c061aSmrg	app->exit_flag = FALSE;
433444c061aSmrg	app->rebuild_fdlist = TRUE;
434444c061aSmrg	UNLOCK_PROCESS;
435444c061aSmrg	UNLOCK_APP(app);
436444c061aSmrg	return app;
437444c061aSmrg}
438444c061aSmrg
439444c061aSmrgvoid XtAppSetExitFlag (
440444c061aSmrg    XtAppContext app)
441444c061aSmrg{
442444c061aSmrg    LOCK_APP(app);
443444c061aSmrg    app->exit_flag = TRUE;
444444c061aSmrg    UNLOCK_APP(app);
445444c061aSmrg}
446444c061aSmrg
447444c061aSmrgBoolean XtAppGetExitFlag (
448444c061aSmrg    XtAppContext app)
449444c061aSmrg{
450444c061aSmrg    Boolean retval;
451444c061aSmrg    LOCK_APP(app);
452444c061aSmrg    retval = app->exit_flag;
453444c061aSmrg    UNLOCK_APP(app);
454444c061aSmrg    return retval;
455444c061aSmrg}
456444c061aSmrg
457444c061aSmrgstatic void DestroyAppContext(XtAppContext app)
458444c061aSmrg{
459444c061aSmrg	XtAppContext* prev_app;
460444c061aSmrg
461444c061aSmrg	prev_app = &app->process->appContextList;
462444c061aSmrg	while (app->count-- > 0) XtCloseDisplay(app->list[app->count]);
463444c061aSmrg	if (app->list != NULL) XtFree((char *)app->list);
464444c061aSmrg	_XtFreeConverterTable(app->converterTable);
465444c061aSmrg	_XtCacheFlushTag(app, (XtPointer)&app->heap);
466444c061aSmrg	_XtFreeActions(app->action_table);
467444c061aSmrg	if (app->destroy_callbacks != NULL) {
468444c061aSmrg	    XtCallCallbackList((Widget) NULL,
469444c061aSmrg			       (XtCallbackList)app->destroy_callbacks,
470444c061aSmrg			       (XtPointer)app);
471444c061aSmrg	    _XtRemoveAllCallbacks(&app->destroy_callbacks);
472444c061aSmrg	}
473444c061aSmrg	while (app->timerQueue) XtRemoveTimeOut((XtIntervalId)app->timerQueue);
474444c061aSmrg	while (app->workQueue) XtRemoveWorkProc((XtWorkProcId)app->workQueue);
475444c061aSmrg	while (app->signalQueue) XtRemoveSignal((XtSignalId)app->signalQueue);
476444c061aSmrg	if (app->input_list) _XtRemoveAllInputs(app);
477444c061aSmrg	XtFree((char*)app->destroy_list);
478444c061aSmrg	_XtHeapFree(&app->heap);
479444c061aSmrg	while (*prev_app != app) prev_app = &(*prev_app)->next;
480444c061aSmrg	*prev_app = app->next;
481444c061aSmrg	if (app->process->defaultAppContext == app)
482444c061aSmrg	    app->process->defaultAppContext = NULL;
483444c061aSmrg	if (app->free_bindings) _XtDoFreeBindings (app);
484444c061aSmrg	FREE_APP_LOCK(app);
485444c061aSmrg	XtFree((char *)app);
486444c061aSmrg}
487444c061aSmrg
488444c061aSmrgstatic XtAppContext* appDestroyList = NULL;
489444c061aSmrgint _XtAppDestroyCount = 0;
490444c061aSmrg
491444c061aSmrgvoid XtDestroyApplicationContext(XtAppContext app)
492444c061aSmrg{
493444c061aSmrg	LOCK_APP(app);
494444c061aSmrg	if (app->being_destroyed) {
495444c061aSmrg	    UNLOCK_APP(app);
496444c061aSmrg	    return;
497444c061aSmrg	}
498444c061aSmrg
499444c061aSmrg	if (_XtSafeToDestroy(app)) {
500444c061aSmrg	    LOCK_PROCESS;
501444c061aSmrg	    DestroyAppContext(app);
502444c061aSmrg	    UNLOCK_PROCESS;
503444c061aSmrg	} else {
504444c061aSmrg	    app->being_destroyed = TRUE;
505444c061aSmrg	    LOCK_PROCESS;
506444c061aSmrg	    _XtAppDestroyCount++;
507444c061aSmrg	    appDestroyList =
508444c061aSmrg		    (XtAppContext *) XtRealloc((char *) appDestroyList,
509444c061aSmrg		    (unsigned) (_XtAppDestroyCount * sizeof(XtAppContext)));
510444c061aSmrg	    appDestroyList[_XtAppDestroyCount-1] = app;
511444c061aSmrg	    UNLOCK_PROCESS;
512444c061aSmrg	    UNLOCK_APP(app);
513444c061aSmrg	}
514444c061aSmrg}
515444c061aSmrg
516444c061aSmrgvoid _XtDestroyAppContexts(void)
517444c061aSmrg{
518444c061aSmrg	int i,ii;
519444c061aSmrg	XtAppContext apps[8];
520444c061aSmrg	XtAppContext* pApps;
521444c061aSmrg
522444c061aSmrg	pApps = XtStackAlloc (sizeof (XtAppContext) * _XtAppDestroyCount, apps);
523444c061aSmrg
524444c061aSmrg	for (i = ii = 0; i < _XtAppDestroyCount; i++) {
525444c061aSmrg	    if (_XtSafeToDestroy(appDestroyList[i]))
526444c061aSmrg		DestroyAppContext(appDestroyList[i]);
527444c061aSmrg	    else
528444c061aSmrg		pApps[ii++] = appDestroyList[i];
529444c061aSmrg	}
530444c061aSmrg	_XtAppDestroyCount = ii;
531444c061aSmrg	if (_XtAppDestroyCount == 0) {
532444c061aSmrg	    XtFree((char *) appDestroyList);
533444c061aSmrg	    appDestroyList = NULL;
534444c061aSmrg	} else {
535444c061aSmrg	    for (i = 0; i < ii; i++)
536444c061aSmrg		appDestroyList[i] = pApps[i];
537444c061aSmrg	}
538444c061aSmrg	XtStackFree ((XtPointer) pApps, apps);
539444c061aSmrg}
540444c061aSmrg
541444c061aSmrgXrmDatabase XtDatabase(Display *dpy)
542444c061aSmrg{
543444c061aSmrg    XrmDatabase retval;
544444c061aSmrg    DPY_TO_APPCON(dpy);
545444c061aSmrg
546444c061aSmrg    LOCK_APP(app);
547444c061aSmrg    retval = XrmGetDatabase(dpy);
548444c061aSmrg    UNLOCK_APP(app);
549444c061aSmrg    return retval;
550444c061aSmrg}
551444c061aSmrg
552444c061aSmrgPerDisplayTablePtr _XtperDisplayList = NULL;
553444c061aSmrg
554444c061aSmrgXtPerDisplay _XtSortPerDisplayList(Display *dpy)
555444c061aSmrg{
556444c061aSmrg	register PerDisplayTablePtr pd, opd = NULL;
557444c061aSmrg
558444c061aSmrg	LOCK_PROCESS;
559444c061aSmrg	for (pd = _XtperDisplayList;
560444c061aSmrg	     pd != NULL && pd->dpy != dpy;
561444c061aSmrg	     pd = pd->next) {
562444c061aSmrg	    opd = pd;
563444c061aSmrg	}
564444c061aSmrg
565444c061aSmrg	if (pd == NULL) {
566444c061aSmrg	    XtErrorMsg(XtNnoPerDisplay, "getPerDisplay", XtCXtToolkitError,
567444c061aSmrg		    "Couldn't find per display information",
568444c061aSmrg		    (String *) NULL, (Cardinal *)NULL);
569444c061aSmrg	}
570444c061aSmrg
571444c061aSmrg	if (pd != _XtperDisplayList) {	/* move it to the front */
572444c061aSmrg	    /* opd points to the previous one... */
573444c061aSmrg
574444c061aSmrg	    opd->next = pd->next;
575444c061aSmrg	    pd->next = _XtperDisplayList;
576444c061aSmrg	    _XtperDisplayList = pd;
577444c061aSmrg	}
578444c061aSmrg	UNLOCK_PROCESS;
579444c061aSmrg	return &(pd->perDpy);
580444c061aSmrg}
581444c061aSmrg
582444c061aSmrgXtAppContext XtDisplayToApplicationContext(Display *dpy)
583444c061aSmrg{
584444c061aSmrg	XtAppContext retval;
585444c061aSmrg
586444c061aSmrg	retval = _XtGetPerDisplay(dpy)->appContext;
587444c061aSmrg	return retval;
588444c061aSmrg}
589444c061aSmrg
590444c061aSmrgstatic void CloseDisplay(Display *dpy)
591444c061aSmrg{
592444c061aSmrg        register XtPerDisplay xtpd;
593444c061aSmrg	register PerDisplayTablePtr pd, opd = NULL;
594444c061aSmrg	XrmDatabase db;
595444c061aSmrg	int i;
596444c061aSmrg
597444c061aSmrg	XtDestroyWidget(XtHooksOfDisplay(dpy));
598444c061aSmrg
599444c061aSmrg	LOCK_PROCESS;
600444c061aSmrg	for (pd = _XtperDisplayList;
601444c061aSmrg	     pd != NULL && pd->dpy != dpy;
602444c061aSmrg	     pd = pd->next){
603444c061aSmrg	    opd = pd;
604444c061aSmrg	}
605444c061aSmrg
606444c061aSmrg	if (pd == NULL) {
607444c061aSmrg	    XtErrorMsg(XtNnoPerDisplay, "closeDisplay", XtCXtToolkitError,
608444c061aSmrg		    "Couldn't find per display information",
609444c061aSmrg		    (String *) NULL, (Cardinal *)NULL);
610444c061aSmrg	}
611444c061aSmrg
612444c061aSmrg	if (pd == _XtperDisplayList) _XtperDisplayList = pd->next;
613444c061aSmrg	else opd->next = pd->next;
614444c061aSmrg
615444c061aSmrg	xtpd = &(pd->perDpy);
616444c061aSmrg
617444c061aSmrg        if (xtpd != NULL) {
618444c061aSmrg	    if (xtpd->destroy_callbacks != NULL) {
619444c061aSmrg		XtCallCallbackList((Widget) NULL,
620444c061aSmrg				   (XtCallbackList)xtpd->destroy_callbacks,
621444c061aSmrg				   (XtPointer)xtpd);
622444c061aSmrg		_XtRemoveAllCallbacks(&xtpd->destroy_callbacks);
623444c061aSmrg	    }
624444c061aSmrg	    if (xtpd->mapping_callbacks != NULL)
625444c061aSmrg		_XtRemoveAllCallbacks(&xtpd->mapping_callbacks);
626444c061aSmrg	    XtDeleteFromAppContext(dpy, xtpd->appContext);
627444c061aSmrg	    if (xtpd->keysyms)
628444c061aSmrg		XFree((char *) xtpd->keysyms);
629444c061aSmrg            XtFree((char *) xtpd->modKeysyms);
630444c061aSmrg            XtFree((char *) xtpd->modsToKeysyms);
631444c061aSmrg            xtpd->keysyms_per_keycode = 0;
632444c061aSmrg            xtpd->being_destroyed = FALSE;
633444c061aSmrg            xtpd->keysyms = NULL;
634444c061aSmrg            xtpd->modKeysyms = NULL;
635444c061aSmrg            xtpd->modsToKeysyms = NULL;
636444c061aSmrg	    XDestroyRegion(xtpd->region);
637444c061aSmrg	    _XtCacheFlushTag(xtpd->appContext, (XtPointer)&xtpd->heap);
638444c061aSmrg	    _XtGClistFree(dpy, xtpd);
639444c061aSmrg	    XtFree((char*)xtpd->pdi.trace);
640444c061aSmrg	    _XtHeapFree(&xtpd->heap);
641444c061aSmrg	    _XtFreeWWTable(xtpd);
642444c061aSmrg	    xtpd->per_screen_db[DefaultScreen(dpy)] = (XrmDatabase)NULL;
643444c061aSmrg	    for (i = ScreenCount(dpy); --i >= 0; ) {
644444c061aSmrg		db = xtpd->per_screen_db[i];
645444c061aSmrg		if (db)
646444c061aSmrg		    XrmDestroyDatabase(db);
647444c061aSmrg	    }
648444c061aSmrg	    XtFree((char *)xtpd->per_screen_db);
649444c061aSmrg	    if ((db = XrmGetDatabase(dpy)))
650444c061aSmrg		XrmDestroyDatabase(db);
651444c061aSmrg	    if (xtpd->cmd_db)
652444c061aSmrg		XrmDestroyDatabase(xtpd->cmd_db);
653444c061aSmrg	    if (xtpd->server_db)
654444c061aSmrg		XrmDestroyDatabase(xtpd->server_db);
655444c061aSmrg	    XtFree(xtpd->language);
656444c061aSmrg	    if (xtpd->dispatcher_list != NULL)
657444c061aSmrg		XtFree((char *) xtpd->dispatcher_list);
658444c061aSmrg	    if (xtpd->ext_select_list != NULL)
659444c061aSmrg		XtFree((char *) xtpd->ext_select_list);
660444c061aSmrg        }
661444c061aSmrg	XtFree((char*)pd);
662444c061aSmrg	XrmSetDatabase(dpy, (XrmDatabase)NULL);
663444c061aSmrg	XCloseDisplay(dpy);
664444c061aSmrg	UNLOCK_PROCESS;
665444c061aSmrg}
666444c061aSmrg
667444c061aSmrgvoid XtCloseDisplay(Display *dpy)
668444c061aSmrg{
669444c061aSmrg	XtPerDisplay pd;
670444c061aSmrg	XtAppContext app = XtDisplayToApplicationContext(dpy);
671444c061aSmrg
672444c061aSmrg	LOCK_APP(app);
673444c061aSmrg	pd = _XtGetPerDisplay(dpy);
674444c061aSmrg	if (pd->being_destroyed) {
675444c061aSmrg	    UNLOCK_APP(app);
676444c061aSmrg	    return;
677444c061aSmrg	}
678444c061aSmrg
679444c061aSmrg	if (_XtSafeToDestroy(app)) CloseDisplay(dpy);
680444c061aSmrg	else {
681444c061aSmrg	    pd->being_destroyed = TRUE;
682444c061aSmrg	    app->dpy_destroy_count++;
683444c061aSmrg	    app->dpy_destroy_list = (Display **)
684444c061aSmrg		XtRealloc((char *) app->dpy_destroy_list,
685444c061aSmrg		    (unsigned) (app->dpy_destroy_count * sizeof(Display *)));
686444c061aSmrg	    app->dpy_destroy_list[app->dpy_destroy_count-1] = dpy;
687444c061aSmrg	}
688444c061aSmrg	UNLOCK_APP(app);
689444c061aSmrg}
690444c061aSmrg
691444c061aSmrgvoid _XtCloseDisplays(XtAppContext app)
692444c061aSmrg{
693444c061aSmrg	int i;
694444c061aSmrg
695444c061aSmrg	LOCK_APP(app);
696444c061aSmrg	for (i = 0; i < app->dpy_destroy_count; i++) {
697444c061aSmrg	    CloseDisplay(app->dpy_destroy_list[i]);
698444c061aSmrg	}
699444c061aSmrg	app->dpy_destroy_count = 0;
700444c061aSmrg	XtFree((char *) app->dpy_destroy_list);
701444c061aSmrg	app->dpy_destroy_list = NULL;
702444c061aSmrg	UNLOCK_APP(app);
703444c061aSmrg}
704444c061aSmrg
705444c061aSmrgXtAppContext XtWidgetToApplicationContext(Widget w)
706444c061aSmrg{
707444c061aSmrg	XtAppContext retval;
708444c061aSmrg
709444c061aSmrg	retval = _XtGetPerDisplay(XtDisplayOfObject(w))->appContext;
710444c061aSmrg	return retval;
711444c061aSmrg}
712444c061aSmrg
713444c061aSmrg
714444c061aSmrgvoid XtGetApplicationNameAndClass(
715444c061aSmrg    Display *dpy,
716444c061aSmrg    String *name_return,
717444c061aSmrg    String *class_return)
718444c061aSmrg{
719444c061aSmrg    XtPerDisplay pd;
720444c061aSmrg
721444c061aSmrg    pd = _XtGetPerDisplay(dpy);
722444c061aSmrg    *name_return = XrmQuarkToString(pd->name);
723444c061aSmrg    *class_return = XrmQuarkToString(pd->class);
724444c061aSmrg}
725444c061aSmrg
726444c061aSmrgXtPerDisplay _XtGetPerDisplay (Display* display)
727444c061aSmrg{
728444c061aSmrg    XtPerDisplay retval;
729444c061aSmrg
730444c061aSmrg    LOCK_PROCESS;
731444c061aSmrg    retval = ((_XtperDisplayList != NULL &&
732444c061aSmrg	      _XtperDisplayList->dpy == display)
733444c061aSmrg	      ? &_XtperDisplayList->perDpy
734444c061aSmrg	      : _XtSortPerDisplayList(display));
735444c061aSmrg    UNLOCK_PROCESS;
736444c061aSmrg    return retval;
737444c061aSmrg}
738444c061aSmrg
739444c061aSmrgXtPerDisplayInputRec* _XtGetPerDisplayInput(Display* display)
740444c061aSmrg{
741444c061aSmrg    XtPerDisplayInputRec* retval;
742444c061aSmrg    LOCK_PROCESS;
743444c061aSmrg    retval = ((_XtperDisplayList != NULL &&
744444c061aSmrg	      _XtperDisplayList->dpy == display)
745444c061aSmrg	      ? &_XtperDisplayList->perDpy.pdi
746444c061aSmrg	      : &_XtSortPerDisplayList(display)->pdi);
747444c061aSmrg    UNLOCK_PROCESS;
748444c061aSmrg    return retval;
749444c061aSmrg}
750444c061aSmrg
751444c061aSmrgvoid XtGetDisplays(
752444c061aSmrg    XtAppContext app_context,
753444c061aSmrg    Display*** dpy_return,
754444c061aSmrg    Cardinal* num_dpy_return)
755444c061aSmrg{
756444c061aSmrg    int ii;
757444c061aSmrg    LOCK_APP(app_context);
758444c061aSmrg    *num_dpy_return = app_context->count;
759444c061aSmrg    *dpy_return = (Display**)__XtMalloc(app_context->count * sizeof(Display*));
760444c061aSmrg    for (ii = 0; ii < app_context->count; ii++)
761444c061aSmrg	(*dpy_return)[ii] = app_context->list[ii];
762444c061aSmrg    UNLOCK_APP(app_context);
763444c061aSmrg}
764