1/*********************************************************** 2Copyright (c) 1993, Oracle and/or its affiliates. 3 4Permission is hereby granted, free of charge, to any person obtaining a 5copy of this software and associated documentation files (the "Software"), 6to deal in the Software without restriction, including without limitation 7the rights to use, copy, modify, merge, publish, distribute, sublicense, 8and/or sell copies of the Software, and to permit persons to whom the 9Software is furnished to do so, subject to the following conditions: 10 11The above copyright notice and this permission notice (including the next 12paragraph) shall be included in all copies or substantial portions of the 13Software. 14 15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21DEALINGS IN THE SOFTWARE. 22 23Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. 24 25 All Rights Reserved 26 27Permission to use, copy, modify, and distribute this software and its 28documentation for any purpose and without fee is hereby granted, 29provided that the above copyright notice appear in all copies and that 30both that copyright notice and this permission notice appear in 31supporting documentation, and that the name of Digital not be 32used in advertising or publicity pertaining to distribution of the 33software without specific, written prior permission. 34 35DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 36ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 37DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 38ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 39WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 40ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 41SOFTWARE. 42 43******************************************************************/ 44 45/* 46 47Copyright 1987, 1988, 1998 The Open Group 48 49Permission to use, copy, modify, distribute, and sell this software and its 50documentation for any purpose is hereby granted without fee, provided that 51the above copyright notice appear in all copies and that both that 52copyright notice and this permission notice appear in supporting 53documentation. 54 55The above copyright notice and this permission notice shall be included in 56all copies or substantial portions of the Software. 57 58THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 59IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 60FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 61OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 62AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 63CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 64 65Except as contained in this notice, the name of The Open Group shall not be 66used in advertising or otherwise to promote the sale, use or other dealings 67in 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 82void (*_XtProcessLock) (void) = NULL; 83void (*_XtProcessUnlock) (void) = NULL; 84void (*_XtInitAppLock) (XtAppContext) = NULL; 85#endif 86 87static _Xconst _XtString XtNnoPerDisplay = "noPerDisplay"; 88 89ProcessContext 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 102XtAppContext 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 117static void 118AddToAppContext(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 = XtReallocArray(app->list, 125 (Cardinal) app->max, 126 (Cardinal) 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 141static void 142XtDeleteFromAppContext(const 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 168static XtPerDisplay 169NewPerDisplay(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 183static XtPerDisplay 184InitPerDisplay(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" 253Display * 254XtOpenDisplay(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 333Display * 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 = XtMallocArray((Cardinal) *argc_in_out + 1, 350 (Cardinal) sizeof(_XtString)); 351 352 for (i = 0; i < *argc_in_out; i++) 353 saved_argv[i] = (*argv_in_out)[i]; 354 saved_argv[i] = NULL; /* NULL terminate that sucker. */ 355 356 *app_context_return = XtCreateApplicationContext(); 357 358 LOCK_APP((*app_context_return)); 359 if (fallback_resources) /* save a procedure call */ 360 XtAppSetFallbackResources(*app_context_return, fallback_resources); 361 362 dpy = XtOpenDisplay(*app_context_return, NULL, NULL, 363 application_class, 364 options, num_options, argc_in_out, *argv_in_out); 365 366 if (!dpy) { 367 String param = (*app_context_return)->display_name_tried; 368 Cardinal param_count = 1; 369 370 XtErrorMsg("invalidDisplay", "xtInitialize", XtCXtToolkitError, 371 "Can't open display: %s", ¶m, ¶m_count); 372 XtFree((char *) (*app_context_return)->display_name_tried); 373 } 374 *argv_in_out = saved_argv; 375 UNLOCK_APP((*app_context_return)); 376 return dpy; 377} 378 379void 380XtDisplayInitialize(XtAppContext app, 381 Display *dpy, 382 _Xconst _XtString name, 383 _Xconst _XtString classname, 384 XrmOptionDescRec *urlist, 385 Cardinal num_urs, 386 int *argc, 387 _XtString *argv) 388{ 389 XtPerDisplay pd; 390 XrmDatabase db = NULL; 391 392 LOCK_APP(app); 393 pd = InitPerDisplay(dpy, app, name, classname); 394 LOCK_PROCESS; 395 if (app->process->globalLangProcRec.proc) 396 /* pre-parse the command line for the language resource */ 397 db = _XtPreparseCommandLine(urlist, num_urs, *argc, argv, NULL, NULL, 398 &pd->language); 399 UNLOCK_PROCESS; 400 _XtDisplayInitialize(dpy, pd, name, urlist, num_urs, argc, argv); 401 if (db) 402 XrmDestroyDatabase(db); 403 UNLOCK_APP(app); 404} 405 406XtAppContext 407XtCreateApplicationContext(void) 408{ 409 XtAppContext app = XtNew(XtAppStruct); 410 411#ifdef XTHREADS 412 app->lock_info = NULL; 413 app->lock = NULL; 414 app->unlock = NULL; 415 app->yield_lock = NULL; 416 app->restore_lock = NULL; 417 app->free_lock = NULL; 418#endif 419 INIT_APP_LOCK(app); 420 LOCK_APP(app); 421 LOCK_PROCESS; 422 app->process = _XtGetProcessContext(); 423 app->next = app->process->appContextList; 424 app->process->appContextList = app; 425 app->langProcRec.proc = app->process->globalLangProcRec.proc; 426 app->langProcRec.closure = app->process->globalLangProcRec.closure; 427 app->destroy_callbacks = NULL; 428 app->list = NULL; 429 app->count = app->max = app->last = 0; 430 app->timerQueue = NULL; 431 app->workQueue = NULL; 432 app->signalQueue = NULL; 433 app->input_list = NULL; 434 app->outstandingQueue = NULL; 435 app->errorDB = NULL; 436 _XtSetDefaultErrorHandlers(&app->errorMsgHandler, 437 &app->warningMsgHandler, &app->errorHandler, 438 &app->warningHandler); 439 app->action_table = NULL; 440 _XtSetDefaultSelectionTimeout(&app->selectionTimeout); 441 _XtSetDefaultConverterTable(&app->converterTable); 442 app->sync = app->being_destroyed = app->error_inited = FALSE; 443 app->in_phase2_destroy = NULL; 444#ifndef USE_POLL 445 FD_ZERO(&app->fds.rmask); 446 FD_ZERO(&app->fds.wmask); 447 FD_ZERO(&app->fds.emask); 448#endif 449 app->fds.nfds = 0; 450 app->input_count = app->input_max = 0; 451 _XtHeapInit(&app->heap); 452 app->fallback_resources = NULL; 453 _XtPopupInitialize(app); 454 app->action_hook_list = NULL; 455 app->block_hook_list = NULL; 456 app->destroy_list_size = app->destroy_count = app->dispatch_level = 0; 457 app->destroy_list = NULL; 458#ifndef NO_IDENTIFY_WINDOWS 459 app->identify_windows = False; 460#endif 461 app->free_bindings = NULL; 462 app->display_name_tried = NULL; 463 app->dpy_destroy_count = 0; 464 app->dpy_destroy_list = NULL; 465 app->exit_flag = FALSE; 466 app->rebuild_fdlist = TRUE; 467 UNLOCK_PROCESS; 468 UNLOCK_APP(app); 469 return app; 470} 471 472void 473XtAppSetExitFlag(XtAppContext app) 474{ 475 LOCK_APP(app); 476 app->exit_flag = TRUE; 477 UNLOCK_APP(app); 478} 479 480Boolean 481XtAppGetExitFlag(XtAppContext app) 482{ 483 Boolean retval; 484 485 LOCK_APP(app); 486 retval = app->exit_flag; 487 UNLOCK_APP(app); 488 return retval; 489} 490 491static void 492DestroyAppContext(XtAppContext app) 493{ 494 XtAppContext *prev_app; 495 496 prev_app = &app->process->appContextList; 497 while (app->count-- > 0) 498 XtCloseDisplay(app->list[app->count]); 499 if (app->list != NULL) 500 XtFree((char *) app->list); 501 _XtFreeConverterTable(app->converterTable); 502 _XtCacheFlushTag(app, (XtPointer) &app->heap); 503 _XtFreeActions(app->action_table); 504 if (app->destroy_callbacks != NULL) { 505 XtCallCallbackList((Widget) NULL, 506 (XtCallbackList) app->destroy_callbacks, 507 (XtPointer) app); 508 _XtRemoveAllCallbacks(&app->destroy_callbacks); 509 } 510 while (app->timerQueue) 511 XtRemoveTimeOut((XtIntervalId) app->timerQueue); 512 while (app->workQueue) 513 XtRemoveWorkProc((XtWorkProcId) app->workQueue); 514 while (app->signalQueue) 515 XtRemoveSignal((XtSignalId) app->signalQueue); 516 if (app->input_list) 517 _XtRemoveAllInputs(app); 518 XtFree((char *) app->destroy_list); 519 _XtHeapFree(&app->heap); 520 while (*prev_app != app) 521 prev_app = &(*prev_app)->next; 522 *prev_app = app->next; 523 if (app->process->defaultAppContext == app) 524 app->process->defaultAppContext = NULL; 525 if (app->free_bindings) 526 _XtDoFreeBindings(app); 527 FREE_APP_LOCK(app); 528 XtFree((char *) app); 529} 530 531static XtAppContext *appDestroyList = NULL; 532int _XtAppDestroyCount = 0; 533 534void 535XtDestroyApplicationContext(XtAppContext app) 536{ 537 LOCK_APP(app); 538 if (app->being_destroyed) { 539 UNLOCK_APP(app); 540 return; 541 } 542 543 if (_XtSafeToDestroy(app)) { 544 LOCK_PROCESS; 545 DestroyAppContext(app); 546 UNLOCK_PROCESS; 547 } 548 else { 549 app->being_destroyed = TRUE; 550 LOCK_PROCESS; 551 _XtAppDestroyCount++; 552 appDestroyList = XtReallocArray(appDestroyList, 553 (Cardinal) _XtAppDestroyCount, 554 (Cardinal) sizeof(XtAppContext)); 555 appDestroyList[_XtAppDestroyCount - 1] = app; 556 UNLOCK_PROCESS; 557 UNLOCK_APP(app); 558 } 559} 560 561void 562_XtDestroyAppContexts(void) 563{ 564 int i, ii; 565 XtAppContext apps[8]; 566 XtAppContext *pApps; 567 568 pApps = 569 XtStackAlloc(sizeof(XtAppContext) * (size_t) _XtAppDestroyCount, apps); 570 571 for (i = ii = 0; i < _XtAppDestroyCount; i++) { 572 if (_XtSafeToDestroy(appDestroyList[i])) 573 DestroyAppContext(appDestroyList[i]); 574 else 575 pApps[ii++] = appDestroyList[i]; 576 } 577 _XtAppDestroyCount = ii; 578 if (_XtAppDestroyCount == 0) { 579 XtFree((char *) appDestroyList); 580 appDestroyList = NULL; 581 } 582 else { 583 for (i = 0; i < ii; i++) 584 appDestroyList[i] = pApps[i]; 585 } 586 XtStackFree((XtPointer) pApps, apps); 587} 588 589XrmDatabase 590XtDatabase(Display *dpy) 591{ 592 XrmDatabase retval; 593 594 DPY_TO_APPCON(dpy); 595 596 LOCK_APP(app); 597 retval = XrmGetDatabase(dpy); 598 UNLOCK_APP(app); 599 return retval; 600} 601 602PerDisplayTablePtr _XtperDisplayList = NULL; 603 604XtPerDisplay 605_XtSortPerDisplayList(Display *dpy) 606{ 607 register PerDisplayTablePtr pd, opd = NULL; 608 XtPerDisplay result = NULL; 609 610 LOCK_PROCESS; 611 for (pd = _XtperDisplayList; pd != NULL && pd->dpy != dpy; pd = pd->next) { 612 opd = pd; 613 } 614 615 if (pd == NULL) { 616 XtErrorMsg(XtNnoPerDisplay, "getPerDisplay", XtCXtToolkitError, 617 "Couldn't find per display information", NULL, NULL); 618 } 619 else { 620 if (pd != _XtperDisplayList) { /* move it to the front */ 621 /* opd points to the previous one... */ 622 623 opd->next = pd->next; 624 pd->next = _XtperDisplayList; 625 _XtperDisplayList = pd; 626 } 627 result = &(pd->perDpy); 628 } 629 UNLOCK_PROCESS; 630 return result; 631} 632 633XtAppContext 634XtDisplayToApplicationContext(Display *dpy) 635{ 636 XtAppContext retval; 637 638 retval = _XtGetPerDisplay(dpy)->appContext; 639 return retval; 640} 641 642static void 643CloseDisplay(Display *dpy) 644{ 645 register XtPerDisplay xtpd = NULL; 646 register PerDisplayTablePtr pd, opd = NULL; 647 XrmDatabase db; 648 649 XtDestroyWidget(XtHooksOfDisplay(dpy)); 650 651 LOCK_PROCESS; 652 for (pd = _XtperDisplayList; pd != NULL && pd->dpy != dpy; pd = pd->next) { 653 opd = pd; 654 } 655 656 if (pd == NULL) { 657 XtErrorMsg(XtNnoPerDisplay, "closeDisplay", XtCXtToolkitError, 658 "Couldn't find per display information", NULL, NULL); 659 } 660 else { 661 662 if (pd == _XtperDisplayList) 663 _XtperDisplayList = pd->next; 664 else 665 opd->next = pd->next; 666 667 xtpd = &(pd->perDpy); 668 } 669 670 if (xtpd != NULL) { 671 int i; 672 673 if (xtpd->destroy_callbacks != NULL) { 674 XtCallCallbackList((Widget) NULL, 675 (XtCallbackList) xtpd->destroy_callbacks, 676 (XtPointer) xtpd); 677 _XtRemoveAllCallbacks(&xtpd->destroy_callbacks); 678 } 679 if (xtpd->mapping_callbacks != NULL) 680 _XtRemoveAllCallbacks(&xtpd->mapping_callbacks); 681 XtDeleteFromAppContext(dpy, xtpd->appContext); 682 if (xtpd->keysyms) 683 XFree((char *) xtpd->keysyms); 684 XtFree((char *) xtpd->modKeysyms); 685 XtFree((char *) xtpd->modsToKeysyms); 686 xtpd->keysyms_per_keycode = 0; 687 xtpd->being_destroyed = FALSE; 688 xtpd->keysyms = NULL; 689 xtpd->modKeysyms = NULL; 690 xtpd->modsToKeysyms = NULL; 691 XDestroyRegion(xtpd->region); 692 _XtCacheFlushTag(xtpd->appContext, (XtPointer) &xtpd->heap); 693 _XtGClistFree(dpy, xtpd); 694 XtFree((char *) xtpd->pdi.trace); 695 _XtHeapFree(&xtpd->heap); 696 _XtFreeWWTable(xtpd); 697 xtpd->per_screen_db[DefaultScreen(dpy)] = (XrmDatabase) NULL; 698 for (i = ScreenCount(dpy); --i >= 0;) { 699 db = xtpd->per_screen_db[i]; 700 if (db) 701 XrmDestroyDatabase(db); 702 } 703 XtFree((char *) xtpd->per_screen_db); 704 if ((db = XrmGetDatabase(dpy))) 705 XrmDestroyDatabase(db); 706 if (xtpd->cmd_db) 707 XrmDestroyDatabase(xtpd->cmd_db); 708 if (xtpd->server_db) 709 XrmDestroyDatabase(xtpd->server_db); 710 XtFree((_XtString) xtpd->language); 711 if (xtpd->dispatcher_list != NULL) 712 XtFree((char *) xtpd->dispatcher_list); 713 if (xtpd->ext_select_list != NULL) 714 XtFree((char *) xtpd->ext_select_list); 715 } 716 XtFree((char *) pd); 717 XrmSetDatabase(dpy, (XrmDatabase) NULL); 718 XCloseDisplay(dpy); 719 UNLOCK_PROCESS; 720} 721 722void 723XtCloseDisplay(Display *dpy) 724{ 725 XtPerDisplay pd; 726 XtAppContext app = XtDisplayToApplicationContext(dpy); 727 728 LOCK_APP(app); 729 pd = _XtGetPerDisplay(dpy); 730 if (pd->being_destroyed) { 731 UNLOCK_APP(app); 732 return; 733 } 734 735 if (_XtSafeToDestroy(app)) 736 CloseDisplay(dpy); 737 else { 738 pd->being_destroyed = TRUE; 739 app->dpy_destroy_count++; 740 app->dpy_destroy_list = XtReallocArray(app->dpy_destroy_list, 741 (Cardinal) app->dpy_destroy_count, 742 (Cardinal) sizeof(Display *)); 743 app->dpy_destroy_list[app->dpy_destroy_count - 1] = dpy; 744 } 745 UNLOCK_APP(app); 746} 747 748void 749_XtCloseDisplays(XtAppContext app) 750{ 751 int i; 752 753 LOCK_APP(app); 754 for (i = 0; i < app->dpy_destroy_count; i++) { 755 CloseDisplay(app->dpy_destroy_list[i]); 756 } 757 app->dpy_destroy_count = 0; 758 XtFree((char *) app->dpy_destroy_list); 759 app->dpy_destroy_list = NULL; 760 UNLOCK_APP(app); 761} 762 763XtAppContext 764XtWidgetToApplicationContext(Widget w) 765{ 766 XtAppContext retval; 767 768 retval = _XtGetPerDisplay(XtDisplayOfObject(w))->appContext; 769 return retval; 770} 771 772void 773XtGetApplicationNameAndClass(Display *dpy, 774 String *name_return, 775 String *class_return) 776{ 777 XtPerDisplay pd; 778 779 pd = _XtGetPerDisplay(dpy); 780 *name_return = XrmQuarkToString(pd->name); 781 *class_return = XrmQuarkToString(pd->class); 782} 783 784XtPerDisplay 785_XtGetPerDisplay(Display *display) 786{ 787 XtPerDisplay retval; 788 789 LOCK_PROCESS; 790 retval = ((_XtperDisplayList != NULL && _XtperDisplayList->dpy == display) 791 ? &_XtperDisplayList->perDpy : _XtSortPerDisplayList(display)); 792 793 UNLOCK_PROCESS; 794 return retval; 795} 796 797XtPerDisplayInputRec * 798_XtGetPerDisplayInput(Display *display) 799{ 800 XtPerDisplayInputRec *retval; 801 802 LOCK_PROCESS; 803 retval = ((_XtperDisplayList != NULL && _XtperDisplayList->dpy == display) 804 ? &_XtperDisplayList->perDpy.pdi 805 : &_XtSortPerDisplayList(display)->pdi); 806 UNLOCK_PROCESS; 807 return retval; 808} 809 810void 811XtGetDisplays(XtAppContext app_context, 812 Display ***dpy_return, 813 Cardinal *num_dpy_return) 814{ 815 int ii; 816 817 LOCK_APP(app_context); 818 *num_dpy_return = (Cardinal) app_context->count; 819 *dpy_return = XtMallocArray((Cardinal) app_context->count, 820 (Cardinal) sizeof(Display *)); 821 for (ii = 0; ii < app_context->count; ii++) 822 (*dpy_return)[ii] = app_context->list[ii]; 823 UNLOCK_APP(app_context); 824} 825