OpenDis.c revision 2d67cb4f
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 = 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 OutOfMemory(dpy); 131 return NULL; 132 } 133 134 /* Initialize as much of the display structure as we can. 135 * Initialize pointers to NULL so that XFreeDisplayStructure will 136 * work if we run out of memory before we finish initializing. 137 */ 138 dpy->keysyms = (KeySym *) NULL; 139 dpy->modifiermap = NULL; 140 dpy->lock_meaning = NoSymbol; 141 dpy->keysyms_per_keycode = 0; 142 dpy->xdefaults = (char *)NULL; 143 dpy->scratch_length = 0L; 144 dpy->scratch_buffer = NULL; 145 dpy->key_bindings = NULL; 146 dpy->ext_procs = (_XExtension *)NULL; 147 dpy->ext_data = (XExtData *)NULL; 148 dpy->ext_number = 0; 149 dpy->event_vec[X_Error] = _XUnknownWireEvent; 150 dpy->event_vec[X_Reply] = _XUnknownWireEvent; 151 dpy->wire_vec[X_Error] = _XUnknownNativeEvent; 152 dpy->wire_vec[X_Reply] = _XUnknownNativeEvent; 153 for (i = KeyPress; i < LASTEvent; i++) { 154 dpy->event_vec[i] = _XWireToEvent; 155 dpy->wire_vec[i] = NULL; 156 } 157 for (i = LASTEvent; i < 128; i++) { 158 dpy->event_vec[i] = _XUnknownWireEvent; 159 dpy->wire_vec[i] = _XUnknownNativeEvent; 160 } 161 dpy->resource_id = 0; 162 dpy->db = (struct _XrmHashBucketRec *)NULL; 163 dpy->cursor_font = None; 164 dpy->flags = 0; 165 dpy->async_handlers = NULL; 166 dpy->screens = NULL; 167 dpy->vendor = NULL; 168 dpy->buffer = NULL; 169 dpy->atoms = NULL; 170 dpy->error_vec = NULL; 171 dpy->context_db = NULL; 172 dpy->free_funcs = NULL; 173 dpy->pixmap_format = NULL; 174 dpy->cms.clientCmaps = NULL; 175 dpy->cms.defaultCCCs = NULL; 176 dpy->cms.perVisualIntensityMaps = NULL; 177 dpy->im_filters = NULL; 178 dpy->bigreq_size = 0; 179 dpy->lock = NULL; 180 dpy->lock_fns = NULL; 181 dpy->qfree = NULL; 182 dpy->next_event_serial_num = 1; 183 dpy->im_fd_info = NULL; 184 dpy->im_fd_length = 0; 185 dpy->conn_watchers = NULL; 186 dpy->watcher_count = 0; 187 dpy->filedes = NULL; 188 dpy->flushes = NULL; 189 dpy->xcmisc_opcode = 0; 190 dpy->xkb_info = NULL; 191 192/* 193 * Setup other information in this display structure. 194 */ 195 dpy->vnumber = X_PROTOCOL; 196 dpy->resource_alloc = _XAllocID; 197 dpy->idlist_alloc = _XAllocIDs; 198 dpy->synchandler = NULL; 199 dpy->savedsynchandler = NULL; 200 X_DPY_SET_REQUEST(dpy, 0); 201 X_DPY_SET_LAST_REQUEST_READ(dpy, 0); 202 dpy->default_screen = iscreen; /* Value returned by ConnectDisplay */ 203 dpy->last_req = (char *)&_dummy_request; 204 205 /* Initialize the display lock */ 206 if (InitDisplayLock(dpy) != 0) { 207 OutOfMemory (dpy); 208 return(NULL); 209 } 210 211 if (!_XPollfdCacheInit(dpy)) { 212 OutOfMemory (dpy); 213 return(NULL); 214 } 215 216 /* Set up the output buffers. */ 217#ifndef XLIBDEFAULTBUFSIZE 218#define XLIBDEFAULTBUFSIZE 16384 /* 16k */ 219#endif 220#ifndef XLIBMINBUFSIZE 221#define XLIBMINBUFSIZE BUFSIZE /* old default buffer size */ 222#endif 223 xlib_buffer_size = getenv("XLIBBUFFERSIZE"); 224 225#ifdef __sun /* Backwards compatibility for old Solaris libX11 name */ 226 if (xlib_buffer_size == NULL) 227 xlib_buffer_size = getenv("XSUNBUFFERSIZE"); 228#endif 229 230 if (xlib_buffer_size == NULL) 231 conn_buf_size = XLIBDEFAULTBUFSIZE; 232 else 233 conn_buf_size = 1024 * strtol(xlib_buffer_size, NULL, 10); 234 if (conn_buf_size < XLIBMINBUFSIZE) 235 conn_buf_size = XLIBMINBUFSIZE; 236 237 if ((dpy->bufptr = dpy->buffer = Xcalloc(1, conn_buf_size)) == NULL) { 238 OutOfMemory (dpy); 239 return(NULL); 240 } 241 dpy->xcb->real_bufmax = dpy->buffer + conn_buf_size; 242 dpy->bufmax = dpy->buffer; 243 244 /* Set up the input event queue and input event queue parameters. */ 245 dpy->head = dpy->tail = NULL; 246 dpy->qlen = 0; 247 248 /* Set up free-function record */ 249 if ((dpy->free_funcs = Xcalloc(1, sizeof(_XFreeFuncRec))) == NULL) { 250 OutOfMemory (dpy); 251 return(NULL); 252 } 253 254 { 255 const struct xcb_setup_t *xcbsetup = xcb_get_setup(dpy->xcb->connection); 256 memcpy(&prefix, xcbsetup, sizeof(prefix)); 257 setuplength = prefix.length << 2; 258 setup = (char *) xcbsetup; 259 setup += SIZEOF(xConnSetupPrefix); 260 u.setup = (xConnSetup *) setup; 261 } 262 263/* 264 * Check if the reply was long enough to get any information out of it. 265 */ 266 usedbytes = sz_xConnSetup; 267 if (setuplength < usedbytes ) { 268 fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength); 269 OutOfMemory(dpy); 270 return (NULL); 271 } 272 273/* 274 * We succeeded at authorization, so let us move the data into 275 * the display structure. 276 */ 277 dpy->proto_major_version= prefix.majorVersion; 278 dpy->proto_minor_version= prefix.minorVersion; 279 dpy->release = u.setup->release; 280 dpy->resource_base = u.setup->ridBase; 281 dpy->resource_mask = u.setup->ridMask; 282 dpy->min_keycode = u.setup->minKeyCode; 283 dpy->max_keycode = u.setup->maxKeyCode; 284 dpy->motion_buffer = u.setup->motionBufferSize; 285 dpy->nformats = u.setup->numFormats; 286 dpy->nscreens = u.setup->numRoots; 287 dpy->byte_order = u.setup->imageByteOrder; 288 dpy->bitmap_unit = u.setup->bitmapScanlineUnit; 289 dpy->bitmap_pad = u.setup->bitmapScanlinePad; 290 dpy->bitmap_bit_order = u.setup->bitmapBitOrder; 291 dpy->max_request_size = u.setup->maxRequestSize; 292 mask = dpy->resource_mask; 293 dpy->resource_shift = 0; 294 if (!mask) 295 { 296 fprintf (stderr, "Xlib: connection to \"%s\" invalid setup\n", 297 dpy->display_name); 298 OutOfMemory(dpy); 299 return (NULL); 300 } 301 302 while (!(mask & 1)) { 303 dpy->resource_shift++; 304 mask = mask >> 1; 305 } 306 dpy->resource_max = (dpy->resource_mask >> dpy->resource_shift) - 5; 307/* 308 * now extract the vendor string... String must be null terminated, 309 * padded to multiple of 4 bytes. 310 */ 311 /* Check for a sane vendor string length */ 312 if (u.setup->nbytesVendor > 256) { 313 OutOfMemory(dpy); 314 return (NULL); 315 } 316 317 dpy->vendor = Xmalloc(u.setup->nbytesVendor + 1); 318 if (dpy->vendor == NULL) { 319 OutOfMemory(dpy); 320 return (NULL); 321 } 322 vendorlen = u.setup->nbytesVendor; 323 324/* 325 * validate setup length 326 */ 327 usedbytes += (vendorlen + 3) & ~3; 328 if (setuplength < usedbytes) { 329 fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength); 330 OutOfMemory(dpy); 331 return (NULL); 332 } 333 334 u.setup = (xConnSetup *) (((char *) u.setup) + sz_xConnSetup); 335 (void) strncpy(dpy->vendor, u.vendor, vendorlen); 336 dpy->vendor[vendorlen] = '\0'; 337 vendorlen = (vendorlen + 3) & ~3; /* round up */ 338 u.vendor += vendorlen; 339 340/* 341 * Now iterate down setup information..... 342 */ 343 dpy->pixmap_format = Xcalloc(dpy->nformats, sizeof(ScreenFormat)); 344 if (dpy->pixmap_format == NULL) { 345 OutOfMemory (dpy); 346 return(NULL); 347 } 348/* 349 * First decode the Z axis Screen format information. 350 */ 351 usedbytes += dpy->nformats * sz_xPixmapFormat; 352 353 if (setuplength < usedbytes) { 354 fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength); 355 OutOfMemory (dpy); 356 return(NULL); 357 } 358 359 for (i = 0; i < dpy->nformats; i++) { 360 register ScreenFormat *fmt = &dpy->pixmap_format[i]; 361 fmt->depth = u.sf->depth; 362 fmt->bits_per_pixel = u.sf->bitsPerPixel; 363 fmt->scanline_pad = u.sf->scanLinePad; 364 fmt->ext_data = NULL; 365 u.sf = (xPixmapFormat *) (((char *) u.sf) + sz_xPixmapFormat); 366 } 367 368/* 369 * next the Screen structures. 370 */ 371 dpy->screens = Xcalloc(dpy->nscreens, sizeof(Screen)); 372 if (dpy->screens == NULL) { 373 OutOfMemory (dpy); 374 return(NULL); 375 } 376 377/* 378 * Now go deal with each screen structure. 379 */ 380 for (i = 0; i < dpy->nscreens; i++) { 381 register Screen *sp = &dpy->screens[i]; 382 VisualID root_visualID; 383 384 usedbytes += sz_xWindowRoot; 385 if (setuplength < usedbytes) { 386 fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength); 387 OutOfMemory (dpy); 388 return(NULL); 389 } 390 391 root_visualID = u.rp->rootVisualID; 392 sp->display = dpy; 393 sp->root = u.rp->windowId; 394 sp->cmap = u.rp->defaultColormap; 395 sp->white_pixel = u.rp->whitePixel; 396 sp->black_pixel = u.rp->blackPixel; 397 sp->root_input_mask = u.rp->currentInputMask; 398 sp->width = u.rp->pixWidth; 399 sp->height = u.rp->pixHeight; 400 sp->mwidth = u.rp->mmWidth; 401 sp->mheight = u.rp->mmHeight; 402 sp->min_maps = u.rp->minInstalledMaps; 403 sp->max_maps = u.rp->maxInstalledMaps; 404 sp->backing_store= u.rp->backingStore; 405 sp->save_unders = u.rp->saveUnders; 406 sp->root_depth = u.rp->rootDepth; 407 sp->ndepths = u.rp->nDepths; 408 sp->ext_data = NULL; 409 u.rp = (xWindowRoot *) (((char *) u.rp) + sz_xWindowRoot); 410/* 411 * lets set up the depth structures. 412 */ 413 sp->depths = Xcalloc(sp->ndepths, sizeof(Depth)); 414 if (sp->depths == NULL) { 415 OutOfMemory (dpy); 416 return(NULL); 417 } 418 /* 419 * for all depths on this screen. 420 */ 421 for (j = 0; j < sp->ndepths; j++) { 422 Depth *dp = &sp->depths[j]; 423 424 usedbytes += sz_xDepth; 425 if (setuplength < usedbytes) { 426 fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength); 427 OutOfMemory (dpy); 428 return(NULL); 429 } 430 431 dp->depth = u.dp->depth; 432 dp->nvisuals = u.dp->nVisuals; 433 u.dp = (xDepth *) (((char *) u.dp) + sz_xDepth); 434 if (dp->nvisuals > 0) { 435 dp->visuals = Xcalloc(dp->nvisuals, sizeof(Visual)); 436 if (dp->visuals == NULL) { 437 OutOfMemory (dpy); 438 return(NULL); 439 } 440 for (k = 0; k < dp->nvisuals; k++) { 441 register Visual *vp = &dp->visuals[k]; 442 443 usedbytes += sz_xVisualType; 444 if (setuplength < usedbytes) { 445 fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength); 446 OutOfMemory (dpy); 447 return(NULL); 448 } 449 450 vp->visualid = u.vp->visualID; 451 vp->class = u.vp->class; 452 vp->bits_per_rgb= u.vp->bitsPerRGB; 453 vp->map_entries = u.vp->colormapEntries; 454 vp->red_mask = u.vp->redMask; 455 vp->green_mask = u.vp->greenMask; 456 vp->blue_mask = u.vp->blueMask; 457 vp->ext_data = NULL; 458 u.vp = (xVisualType *) (((char *) u.vp) + 459 sz_xVisualType); 460 } 461 if (dp->depth == 32 && getenv ("XLIB_SKIP_ARGB_VISUALS")) 462 { 463 Xfree (dp->visuals); 464 dp->visuals = NULL; 465 dp->nvisuals = 0; 466 } 467 } else { 468 dp->visuals = (Visual *) NULL; 469 } 470 } 471 sp->root_visual = _XVIDtoVisual(dpy, root_visualID); 472 } 473 474 if(usedbytes != setuplength){ 475 /* Sanity check, shouldn't happen. */ 476 fprintf(stderr, "Xlib: Did not parse entire setup message: " 477 "parsed: %ld, message: %ld\n", 478 usedbytes, setuplength); 479 OutOfMemory(dpy); 480 return(NULL); 481 } 482 483/* 484 * Now start talking to the server to setup all other information... 485 */ 486 487/* 488 * Make sure default screen is legal. 489 */ 490 if (iscreen >= dpy->nscreens) { 491 OutOfMemory(dpy); 492 return(NULL); 493 } 494 495/* 496 * get availability of large requests 497 */ 498 dpy->bigreq_size = xcb_get_maximum_request_length(dpy->xcb->connection); 499 if(dpy->bigreq_size <= dpy->max_request_size) 500 dpy->bigreq_size = 0; 501 502/* 503 * Set up other stuff clients are always going to use. 504 */ 505 for (i = 0; i < dpy->nscreens; i++) { 506 register Screen *sp = &dpy->screens[i]; 507 XGCValues values; 508 values.foreground = sp->black_pixel; 509 values.background = sp->white_pixel; 510 if ((sp->default_gc = XCreateGC (dpy, sp->root, 511 GCForeground|GCBackground, 512 &values)) == NULL) { 513 OutOfMemory(dpy); 514 return (NULL); 515 } 516 } 517/* 518 * call into synchronization routine so that all programs can be 519 * forced synchronous 520 */ 521 (void) XSynchronize(dpy, _Xdebug); 522 523/* 524 * get the resource manager database off the root window. 525 */ 526 LockDisplay(dpy); 527 { 528 xGetPropertyReply reply; 529 xGetPropertyReq *req; 530 531 GetReq (GetProperty, req); 532 req->window = RootWindow(dpy, 0); 533 req->property = XA_RESOURCE_MANAGER; 534 req->type = XA_STRING; 535 req->delete = False; 536 req->longOffset = 0; 537 req->longLength = 100000000L; 538 539 if (_XReply (dpy, (xReply *) &reply, 0, xFalse)) { 540 if (reply.format == 8 && reply.propertyType == XA_STRING && 541 (reply.nItems + 1 > 0) && 542 (reply.nItems <= req->longLength * 4) && 543 (dpy->xdefaults = Xmalloc (reply.nItems + 1))) { 544 _XReadPad (dpy, dpy->xdefaults, reply.nItems); 545 dpy->xdefaults[reply.nItems] = '\0'; 546 } 547 else if (reply.propertyType != None) 548 _XEatDataWords(dpy, reply.length); 549 } 550 } 551 UnlockDisplay(dpy); 552 553#ifdef MOTIFBC 554 { 555 extern Display *_XHeadOfDisplayList; 556 _XHeadOfDisplayList = dpy; 557 } 558#endif 559#ifdef XKB 560 XkbUseExtension(dpy,NULL,NULL); 561#endif 562/* 563 * and return successfully 564 */ 565 return(dpy); 566} 567 568/* XFreeDisplayStructure frees all the storage associated with a 569 * Display. It is used by XOpenDisplay if it runs out of memory, 570 * and also by XCloseDisplay. It needs to check whether all pointers 571 * are non-NULL before dereferencing them, since it may be called 572 * by XOpenDisplay before the Display structure is fully formed. 573 * XOpenDisplay must be sure to initialize all the pointers to NULL 574 * before the first possible call on this. 575 */ 576 577void _XFreeDisplayStructure(Display *dpy) 578{ 579 /* move all cookies in the EQ to the jar, then free them. */ 580 if (dpy->qfree) { 581 _XQEvent *qelt = dpy->qfree; 582 while (qelt) { 583 if (_XIsEventCookie(dpy, &qelt->event)) 584 _XStoreEventCookie(dpy, &qelt->event); 585 qelt = qelt->next; 586 } 587 } 588 if (dpy->cookiejar) 589 _XFreeEventCookies(dpy); 590 while (dpy->ext_procs) { 591 _XExtension *ext = dpy->ext_procs; 592 dpy->ext_procs = ext->next; 593 Xfree (ext->name); 594 Xfree (ext); 595 } 596 if (dpy->im_filters) 597 (*dpy->free_funcs->im_filters)(dpy); 598 if (dpy->cms.clientCmaps) 599 (*dpy->free_funcs->clientCmaps)(dpy); 600 if (dpy->cms.defaultCCCs) 601 (*dpy->free_funcs->defaultCCCs)(dpy); 602 if (dpy->cms.perVisualIntensityMaps) 603 (*dpy->free_funcs->intensityMaps)(dpy); 604 if (dpy->atoms) 605 (*dpy->free_funcs->atoms)(dpy); 606 if (dpy->modifiermap) 607 (*dpy->free_funcs->modifiermap)(dpy->modifiermap); 608 if (dpy->key_bindings) 609 (*dpy->free_funcs->key_bindings)(dpy); 610 if (dpy->context_db) 611 (*dpy->free_funcs->context_db)(dpy); 612 if (dpy->xkb_info) 613 (*dpy->free_funcs->xkb)(dpy); 614 615 /* if RM database was allocated by XGetDefault() free it */ 616 if (dpy->db && (dpy->flags & XlibDisplayDfltRMDB)) 617 XrmDestroyDatabase(dpy->db); 618 619 if (dpy->screens) { 620 register int i; 621 622 for (i = 0; i < dpy->nscreens; i++) { 623 Screen *sp = &dpy->screens[i]; 624 625 if (sp->depths) { 626 register int j; 627 628 for (j = 0; j < sp->ndepths; j++) { 629 Depth *dp = &sp->depths[j]; 630 631 if (dp->visuals) { 632 register int k; 633 634 for (k = 0; k < dp->nvisuals; k++) 635 _XFreeExtData (dp->visuals[k].ext_data); 636 Xfree (dp->visuals); 637 } 638 } 639 640 Xfree (sp->depths); 641 } 642 643 _XFreeExtData (sp->ext_data); 644 } 645 646 Xfree (dpy->screens); 647 } 648 649 if (dpy->pixmap_format) { 650 register int i; 651 652 for (i = 0; i < dpy->nformats; i++) 653 _XFreeExtData (dpy->pixmap_format[i].ext_data); 654 Xfree (dpy->pixmap_format); 655 } 656 657 free(dpy->display_name); 658 659 Xfree (dpy->vendor); 660 Xfree (dpy->buffer); 661 Xfree (dpy->keysyms); 662 Xfree (dpy->xdefaults); 663 Xfree (dpy->error_vec); 664 665 _XFreeExtData (dpy->ext_data); 666 667 Xfree (dpy->free_funcs); 668 Xfree (dpy->scratch_buffer); 669 FreeDisplayLock(dpy); 670 671 if (dpy->qfree) { 672 register _XQEvent *qelt = dpy->qfree; 673 674 while (qelt) { 675 register _XQEvent *qnxt = qelt->next; 676 Xfree (qelt); 677 qelt = qnxt; 678 } 679 } 680 while (dpy->im_fd_info) { 681 struct _XConnectionInfo *conni = dpy->im_fd_info; 682 dpy->im_fd_info = conni->next; 683 Xfree (conni->watch_data); 684 Xfree (conni); 685 } 686 if (dpy->conn_watchers) { 687 struct _XConnWatchInfo *watcher = dpy->conn_watchers; 688 dpy->conn_watchers = watcher->next; 689 Xfree (watcher); 690 } 691 692 Xfree (dpy->filedes); 693 694 _XFreeX11XCBStructure(dpy); 695 696 Xfree (dpy); 697} 698 699/* OutOfMemory is called if malloc fails. XOpenDisplay returns NULL 700 after this returns. */ 701 702static void OutOfMemory(Display *dpy) 703{ 704 if(dpy->xcb->connection) 705 xcb_disconnect(dpy->xcb->connection); 706 _XFreeDisplayStructure (dpy); 707} 708