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