Display.c revision a3bd7f05
1/*********************************************************** 2Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved. 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 = (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 141static void 142XtDeleteFromAppContext(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 = (_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 380void 381XtDisplayInitialize(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 407XtAppContext 408XtCreateApplicationContext(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 473void 474XtAppSetExitFlag(XtAppContext app) 475{ 476 LOCK_APP(app); 477 app->exit_flag = TRUE; 478 UNLOCK_APP(app); 479} 480 481Boolean 482XtAppGetExitFlag(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 492static void 493DestroyAppContext(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 532static XtAppContext *appDestroyList = NULL; 533int _XtAppDestroyCount = 0; 534 535void 536XtDestroyApplicationContext(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 563void 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 591XrmDatabase 592XtDatabase(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 604PerDisplayTablePtr _XtperDisplayList = NULL; 605 606XtPerDisplay 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 635XtAppContext 636XtDisplayToApplicationContext(Display *dpy) 637{ 638 XtAppContext retval; 639 640 retval = _XtGetPerDisplay(dpy)->appContext; 641 return retval; 642} 643 644static void 645CloseDisplay(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 724void 725XtCloseDisplay(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 751void 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 766XtAppContext 767XtWidgetToApplicationContext(Widget w) 768{ 769 XtAppContext retval; 770 771 retval = _XtGetPerDisplay(XtDisplayOfObject(w))->appContext; 772 return retval; 773} 774 775void 776XtGetApplicationNameAndClass(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 787XtPerDisplay 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 800XtPerDisplayInputRec * 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 813void 814XtGetDisplays(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