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