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