Home | History | Annotate | Line # | Download | only in src
      1 /*
      2 
      3 Copyright 1985, 1986, 1998  The Open Group
      4 
      5 Permission to use, copy, modify, distribute, and sell this software and its
      6 documentation for any purpose is hereby granted without fee, provided that
      7 the above copyright notice appear in all copies and that both that
      8 copyright notice and this permission notice appear in supporting
      9 documentation.
     10 
     11 The above copyright notice and this permission notice shall be included in
     12 all copies or substantial portions of the Software.
     13 
     14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     20 
     21 Except as contained in this notice, the name of The Open Group shall not be
     22 used in advertising or otherwise to promote the sale, use or other dealings
     23 in 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"
     43 int  (*_XInitDisplayLock_fn)(Display *dpy) = NULL;
     44 void (*_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 
     53 static xReq _dummy_request = {
     54 	0, 0, 0
     55 };
     56 
     57 static 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  */
     63 Display *
     64 XOpenDisplay (
     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         = 0;
    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 	    if (sp->root_visual == NULL) {
    477 		OutOfMemory(dpy);
    478 		return(NULL);
    479 	    }
    480 	}
    481 
    482 	if(usedbytes != setuplength){
    483 	    /* Sanity check, shouldn't happen. */
    484 	    fprintf(stderr, "Xlib: Did not parse entire setup message: "
    485 	                    "parsed: %ld, message: %ld\n",
    486 		    usedbytes, setuplength);
    487 	    OutOfMemory(dpy);
    488 	    return(NULL);
    489 	}
    490 
    491 /*
    492  * Now start talking to the server to setup all other information...
    493  */
    494 
    495 /*
    496  * Make sure default screen is legal.
    497  */
    498 	if (iscreen >= dpy->nscreens) {
    499 	    OutOfMemory(dpy);
    500 	    return(NULL);
    501 	}
    502 
    503 /*
    504  * get availability of large requests
    505  */
    506 	dpy->bigreq_size = xcb_get_maximum_request_length(dpy->xcb->connection);
    507 	if(dpy->bigreq_size <= dpy->max_request_size)
    508 		dpy->bigreq_size = 0;
    509 
    510 /*
    511  * Set up other stuff clients are always going to use.
    512  */
    513 	for (i = 0; i < dpy->nscreens; i++) {
    514 	    register Screen *sp = &dpy->screens[i];
    515 	    XGCValues values;
    516 	    values.foreground = sp->black_pixel;
    517 	    values.background = sp->white_pixel;
    518 	    if ((sp->default_gc = XCreateGC (dpy, sp->root,
    519 					     GCForeground|GCBackground,
    520 					     &values)) == NULL) {
    521 		OutOfMemory(dpy);
    522 		return (NULL);
    523 	    }
    524 	}
    525 /*
    526  * call into synchronization routine so that all programs can be
    527  * forced synchronous
    528  */
    529 	(void) XSynchronize(dpy, _Xdebug);
    530 
    531 /*
    532  * get the resource manager database off the root window.
    533  */
    534 	LockDisplay(dpy);
    535 	{
    536 	    xGetPropertyReply reply;
    537 	    xGetPropertyReq *req;
    538 
    539 	    GetReq (GetProperty, req);
    540 	    req->window = RootWindow(dpy, 0);
    541 	    req->property = XA_RESOURCE_MANAGER;
    542 	    req->type = XA_STRING;
    543 	    req->delete = False;
    544 	    req->longOffset = 0;
    545 	    req->longLength = 100000000L;
    546 
    547 	    if (_XReply (dpy, (xReply *) &reply, 0, xFalse)) {
    548 		if (reply.format == 8 && reply.propertyType == XA_STRING &&
    549 		    (reply.nItems + 1 > 0) &&
    550 		    (reply.nItems <= req->longLength * 4) &&
    551 		    (dpy->xdefaults = Xmalloc (reply.nItems + 1))) {
    552 		    _XReadPad (dpy, dpy->xdefaults, reply.nItems);
    553 		    dpy->xdefaults[reply.nItems] = '\0';
    554 		}
    555 		else if (reply.propertyType != None)
    556 		    _XEatDataWords(dpy, reply.length);
    557 	    }
    558 	}
    559 	UnlockDisplay(dpy);
    560 
    561 #ifdef MOTIFBC
    562 	{
    563 	    extern Display *_XHeadOfDisplayList;
    564 	    _XHeadOfDisplayList = dpy;
    565 	}
    566 #endif
    567 #ifdef XKB
    568 	XkbUseExtension(dpy,NULL,NULL);
    569 #endif
    570 /*
    571  * and return successfully
    572  */
    573  	return(dpy);
    574 }
    575 
    576 /* XFreeDisplayStructure frees all the storage associated with a
    577  * Display.  It is used by XOpenDisplay if it runs out of memory,
    578  * and also by XCloseDisplay.   It needs to check whether all pointers
    579  * are non-NULL before dereferencing them, since it may be called
    580  * by XOpenDisplay before the Display structure is fully formed.
    581  * XOpenDisplay must be sure to initialize all the pointers to NULL
    582  * before the first possible call on this.
    583  */
    584 
    585 void _XFreeDisplayStructure(Display *dpy)
    586 {
    587 	/* move all cookies in the EQ to the jar, then free them. */
    588 	if (dpy->qfree) {
    589 	    _XQEvent *qelt = dpy->qfree;
    590 	    while (qelt) {
    591 		if (_XIsEventCookie(dpy, &qelt->event))
    592 		    _XStoreEventCookie(dpy, &qelt->event);
    593 		qelt = qelt->next;
    594 	    }
    595         }
    596 	if (dpy->cookiejar)
    597 	    _XFreeEventCookies(dpy);
    598 	while (dpy->ext_procs) {
    599 	    _XExtension *ext = dpy->ext_procs;
    600 	    dpy->ext_procs = ext->next;
    601 	    Xfree (ext->name);
    602 	    Xfree (ext);
    603 	}
    604 	if (dpy->im_filters)
    605 	   (*dpy->free_funcs->im_filters)(dpy);
    606 	if (dpy->cms.clientCmaps)
    607 	   (*dpy->free_funcs->clientCmaps)(dpy);
    608 	if (dpy->cms.defaultCCCs)
    609 	   (*dpy->free_funcs->defaultCCCs)(dpy);
    610 	if (dpy->cms.perVisualIntensityMaps)
    611 	   (*dpy->free_funcs->intensityMaps)(dpy);
    612 	if (dpy->atoms)
    613 	    (*dpy->free_funcs->atoms)(dpy);
    614 	if (dpy->modifiermap)
    615 	   (*dpy->free_funcs->modifiermap)(dpy->modifiermap);
    616 	if (dpy->key_bindings)
    617 	   (*dpy->free_funcs->key_bindings)(dpy);
    618 	if (dpy->context_db)
    619 	   (*dpy->free_funcs->context_db)(dpy);
    620 	if (dpy->xkb_info)
    621 	   (*dpy->free_funcs->xkb)(dpy);
    622 
    623 	/* if RM database was allocated by XGetDefault() free it */
    624 	if (dpy->db && (dpy->flags & XlibDisplayDfltRMDB))
    625 	    XrmDestroyDatabase(dpy->db);
    626 
    627 	if (dpy->screens) {
    628 	    register int i;
    629 
    630             for (i = 0; i < dpy->nscreens; i++) {
    631 		Screen *sp = &dpy->screens[i];
    632 
    633 		if (sp->depths) {
    634 		   register int j;
    635 
    636 		   for (j = 0; j < sp->ndepths; j++) {
    637 			Depth *dp = &sp->depths[j];
    638 
    639 			if (dp->visuals) {
    640 			   register int k;
    641 
    642 			   for (k = 0; k < dp->nvisuals; k++)
    643 			     _XFreeExtData (dp->visuals[k].ext_data);
    644 			   Xfree (dp->visuals);
    645 			   }
    646 			}
    647 
    648 		   Xfree (sp->depths);
    649 		   }
    650 
    651 		_XFreeExtData (sp->ext_data);
    652 		}
    653 
    654 	    Xfree (dpy->screens);
    655 	    }
    656 
    657 	if (dpy->pixmap_format) {
    658 	    register int i;
    659 
    660 	    for (i = 0; i < dpy->nformats; i++)
    661 	      _XFreeExtData (dpy->pixmap_format[i].ext_data);
    662             Xfree (dpy->pixmap_format);
    663 	    }
    664 
    665 	free(dpy->display_name);
    666 
    667 	Xfree (dpy->vendor);
    668 	Xfree (dpy->buffer);
    669 	Xfree (dpy->keysyms);
    670 	Xfree (dpy->xdefaults);
    671 	Xfree (dpy->error_vec);
    672 
    673 	_XFreeExtData (dpy->ext_data);
    674 
    675 	Xfree (dpy->free_funcs);
    676 	Xfree (dpy->scratch_buffer);
    677 	FreeDisplayLock(dpy);
    678 
    679 	if (dpy->qfree) {
    680 	    register _XQEvent *qelt = dpy->qfree;
    681 
    682 	    while (qelt) {
    683 		register _XQEvent *qnxt = qelt->next;
    684 		Xfree (qelt);
    685 		qelt = qnxt;
    686 	    }
    687 	}
    688 	while (dpy->im_fd_info) {
    689 	    struct _XConnectionInfo *conni = dpy->im_fd_info;
    690 	    dpy->im_fd_info = conni->next;
    691 	    Xfree (conni->watch_data);
    692 	    Xfree (conni);
    693 	}
    694 	if (dpy->conn_watchers) {
    695 	    struct _XConnWatchInfo *watcher = dpy->conn_watchers;
    696 	    dpy->conn_watchers = watcher->next;
    697 	    Xfree (watcher);
    698 	}
    699 
    700 	Xfree (dpy->filedes);
    701 
    702 	_XFreeX11XCBStructure(dpy);
    703 
    704 	Xfree (dpy);
    705 }
    706 
    707 /* OutOfMemory is called if malloc fails.  XOpenDisplay returns NULL
    708    after this returns. */
    709 
    710 static void OutOfMemory(Display *dpy)
    711 {
    712 	xcb_connection_t *connection = dpy->xcb->connection;
    713 
    714 	_XFreeDisplayStructure (dpy);
    715 
    716 	if (connection)
    717 	    xcb_disconnect(connection);
    718 }
    719