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