OpenDis.c revision e9fcaa8a
1/* 2 3Copyright 1985, 1986, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from The Open Group. 24 25*/ 26 27#ifdef HAVE_CONFIG_H 28#include <config.h> 29#endif 30#include "Xlibint.h" 31#include "Xxcbint.h" 32#include <X11/Xatom.h> 33#include <X11/Xresource.h> 34#include <stdio.h> 35#include "Xintconn.h" 36 37#ifdef XKB 38#include "XKBlib.h" 39#endif /* XKB */ 40 41#ifdef XTHREADS 42#include "locking.h" 43int (*_XInitDisplayLock_fn)(Display *dpy) = NULL; 44void (*_XFreeDisplayLock_fn)(Display *dpy) = NULL; 45 46#define InitDisplayLock(d) (_XInitDisplayLock_fn ? (*_XInitDisplayLock_fn)(d) : Success) 47#define FreeDisplayLock(d) if (_XFreeDisplayLock_fn) (*_XFreeDisplayLock_fn)(d) 48#else 49#define InitDisplayLock(dis) Success 50#define FreeDisplayLock(dis) 51#endif /* XTHREADS */ 52 53static xReq _dummy_request = { 54 0, 0, 0 55}; 56 57static void OutOfMemory(Display *dpy); 58 59/* 60 * Connects to a server, creates a Display object and returns a pointer to 61 * the newly created Display back to the caller. 62 */ 63Display * 64XOpenDisplay ( 65 register _Xconst char *display) 66{ 67 register Display *dpy; /* New Display object being created. */ 68 register int i; 69 int j, k; /* random iterator indexes */ 70 char *display_name; /* pointer to display name */ 71 char *setup = NULL; /* memory allocated at startup */ 72 int iscreen; /* screen number */ 73 xConnSetupPrefix prefix; /* prefix information */ 74 int vendorlen; /* length of vendor string */ 75 union { 76 xConnSetup *setup; 77 char *failure; 78 char *vendor; 79 xPixmapFormat *sf; 80 xWindowRoot *rp; 81 xDepth *dp; 82 xVisualType *vp; 83 } u; /* proto data returned from server */ 84 long setuplength; /* number of bytes in setup message */ 85 long usedbytes = 0; /* number of bytes we have processed */ 86 unsigned long mask; 87 long int conn_buf_size; 88 char *xlib_buffer_size; 89 90 /* 91 * If the display specifier string supplied as an argument to this 92 * routine is NULL or a pointer to NULL, read the DISPLAY variable. 93 */ 94 if (display == NULL || *display == '\0') { 95 if ((display_name = getenv("DISPLAY")) == NULL) { 96 /* Oops! No DISPLAY environment variable - error. */ 97 return(NULL); 98 } 99 } 100 else { 101 /* Display is non-NULL, copy the pointer */ 102 display_name = (char *)display; 103 } 104 105/* 106 * Set the default error handlers. This allows the global variables to 107 * default to NULL for use with shared libraries. 108 */ 109 if (_XErrorFunction == NULL) (void) XSetErrorHandler (NULL); 110 if (_XIOErrorFunction == NULL) (void) XSetIOErrorHandler (NULL); 111 112/* 113 * Attempt to allocate a display structure. Return NULL if allocation fails. 114 */ 115 if ((dpy = (Display *)Xcalloc(1, sizeof(Display))) == NULL) { 116 return(NULL); 117 } 118 119 if ((dpy->display_name = strdup(display_name)) == NULL) { 120 OutOfMemory(dpy); 121 return(NULL); 122 } 123 124/* 125 * Call the Connect routine to get the transport connection object. 126 * If NULL is returned, the connection failed. 127 */ 128 129 if(!_XConnectXCB(dpy, display, &iscreen)) { 130 /* Try falling back on other transports if no transport specified */ 131 const char *slash = strrchr(display_name, '/'); 132 if(slash == NULL) { 133 const char *protocols[] = {"local", "unix", "tcp", "inet6", "inet", NULL}; 134 const char **s; 135 size_t buf_size = strlen(display_name) + 7; // max strlen + 2 (null + /) 136 char *buf = Xmalloc(buf_size * sizeof(char)); 137 138 if(buf) { 139 for(s = protocols; buf && *s; s++) { 140 snprintf(buf, buf_size, "%s/%s", *s, display_name); 141 if(_XConnectXCB(dpy, buf, &iscreen)) 142 goto fallback_success; 143 } 144 Xfree(buf); 145 } 146 } 147 148 OutOfMemory(dpy); 149 return NULL; 150 } 151fallback_success: 152 153 /* Initialize as much of the display structure as we can. 154 * Initialize pointers to NULL so that XFreeDisplayStructure will 155 * work if we run out of memory before we finish initializing. 156 */ 157 dpy->keysyms = (KeySym *) NULL; 158 dpy->modifiermap = NULL; 159 dpy->lock_meaning = NoSymbol; 160 dpy->keysyms_per_keycode = 0; 161 dpy->xdefaults = (char *)NULL; 162 dpy->scratch_length = 0L; 163 dpy->scratch_buffer = NULL; 164 dpy->key_bindings = NULL; 165 dpy->ext_procs = (_XExtension *)NULL; 166 dpy->ext_data = (XExtData *)NULL; 167 dpy->ext_number = 0; 168 dpy->event_vec[X_Error] = _XUnknownWireEvent; 169 dpy->event_vec[X_Reply] = _XUnknownWireEvent; 170 dpy->wire_vec[X_Error] = _XUnknownNativeEvent; 171 dpy->wire_vec[X_Reply] = _XUnknownNativeEvent; 172 for (i = KeyPress; i < LASTEvent; i++) { 173 dpy->event_vec[i] = _XWireToEvent; 174 dpy->wire_vec[i] = NULL; 175 } 176 for (i = LASTEvent; i < 128; i++) { 177 dpy->event_vec[i] = _XUnknownWireEvent; 178 dpy->wire_vec[i] = _XUnknownNativeEvent; 179 } 180 dpy->resource_id = 0; 181 dpy->db = (struct _XrmHashBucketRec *)NULL; 182 dpy->cursor_font = None; 183 dpy->flags = 0; 184 dpy->async_handlers = NULL; 185 dpy->screens = NULL; 186 dpy->vendor = NULL; 187 dpy->buffer = NULL; 188 dpy->atoms = NULL; 189 dpy->error_vec = NULL; 190 dpy->context_db = NULL; 191 dpy->free_funcs = NULL; 192 dpy->pixmap_format = NULL; 193 dpy->cms.clientCmaps = NULL; 194 dpy->cms.defaultCCCs = NULL; 195 dpy->cms.perVisualIntensityMaps = NULL; 196 dpy->im_filters = NULL; 197 dpy->bigreq_size = 0; 198 dpy->lock = NULL; 199 dpy->lock_fns = NULL; 200 dpy->qfree = NULL; 201 dpy->next_event_serial_num = 1; 202 dpy->im_fd_info = NULL; 203 dpy->im_fd_length = 0; 204 dpy->conn_watchers = NULL; 205 dpy->watcher_count = 0; 206 dpy->filedes = NULL; 207 dpy->flushes = NULL; 208 dpy->xcmisc_opcode = 0; 209 dpy->xkb_info = NULL; 210 211/* 212 * Setup other information in this display structure. 213 */ 214 dpy->vnumber = X_PROTOCOL; 215 dpy->resource_alloc = _XAllocID; 216 dpy->idlist_alloc = _XAllocIDs; 217 dpy->synchandler = NULL; 218 dpy->savedsynchandler = NULL; 219 dpy->request = 0; 220 dpy->last_request_read = 0; 221 dpy->default_screen = iscreen; /* Value returned by ConnectDisplay */ 222 dpy->last_req = (char *)&_dummy_request; 223 224 /* Initialize the display lock */ 225 if (InitDisplayLock(dpy) != 0) { 226 OutOfMemory (dpy); 227 return(NULL); 228 } 229 230 if (!_XPollfdCacheInit(dpy)) { 231 OutOfMemory (dpy); 232 return(NULL); 233 } 234 235 /* Set up the output buffers. */ 236#ifndef XLIBDEFAULTBUFSIZE 237#define XLIBDEFAULTBUFSIZE 16384 /* 16k */ 238#endif 239#ifndef XLIBMINBUFSIZE 240#define XLIBMINBUFSIZE BUFSIZE /* old default buffer size */ 241#endif 242 xlib_buffer_size = getenv("XLIBBUFFERSIZE"); 243 244#ifdef __sun /* Backwards compatibility for old Solaris libX11 name */ 245 if (xlib_buffer_size == NULL) 246 xlib_buffer_size = getenv("XSUNBUFFERSIZE"); 247#endif 248 249 if (xlib_buffer_size == NULL) 250 conn_buf_size = XLIBDEFAULTBUFSIZE; 251 else 252 conn_buf_size = 1024 * strtol(xlib_buffer_size, NULL, 10); 253 if (conn_buf_size < XLIBMINBUFSIZE) 254 conn_buf_size = XLIBMINBUFSIZE; 255 256 if ((dpy->bufptr = dpy->buffer = Xcalloc(1, conn_buf_size)) == NULL) { 257 OutOfMemory (dpy); 258 return(NULL); 259 } 260 dpy->xcb->real_bufmax = dpy->buffer + conn_buf_size; 261 dpy->bufmax = dpy->buffer; 262 263 /* Set up the input event queue and input event queue parameters. */ 264 dpy->head = dpy->tail = NULL; 265 dpy->qlen = 0; 266 267 /* Set up free-function record */ 268 if ((dpy->free_funcs = (_XFreeFuncRec *)Xcalloc(1, 269 sizeof(_XFreeFuncRec))) 270 == NULL) { 271 OutOfMemory (dpy); 272 return(NULL); 273 } 274 275 { 276 const struct xcb_setup_t *xcbsetup = xcb_get_setup(dpy->xcb->connection); 277 memcpy(&prefix, xcbsetup, sizeof(prefix)); 278 setuplength = prefix.length << 2; 279 setup = (char *) xcbsetup; 280 setup += SIZEOF(xConnSetupPrefix); 281 u.setup = (xConnSetup *) setup; 282 } 283 284/* 285 * Check if the reply was long enough to get any information out of it. 286 */ 287 usedbytes = sz_xConnSetup; 288 if (setuplength < usedbytes ) { 289 fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength); 290 OutOfMemory(dpy); 291 return (NULL); 292 } 293 294/* 295 * We succeeded at authorization, so let us move the data into 296 * the display structure. 297 */ 298 dpy->proto_major_version= prefix.majorVersion; 299 dpy->proto_minor_version= prefix.minorVersion; 300 dpy->release = u.setup->release; 301 dpy->resource_base = u.setup->ridBase; 302 dpy->resource_mask = u.setup->ridMask; 303 dpy->min_keycode = u.setup->minKeyCode; 304 dpy->max_keycode = u.setup->maxKeyCode; 305 dpy->motion_buffer = u.setup->motionBufferSize; 306 dpy->nformats = u.setup->numFormats; 307 dpy->nscreens = u.setup->numRoots; 308 dpy->byte_order = u.setup->imageByteOrder; 309 dpy->bitmap_unit = u.setup->bitmapScanlineUnit; 310 dpy->bitmap_pad = u.setup->bitmapScanlinePad; 311 dpy->bitmap_bit_order = u.setup->bitmapBitOrder; 312 dpy->max_request_size = u.setup->maxRequestSize; 313 mask = dpy->resource_mask; 314 dpy->resource_shift = 0; 315 if (!mask) 316 { 317 fprintf (stderr, "Xlib: connection to \"%s\" invalid setup\n", 318 dpy->display_name); 319 OutOfMemory(dpy); 320 return (NULL); 321 } 322 323 while (!(mask & 1)) { 324 dpy->resource_shift++; 325 mask = mask >> 1; 326 } 327 dpy->resource_max = (dpy->resource_mask >> dpy->resource_shift) - 5; 328/* 329 * now extract the vendor string... String must be null terminated, 330 * padded to multiple of 4 bytes. 331 */ 332 /* Check for a sane vendor string length */ 333 if (u.setup->nbytesVendor > 256) { 334 OutOfMemory(dpy); 335 return (NULL); 336 } 337 338 dpy->vendor = (char *) Xmalloc((unsigned) (u.setup->nbytesVendor + 1)); 339 if (dpy->vendor == NULL) { 340 OutOfMemory(dpy); 341 return (NULL); 342 } 343 vendorlen = u.setup->nbytesVendor; 344 345/* 346 * validate setup length 347 */ 348 usedbytes += (vendorlen + 3) & ~3; 349 if (setuplength < usedbytes) { 350 fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength); 351 OutOfMemory(dpy); 352 return (NULL); 353 } 354 355 u.setup = (xConnSetup *) (((char *) u.setup) + sz_xConnSetup); 356 (void) strncpy(dpy->vendor, u.vendor, vendorlen); 357 dpy->vendor[vendorlen] = '\0'; 358 vendorlen = (vendorlen + 3) & ~3; /* round up */ 359 u.vendor += vendorlen; 360 361/* 362 * Now iterate down setup information..... 363 */ 364 dpy->pixmap_format = 365 (ScreenFormat *)Xmalloc( 366 (unsigned) (dpy->nformats *sizeof(ScreenFormat))); 367 if (dpy->pixmap_format == NULL) { 368 OutOfMemory (dpy); 369 return(NULL); 370 } 371/* 372 * First decode the Z axis Screen format information. 373 */ 374 usedbytes += dpy->nformats * sz_xPixmapFormat; 375 376 if (setuplength < usedbytes) { 377 fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength); 378 OutOfMemory (dpy); 379 return(NULL); 380 } 381 382 for (i = 0; i < dpy->nformats; i++) { 383 register ScreenFormat *fmt = &dpy->pixmap_format[i]; 384 fmt->depth = u.sf->depth; 385 fmt->bits_per_pixel = u.sf->bitsPerPixel; 386 fmt->scanline_pad = u.sf->scanLinePad; 387 fmt->ext_data = NULL; 388 u.sf = (xPixmapFormat *) (((char *) u.sf) + sz_xPixmapFormat); 389 } 390 391/* 392 * next the Screen structures. 393 */ 394 dpy->screens = 395 (Screen *)Xmalloc((unsigned) dpy->nscreens*sizeof(Screen)); 396 if (dpy->screens == NULL) { 397 OutOfMemory (dpy); 398 return(NULL); 399 } 400 401/* 402 * Now go deal with each screen structure. 403 */ 404 for (i = 0; i < dpy->nscreens; i++) { 405 register Screen *sp = &dpy->screens[i]; 406 VisualID root_visualID; 407 408 usedbytes += sz_xWindowRoot; 409 if (setuplength < usedbytes) { 410 fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength); 411 OutOfMemory (dpy); 412 return(NULL); 413 } 414 415 root_visualID = u.rp->rootVisualID; 416 sp->display = dpy; 417 sp->root = u.rp->windowId; 418 sp->cmap = u.rp->defaultColormap; 419 sp->white_pixel = u.rp->whitePixel; 420 sp->black_pixel = u.rp->blackPixel; 421 sp->root_input_mask = u.rp->currentInputMask; 422 sp->width = u.rp->pixWidth; 423 sp->height = u.rp->pixHeight; 424 sp->mwidth = u.rp->mmWidth; 425 sp->mheight = u.rp->mmHeight; 426 sp->min_maps = u.rp->minInstalledMaps; 427 sp->max_maps = u.rp->maxInstalledMaps; 428 sp->backing_store= u.rp->backingStore; 429 sp->save_unders = u.rp->saveUnders; 430 sp->root_depth = u.rp->rootDepth; 431 sp->ndepths = u.rp->nDepths; 432 sp->ext_data = NULL; 433 u.rp = (xWindowRoot *) (((char *) u.rp) + sz_xWindowRoot); 434/* 435 * lets set up the depth structures. 436 */ 437 sp->depths = (Depth *)Xmalloc( 438 (unsigned)sp->ndepths*sizeof(Depth)); 439 if (sp->depths == NULL) { 440 OutOfMemory (dpy); 441 return(NULL); 442 } 443 /* 444 * for all depths on this screen. 445 */ 446 for (j = 0; j < sp->ndepths; j++) { 447 Depth *dp = &sp->depths[j]; 448 449 usedbytes += sz_xDepth; 450 if (setuplength < usedbytes) { 451 fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength); 452 OutOfMemory (dpy); 453 return(NULL); 454 } 455 456 dp->depth = u.dp->depth; 457 dp->nvisuals = u.dp->nVisuals; 458 u.dp = (xDepth *) (((char *) u.dp) + sz_xDepth); 459 if (dp->nvisuals > 0) { 460 dp->visuals = 461 (Visual *)Xmalloc((unsigned)dp->nvisuals*sizeof(Visual)); 462 if (dp->visuals == NULL) { 463 OutOfMemory (dpy); 464 return(NULL); 465 } 466 for (k = 0; k < dp->nvisuals; k++) { 467 register Visual *vp = &dp->visuals[k]; 468 469 usedbytes += sz_xVisualType; 470 if (setuplength < usedbytes) { 471 fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength); 472 OutOfMemory (dpy); 473 return(NULL); 474 } 475 476 vp->visualid = u.vp->visualID; 477 vp->class = u.vp->class; 478 vp->bits_per_rgb= u.vp->bitsPerRGB; 479 vp->map_entries = u.vp->colormapEntries; 480 vp->red_mask = u.vp->redMask; 481 vp->green_mask = u.vp->greenMask; 482 vp->blue_mask = u.vp->blueMask; 483 vp->ext_data = NULL; 484 u.vp = (xVisualType *) (((char *) u.vp) + 485 sz_xVisualType); 486 } 487 if (dp->depth == 32 && getenv ("XLIB_SKIP_ARGB_VISUALS")) 488 { 489 Xfree (dp->visuals); 490 dp->visuals = NULL; 491 dp->nvisuals = 0; 492 } 493 } else { 494 dp->visuals = (Visual *) NULL; 495 } 496 } 497 sp->root_visual = _XVIDtoVisual(dpy, root_visualID); 498 } 499 500 if(usedbytes != setuplength){ 501 /* Sanity check, shouldn't happen. */ 502 fprintf(stderr, "Xlib: Did not parse entire setup message: " 503 "parsed: %ld, message: %ld\n", 504 usedbytes, setuplength); 505 OutOfMemory(dpy); 506 return(NULL); 507 } 508 509/* 510 * Now start talking to the server to setup all other information... 511 */ 512 513/* 514 * Make sure default screen is legal. 515 */ 516 if (iscreen >= dpy->nscreens) { 517 OutOfMemory(dpy); 518 return(NULL); 519 } 520 521 dpy->bigreq_size = xcb_get_maximum_request_length(dpy->xcb->connection); 522 if(dpy->bigreq_size <= dpy->max_request_size) 523 dpy->bigreq_size = 0; 524 525/* 526 * Set up other stuff clients are always going to use. 527 */ 528 for (i = 0; i < dpy->nscreens; i++) { 529 register Screen *sp = &dpy->screens[i]; 530 XGCValues values; 531 values.foreground = sp->black_pixel; 532 values.background = sp->white_pixel; 533 if ((sp->default_gc = XCreateGC (dpy, sp->root, 534 GCForeground|GCBackground, 535 &values)) == NULL) { 536 OutOfMemory(dpy); 537 return (NULL); 538 } 539 } 540/* 541 * call into synchronization routine so that all programs can be 542 * forced synchronous 543 */ 544 (void) XSynchronize(dpy, _Xdebug); 545 546/* 547 * get availability of large requests, and 548 * get the resource manager database off the root window. 549 */ 550 LockDisplay(dpy); 551 { 552 xGetPropertyReply reply; 553 xGetPropertyReq *req; 554 555 GetReq (GetProperty, req); 556 req->window = RootWindow(dpy, 0); 557 req->property = XA_RESOURCE_MANAGER; 558 req->type = XA_STRING; 559 req->delete = False; 560 req->longOffset = 0; 561 req->longLength = 100000000L; 562 563 if (_XReply (dpy, (xReply *) &reply, 0, xFalse)) { 564 if (reply.format == 8 && reply.propertyType == XA_STRING && 565 (reply.nItems + 1 > 0) && 566 (reply.nItems <= req->longLength * 4) && 567 (dpy->xdefaults = Xmalloc (reply.nItems + 1))) { 568 _XReadPad (dpy, dpy->xdefaults, reply.nItems); 569 dpy->xdefaults[reply.nItems] = '\0'; 570 } 571 else if (reply.propertyType != None) 572 _XEatData(dpy, reply.nItems * (reply.format >> 3)); 573 } 574 } 575 UnlockDisplay(dpy); 576 577#ifdef MOTIFBC 578 { 579 extern Display *_XHeadOfDisplayList; 580 _XHeadOfDisplayList = dpy; 581 } 582#endif 583#ifdef XKB 584 XkbUseExtension(dpy,NULL,NULL); 585#endif 586/* 587 * and return successfully 588 */ 589 return(dpy); 590} 591 592/* XFreeDisplayStructure frees all the storage associated with a 593 * Display. It is used by XOpenDisplay if it runs out of memory, 594 * and also by XCloseDisplay. It needs to check whether all pointers 595 * are non-NULL before dereferencing them, since it may be called 596 * by XOpenDisplay before the Display structure is fully formed. 597 * XOpenDisplay must be sure to initialize all the pointers to NULL 598 * before the first possible call on this. 599 */ 600 601void _XFreeDisplayStructure(Display *dpy) 602{ 603 /* move all cookies in the EQ to the jar, then free them. */ 604 if (dpy->qfree) { 605 _XQEvent *qelt = dpy->qfree; 606 while (qelt) { 607 if (_XIsEventCookie(dpy, &qelt->event)) 608 _XStoreEventCookie(dpy, &qelt->event); 609 qelt = qelt->next; 610 } 611 } 612 if (dpy->cookiejar) 613 _XFreeEventCookies(dpy); 614 while (dpy->ext_procs) { 615 _XExtension *ext = dpy->ext_procs; 616 dpy->ext_procs = ext->next; 617 if (ext->name) 618 Xfree (ext->name); 619 Xfree ((char *)ext); 620 } 621 if (dpy->im_filters) 622 (*dpy->free_funcs->im_filters)(dpy); 623 if (dpy->cms.clientCmaps) 624 (*dpy->free_funcs->clientCmaps)(dpy); 625 if (dpy->cms.defaultCCCs) 626 (*dpy->free_funcs->defaultCCCs)(dpy); 627 if (dpy->cms.perVisualIntensityMaps) 628 (*dpy->free_funcs->intensityMaps)(dpy); 629 if (dpy->atoms) 630 (*dpy->free_funcs->atoms)(dpy); 631 if (dpy->modifiermap) 632 (*dpy->free_funcs->modifiermap)(dpy->modifiermap); 633 if (dpy->key_bindings) 634 (*dpy->free_funcs->key_bindings)(dpy); 635 if (dpy->context_db) 636 (*dpy->free_funcs->context_db)(dpy); 637 if (dpy->xkb_info) 638 (*dpy->free_funcs->xkb)(dpy); 639 640 /* if RM database was allocated by XGetDefault() free it */ 641 if (dpy->db && (dpy->flags & XlibDisplayDfltRMDB)) 642 XrmDestroyDatabase(dpy->db); 643 644 if (dpy->screens) { 645 register int i; 646 647 for (i = 0; i < dpy->nscreens; i++) { 648 Screen *sp = &dpy->screens[i]; 649 650 if (sp->depths) { 651 register int j; 652 653 for (j = 0; j < sp->ndepths; j++) { 654 Depth *dp = &sp->depths[j]; 655 656 if (dp->visuals) { 657 register int k; 658 659 for (k = 0; k < dp->nvisuals; k++) 660 _XFreeExtData (dp->visuals[k].ext_data); 661 Xfree ((char *) dp->visuals); 662 } 663 } 664 665 Xfree ((char *) sp->depths); 666 } 667 668 _XFreeExtData (sp->ext_data); 669 } 670 671 Xfree ((char *)dpy->screens); 672 } 673 674 if (dpy->pixmap_format) { 675 register int i; 676 677 for (i = 0; i < dpy->nformats; i++) 678 _XFreeExtData (dpy->pixmap_format[i].ext_data); 679 Xfree ((char *)dpy->pixmap_format); 680 } 681 682 free(dpy->display_name); 683 if (dpy->vendor) 684 Xfree (dpy->vendor); 685 686 if (dpy->buffer) 687 Xfree (dpy->buffer); 688 if (dpy->keysyms) 689 Xfree ((char *) dpy->keysyms); 690 if (dpy->xdefaults) 691 Xfree (dpy->xdefaults); 692 if (dpy->error_vec) 693 Xfree ((char *)dpy->error_vec); 694 695 _XFreeExtData (dpy->ext_data); 696 if (dpy->free_funcs) 697 Xfree ((char *)dpy->free_funcs); 698 if (dpy->scratch_buffer) 699 Xfree (dpy->scratch_buffer); 700 FreeDisplayLock(dpy); 701 702 if (dpy->qfree) { 703 register _XQEvent *qelt = dpy->qfree; 704 705 while (qelt) { 706 register _XQEvent *qnxt = qelt->next; 707 Xfree ((char *) qelt); 708 qelt = qnxt; 709 } 710 } 711 while (dpy->im_fd_info) { 712 struct _XConnectionInfo *conni = dpy->im_fd_info; 713 dpy->im_fd_info = conni->next; 714 if (conni->watch_data) 715 Xfree (conni->watch_data); 716 Xfree (conni); 717 } 718 if (dpy->conn_watchers) { 719 struct _XConnWatchInfo *watcher = dpy->conn_watchers; 720 dpy->conn_watchers = watcher->next; 721 Xfree (watcher); 722 } 723 if (dpy->filedes) 724 Xfree (dpy->filedes); 725 726 _XFreeX11XCBStructure(dpy); 727 728 Xfree ((char *)dpy); 729} 730 731/* OutOfMemory is called if malloc fails. XOpenDisplay returns NULL 732 after this returns. */ 733 734static void OutOfMemory(Display *dpy) 735{ 736 if(dpy->xcb->connection) 737 xcb_disconnect(dpy->xcb->connection); 738 _XFreeDisplayStructure (dpy); 739} 740