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