1 /***********************************************************
2 Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
3
4 Permission is hereby granted, free of charge, to any person obtaining a
5 copy of this software and associated documentation files (the "Software"),
6 to deal in the Software without restriction, including without limitation
7 the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 and/or sell copies of the Software, and to permit persons to whom the
9 Software is furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice (including the next
12 paragraph) shall be included in all copies or substantial portions of the
13 Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 DEALINGS IN THE SOFTWARE.
22
23 Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
24
25 All Rights Reserved
26
27 Permission to use, copy, modify, and distribute this software and its
28 documentation for any purpose and without fee is hereby granted,
29 provided that the above copyright notice appear in all copies and that
30 both that copyright notice and this permission notice appear in
31 supporting documentation, and that the name of Digital not be
32 used in advertising or publicity pertaining to distribution of the
33 software without specific, written prior permission.
34
35 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
36 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
37 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
38 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
39 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
40 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
41 SOFTWARE.
42
43 ******************************************************************/
44
45 /*
46
47 Copyright 1987, 1988, 1998 The Open Group
48
49 Permission to use, copy, modify, distribute, and sell this software and its
50 documentation for any purpose is hereby granted without fee, provided that
51 the above copyright notice appear in all copies and that both that
52 copyright notice and this permission notice appear in supporting
53 documentation.
54
55 The above copyright notice and this permission notice shall be included in
56 all copies or substantial portions of the Software.
57
58 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
61 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
62 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
63 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
64
65 Except as contained in this notice, the name of The Open Group shall not be
66 used in advertising or otherwise to promote the sale, use or other dealings
67 in this Software without prior written authorization from The Open Group.
68
69 */
70
71 #ifdef HAVE_CONFIG_H
72 #include <config.h>
73 #endif
74 #include "IntrinsicI.h"
75 #ifndef X_NO_RESOURCE_CONFIGURATION_MANAGEMENT
76 #include "ResConfigP.h"
77 #endif
78
79 #include <stdlib.h>
80
81 #ifdef XTHREADS
82 void (*_XtProcessLock) (void) = NULL;
83 void (*_XtProcessUnlock) (void) = NULL;
84 void (*_XtInitAppLock) (XtAppContext) = NULL;
85 #endif
86
87 static _Xconst _XtString XtNnoPerDisplay = "noPerDisplay";
88
89 ProcessContext
_XtGetProcessContext(void)90 _XtGetProcessContext(void)
91 {
92 static ProcessContextRec processContextRec = {
93 (XtAppContext) NULL,
94 (XtAppContext) NULL,
95 (ConverterTable) NULL,
96 {(XtLanguageProc) NULL, (XtPointer) NULL}
97 };
98
99 return &processContextRec;
100 }
101
102 XtAppContext
_XtDefaultAppContext(void)103 _XtDefaultAppContext(void)
104 {
105 ProcessContext process = _XtGetProcessContext();
106 XtAppContext app;
107
108 LOCK_PROCESS;
109 if (process->defaultAppContext == NULL) {
110 process->defaultAppContext = XtCreateApplicationContext();
111 }
112 app = process->defaultAppContext;
113 UNLOCK_PROCESS;
114 return app;
115 }
116
117 static void
AddToAppContext(Display * d,XtAppContext app)118 AddToAppContext(Display *d, XtAppContext app)
119 {
120 #define DISPLAYS_TO_ADD 4
121
122 if (app->count >= app->max) {
123 app->max = (short) (app->max + DISPLAYS_TO_ADD);
124 app->list = (Display **) XtRealloc((char *) app->list,
125 (Cardinal) (((size_t) app->max) *
126 sizeof(Display *)));
127 }
128
129 app->list[app->count++] = d;
130 app->rebuild_fdlist = TRUE;
131 #ifdef USE_POLL
132 app->fds.nfds++;
133 #else
134 if (ConnectionNumber(d) + 1 > app->fds.nfds) {
135 app->fds.nfds = ConnectionNumber(d) + 1;
136 }
137 #endif
138 #undef DISPLAYS_TO_ADD
139 }
140
141 static void
XtDeleteFromAppContext(Display * d,register XtAppContext app)142 XtDeleteFromAppContext(Display *d, register XtAppContext app)
143 {
144 register int i;
145
146 for (i = 0; i < app->count; i++)
147 if (app->list[i] == d)
148 break;
149
150 if (i < app->count) {
151 if (i <= app->last && app->last > 0)
152 app->last--;
153 for (i++; i < app->count; i++)
154 app->list[i - 1] = app->list[i];
155 app->count--;
156 }
157 app->rebuild_fdlist = TRUE;
158 #ifdef USE_POLL
159 app->fds.nfds--;
160 #else
161 if ((ConnectionNumber(d) + 1) == app->fds.nfds)
162 app->fds.nfds--;
163 else /* Unnecessary, just to be fool-proof */
164 FD_CLR(ConnectionNumber(d), &app->fds.rmask);
165 #endif
166 }
167
168 static XtPerDisplay
NewPerDisplay(Display * dpy)169 NewPerDisplay(Display *dpy)
170 {
171 PerDisplayTablePtr pd;
172
173 pd = XtNew(PerDisplayTable);
174
175 LOCK_PROCESS;
176 pd->dpy = dpy;
177 pd->next = _XtperDisplayList;
178 _XtperDisplayList = pd;
179 UNLOCK_PROCESS;
180 return &(pd->perDpy);
181 }
182
183 static XtPerDisplay
InitPerDisplay(Display * dpy,XtAppContext app,_Xconst char * name,_Xconst char * classname)184 InitPerDisplay(Display *dpy,
185 XtAppContext app,
186 _Xconst char *name,
187 _Xconst char *classname)
188 {
189 XtPerDisplay pd;
190
191 AddToAppContext(dpy, app);
192
193 pd = NewPerDisplay(dpy);
194 _XtHeapInit(&pd->heap);
195 pd->destroy_callbacks = NULL;
196 pd->region = XCreateRegion();
197 pd->case_cvt = NULL;
198 pd->defaultKeycodeTranslator = XtTranslateKey;
199 pd->keysyms_serial = 0;
200 pd->keysyms = NULL;
201 XDisplayKeycodes(dpy, &pd->min_keycode, &pd->max_keycode);
202 pd->modKeysyms = NULL;
203 pd->modsToKeysyms = NULL;
204 pd->appContext = app;
205 pd->name = XrmStringToName(name);
206 pd->class = XrmStringToClass(classname);
207 pd->being_destroyed = False;
208 pd->GClist = NULL;
209 pd->pixmap_tab = NULL;
210 pd->language = NULL;
211 pd->rv = False;
212 pd->last_event.xany.serial = 0;
213 pd->last_timestamp = 0;
214 _XtAllocTMContext(pd);
215 pd->mapping_callbacks = NULL;
216
217 pd->pdi.grabList = NULL;
218 pd->pdi.trace = NULL;
219 pd->pdi.traceDepth = 0;
220 pd->pdi.traceMax = 0;
221 pd->pdi.focusWidget = NULL;
222 pd->pdi.activatingKey = 0;
223 pd->pdi.keyboard.grabType = XtNoServerGrab;
224 pd->pdi.pointer.grabType = XtNoServerGrab;
225
226 _XtAllocWWTable(pd);
227 pd->per_screen_db = (XrmDatabase *) __XtCalloc((Cardinal) ScreenCount(dpy),
228 (Cardinal)
229 sizeof(XrmDatabase));
230 pd->cmd_db = (XrmDatabase) NULL;
231 pd->server_db = (XrmDatabase) NULL;
232 pd->dispatcher_list = NULL;
233 pd->ext_select_list = NULL;
234 pd->ext_select_count = 0;
235 pd->hook_object = NULL;
236 #if 0
237 pd->hook_object = _XtCreate("hooks", "Hooks", hookObjectClass,
238 (Widget) NULL,
239 (Screen *) DefaultScreenOfDisplay(dpy),
240 (ArgList) NULL, 0, (XtTypedArgList) NULL, 0,
241 (ConstraintWidgetClass) NULL);
242 #endif
243
244 #ifndef X_NO_RESOURCE_CONFIGURATION_MANAGEMENT
245 pd->rcm_init = XInternAtom(dpy, RCM_INIT, 0);
246 pd->rcm_data = XInternAtom(dpy, RCM_DATA, 0);
247 #endif
248
249 return pd;
250 }
251
252 #define THIS_FUNC "XtOpenDisplay"
253 Display *
XtOpenDisplay(XtAppContext app,_Xconst _XtString displayName,_Xconst _XtString applName,_Xconst _XtString className,XrmOptionDescRec * urlist,Cardinal num_urs,int * argc,_XtString * argv)254 XtOpenDisplay(XtAppContext app,
255 _Xconst _XtString displayName,
256 _Xconst _XtString applName,
257 _Xconst _XtString className,
258 XrmOptionDescRec *urlist,
259 Cardinal num_urs,
260 int *argc,
261 _XtString *argv)
262 {
263 Display *d;
264 XrmDatabase db = NULL;
265 String language = NULL;
266
267 LOCK_APP(app);
268 LOCK_PROCESS;
269 /* parse the command line for name, display, and/or language */
270 db = _XtPreparseCommandLine(urlist, num_urs, *argc, argv,
271 (String *) &applName,
272 (String *) (displayName ? NULL : &displayName),
273 (app->process->globalLangProcRec.proc ?
274 &language : NULL));
275 UNLOCK_PROCESS;
276 d = XOpenDisplay(displayName);
277 if (d != NULL) {
278 if (ScreenCount(d) <= 0) {
279 XtErrorMsg("nullDisplay",
280 THIS_FUNC, XtCXtToolkitError,
281 THIS_FUNC " requires a non-NULL display",
282 NULL, NULL);
283 }
284 if (DefaultScreen(d) < 0 || DefaultScreen(d) >= ScreenCount(d)) {
285 XtWarningMsg("nullDisplay",
286 THIS_FUNC, XtCXtToolkitError,
287 THIS_FUNC " default screen is invalid (ignoring)",
288 NULL, NULL);
289 DefaultScreen(d) = 0;
290 }
291 }
292
293 if (!applName && !(applName = getenv("RESOURCE_NAME"))) {
294 if (*argc > 0 && argv[0] && *argv[0]) {
295 #ifdef WIN32
296 char *ptr = strrchr(argv[0], '\\');
297 #else
298 char *ptr = strrchr(argv[0], '/');
299 #endif
300
301 if (ptr)
302 applName = ++ptr;
303 else
304 applName = argv[0];
305 }
306 else
307 applName = "main";
308 }
309
310 if (d) {
311 XtPerDisplay pd;
312
313 pd = InitPerDisplay(d, app, applName, className);
314 pd->language = language;
315 _XtDisplayInitialize(d, pd, applName, urlist, num_urs, argc, argv);
316 }
317 else {
318 int len;
319
320 displayName = XDisplayName(displayName);
321 len = (int) strlen(displayName);
322 app->display_name_tried = (_XtString) __XtMalloc((Cardinal) (len + 1));
323 strncpy((char *) app->display_name_tried, displayName,
324 (size_t) (len + 1));
325 app->display_name_tried[len] = '\0';
326 }
327 if (db)
328 XrmDestroyDatabase(db);
329 UNLOCK_APP(app);
330 return d;
331 }
332
333 Display *
_XtAppInit(XtAppContext * app_context_return,String application_class,XrmOptionDescRec * options,Cardinal num_options,int * argc_in_out,_XtString ** argv_in_out,String * fallback_resources)334 _XtAppInit(XtAppContext *app_context_return,
335 String application_class,
336 XrmOptionDescRec *options,
337 Cardinal num_options,
338 int *argc_in_out,
339 _XtString **argv_in_out,
340 String *fallback_resources)
341 {
342 _XtString *saved_argv;
343 int i;
344 Display *dpy;
345
346 /*
347 * Save away argv and argc so we can set the properties later
348 */
349 saved_argv = (_XtString *)
350 __XtMalloc((Cardinal)
351 ((size_t) (*argc_in_out + 1) * sizeof(_XtString)));
352
353 for (i = 0; i < *argc_in_out; i++)
354 saved_argv[i] = (*argv_in_out)[i];
355 saved_argv[i] = NULL; /* NULL terminate that sucker. */
356
357 *app_context_return = XtCreateApplicationContext();
358
359 LOCK_APP((*app_context_return));
360 if (fallback_resources) /* save a procedure call */
361 XtAppSetFallbackResources(*app_context_return, fallback_resources);
362
363 dpy = XtOpenDisplay(*app_context_return, NULL, NULL,
364 application_class,
365 options, num_options, argc_in_out, *argv_in_out);
366
367 if (!dpy) {
368 String param = (*app_context_return)->display_name_tried;
369 Cardinal param_count = 1;
370
371 XtErrorMsg("invalidDisplay", "xtInitialize", XtCXtToolkitError,
372 "Can't open display: %s", ¶m, ¶m_count);
373 XtFree((char *) (*app_context_return)->display_name_tried);
374 }
375 *argv_in_out = saved_argv;
376 UNLOCK_APP((*app_context_return));
377 return dpy;
378 }
379
380 void
XtDisplayInitialize(XtAppContext app,Display * dpy,_Xconst _XtString name,_Xconst _XtString classname,XrmOptionDescRec * urlist,Cardinal num_urs,int * argc,_XtString * argv)381 XtDisplayInitialize(XtAppContext app,
382 Display *dpy,
383 _Xconst _XtString name,
384 _Xconst _XtString classname,
385 XrmOptionDescRec *urlist,
386 Cardinal num_urs,
387 int *argc,
388 _XtString *argv)
389 {
390 XtPerDisplay pd;
391 XrmDatabase db = NULL;
392
393 LOCK_APP(app);
394 pd = InitPerDisplay(dpy, app, name, classname);
395 LOCK_PROCESS;
396 if (app->process->globalLangProcRec.proc)
397 /* pre-parse the command line for the language resource */
398 db = _XtPreparseCommandLine(urlist, num_urs, *argc, argv, NULL, NULL,
399 &pd->language);
400 UNLOCK_PROCESS;
401 _XtDisplayInitialize(dpy, pd, name, urlist, num_urs, argc, argv);
402 if (db)
403 XrmDestroyDatabase(db);
404 UNLOCK_APP(app);
405 }
406
407 XtAppContext
XtCreateApplicationContext(void)408 XtCreateApplicationContext(void)
409 {
410 XtAppContext app = XtNew(XtAppStruct);
411
412 #ifdef XTHREADS
413 app->lock_info = NULL;
414 app->lock = NULL;
415 app->unlock = NULL;
416 app->yield_lock = NULL;
417 app->restore_lock = NULL;
418 app->free_lock = NULL;
419 #endif
420 INIT_APP_LOCK(app);
421 LOCK_APP(app);
422 LOCK_PROCESS;
423 app->process = _XtGetProcessContext();
424 app->next = app->process->appContextList;
425 app->process->appContextList = app;
426 app->langProcRec.proc = app->process->globalLangProcRec.proc;
427 app->langProcRec.closure = app->process->globalLangProcRec.closure;
428 app->destroy_callbacks = NULL;
429 app->list = NULL;
430 app->count = app->max = app->last = 0;
431 app->timerQueue = NULL;
432 app->workQueue = NULL;
433 app->signalQueue = NULL;
434 app->input_list = NULL;
435 app->outstandingQueue = NULL;
436 app->errorDB = NULL;
437 _XtSetDefaultErrorHandlers(&app->errorMsgHandler,
438 &app->warningMsgHandler, &app->errorHandler,
439 &app->warningHandler);
440 app->action_table = NULL;
441 _XtSetDefaultSelectionTimeout(&app->selectionTimeout);
442 _XtSetDefaultConverterTable(&app->converterTable);
443 app->sync = app->being_destroyed = app->error_inited = FALSE;
444 app->in_phase2_destroy = NULL;
445 #ifndef USE_POLL
446 FD_ZERO(&app->fds.rmask);
447 FD_ZERO(&app->fds.wmask);
448 FD_ZERO(&app->fds.emask);
449 #endif
450 app->fds.nfds = 0;
451 app->input_count = app->input_max = 0;
452 _XtHeapInit(&app->heap);
453 app->fallback_resources = NULL;
454 _XtPopupInitialize(app);
455 app->action_hook_list = NULL;
456 app->block_hook_list = NULL;
457 app->destroy_list_size = app->destroy_count = app->dispatch_level = 0;
458 app->destroy_list = NULL;
459 #ifndef NO_IDENTIFY_WINDOWS
460 app->identify_windows = False;
461 #endif
462 app->free_bindings = NULL;
463 app->display_name_tried = NULL;
464 app->dpy_destroy_count = 0;
465 app->dpy_destroy_list = NULL;
466 app->exit_flag = FALSE;
467 app->rebuild_fdlist = TRUE;
468 UNLOCK_PROCESS;
469 UNLOCK_APP(app);
470 return app;
471 }
472
473 void
XtAppSetExitFlag(XtAppContext app)474 XtAppSetExitFlag(XtAppContext app)
475 {
476 LOCK_APP(app);
477 app->exit_flag = TRUE;
478 UNLOCK_APP(app);
479 }
480
481 Boolean
XtAppGetExitFlag(XtAppContext app)482 XtAppGetExitFlag(XtAppContext app)
483 {
484 Boolean retval;
485
486 LOCK_APP(app);
487 retval = app->exit_flag;
488 UNLOCK_APP(app);
489 return retval;
490 }
491
492 static void
DestroyAppContext(XtAppContext app)493 DestroyAppContext(XtAppContext app)
494 {
495 XtAppContext *prev_app;
496
497 prev_app = &app->process->appContextList;
498 while (app->count-- > 0)
499 XtCloseDisplay(app->list[app->count]);
500 if (app->list != NULL)
501 XtFree((char *) app->list);
502 _XtFreeConverterTable(app->converterTable);
503 _XtCacheFlushTag(app, (XtPointer) &app->heap);
504 _XtFreeActions(app->action_table);
505 if (app->destroy_callbacks != NULL) {
506 XtCallCallbackList((Widget) NULL,
507 (XtCallbackList) app->destroy_callbacks,
508 (XtPointer) app);
509 _XtRemoveAllCallbacks(&app->destroy_callbacks);
510 }
511 while (app->timerQueue)
512 XtRemoveTimeOut((XtIntervalId) app->timerQueue);
513 while (app->workQueue)
514 XtRemoveWorkProc((XtWorkProcId) app->workQueue);
515 while (app->signalQueue)
516 XtRemoveSignal((XtSignalId) app->signalQueue);
517 if (app->input_list)
518 _XtRemoveAllInputs(app);
519 XtFree((char *) app->destroy_list);
520 _XtHeapFree(&app->heap);
521 while (*prev_app != app)
522 prev_app = &(*prev_app)->next;
523 *prev_app = app->next;
524 if (app->process->defaultAppContext == app)
525 app->process->defaultAppContext = NULL;
526 if (app->free_bindings)
527 _XtDoFreeBindings(app);
528 FREE_APP_LOCK(app);
529 XtFree((char *) app);
530 }
531
532 static XtAppContext *appDestroyList = NULL;
533 int _XtAppDestroyCount = 0;
534
535 void
XtDestroyApplicationContext(XtAppContext app)536 XtDestroyApplicationContext(XtAppContext app)
537 {
538 LOCK_APP(app);
539 if (app->being_destroyed) {
540 UNLOCK_APP(app);
541 return;
542 }
543
544 if (_XtSafeToDestroy(app)) {
545 LOCK_PROCESS;
546 DestroyAppContext(app);
547 UNLOCK_PROCESS;
548 }
549 else {
550 app->being_destroyed = TRUE;
551 LOCK_PROCESS;
552 _XtAppDestroyCount++;
553 appDestroyList =
554 (XtAppContext *) XtRealloc((char *) appDestroyList,
555 (unsigned) ((size_t) _XtAppDestroyCount *
556 sizeof(XtAppContext)));
557 appDestroyList[_XtAppDestroyCount - 1] = app;
558 UNLOCK_PROCESS;
559 UNLOCK_APP(app);
560 }
561 }
562
563 void
_XtDestroyAppContexts(void)564 _XtDestroyAppContexts(void)
565 {
566 int i, ii;
567 XtAppContext apps[8];
568 XtAppContext *pApps;
569
570 pApps =
571 XtStackAlloc(sizeof(XtAppContext) * (size_t) _XtAppDestroyCount, apps);
572
573 for (i = ii = 0; i < _XtAppDestroyCount; i++) {
574 if (_XtSafeToDestroy(appDestroyList[i]))
575 DestroyAppContext(appDestroyList[i]);
576 else
577 pApps[ii++] = appDestroyList[i];
578 }
579 _XtAppDestroyCount = ii;
580 if (_XtAppDestroyCount == 0) {
581 XtFree((char *) appDestroyList);
582 appDestroyList = NULL;
583 }
584 else {
585 for (i = 0; i < ii; i++)
586 appDestroyList[i] = pApps[i];
587 }
588 XtStackFree((XtPointer) pApps, apps);
589 }
590
591 XrmDatabase
XtDatabase(Display * dpy)592 XtDatabase(Display *dpy)
593 {
594 XrmDatabase retval;
595
596 DPY_TO_APPCON(dpy);
597
598 LOCK_APP(app);
599 retval = XrmGetDatabase(dpy);
600 UNLOCK_APP(app);
601 return retval;
602 }
603
604 PerDisplayTablePtr _XtperDisplayList = NULL;
605
606 XtPerDisplay
_XtSortPerDisplayList(Display * dpy)607 _XtSortPerDisplayList(Display *dpy)
608 {
609 register PerDisplayTablePtr pd, opd = NULL;
610 XtPerDisplay result = NULL;
611
612 LOCK_PROCESS;
613 for (pd = _XtperDisplayList; pd != NULL && pd->dpy != dpy; pd = pd->next) {
614 opd = pd;
615 }
616
617 if (pd == NULL) {
618 XtErrorMsg(XtNnoPerDisplay, "getPerDisplay", XtCXtToolkitError,
619 "Couldn't find per display information", NULL, NULL);
620 }
621 else {
622 if (pd != _XtperDisplayList) { /* move it to the front */
623 /* opd points to the previous one... */
624
625 opd->next = pd->next;
626 pd->next = _XtperDisplayList;
627 _XtperDisplayList = pd;
628 }
629 result = &(pd->perDpy);
630 }
631 UNLOCK_PROCESS;
632 return result;
633 }
634
635 XtAppContext
XtDisplayToApplicationContext(Display * dpy)636 XtDisplayToApplicationContext(Display *dpy)
637 {
638 XtAppContext retval;
639
640 retval = _XtGetPerDisplay(dpy)->appContext;
641 return retval;
642 }
643
644 static void
CloseDisplay(Display * dpy)645 CloseDisplay(Display *dpy)
646 {
647 register XtPerDisplay xtpd = NULL;
648 register PerDisplayTablePtr pd, opd = NULL;
649 XrmDatabase db;
650
651 XtDestroyWidget(XtHooksOfDisplay(dpy));
652
653 LOCK_PROCESS;
654 for (pd = _XtperDisplayList; pd != NULL && pd->dpy != dpy; pd = pd->next) {
655 opd = pd;
656 }
657
658 if (pd == NULL) {
659 XtErrorMsg(XtNnoPerDisplay, "closeDisplay", XtCXtToolkitError,
660 "Couldn't find per display information", NULL, NULL);
661 }
662 else {
663
664 if (pd == _XtperDisplayList)
665 _XtperDisplayList = pd->next;
666 else
667 opd->next = pd->next;
668
669 xtpd = &(pd->perDpy);
670 }
671
672 if (xtpd != NULL) {
673 int i;
674
675 if (xtpd->destroy_callbacks != NULL) {
676 XtCallCallbackList((Widget) NULL,
677 (XtCallbackList) xtpd->destroy_callbacks,
678 (XtPointer) xtpd);
679 _XtRemoveAllCallbacks(&xtpd->destroy_callbacks);
680 }
681 if (xtpd->mapping_callbacks != NULL)
682 _XtRemoveAllCallbacks(&xtpd->mapping_callbacks);
683 XtDeleteFromAppContext(dpy, xtpd->appContext);
684 if (xtpd->keysyms)
685 XFree((char *) xtpd->keysyms);
686 XtFree((char *) xtpd->modKeysyms);
687 XtFree((char *) xtpd->modsToKeysyms);
688 xtpd->keysyms_per_keycode = 0;
689 xtpd->being_destroyed = FALSE;
690 xtpd->keysyms = NULL;
691 xtpd->modKeysyms = NULL;
692 xtpd->modsToKeysyms = NULL;
693 XDestroyRegion(xtpd->region);
694 _XtCacheFlushTag(xtpd->appContext, (XtPointer) &xtpd->heap);
695 _XtGClistFree(dpy, xtpd);
696 XtFree((char *) xtpd->pdi.trace);
697 _XtHeapFree(&xtpd->heap);
698 _XtFreeWWTable(xtpd);
699 xtpd->per_screen_db[DefaultScreen(dpy)] = (XrmDatabase) NULL;
700 for (i = ScreenCount(dpy); --i >= 0;) {
701 db = xtpd->per_screen_db[i];
702 if (db)
703 XrmDestroyDatabase(db);
704 }
705 XtFree((char *) xtpd->per_screen_db);
706 if ((db = XrmGetDatabase(dpy)))
707 XrmDestroyDatabase(db);
708 if (xtpd->cmd_db)
709 XrmDestroyDatabase(xtpd->cmd_db);
710 if (xtpd->server_db)
711 XrmDestroyDatabase(xtpd->server_db);
712 XtFree((_XtString) xtpd->language);
713 if (xtpd->dispatcher_list != NULL)
714 XtFree((char *) xtpd->dispatcher_list);
715 if (xtpd->ext_select_list != NULL)
716 XtFree((char *) xtpd->ext_select_list);
717 }
718 XtFree((char *) pd);
719 XrmSetDatabase(dpy, (XrmDatabase) NULL);
720 XCloseDisplay(dpy);
721 UNLOCK_PROCESS;
722 }
723
724 void
XtCloseDisplay(Display * dpy)725 XtCloseDisplay(Display *dpy)
726 {
727 XtPerDisplay pd;
728 XtAppContext app = XtDisplayToApplicationContext(dpy);
729
730 LOCK_APP(app);
731 pd = _XtGetPerDisplay(dpy);
732 if (pd->being_destroyed) {
733 UNLOCK_APP(app);
734 return;
735 }
736
737 if (_XtSafeToDestroy(app))
738 CloseDisplay(dpy);
739 else {
740 pd->being_destroyed = TRUE;
741 app->dpy_destroy_count++;
742 app->dpy_destroy_list = (Display **)
743 XtRealloc((char *) app->dpy_destroy_list,
744 (Cardinal) ((size_t) app->dpy_destroy_count *
745 sizeof(Display *)));
746 app->dpy_destroy_list[app->dpy_destroy_count - 1] = dpy;
747 }
748 UNLOCK_APP(app);
749 }
750
751 void
_XtCloseDisplays(XtAppContext app)752 _XtCloseDisplays(XtAppContext app)
753 {
754 int i;
755
756 LOCK_APP(app);
757 for (i = 0; i < app->dpy_destroy_count; i++) {
758 CloseDisplay(app->dpy_destroy_list[i]);
759 }
760 app->dpy_destroy_count = 0;
761 XtFree((char *) app->dpy_destroy_list);
762 app->dpy_destroy_list = NULL;
763 UNLOCK_APP(app);
764 }
765
766 XtAppContext
XtWidgetToApplicationContext(Widget w)767 XtWidgetToApplicationContext(Widget w)
768 {
769 XtAppContext retval;
770
771 retval = _XtGetPerDisplay(XtDisplayOfObject(w))->appContext;
772 return retval;
773 }
774
775 void
XtGetApplicationNameAndClass(Display * dpy,String * name_return,String * class_return)776 XtGetApplicationNameAndClass(Display *dpy,
777 String *name_return,
778 String *class_return)
779 {
780 XtPerDisplay pd;
781
782 pd = _XtGetPerDisplay(dpy);
783 *name_return = XrmQuarkToString(pd->name);
784 *class_return = XrmQuarkToString(pd->class);
785 }
786
787 XtPerDisplay
_XtGetPerDisplay(Display * display)788 _XtGetPerDisplay(Display *display)
789 {
790 XtPerDisplay retval;
791
792 LOCK_PROCESS;
793 retval = ((_XtperDisplayList != NULL && _XtperDisplayList->dpy == display)
794 ? &_XtperDisplayList->perDpy : _XtSortPerDisplayList(display));
795
796 UNLOCK_PROCESS;
797 return retval;
798 }
799
800 XtPerDisplayInputRec *
_XtGetPerDisplayInput(Display * display)801 _XtGetPerDisplayInput(Display *display)
802 {
803 XtPerDisplayInputRec *retval;
804
805 LOCK_PROCESS;
806 retval = ((_XtperDisplayList != NULL && _XtperDisplayList->dpy == display)
807 ? &_XtperDisplayList->perDpy.pdi
808 : &_XtSortPerDisplayList(display)->pdi);
809 UNLOCK_PROCESS;
810 return retval;
811 }
812
813 void
XtGetDisplays(XtAppContext app_context,Display *** dpy_return,Cardinal * num_dpy_return)814 XtGetDisplays(XtAppContext app_context,
815 Display ***dpy_return,
816 Cardinal *num_dpy_return)
817 {
818 int ii;
819
820 LOCK_APP(app_context);
821 *num_dpy_return = (Cardinal) app_context->count;
822 *dpy_return = (Display **)
823 __XtMalloc((Cardinal)
824 ((size_t) app_context->count * sizeof(Display *)));
825 for (ii = 0; ii < app_context->count; ii++)
826 (*dpy_return)[ii] = app_context->list[ii];
827 UNLOCK_APP(app_context);
828 }
829