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