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