OpenDis.c revision 88de56cc
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#define NEED_REPLIES
28#define NEED_EVENTS
29#ifdef HAVE_CONFIG_H
30#include <config.h>
31#endif
32#include "Xlibint.h"
33#if USE_XCB
34#include "Xxcbint.h"
35#else /* !USE_XCB */
36#include <X11/Xtrans/Xtrans.h>
37#include <X11/extensions/bigreqstr.h>
38#endif /* USE_XCB */
39#include <X11/Xatom.h>
40#include <X11/Xresource.h>
41#include <stdio.h>
42#include "Xintconn.h"
43
44#ifdef XKB
45#include "XKBlib.h"
46#endif /* XKB */
47
48#if !USE_XCB
49#ifdef X_NOT_POSIX
50#define Size_t unsigned int
51#else
52#define Size_t size_t
53#endif
54
55#define bignamelen (sizeof(XBigReqExtensionName) - 1)
56
57typedef struct {
58    unsigned long seq;
59    int opcode;
60} _XBigReqState;
61#endif /* !USE_XCB */
62
63#ifdef XTHREADS
64#include "locking.h"
65int  (*_XInitDisplayLock_fn)(Display *dpy) = NULL;
66void (*_XFreeDisplayLock_fn)(Display *dpy) = NULL;
67
68#define InitDisplayLock(d)	(_XInitDisplayLock_fn ? (*_XInitDisplayLock_fn)(d) : Success)
69#define FreeDisplayLock(d)	if (_XFreeDisplayLock_fn) (*_XFreeDisplayLock_fn)(d)
70#else
71#define InitDisplayLock(dis) Success
72#define FreeDisplayLock(dis)
73#endif /* XTHREADS */
74
75static xReq _dummy_request = {
76	0, 0, 0
77};
78
79static void OutOfMemory(Display *dpy, char *setup);
80#if !USE_XCB
81static Bool _XBigReqHandler(Display *dpy, xReply *rep, char *buf, int len,
82				XPointer data);
83#endif /* !USE_XCB */
84
85/*
86 * Connects to a server, creates a Display object and returns a pointer to
87 * the newly created Display back to the caller.
88 */
89Display *
90XOpenDisplay (
91	register _Xconst char *display)
92{
93	register Display *dpy;		/* New Display object being created. */
94	register int i;
95	int j, k;			/* random iterator indexes */
96	char *display_name;		/* pointer to display name */
97#if !USE_XCB
98	int endian;			/* to determine which endian. */
99	xConnClientPrefix client;	/* client information */
100	int idisplay;			/* display number */
101	int prefixread = 0;             /* setup prefix already read? */
102	char *conn_auth_name, *conn_auth_data;
103	int conn_auth_namelen, conn_auth_datalen;
104#endif /* !USE_XCB */
105	char *setup = NULL;		/* memory allocated at startup */
106	char *fullname = NULL;		/* expanded name of display */
107	int iscreen;			/* screen number */
108	xConnSetupPrefix prefix;	/* prefix information */
109	int vendorlen;			/* length of vendor string */
110	union {
111		xConnSetup *setup;
112		char *failure;
113		char *vendor;
114		xPixmapFormat *sf;
115		xWindowRoot *rp;
116		xDepth *dp;
117		xVisualType *vp;
118	} u;				/* proto data returned from server */
119	long setuplength;	/* number of bytes in setup message */
120	long usedbytes = 0;     /* number of bytes we have processed */
121	unsigned long mask;
122	long int conn_buf_size;
123	char *xlib_buffer_size;
124
125#if !USE_XCB
126	bzero((char *) &client, sizeof(client));
127	bzero((char *) &prefix, sizeof(prefix));
128#endif /* !USE_XCB */
129
130	/*
131	 * If the display specifier string supplied as an argument to this
132	 * routine is NULL or a pointer to NULL, read the DISPLAY variable.
133	 */
134	if (display == NULL || *display == '\0') {
135		if ((display_name = getenv("DISPLAY")) == NULL) {
136			/* Oops! No DISPLAY environment variable - error. */
137			return(NULL);
138		}
139	}
140	else {
141		/* Display is non-NULL, copy the pointer */
142		display_name = (char *)display;
143	}
144
145/*
146 * Set the default error handlers.  This allows the global variables to
147 * default to NULL for use with shared libraries.
148 */
149	if (_XErrorFunction == NULL) (void) XSetErrorHandler (NULL);
150	if (_XIOErrorFunction == NULL) (void) XSetIOErrorHandler (NULL);
151
152/*
153 * Attempt to allocate a display structure. Return NULL if allocation fails.
154 */
155	if ((dpy = (Display *)Xcalloc(1, sizeof(Display))) == NULL) {
156		return(NULL);
157	}
158
159/*
160 * Call the Connect routine to get the transport connection object.
161 * If NULL is returned, the connection failed. The connect routine
162 * will set fullname to point to the expanded name.
163 */
164
165#if USE_XCB
166	if(!_XConnectXCB(dpy, display, &fullname, &iscreen)) {
167		/* Try falling back on other transports if no transport specified */
168		const char *slash = strrchr(display_name, '/');
169		if(slash == NULL) {
170			const char *protocols[] = {"local", "unix", "tcp", "inet6", "inet", NULL};
171			const char **s;
172			size_t buf_size = strlen(display_name) + 7; // max strlen + 2 (null + /)
173			char *buf = Xmalloc(buf_size * sizeof(char));
174
175			if(buf) {
176				for(s = protocols; buf && *s; s++) {
177					snprintf(buf, buf_size, "%s/%s", *s, display_name);
178					if(_XConnectXCB(dpy, buf, &fullname, &iscreen))
179						goto fallback_success;
180				}
181				Xfree(buf);
182			}
183		}
184
185		dpy->display_name = fullname;
186		OutOfMemory(dpy, NULL);
187		return NULL;
188	}
189fallback_success:
190#else /* !USE_XCB */
191	if ((dpy->trans_conn = _X11TransConnectDisplay (
192					 display_name, &fullname, &idisplay,
193					 &iscreen, &conn_auth_name,
194					 &conn_auth_namelen, &conn_auth_data,
195					 &conn_auth_datalen)) == NULL) {
196		Xfree ((char *) dpy);
197		return(NULL);
198	}
199
200	dpy->fd = _X11TransGetConnectionNumber (dpy->trans_conn);
201#endif /* USE_XCB */
202
203	/* Initialize as much of the display structure as we can.
204	 * Initialize pointers to NULL so that XFreeDisplayStructure will
205	 * work if we run out of memory before we finish initializing.
206	 */
207	dpy->display_name	= fullname;
208	dpy->keysyms		= (KeySym *) NULL;
209	dpy->modifiermap	= NULL;
210	dpy->lock_meaning	= NoSymbol;
211	dpy->keysyms_per_keycode = 0;
212	dpy->xdefaults		= (char *)NULL;
213	dpy->scratch_length	= 0L;
214	dpy->scratch_buffer	= NULL;
215	dpy->key_bindings	= NULL;
216	dpy->ext_procs		= (_XExtension *)NULL;
217	dpy->ext_data		= (XExtData *)NULL;
218	dpy->ext_number 	= 0;
219	dpy->event_vec[X_Error] = _XUnknownWireEvent;
220	dpy->event_vec[X_Reply] = _XUnknownWireEvent;
221	dpy->wire_vec[X_Error]  = _XUnknownNativeEvent;
222	dpy->wire_vec[X_Reply]  = _XUnknownNativeEvent;
223	for (i = KeyPress; i < LASTEvent; i++) {
224	    dpy->event_vec[i] 	= _XWireToEvent;
225	    dpy->wire_vec[i] 	= NULL;
226	}
227	for (i = LASTEvent; i < 128; i++) {
228	    dpy->event_vec[i] 	= _XUnknownWireEvent;
229	    dpy->wire_vec[i] 	= _XUnknownNativeEvent;
230	}
231	dpy->resource_id	= 0;
232	dpy->db 		= (struct _XrmHashBucketRec *)NULL;
233	dpy->cursor_font	= None;
234	dpy->flags		= 0;
235	dpy->async_handlers	= NULL;
236	dpy->screens		= NULL;
237	dpy->vendor		= NULL;
238	dpy->buffer		= NULL;
239	dpy->atoms		= NULL;
240	dpy->error_vec		= NULL;
241	dpy->context_db		= NULL;
242	dpy->free_funcs		= NULL;
243	dpy->pixmap_format	= NULL;
244	dpy->cms.clientCmaps	= NULL;
245	dpy->cms.defaultCCCs	= NULL;
246	dpy->cms.perVisualIntensityMaps = NULL;
247	dpy->im_filters		= NULL;
248 	dpy->bigreq_size	= 0;
249	dpy->lock		= NULL;
250	dpy->lock_fns		= NULL;
251	dpy->qfree		= NULL;
252	dpy->next_event_serial_num = 1;
253	dpy->im_fd_info		= NULL;
254	dpy->im_fd_length	= 0;
255	dpy->conn_watchers	= NULL;
256	dpy->watcher_count	= 0;
257	dpy->filedes		= NULL;
258	dpy->flushes		= NULL;
259	dpy->xcmisc_opcode	= 0;
260	dpy->xkb_info		= NULL;
261
262/*
263 * Setup other information in this display structure.
264 */
265	dpy->vnumber = X_PROTOCOL;
266	dpy->resource_alloc = _XAllocID;
267	dpy->idlist_alloc = _XAllocIDs;
268	dpy->synchandler = NULL;
269	dpy->savedsynchandler = NULL;
270	dpy->request = 0;
271	dpy->last_request_read = 0;
272	dpy->default_screen = iscreen;  /* Value returned by ConnectDisplay */
273	dpy->last_req = (char *)&_dummy_request;
274
275	/* Initialize the display lock */
276	if (InitDisplayLock(dpy) != 0) {
277	        OutOfMemory (dpy, setup);
278		return(NULL);
279	}
280
281	if (!_XPollfdCacheInit(dpy)) {
282	        OutOfMemory (dpy, setup);
283		return(NULL);
284	}
285
286	/* Set up the output buffers. */
287#ifndef XLIBDEFAULTBUFSIZE
288#define XLIBDEFAULTBUFSIZE 16384 /* 16k */
289#endif
290#ifndef XLIBMINBUFSIZE
291#define XLIBMINBUFSIZE BUFSIZE /* old default buffer size */
292#endif
293	xlib_buffer_size = getenv("XLIBBUFFERSIZE");
294
295#ifdef __sun /* Backwards compatibility for old Solaris libX11 name */
296	if (xlib_buffer_size == NULL)
297	    xlib_buffer_size = getenv("XSUNBUFFERSIZE");
298#endif
299
300	if (xlib_buffer_size == NULL)
301	    conn_buf_size = XLIBDEFAULTBUFSIZE;
302	else
303	    conn_buf_size = 1024 * strtol(xlib_buffer_size, NULL, 10);
304	if (conn_buf_size < XLIBMINBUFSIZE)
305	    conn_buf_size = XLIBMINBUFSIZE;
306
307	if ((dpy->bufptr = dpy->buffer = Xcalloc(1, conn_buf_size)) == NULL) {
308	    OutOfMemory (dpy, setup);
309	    return(NULL);
310	}
311	dpy->bufmax = dpy->buffer + conn_buf_size;
312#if USE_XCB
313	dpy->xcb->real_bufmax = dpy->bufmax;
314	dpy->bufmax = dpy->buffer;
315#endif
316
317	/* Set up the input event queue and input event queue parameters. */
318	dpy->head = dpy->tail = NULL;
319	dpy->qlen = 0;
320
321	/* Set up free-function record */
322	if ((dpy->free_funcs = (_XFreeFuncRec *)Xcalloc(1,
323							sizeof(_XFreeFuncRec)))
324	    == NULL) {
325	    OutOfMemory (dpy, setup);
326	    return(NULL);
327	}
328
329#if !USE_XCB
330/*
331 * The xConnClientPrefix describes the initial connection setup information
332 * and is followed by the authorization information.  Sites that are interested
333 * in security are strongly encouraged to use an authentication and
334 * authorization system such as Kerberos.
335 */
336	endian = 1;
337	if (*(char *) &endian)
338	    client.byteOrder = '\154'; /* 'l' */
339	else
340	    client.byteOrder = '\102'; /* 'B' */
341	client.majorVersion = X_PROTOCOL;
342	client.minorVersion = X_PROTOCOL_REVISION;
343	client.nbytesAuthProto = conn_auth_namelen;
344	client.nbytesAuthString = conn_auth_datalen;
345	prefixread = _XSendClientPrefix(dpy, &client,
346					conn_auth_name, conn_auth_data,
347					&prefix);
348	if (prefixread < 0)
349	{
350	    _XDisconnectDisplay (dpy->trans_conn);
351	    Xfree ((char *)dpy);
352	    return(NULL);
353	}
354	if (conn_auth_name) Xfree(conn_auth_name);
355	if (conn_auth_data) Xfree(conn_auth_data);
356/*
357 * Now see if connection was accepted...
358 */
359	/* these internal functions expect the display to be locked */
360	LockDisplay(dpy);
361
362	if (prefixread == 0)
363	    _XRead (dpy, (char *)&prefix,(long)SIZEOF(xConnSetupPrefix));
364
365	/* an Authenticate reply we weren't expecting? */
366	if (prefix.success != xTrue && prefix.success != xFalse) {
367	    fprintf (stderr,
368      "Xlib: unexpected connection setup reply from server, type %d.\r\n",
369		     prefix.success);
370	    _XDisconnectDisplay (dpy->trans_conn);
371	    Xfree ((char *)dpy);
372	    return(NULL);
373	}
374
375	if (prefix.majorVersion != X_PROTOCOL) {
376	    /* XXX - printing messages marks a bad programming interface */
377	    fprintf (stderr,
378     "Xlib: client uses different protocol version (%d) than server (%d)!\r\n",
379		     X_PROTOCOL, prefix.majorVersion);
380	    _XDisconnectDisplay (dpy->trans_conn);
381	    Xfree ((char *)dpy);
382	    return(NULL);
383	}
384#endif /* !USE_XCB */
385
386#if USE_XCB
387	{
388		const struct xcb_setup_t *xcbsetup = xcb_get_setup(dpy->xcb->connection);
389		memcpy(&prefix, xcbsetup, sizeof(prefix));
390		setuplength = prefix.length << 2;
391		setup = (char *) xcbsetup;
392		setup += SIZEOF(xConnSetupPrefix);
393		u.setup = (xConnSetup *) setup;
394	}
395#else /* !USE_XCB */
396	setuplength = prefix.length << 2;
397	if ( (u.setup = (xConnSetup *)
398	      (setup =  Xmalloc ((unsigned) setuplength))) == NULL) {
399		_XDisconnectDisplay (dpy->trans_conn);
400		Xfree ((char *)dpy);
401		return(NULL);
402	}
403	_XRead (dpy, (char *)u.setup, setuplength);
404
405/*
406 * If the connection was not accepted by the server due to problems,
407 * give error message to the user....
408 */
409	if (prefix.success != xTrue) {
410		/* XXX - printing messages marks a bad programming interface */
411		fprintf (stderr,
412		      "Xlib: connection to \"%s\" refused by server\r\nXlib: ",
413			 fullname);
414
415		if (prefix.lengthReason > setuplength) {
416		    fprintf (stderr, "Xlib: Broken initial reply: length of reason > length of packet\r\n");
417		}else{
418		    (void) fwrite (u.failure, (Size_t)sizeof(char),
419			       (Size_t)prefix.lengthReason, stderr);
420		    (void) fwrite ("\r\n", sizeof(char), 2, stderr);
421		}
422
423		OutOfMemory(dpy, setup);
424		return (NULL);
425	}
426#endif /* USE_XCB */
427
428/*
429 * Check if the reply was long enough to get any information out of it.
430 */
431	usedbytes = sz_xConnSetup;
432	if (setuplength < usedbytes ) {
433	    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
434	    OutOfMemory(dpy, setup);
435	    return (NULL);
436	}
437
438/*
439 * We succeeded at authorization, so let us move the data into
440 * the display structure.
441 */
442	dpy->proto_major_version= prefix.majorVersion;
443	dpy->proto_minor_version= prefix.minorVersion;
444	dpy->release 		= u.setup->release;
445	dpy->resource_base	= u.setup->ridBase;
446	dpy->resource_mask	= u.setup->ridMask;
447	dpy->min_keycode	= u.setup->minKeyCode;
448	dpy->max_keycode	= u.setup->maxKeyCode;
449	dpy->motion_buffer	= u.setup->motionBufferSize;
450	dpy->nformats		= u.setup->numFormats;
451	dpy->nscreens		= u.setup->numRoots;
452	dpy->byte_order		= u.setup->imageByteOrder;
453	dpy->bitmap_unit	= u.setup->bitmapScanlineUnit;
454	dpy->bitmap_pad		= u.setup->bitmapScanlinePad;
455	dpy->bitmap_bit_order   = u.setup->bitmapBitOrder;
456	dpy->max_request_size	= u.setup->maxRequestSize;
457	mask = dpy->resource_mask;
458	dpy->resource_shift	= 0;
459	if (!mask)
460	{
461	    fprintf (stderr, "Xlib: connection to \"%s\" invalid setup\n",
462		     fullname);
463	    OutOfMemory(dpy, setup);
464	    return (NULL);
465	}
466
467	while (!(mask & 1)) {
468	    dpy->resource_shift++;
469	    mask = mask >> 1;
470	}
471	dpy->resource_max = (dpy->resource_mask >> dpy->resource_shift) - 5;
472/*
473 * now extract the vendor string...  String must be null terminated,
474 * padded to multiple of 4 bytes.
475 */
476	/* Check for a sane vendor string length */
477	if (u.setup->nbytesVendor > 256) {
478	    OutOfMemory(dpy, setup);
479	    return (NULL);
480	}
481
482	dpy->vendor = (char *) Xmalloc((unsigned) (u.setup->nbytesVendor + 1));
483	if (dpy->vendor == NULL) {
484	    OutOfMemory(dpy, setup);
485	    return (NULL);
486	}
487	vendorlen = u.setup->nbytesVendor;
488
489/*
490 * validate setup length
491 */
492	usedbytes += (vendorlen + 3) & ~3;
493	if (setuplength < usedbytes) {
494	    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
495	    OutOfMemory(dpy, setup);
496	    return (NULL);
497	}
498
499 	u.setup = (xConnSetup *) (((char *) u.setup) + sz_xConnSetup);
500  	(void) strncpy(dpy->vendor, u.vendor, vendorlen);
501	dpy->vendor[vendorlen] = '\0';
502 	vendorlen = (vendorlen + 3) & ~3;	/* round up */
503	u.vendor += vendorlen;
504
505/*
506 * Now iterate down setup information.....
507 */
508	dpy->pixmap_format =
509	    (ScreenFormat *)Xmalloc(
510		(unsigned) (dpy->nformats *sizeof(ScreenFormat)));
511	if (dpy->pixmap_format == NULL) {
512	        OutOfMemory (dpy, setup);
513		return(NULL);
514	}
515/*
516 * First decode the Z axis Screen format information.
517 */
518	usedbytes += dpy->nformats * sz_xPixmapFormat;
519
520	if (setuplength < usedbytes) {
521	    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
522	    OutOfMemory (dpy, setup);
523	    return(NULL);
524	}
525
526	for (i = 0; i < dpy->nformats; i++) {
527	    register ScreenFormat *fmt = &dpy->pixmap_format[i];
528	    fmt->depth = u.sf->depth;
529	    fmt->bits_per_pixel = u.sf->bitsPerPixel;
530	    fmt->scanline_pad = u.sf->scanLinePad;
531	    fmt->ext_data = NULL;
532	    u.sf = (xPixmapFormat *) (((char *) u.sf) + sz_xPixmapFormat);
533	}
534
535/*
536 * next the Screen structures.
537 */
538	dpy->screens =
539	    (Screen *)Xmalloc((unsigned) dpy->nscreens*sizeof(Screen));
540	if (dpy->screens == NULL) {
541	        OutOfMemory (dpy, setup);
542		return(NULL);
543	}
544
545/*
546 * Now go deal with each screen structure.
547 */
548	for (i = 0; i < dpy->nscreens; i++) {
549	    register Screen *sp = &dpy->screens[i];
550	    VisualID root_visualID;
551
552	    usedbytes += sz_xWindowRoot;
553	    if (setuplength < usedbytes) {
554		fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
555		OutOfMemory (dpy, setup);
556		return(NULL);
557	    }
558
559	    root_visualID = u.rp->rootVisualID;
560	    sp->display	    = dpy;
561	    sp->root 	    = u.rp->windowId;
562	    sp->cmap 	    = u.rp->defaultColormap;
563	    sp->white_pixel = u.rp->whitePixel;
564	    sp->black_pixel = u.rp->blackPixel;
565	    sp->root_input_mask = u.rp->currentInputMask;
566	    sp->width	    = u.rp->pixWidth;
567	    sp->height	    = u.rp->pixHeight;
568	    sp->mwidth	    = u.rp->mmWidth;
569	    sp->mheight	    = u.rp->mmHeight;
570	    sp->min_maps    = u.rp->minInstalledMaps;
571	    sp->max_maps    = u.rp->maxInstalledMaps;
572	    sp->backing_store= u.rp->backingStore;
573	    sp->save_unders = u.rp->saveUnders;
574	    sp->root_depth  = u.rp->rootDepth;
575	    sp->ndepths	    = u.rp->nDepths;
576	    sp->ext_data   = NULL;
577	    u.rp = (xWindowRoot *) (((char *) u.rp) + sz_xWindowRoot);
578/*
579 * lets set up the depth structures.
580 */
581	    sp->depths = (Depth *)Xmalloc(
582			(unsigned)sp->ndepths*sizeof(Depth));
583	    if (sp->depths == NULL) {
584		OutOfMemory (dpy, setup);
585		return(NULL);
586	    }
587	    /*
588	     * for all depths on this screen.
589	     */
590	    for (j = 0; j < sp->ndepths; j++) {
591		Depth *dp = &sp->depths[j];
592
593		usedbytes += sz_xDepth;
594		if (setuplength < usedbytes) {
595		    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
596		    OutOfMemory (dpy, setup);
597		    return(NULL);
598		}
599
600		dp->depth = u.dp->depth;
601		dp->nvisuals = u.dp->nVisuals;
602		u.dp = (xDepth *) (((char *) u.dp) + sz_xDepth);
603		if (dp->nvisuals > 0) {
604		    dp->visuals =
605		      (Visual *)Xmalloc((unsigned)dp->nvisuals*sizeof(Visual));
606		    if (dp->visuals == NULL) {
607			OutOfMemory (dpy, setup);
608			return(NULL);
609		    }
610		    for (k = 0; k < dp->nvisuals; k++) {
611			register Visual *vp = &dp->visuals[k];
612
613			usedbytes += sz_xVisualType;
614			if (setuplength < usedbytes) {
615			    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
616			    OutOfMemory (dpy, setup);
617			    return(NULL);
618			}
619
620			vp->visualid	= u.vp->visualID;
621			vp->class	= u.vp->class;
622			vp->bits_per_rgb= u.vp->bitsPerRGB;
623			vp->map_entries	= u.vp->colormapEntries;
624			vp->red_mask	= u.vp->redMask;
625			vp->green_mask	= u.vp->greenMask;
626			vp->blue_mask	= u.vp->blueMask;
627			vp->ext_data	= NULL;
628			u.vp = (xVisualType *) (((char *) u.vp) +
629						sz_xVisualType);
630		    }
631		    if (dp->depth == 32 && getenv ("XLIB_SKIP_ARGB_VISUALS"))
632		    {
633			Xfree (dp->visuals);
634			dp->visuals = NULL;
635			dp->nvisuals = 0;
636		    }
637		} else {
638		    dp->visuals = (Visual *) NULL;
639		}
640	    }
641	    sp->root_visual = _XVIDtoVisual(dpy, root_visualID);
642	}
643
644	if(usedbytes != setuplength){
645	    /* Sanity check, shouldn't happen. */
646	    fprintf(stderr, "Xlib: Did not parse entire setup message: "
647	                    "parsed: %ld, message: %ld\n",
648		    usedbytes, setuplength);
649	    OutOfMemory(dpy, setup);
650	    return(NULL);
651	}
652
653/*
654 * Now start talking to the server to setup all other information...
655 */
656
657#if !USE_XCB
658	Xfree (setup);	/* all finished with setup information */
659#endif /* !USE_XCB */
660
661/*
662 * Make sure default screen is legal.
663 */
664	if (iscreen >= dpy->nscreens) {
665	    OutOfMemory(dpy, (char *) NULL);
666	    return(NULL);
667	}
668
669#if !USE_XCB
670/*
671 * finished calling internal routines, now unlock for external routines
672 */
673	UnlockDisplay(dpy);
674#endif /* !USE_XCB */
675
676#if USE_XCB
677	dpy->bigreq_size = xcb_get_maximum_request_length(dpy->xcb->connection);
678	if(dpy->bigreq_size <= dpy->max_request_size)
679		dpy->bigreq_size = 0;
680#endif /* USE_XCB */
681
682/*
683 * Set up other stuff clients are always going to use.
684 */
685	for (i = 0; i < dpy->nscreens; i++) {
686	    register Screen *sp = &dpy->screens[i];
687	    XGCValues values;
688	    values.foreground = sp->black_pixel;
689	    values.background = sp->white_pixel;
690	    if ((sp->default_gc = XCreateGC (dpy, sp->root,
691					     GCForeground|GCBackground,
692					     &values)) == NULL) {
693		OutOfMemory(dpy, (char *) NULL);
694		return (NULL);
695	    }
696	}
697/*
698 * call into synchronization routine so that all programs can be
699 * forced synchronous
700 */
701	(void) XSynchronize(dpy, _Xdebug);
702
703/*
704 * get availability of large requests, and
705 * get the resource manager database off the root window.
706 */
707	LockDisplay(dpy);
708	{
709	    xGetPropertyReply reply;
710	    xGetPropertyReq *req;
711#if !USE_XCB
712	    _XAsyncHandler async;
713	    _XBigReqState async_state;
714	    xQueryExtensionReq *qreq;
715	    xBigReqEnableReq *breq;
716	    xBigReqEnableReply brep;
717
718	    GetReq(QueryExtension, qreq);
719	    async_state.seq = dpy->request;
720	    async_state.opcode = 0;
721	    async.next = dpy->async_handlers;
722	    async.handler = _XBigReqHandler;
723	    async.data = (XPointer)&async_state;
724	    dpy->async_handlers = &async;
725	    qreq->nbytes = bignamelen;
726	    qreq->length += (bignamelen+3)>>2;
727	    Data(dpy, XBigReqExtensionName, bignamelen);
728#endif /* !USE_XCB */
729
730	    GetReq (GetProperty, req);
731	    req->window = RootWindow(dpy, 0);
732	    req->property = XA_RESOURCE_MANAGER;
733	    req->type = XA_STRING;
734	    req->delete = False;
735	    req->longOffset = 0;
736	    req->longLength = 100000000L;
737
738	    if (_XReply (dpy, (xReply *) &reply, 0, xFalse)) {
739		if (reply.format == 8 && reply.propertyType == XA_STRING &&
740		    (reply.nItems + 1 > 0) &&
741		    (reply.nItems <= req->longLength * 4) &&
742		    (dpy->xdefaults = Xmalloc (reply.nItems + 1))) {
743		    _XReadPad (dpy, dpy->xdefaults, reply.nItems);
744		    dpy->xdefaults[reply.nItems] = '\0';
745		}
746		else if (reply.propertyType != None)
747		    _XEatData(dpy, reply.nItems * (reply.format >> 3));
748	    }
749#if !USE_XCB
750	    DeqAsyncHandler(dpy, &async);
751	    if (async_state.opcode) {
752		GetReq(BigReqEnable, breq);
753		breq->reqType = async_state.opcode;
754		breq->brReqType = X_BigReqEnable;
755		if (_XReply(dpy, (xReply *)&brep, 0, xFalse))
756		    dpy->bigreq_size = brep.max_request_size;
757	    }
758#endif /* !USE_XCB */
759	}
760	UnlockDisplay(dpy);
761
762#ifdef MOTIFBC
763	{
764	    extern Display *_XHeadOfDisplayList;
765	    _XHeadOfDisplayList = dpy;
766	}
767#endif
768#ifdef XKB
769	XkbUseExtension(dpy,NULL,NULL);
770#endif
771/*
772 * and return successfully
773 */
774 	return(dpy);
775}
776
777#if !USE_XCB
778static Bool
779_XBigReqHandler(
780    register Display *dpy,
781    register xReply *rep,
782    char *buf,
783    int len,
784    XPointer data)
785{
786    _XBigReqState *state;
787    xQueryExtensionReply replbuf;
788    xQueryExtensionReply *repl;
789
790    state = (_XBigReqState *)data;
791    if (dpy->last_request_read != state->seq)
792	return False;
793    if (rep->generic.type == X_Error)
794	return True;
795    repl = (xQueryExtensionReply *)
796	_XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
797			(SIZEOF(xQueryExtensionReply) - SIZEOF(xReply)) >> 2,
798			True);
799    if (repl->present)
800	state->opcode = repl->major_opcode;
801    return True;
802}
803#endif /* !USE_XCB */
804
805
806/* XFreeDisplayStructure frees all the storage associated with a
807 * Display.  It is used by XOpenDisplay if it runs out of memory,
808 * and also by XCloseDisplay.   It needs to check whether all pointers
809 * are non-NULL before dereferencing them, since it may be called
810 * by XOpenDisplay before the Display structure is fully formed.
811 * XOpenDisplay must be sure to initialize all the pointers to NULL
812 * before the first possible call on this.
813 */
814
815void _XFreeDisplayStructure(Display *dpy)
816{
817	/* move all cookies in the EQ to the jar, then free them. */
818	if (dpy->qfree) {
819	    _XQEvent *qelt = dpy->qfree;
820	    while (qelt) {
821		if (_XIsEventCookie(dpy, &qelt->event))
822		    _XStoreEventCookie(dpy, &qelt->event);
823		qelt = qelt->next;
824	    }
825        }
826	if (dpy->cookiejar)
827	    _XFreeEventCookies(dpy);
828	while (dpy->ext_procs) {
829	    _XExtension *ext = dpy->ext_procs;
830	    dpy->ext_procs = ext->next;
831	    if (ext->name)
832		Xfree (ext->name);
833	    Xfree ((char *)ext);
834	}
835	if (dpy->im_filters)
836	   (*dpy->free_funcs->im_filters)(dpy);
837	if (dpy->cms.clientCmaps)
838	   (*dpy->free_funcs->clientCmaps)(dpy);
839	if (dpy->cms.defaultCCCs)
840	   (*dpy->free_funcs->defaultCCCs)(dpy);
841	if (dpy->cms.perVisualIntensityMaps)
842	   (*dpy->free_funcs->intensityMaps)(dpy);
843	if (dpy->atoms)
844	    (*dpy->free_funcs->atoms)(dpy);
845	if (dpy->modifiermap)
846	   (*dpy->free_funcs->modifiermap)(dpy->modifiermap);
847	if (dpy->key_bindings)
848	   (*dpy->free_funcs->key_bindings)(dpy);
849	if (dpy->context_db)
850	   (*dpy->free_funcs->context_db)(dpy);
851	if (dpy->xkb_info)
852	   (*dpy->free_funcs->xkb)(dpy);
853
854	/* if RM database was allocated by XGetDefault() free it */
855	if (dpy->db && (dpy->flags & XlibDisplayDfltRMDB))
856	    XrmDestroyDatabase(dpy->db);
857
858	if (dpy->screens) {
859	    register int i;
860
861            for (i = 0; i < dpy->nscreens; i++) {
862		Screen *sp = &dpy->screens[i];
863
864		if (sp->depths) {
865		   register int j;
866
867		   for (j = 0; j < sp->ndepths; j++) {
868			Depth *dp = &sp->depths[j];
869
870			if (dp->visuals) {
871			   register int k;
872
873			   for (k = 0; k < dp->nvisuals; k++)
874			     _XFreeExtData (dp->visuals[k].ext_data);
875			   Xfree ((char *) dp->visuals);
876			   }
877			}
878
879		   Xfree ((char *) sp->depths);
880		   }
881
882		_XFreeExtData (sp->ext_data);
883		}
884
885	    Xfree ((char *)dpy->screens);
886	    }
887
888	if (dpy->pixmap_format) {
889	    register int i;
890
891	    for (i = 0; i < dpy->nformats; i++)
892	      _XFreeExtData (dpy->pixmap_format[i].ext_data);
893            Xfree ((char *)dpy->pixmap_format);
894	    }
895
896	if (dpy->display_name)
897	   Xfree (dpy->display_name);
898	if (dpy->vendor)
899	   Xfree (dpy->vendor);
900
901        if (dpy->buffer)
902	   Xfree (dpy->buffer);
903	if (dpy->keysyms)
904	   Xfree ((char *) dpy->keysyms);
905	if (dpy->xdefaults)
906	   Xfree (dpy->xdefaults);
907	if (dpy->error_vec)
908	    Xfree ((char *)dpy->error_vec);
909
910	_XFreeExtData (dpy->ext_data);
911	if (dpy->free_funcs)
912	    Xfree ((char *)dpy->free_funcs);
913 	if (dpy->scratch_buffer)
914 	    Xfree (dpy->scratch_buffer);
915	FreeDisplayLock(dpy);
916
917	if (dpy->qfree) {
918	    register _XQEvent *qelt = dpy->qfree;
919
920	    while (qelt) {
921		register _XQEvent *qnxt = qelt->next;
922		Xfree ((char *) qelt);
923		qelt = qnxt;
924	    }
925	}
926	while (dpy->im_fd_info) {
927	    struct _XConnectionInfo *conni = dpy->im_fd_info;
928	    dpy->im_fd_info = conni->next;
929	    if (conni->watch_data)
930		Xfree (conni->watch_data);
931	    Xfree (conni);
932	}
933	if (dpy->conn_watchers) {
934	    struct _XConnWatchInfo *watcher = dpy->conn_watchers;
935	    dpy->conn_watchers = watcher->next;
936	    Xfree (watcher);
937	}
938	if (dpy->filedes)
939	    Xfree (dpy->filedes);
940
941#if USE_XCB
942	_XFreeX11XCBStructure(dpy);
943#endif /* USE_XCB */
944
945	Xfree ((char *)dpy);
946}
947
948/* OutOfMemory is called if malloc fails.  XOpenDisplay returns NULL
949   after this returns. */
950
951static void OutOfMemory(Display *dpy, char *setup)
952{
953#if USE_XCB
954    if(dpy->xcb->connection)
955	xcb_disconnect(dpy->xcb->connection);
956#else /* !USE_XCB */
957    _XDisconnectDisplay (dpy->trans_conn);
958#endif /* USE_XCB */
959    _XFreeDisplayStructure (dpy);
960#if !USE_XCB
961    if (setup) Xfree (setup);
962#endif /* !USE_XCB */
963}
964