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