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