OpenDis.c revision 4e08afa9
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         = 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
585void _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
710static void OutOfMemory(Display *dpy)
711{
712    if(dpy->xcb->connection)
713	xcb_disconnect(dpy->xcb->connection);
714    _XFreeDisplayStructure (dpy);
715}
716