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