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