11ab64890Smrg/*
21ab64890Smrg
31ab64890SmrgCopyright 1985, 1986, 1998  The Open Group
41ab64890Smrg
51ab64890SmrgPermission to use, copy, modify, distribute, and sell this software and its
61ab64890Smrgdocumentation for any purpose is hereby granted without fee, provided that
71ab64890Smrgthe above copyright notice appear in all copies and that both that
81ab64890Smrgcopyright notice and this permission notice appear in supporting
91ab64890Smrgdocumentation.
101ab64890Smrg
111ab64890SmrgThe above copyright notice and this permission notice shall be included in
121ab64890Smrgall copies or substantial portions of the Software.
131ab64890Smrg
141ab64890SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
151ab64890SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
161ab64890SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
171ab64890SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
181ab64890SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
191ab64890SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
201ab64890Smrg
211ab64890SmrgExcept as contained in this notice, the name of The Open Group shall not be
221ab64890Smrgused in advertising or otherwise to promote the sale, use or other dealings
231ab64890Smrgin this Software without prior written authorization from The Open Group.
241ab64890Smrg
251ab64890Smrg*/
261ab64890Smrg
271ab64890Smrg#ifdef HAVE_CONFIG_H
281ab64890Smrg#include <config.h>
291ab64890Smrg#endif
301ab64890Smrg#include "Xlibint.h"
311ab64890Smrg#include "Xxcbint.h"
321ab64890Smrg#include <X11/Xatom.h>
331ab64890Smrg#include <X11/Xresource.h>
341ab64890Smrg#include <stdio.h>
351ab64890Smrg#include "Xintconn.h"
361ab64890Smrg
371ab64890Smrg#ifdef XKB
381ab64890Smrg#include "XKBlib.h"
391ab64890Smrg#endif /* XKB */
401ab64890Smrg
411ab64890Smrg#ifdef XTHREADS
421ab64890Smrg#include "locking.h"
431ab64890Smrgint  (*_XInitDisplayLock_fn)(Display *dpy) = NULL;
441ab64890Smrgvoid (*_XFreeDisplayLock_fn)(Display *dpy) = NULL;
451ab64890Smrg
461ab64890Smrg#define InitDisplayLock(d)	(_XInitDisplayLock_fn ? (*_XInitDisplayLock_fn)(d) : Success)
471ab64890Smrg#define FreeDisplayLock(d)	if (_XFreeDisplayLock_fn) (*_XFreeDisplayLock_fn)(d)
481ab64890Smrg#else
491ab64890Smrg#define InitDisplayLock(dis) Success
501ab64890Smrg#define FreeDisplayLock(dis)
511ab64890Smrg#endif /* XTHREADS */
521ab64890Smrg
531ab64890Smrgstatic xReq _dummy_request = {
541ab64890Smrg	0, 0, 0
551ab64890Smrg};
561ab64890Smrg
57e9fcaa8aSmrgstatic void OutOfMemory(Display *dpy);
581ab64890Smrg
5961b2299dSmrg/*
601ab64890Smrg * Connects to a server, creates a Display object and returns a pointer to
611ab64890Smrg * the newly created Display back to the caller.
621ab64890Smrg */
631ab64890SmrgDisplay *
641ab64890SmrgXOpenDisplay (
651ab64890Smrg	register _Xconst char *display)
661ab64890Smrg{
671ab64890Smrg	register Display *dpy;		/* New Display object being created. */
681ab64890Smrg	register int i;
691ab64890Smrg	int j, k;			/* random iterator indexes */
701ab64890Smrg	char *display_name;		/* pointer to display name */
711ab64890Smrg	char *setup = NULL;		/* memory allocated at startup */
721ab64890Smrg	int iscreen;			/* screen number */
731ab64890Smrg	xConnSetupPrefix prefix;	/* prefix information */
741ab64890Smrg	int vendorlen;			/* length of vendor string */
751ab64890Smrg	union {
761ab64890Smrg		xConnSetup *setup;
771ab64890Smrg		char *failure;
781ab64890Smrg		char *vendor;
791ab64890Smrg		xPixmapFormat *sf;
801ab64890Smrg		xWindowRoot *rp;
811ab64890Smrg		xDepth *dp;
821ab64890Smrg		xVisualType *vp;
831ab64890Smrg	} u;				/* proto data returned from server */
841ab64890Smrg	long setuplength;	/* number of bytes in setup message */
851ab64890Smrg	long usedbytes = 0;     /* number of bytes we have processed */
861ab64890Smrg	unsigned long mask;
8788de56ccSmrg	long int conn_buf_size;
8888de56ccSmrg	char *xlib_buffer_size;
891ab64890Smrg
901ab64890Smrg	/*
9161b2299dSmrg	 * If the display specifier string supplied as an argument to this
921ab64890Smrg	 * routine is NULL or a pointer to NULL, read the DISPLAY variable.
931ab64890Smrg	 */
941ab64890Smrg	if (display == NULL || *display == '\0') {
951ab64890Smrg		if ((display_name = getenv("DISPLAY")) == NULL) {
961ab64890Smrg			/* Oops! No DISPLAY environment variable - error. */
971ab64890Smrg			return(NULL);
981ab64890Smrg		}
991ab64890Smrg	}
1001ab64890Smrg	else {
1011ab64890Smrg		/* Display is non-NULL, copy the pointer */
1021ab64890Smrg		display_name = (char *)display;
1031ab64890Smrg	}
1041ab64890Smrg
1051ab64890Smrg/*
1061ab64890Smrg * Set the default error handlers.  This allows the global variables to
1071ab64890Smrg * default to NULL for use with shared libraries.
1081ab64890Smrg */
1091ab64890Smrg	if (_XErrorFunction == NULL) (void) XSetErrorHandler (NULL);
1101ab64890Smrg	if (_XIOErrorFunction == NULL) (void) XSetIOErrorHandler (NULL);
1111ab64890Smrg
1121ab64890Smrg/*
1131ab64890Smrg * Attempt to allocate a display structure. Return NULL if allocation fails.
1141ab64890Smrg */
115eb411b4bSmrg	if ((dpy = Xcalloc(1, sizeof(Display))) == NULL) {
1161ab64890Smrg		return(NULL);
1171ab64890Smrg	}
1181ab64890Smrg
119e9fcaa8aSmrg	if ((dpy->display_name = strdup(display_name)) == NULL) {
120e9fcaa8aSmrg		OutOfMemory(dpy);
121e9fcaa8aSmrg		return(NULL);
122e9fcaa8aSmrg	}
123e9fcaa8aSmrg
1241ab64890Smrg/*
1251ab64890Smrg * Call the Connect routine to get the transport connection object.
126e9fcaa8aSmrg * If NULL is returned, the connection failed.
1271ab64890Smrg */
1281ab64890Smrg
129e9fcaa8aSmrg	if(!_XConnectXCB(dpy, display, &iscreen)) {
130e9fcaa8aSmrg		OutOfMemory(dpy);
1312e9c7c8cSmrg		return NULL;
1321ab64890Smrg	}
1331ab64890Smrg
1341ab64890Smrg	/* Initialize as much of the display structure as we can.
1351ab64890Smrg	 * Initialize pointers to NULL so that XFreeDisplayStructure will
1361ab64890Smrg	 * work if we run out of memory before we finish initializing.
1371ab64890Smrg	 */
1381ab64890Smrg	dpy->keysyms		= (KeySym *) NULL;
1391ab64890Smrg	dpy->modifiermap	= NULL;
1401ab64890Smrg	dpy->lock_meaning	= NoSymbol;
1411ab64890Smrg	dpy->keysyms_per_keycode = 0;
1421ab64890Smrg	dpy->xdefaults		= (char *)NULL;
1431ab64890Smrg	dpy->scratch_length	= 0L;
1441ab64890Smrg	dpy->scratch_buffer	= NULL;
1451ab64890Smrg	dpy->key_bindings	= NULL;
1461ab64890Smrg	dpy->ext_procs		= (_XExtension *)NULL;
1471ab64890Smrg	dpy->ext_data		= (XExtData *)NULL;
1481ab64890Smrg	dpy->ext_number 	= 0;
1491ab64890Smrg	dpy->event_vec[X_Error] = _XUnknownWireEvent;
1501ab64890Smrg	dpy->event_vec[X_Reply] = _XUnknownWireEvent;
1511ab64890Smrg	dpy->wire_vec[X_Error]  = _XUnknownNativeEvent;
1521ab64890Smrg	dpy->wire_vec[X_Reply]  = _XUnknownNativeEvent;
1531ab64890Smrg	for (i = KeyPress; i < LASTEvent; i++) {
1541ab64890Smrg	    dpy->event_vec[i] 	= _XWireToEvent;
1551ab64890Smrg	    dpy->wire_vec[i] 	= NULL;
1561ab64890Smrg	}
1571ab64890Smrg	for (i = LASTEvent; i < 128; i++) {
1581ab64890Smrg	    dpy->event_vec[i] 	= _XUnknownWireEvent;
1591ab64890Smrg	    dpy->wire_vec[i] 	= _XUnknownNativeEvent;
1601ab64890Smrg	}
1611ab64890Smrg	dpy->resource_id	= 0;
1621ab64890Smrg	dpy->db 		= (struct _XrmHashBucketRec *)NULL;
1631ab64890Smrg	dpy->cursor_font	= None;
1641ab64890Smrg	dpy->flags		= 0;
1651ab64890Smrg	dpy->async_handlers	= NULL;
1661ab64890Smrg	dpy->screens		= NULL;
1671ab64890Smrg	dpy->vendor		= NULL;
1681ab64890Smrg	dpy->buffer		= NULL;
1691ab64890Smrg	dpy->atoms		= NULL;
1701ab64890Smrg	dpy->error_vec		= NULL;
1711ab64890Smrg	dpy->context_db		= NULL;
1721ab64890Smrg	dpy->free_funcs		= NULL;
1731ab64890Smrg	dpy->pixmap_format	= NULL;
1741ab64890Smrg	dpy->cms.clientCmaps	= NULL;
1751ab64890Smrg	dpy->cms.defaultCCCs	= NULL;
1761ab64890Smrg	dpy->cms.perVisualIntensityMaps = NULL;
1771ab64890Smrg	dpy->im_filters		= NULL;
1781ab64890Smrg 	dpy->bigreq_size	= 0;
1791ab64890Smrg	dpy->lock		= NULL;
1801ab64890Smrg	dpy->lock_fns		= NULL;
1811ab64890Smrg	dpy->qfree		= NULL;
1821ab64890Smrg	dpy->next_event_serial_num = 1;
1831ab64890Smrg	dpy->im_fd_info		= NULL;
1841ab64890Smrg	dpy->im_fd_length	= 0;
1851ab64890Smrg	dpy->conn_watchers	= NULL;
1861ab64890Smrg	dpy->watcher_count	= 0;
1871ab64890Smrg	dpy->filedes		= NULL;
1881ab64890Smrg	dpy->flushes		= NULL;
1891ab64890Smrg	dpy->xcmisc_opcode	= 0;
1901ab64890Smrg	dpy->xkb_info		= NULL;
191d4a3aaf4Smrg	dpy->exit_handler_data	= NULL;
1920efe039aSmartin	dpy->in_ifevent         = 0;
1931ab64890Smrg
1941ab64890Smrg/*
1951ab64890Smrg * Setup other information in this display structure.
1961ab64890Smrg */
1971ab64890Smrg	dpy->vnumber = X_PROTOCOL;
1981ab64890Smrg	dpy->resource_alloc = _XAllocID;
1991ab64890Smrg	dpy->idlist_alloc = _XAllocIDs;
2001ab64890Smrg	dpy->synchandler = NULL;
2011ab64890Smrg	dpy->savedsynchandler = NULL;
2022d67cb4fSmrg	X_DPY_SET_REQUEST(dpy, 0);
2032d67cb4fSmrg	X_DPY_SET_LAST_REQUEST_READ(dpy, 0);
2041ab64890Smrg	dpy->default_screen = iscreen;  /* Value returned by ConnectDisplay */
2051ab64890Smrg	dpy->last_req = (char *)&_dummy_request;
206d4a3aaf4Smrg	dpy->error_threads = NULL;
207d4a3aaf4Smrg	dpy->exit_handler = _XDefaultIOErrorExit;
2081ab64890Smrg
2091ab64890Smrg	/* Initialize the display lock */
2101ab64890Smrg	if (InitDisplayLock(dpy) != 0) {
211e9fcaa8aSmrg	        OutOfMemory (dpy);
2121ab64890Smrg		return(NULL);
2131ab64890Smrg	}
2141ab64890Smrg
2151ab64890Smrg	if (!_XPollfdCacheInit(dpy)) {
216e9fcaa8aSmrg	        OutOfMemory (dpy);
2171ab64890Smrg		return(NULL);
21861b2299dSmrg	}
2191ab64890Smrg
2201ab64890Smrg	/* Set up the output buffers. */
2211ab64890Smrg#ifndef XLIBDEFAULTBUFSIZE
2221ab64890Smrg#define XLIBDEFAULTBUFSIZE 16384 /* 16k */
2231ab64890Smrg#endif
2241ab64890Smrg#ifndef XLIBMINBUFSIZE
2251ab64890Smrg#define XLIBMINBUFSIZE BUFSIZE /* old default buffer size */
2261ab64890Smrg#endif
227b4ee4795Smrg	xlib_buffer_size = getenv("XLIBBUFFERSIZE");
228b4ee4795Smrg
229b4ee4795Smrg#ifdef __sun /* Backwards compatibility for old Solaris libX11 name */
230b4ee4795Smrg	if (xlib_buffer_size == NULL)
231b4ee4795Smrg	    xlib_buffer_size = getenv("XSUNBUFFERSIZE");
232b4ee4795Smrg#endif
233b4ee4795Smrg
234b4ee4795Smrg	if (xlib_buffer_size == NULL)
235b4ee4795Smrg	    conn_buf_size = XLIBDEFAULTBUFSIZE;
236b4ee4795Smrg	else
237b4ee4795Smrg	    conn_buf_size = 1024 * strtol(xlib_buffer_size, NULL, 10);
238b4ee4795Smrg	if (conn_buf_size < XLIBMINBUFSIZE)
239b4ee4795Smrg	    conn_buf_size = XLIBMINBUFSIZE;
240b4ee4795Smrg
241b4ee4795Smrg	if ((dpy->bufptr = dpy->buffer = Xcalloc(1, conn_buf_size)) == NULL) {
242e9fcaa8aSmrg	    OutOfMemory (dpy);
243b4ee4795Smrg	    return(NULL);
244b4ee4795Smrg	}
245e9fcaa8aSmrg	dpy->xcb->real_bufmax = dpy->buffer + conn_buf_size;
246b4ee4795Smrg	dpy->bufmax = dpy->buffer;
24761b2299dSmrg
2481ab64890Smrg	/* Set up the input event queue and input event queue parameters. */
2491ab64890Smrg	dpy->head = dpy->tail = NULL;
2501ab64890Smrg	dpy->qlen = 0;
2511ab64890Smrg
2521ab64890Smrg	/* Set up free-function record */
253eb411b4bSmrg	if ((dpy->free_funcs = Xcalloc(1, sizeof(_XFreeFuncRec))) == NULL) {
254e9fcaa8aSmrg	    OutOfMemory (dpy);
2551ab64890Smrg	    return(NULL);
2561ab64890Smrg	}
2571ab64890Smrg
2581ab64890Smrg	{
2591ab64890Smrg		const struct xcb_setup_t *xcbsetup = xcb_get_setup(dpy->xcb->connection);
2601ab64890Smrg		memcpy(&prefix, xcbsetup, sizeof(prefix));
2611ab64890Smrg		setuplength = prefix.length << 2;
2621ab64890Smrg		setup = (char *) xcbsetup;
2631ab64890Smrg		setup += SIZEOF(xConnSetupPrefix);
2641ab64890Smrg		u.setup = (xConnSetup *) setup;
2651ab64890Smrg	}
2661ab64890Smrg
2671ab64890Smrg/*
2681ab64890Smrg * Check if the reply was long enough to get any information out of it.
2691ab64890Smrg */
2701ab64890Smrg	usedbytes = sz_xConnSetup;
2711ab64890Smrg	if (setuplength < usedbytes ) {
2721ab64890Smrg	    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
273e9fcaa8aSmrg	    OutOfMemory(dpy);
2741ab64890Smrg	    return (NULL);
2751ab64890Smrg	}
2761ab64890Smrg
2771ab64890Smrg/*
2781ab64890Smrg * We succeeded at authorization, so let us move the data into
2791ab64890Smrg * the display structure.
2801ab64890Smrg */
2811ab64890Smrg	dpy->proto_major_version= prefix.majorVersion;
2821ab64890Smrg	dpy->proto_minor_version= prefix.minorVersion;
2831ab64890Smrg	dpy->release 		= u.setup->release;
2841ab64890Smrg	dpy->resource_base	= u.setup->ridBase;
2851ab64890Smrg	dpy->resource_mask	= u.setup->ridMask;
2861ab64890Smrg	dpy->min_keycode	= u.setup->minKeyCode;
2871ab64890Smrg	dpy->max_keycode	= u.setup->maxKeyCode;
2881ab64890Smrg	dpy->motion_buffer	= u.setup->motionBufferSize;
2891ab64890Smrg	dpy->nformats		= u.setup->numFormats;
2901ab64890Smrg	dpy->nscreens		= u.setup->numRoots;
2911ab64890Smrg	dpy->byte_order		= u.setup->imageByteOrder;
2921ab64890Smrg	dpy->bitmap_unit	= u.setup->bitmapScanlineUnit;
2931ab64890Smrg	dpy->bitmap_pad		= u.setup->bitmapScanlinePad;
2941ab64890Smrg	dpy->bitmap_bit_order   = u.setup->bitmapBitOrder;
2951ab64890Smrg	dpy->max_request_size	= u.setup->maxRequestSize;
2961ab64890Smrg	mask = dpy->resource_mask;
2971ab64890Smrg	dpy->resource_shift	= 0;
2981ab64890Smrg	if (!mask)
2991ab64890Smrg	{
3001ab64890Smrg	    fprintf (stderr, "Xlib: connection to \"%s\" invalid setup\n",
301e9fcaa8aSmrg		     dpy->display_name);
302e9fcaa8aSmrg	    OutOfMemory(dpy);
3031ab64890Smrg	    return (NULL);
3041ab64890Smrg	}
30561b2299dSmrg
3061ab64890Smrg	while (!(mask & 1)) {
3071ab64890Smrg	    dpy->resource_shift++;
3081ab64890Smrg	    mask = mask >> 1;
3091ab64890Smrg	}
3101ab64890Smrg	dpy->resource_max = (dpy->resource_mask >> dpy->resource_shift) - 5;
3111ab64890Smrg/*
3121ab64890Smrg * now extract the vendor string...  String must be null terminated,
3131ab64890Smrg * padded to multiple of 4 bytes.
3141ab64890Smrg */
3151ab64890Smrg	/* Check for a sane vendor string length */
3161ab64890Smrg	if (u.setup->nbytesVendor > 256) {
317e9fcaa8aSmrg	    OutOfMemory(dpy);
3181ab64890Smrg	    return (NULL);
3191ab64890Smrg	}
3201ab64890Smrg
321eb411b4bSmrg	dpy->vendor = Xmalloc(u.setup->nbytesVendor + 1);
3221ab64890Smrg	if (dpy->vendor == NULL) {
323e9fcaa8aSmrg	    OutOfMemory(dpy);
3241ab64890Smrg	    return (NULL);
3251ab64890Smrg	}
3261ab64890Smrg	vendorlen = u.setup->nbytesVendor;
3271ab64890Smrg
3281ab64890Smrg/*
3291ab64890Smrg * validate setup length
3301ab64890Smrg */
3311ab64890Smrg	usedbytes += (vendorlen + 3) & ~3;
3321ab64890Smrg	if (setuplength < usedbytes) {
3331ab64890Smrg	    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
334e9fcaa8aSmrg	    OutOfMemory(dpy);
3351ab64890Smrg	    return (NULL);
3361ab64890Smrg	}
3371ab64890Smrg
3381ab64890Smrg 	u.setup = (xConnSetup *) (((char *) u.setup) + sz_xConnSetup);
3399c019ec5Smaya  	(void) strncpy(dpy->vendor, u.vendor, (size_t) vendorlen);
3401ab64890Smrg	dpy->vendor[vendorlen] = '\0';
3411ab64890Smrg 	vendorlen = (vendorlen + 3) & ~3;	/* round up */
3421ab64890Smrg	u.vendor += vendorlen;
3431ab64890Smrg
3441ab64890Smrg/*
3451ab64890Smrg * Now iterate down setup information.....
3461ab64890Smrg */
347eb411b4bSmrg	dpy->pixmap_format = Xcalloc(dpy->nformats, sizeof(ScreenFormat));
3481ab64890Smrg	if (dpy->pixmap_format == NULL) {
349e9fcaa8aSmrg	        OutOfMemory (dpy);
3501ab64890Smrg		return(NULL);
3511ab64890Smrg	}
3521ab64890Smrg/*
3531ab64890Smrg * First decode the Z axis Screen format information.
3541ab64890Smrg */
3551ab64890Smrg	usedbytes += dpy->nformats * sz_xPixmapFormat;
3561ab64890Smrg
3571ab64890Smrg	if (setuplength < usedbytes) {
3581ab64890Smrg	    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
359e9fcaa8aSmrg	    OutOfMemory (dpy);
3601ab64890Smrg	    return(NULL);
3611ab64890Smrg	}
3621ab64890Smrg
3631ab64890Smrg	for (i = 0; i < dpy->nformats; i++) {
3641ab64890Smrg	    register ScreenFormat *fmt = &dpy->pixmap_format[i];
3651ab64890Smrg	    fmt->depth = u.sf->depth;
3661ab64890Smrg	    fmt->bits_per_pixel = u.sf->bitsPerPixel;
3671ab64890Smrg	    fmt->scanline_pad = u.sf->scanLinePad;
3681ab64890Smrg	    fmt->ext_data = NULL;
3691ab64890Smrg	    u.sf = (xPixmapFormat *) (((char *) u.sf) + sz_xPixmapFormat);
3701ab64890Smrg	}
3711ab64890Smrg
3721ab64890Smrg/*
3731ab64890Smrg * next the Screen structures.
3741ab64890Smrg */
375eb411b4bSmrg	dpy->screens = Xcalloc(dpy->nscreens, sizeof(Screen));
3761ab64890Smrg	if (dpy->screens == NULL) {
377e9fcaa8aSmrg	        OutOfMemory (dpy);
3781ab64890Smrg		return(NULL);
3791ab64890Smrg	}
3801ab64890Smrg
3811ab64890Smrg/*
3821ab64890Smrg * Now go deal with each screen structure.
3831ab64890Smrg */
3841ab64890Smrg	for (i = 0; i < dpy->nscreens; i++) {
3851ab64890Smrg	    register Screen *sp = &dpy->screens[i];
3861ab64890Smrg	    VisualID root_visualID;
3871ab64890Smrg
3881ab64890Smrg	    usedbytes += sz_xWindowRoot;
3891ab64890Smrg	    if (setuplength < usedbytes) {
3901ab64890Smrg		fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
391e9fcaa8aSmrg		OutOfMemory (dpy);
3921ab64890Smrg		return(NULL);
3931ab64890Smrg	    }
3941ab64890Smrg
39561b2299dSmrg	    root_visualID = u.rp->rootVisualID;
3961ab64890Smrg	    sp->display	    = dpy;
3971ab64890Smrg	    sp->root 	    = u.rp->windowId;
3981ab64890Smrg	    sp->cmap 	    = u.rp->defaultColormap;
3991ab64890Smrg	    sp->white_pixel = u.rp->whitePixel;
4001ab64890Smrg	    sp->black_pixel = u.rp->blackPixel;
4011ab64890Smrg	    sp->root_input_mask = u.rp->currentInputMask;
4021ab64890Smrg	    sp->width	    = u.rp->pixWidth;
4031ab64890Smrg	    sp->height	    = u.rp->pixHeight;
4041ab64890Smrg	    sp->mwidth	    = u.rp->mmWidth;
4051ab64890Smrg	    sp->mheight	    = u.rp->mmHeight;
4061ab64890Smrg	    sp->min_maps    = u.rp->minInstalledMaps;
4071ab64890Smrg	    sp->max_maps    = u.rp->maxInstalledMaps;
4081ab64890Smrg	    sp->backing_store= u.rp->backingStore;
4091ab64890Smrg	    sp->save_unders = u.rp->saveUnders;
4101ab64890Smrg	    sp->root_depth  = u.rp->rootDepth;
4111ab64890Smrg	    sp->ndepths	    = u.rp->nDepths;
4121ab64890Smrg	    sp->ext_data   = NULL;
4131ab64890Smrg	    u.rp = (xWindowRoot *) (((char *) u.rp) + sz_xWindowRoot);
4141ab64890Smrg/*
4151ab64890Smrg * lets set up the depth structures.
4161ab64890Smrg */
417eb411b4bSmrg	    sp->depths = Xcalloc(sp->ndepths, sizeof(Depth));
4181ab64890Smrg	    if (sp->depths == NULL) {
419e9fcaa8aSmrg		OutOfMemory (dpy);
4201ab64890Smrg		return(NULL);
4211ab64890Smrg	    }
4221ab64890Smrg	    /*
4231ab64890Smrg	     * for all depths on this screen.
4241ab64890Smrg	     */
4251ab64890Smrg	    for (j = 0; j < sp->ndepths; j++) {
4261ab64890Smrg		Depth *dp = &sp->depths[j];
4271ab64890Smrg
4281ab64890Smrg		usedbytes += sz_xDepth;
4291ab64890Smrg		if (setuplength < usedbytes) {
4301ab64890Smrg		    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
431e9fcaa8aSmrg		    OutOfMemory (dpy);
4321ab64890Smrg		    return(NULL);
4331ab64890Smrg		}
43461b2299dSmrg
4351ab64890Smrg		dp->depth = u.dp->depth;
4361ab64890Smrg		dp->nvisuals = u.dp->nVisuals;
4371ab64890Smrg		u.dp = (xDepth *) (((char *) u.dp) + sz_xDepth);
4381ab64890Smrg		if (dp->nvisuals > 0) {
439eb411b4bSmrg		    dp->visuals = Xcalloc(dp->nvisuals, sizeof(Visual));
4401ab64890Smrg		    if (dp->visuals == NULL) {
441e9fcaa8aSmrg			OutOfMemory (dpy);
4421ab64890Smrg			return(NULL);
4431ab64890Smrg		    }
4441ab64890Smrg		    for (k = 0; k < dp->nvisuals; k++) {
4451ab64890Smrg			register Visual *vp = &dp->visuals[k];
4461ab64890Smrg
4471ab64890Smrg			usedbytes += sz_xVisualType;
4481ab64890Smrg			if (setuplength < usedbytes) {
4491ab64890Smrg			    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
450e9fcaa8aSmrg			    OutOfMemory (dpy);
4511ab64890Smrg			    return(NULL);
4521ab64890Smrg			}
45361b2299dSmrg
4541ab64890Smrg			vp->visualid	= u.vp->visualID;
4551ab64890Smrg			vp->class	= u.vp->class;
4561ab64890Smrg			vp->bits_per_rgb= u.vp->bitsPerRGB;
4571ab64890Smrg			vp->map_entries	= u.vp->colormapEntries;
4581ab64890Smrg			vp->red_mask	= u.vp->redMask;
4591ab64890Smrg			vp->green_mask	= u.vp->greenMask;
4601ab64890Smrg			vp->blue_mask	= u.vp->blueMask;
4611ab64890Smrg			vp->ext_data	= NULL;
4621ab64890Smrg			u.vp = (xVisualType *) (((char *) u.vp) +
4631ab64890Smrg						sz_xVisualType);
4641ab64890Smrg		    }
4651ab64890Smrg		    if (dp->depth == 32 && getenv ("XLIB_SKIP_ARGB_VISUALS"))
4661ab64890Smrg		    {
4671ab64890Smrg			Xfree (dp->visuals);
4681ab64890Smrg			dp->visuals = NULL;
4691ab64890Smrg			dp->nvisuals = 0;
4701ab64890Smrg		    }
4711ab64890Smrg		} else {
4721ab64890Smrg		    dp->visuals = (Visual *) NULL;
4731ab64890Smrg		}
4741ab64890Smrg	    }
4751ab64890Smrg	    sp->root_visual = _XVIDtoVisual(dpy, root_visualID);
4764e08afa9Smrg	    if (sp->root_visual == NULL) {
4774e08afa9Smrg		OutOfMemory(dpy);
4784e08afa9Smrg		return(NULL);
4794e08afa9Smrg	    }
4801ab64890Smrg	}
4811ab64890Smrg
4821ab64890Smrg	if(usedbytes != setuplength){
4831ab64890Smrg	    /* Sanity check, shouldn't happen. */
4841ab64890Smrg	    fprintf(stderr, "Xlib: Did not parse entire setup message: "
4851ab64890Smrg	                    "parsed: %ld, message: %ld\n",
4861ab64890Smrg		    usedbytes, setuplength);
487e9fcaa8aSmrg	    OutOfMemory(dpy);
4881ab64890Smrg	    return(NULL);
4891ab64890Smrg	}
4901ab64890Smrg
4911ab64890Smrg/*
4921ab64890Smrg * Now start talking to the server to setup all other information...
4931ab64890Smrg */
4941ab64890Smrg
4951ab64890Smrg/*
4961ab64890Smrg * Make sure default screen is legal.
4971ab64890Smrg */
4981ab64890Smrg	if (iscreen >= dpy->nscreens) {
499e9fcaa8aSmrg	    OutOfMemory(dpy);
5001ab64890Smrg	    return(NULL);
5011ab64890Smrg	}
5021ab64890Smrg
503eb411b4bSmrg/*
504eb411b4bSmrg * get availability of large requests
505eb411b4bSmrg */
50661b2299dSmrg	dpy->bigreq_size = xcb_get_maximum_request_length(dpy->xcb->connection);
50761b2299dSmrg	if(dpy->bigreq_size <= dpy->max_request_size)
50861b2299dSmrg		dpy->bigreq_size = 0;
50961b2299dSmrg
5101ab64890Smrg/*
5111ab64890Smrg * Set up other stuff clients are always going to use.
5121ab64890Smrg */
5131ab64890Smrg	for (i = 0; i < dpy->nscreens; i++) {
5141ab64890Smrg	    register Screen *sp = &dpy->screens[i];
5151ab64890Smrg	    XGCValues values;
5161ab64890Smrg	    values.foreground = sp->black_pixel;
5171ab64890Smrg	    values.background = sp->white_pixel;
5181ab64890Smrg	    if ((sp->default_gc = XCreateGC (dpy, sp->root,
5191ab64890Smrg					     GCForeground|GCBackground,
5201ab64890Smrg					     &values)) == NULL) {
521e9fcaa8aSmrg		OutOfMemory(dpy);
5221ab64890Smrg		return (NULL);
5231ab64890Smrg	    }
5241ab64890Smrg	}
5251ab64890Smrg/*
5261ab64890Smrg * call into synchronization routine so that all programs can be
5271ab64890Smrg * forced synchronous
5281ab64890Smrg */
5291ab64890Smrg	(void) XSynchronize(dpy, _Xdebug);
5301ab64890Smrg
5311ab64890Smrg/*
5321ab64890Smrg * get the resource manager database off the root window.
5331ab64890Smrg */
5341ab64890Smrg	LockDisplay(dpy);
5351ab64890Smrg	{
5361ab64890Smrg	    xGetPropertyReply reply;
5371ab64890Smrg	    xGetPropertyReq *req;
5381ab64890Smrg
5391ab64890Smrg	    GetReq (GetProperty, req);
5401ab64890Smrg	    req->window = RootWindow(dpy, 0);
5411ab64890Smrg	    req->property = XA_RESOURCE_MANAGER;
5421ab64890Smrg	    req->type = XA_STRING;
5431ab64890Smrg	    req->delete = False;
5441ab64890Smrg	    req->longOffset = 0;
5451ab64890Smrg	    req->longLength = 100000000L;
5461ab64890Smrg
5471ab64890Smrg	    if (_XReply (dpy, (xReply *) &reply, 0, xFalse)) {
5481ab64890Smrg		if (reply.format == 8 && reply.propertyType == XA_STRING &&
5491ab64890Smrg		    (reply.nItems + 1 > 0) &&
5501ab64890Smrg		    (reply.nItems <= req->longLength * 4) &&
5511ab64890Smrg		    (dpy->xdefaults = Xmalloc (reply.nItems + 1))) {
5521ab64890Smrg		    _XReadPad (dpy, dpy->xdefaults, reply.nItems);
5531ab64890Smrg		    dpy->xdefaults[reply.nItems] = '\0';
5541ab64890Smrg		}
5551ab64890Smrg		else if (reply.propertyType != None)
556eb411b4bSmrg		    _XEatDataWords(dpy, reply.length);
5571ab64890Smrg	    }
5581ab64890Smrg	}
5591ab64890Smrg	UnlockDisplay(dpy);
5601ab64890Smrg
5611ab64890Smrg#ifdef MOTIFBC
5621ab64890Smrg	{
5631ab64890Smrg	    extern Display *_XHeadOfDisplayList;
5641ab64890Smrg	    _XHeadOfDisplayList = dpy;
5651ab64890Smrg	}
5661ab64890Smrg#endif
5671ab64890Smrg#ifdef XKB
5681ab64890Smrg	XkbUseExtension(dpy,NULL,NULL);
5691ab64890Smrg#endif
5701ab64890Smrg/*
5711ab64890Smrg * and return successfully
5721ab64890Smrg */
5731ab64890Smrg 	return(dpy);
5741ab64890Smrg}
5751ab64890Smrg
57661b2299dSmrg/* XFreeDisplayStructure frees all the storage associated with a
5771ab64890Smrg * Display.  It is used by XOpenDisplay if it runs out of memory,
5781ab64890Smrg * and also by XCloseDisplay.   It needs to check whether all pointers
5791ab64890Smrg * are non-NULL before dereferencing them, since it may be called
5801ab64890Smrg * by XOpenDisplay before the Display structure is fully formed.
5811ab64890Smrg * XOpenDisplay must be sure to initialize all the pointers to NULL
5821ab64890Smrg * before the first possible call on this.
5831ab64890Smrg */
5841ab64890Smrg
58561b2299dSmrgvoid _XFreeDisplayStructure(Display *dpy)
5861ab64890Smrg{
587b4ee4795Smrg	/* move all cookies in the EQ to the jar, then free them. */
588b4ee4795Smrg	if (dpy->qfree) {
589b4ee4795Smrg	    _XQEvent *qelt = dpy->qfree;
590b4ee4795Smrg	    while (qelt) {
591b4ee4795Smrg		if (_XIsEventCookie(dpy, &qelt->event))
592b4ee4795Smrg		    _XStoreEventCookie(dpy, &qelt->event);
593b4ee4795Smrg		qelt = qelt->next;
594b4ee4795Smrg	    }
595b4ee4795Smrg        }
596b4ee4795Smrg	if (dpy->cookiejar)
597b4ee4795Smrg	    _XFreeEventCookies(dpy);
5981ab64890Smrg	while (dpy->ext_procs) {
5991ab64890Smrg	    _XExtension *ext = dpy->ext_procs;
6001ab64890Smrg	    dpy->ext_procs = ext->next;
6010f8248bfSmrg	    Xfree (ext->name);
602818534a1Smrg	    Xfree (ext);
6031ab64890Smrg	}
6041ab64890Smrg	if (dpy->im_filters)
6051ab64890Smrg	   (*dpy->free_funcs->im_filters)(dpy);
6061ab64890Smrg	if (dpy->cms.clientCmaps)
6071ab64890Smrg	   (*dpy->free_funcs->clientCmaps)(dpy);
6081ab64890Smrg	if (dpy->cms.defaultCCCs)
6091ab64890Smrg	   (*dpy->free_funcs->defaultCCCs)(dpy);
6101ab64890Smrg	if (dpy->cms.perVisualIntensityMaps)
6111ab64890Smrg	   (*dpy->free_funcs->intensityMaps)(dpy);
6121ab64890Smrg	if (dpy->atoms)
6131ab64890Smrg	    (*dpy->free_funcs->atoms)(dpy);
6141ab64890Smrg	if (dpy->modifiermap)
6151ab64890Smrg	   (*dpy->free_funcs->modifiermap)(dpy->modifiermap);
6161ab64890Smrg	if (dpy->key_bindings)
6171ab64890Smrg	   (*dpy->free_funcs->key_bindings)(dpy);
6181ab64890Smrg	if (dpy->context_db)
6191ab64890Smrg	   (*dpy->free_funcs->context_db)(dpy);
6201ab64890Smrg	if (dpy->xkb_info)
6211ab64890Smrg	   (*dpy->free_funcs->xkb)(dpy);
6221ab64890Smrg
6231ab64890Smrg	/* if RM database was allocated by XGetDefault() free it */
6241ab64890Smrg	if (dpy->db && (dpy->flags & XlibDisplayDfltRMDB))
6251ab64890Smrg	    XrmDestroyDatabase(dpy->db);
6261ab64890Smrg
6271ab64890Smrg	if (dpy->screens) {
6281ab64890Smrg	    register int i;
6291ab64890Smrg
6301ab64890Smrg            for (i = 0; i < dpy->nscreens; i++) {
6311ab64890Smrg		Screen *sp = &dpy->screens[i];
6321ab64890Smrg
6331ab64890Smrg		if (sp->depths) {
6341ab64890Smrg		   register int j;
6351ab64890Smrg
6361ab64890Smrg		   for (j = 0; j < sp->ndepths; j++) {
6371ab64890Smrg			Depth *dp = &sp->depths[j];
6381ab64890Smrg
6391ab64890Smrg			if (dp->visuals) {
6401ab64890Smrg			   register int k;
6411ab64890Smrg
6421ab64890Smrg			   for (k = 0; k < dp->nvisuals; k++)
6431ab64890Smrg			     _XFreeExtData (dp->visuals[k].ext_data);
644818534a1Smrg			   Xfree (dp->visuals);
6451ab64890Smrg			   }
6461ab64890Smrg			}
6471ab64890Smrg
648818534a1Smrg		   Xfree (sp->depths);
6491ab64890Smrg		   }
6501ab64890Smrg
6511ab64890Smrg		_XFreeExtData (sp->ext_data);
6521ab64890Smrg		}
6531ab64890Smrg
654818534a1Smrg	    Xfree (dpy->screens);
6551ab64890Smrg	    }
65661b2299dSmrg
6571ab64890Smrg	if (dpy->pixmap_format) {
6581ab64890Smrg	    register int i;
6591ab64890Smrg
6601ab64890Smrg	    for (i = 0; i < dpy->nformats; i++)
6611ab64890Smrg	      _XFreeExtData (dpy->pixmap_format[i].ext_data);
662818534a1Smrg            Xfree (dpy->pixmap_format);
6631ab64890Smrg	    }
6641ab64890Smrg
665e9fcaa8aSmrg	free(dpy->display_name);
6660f8248bfSmrg
6670f8248bfSmrg	Xfree (dpy->vendor);
6680f8248bfSmrg	Xfree (dpy->buffer);
6690f8248bfSmrg	Xfree (dpy->keysyms);
6700f8248bfSmrg	Xfree (dpy->xdefaults);
6710f8248bfSmrg	Xfree (dpy->error_vec);
6721ab64890Smrg
6731ab64890Smrg	_XFreeExtData (dpy->ext_data);
6740f8248bfSmrg
6750f8248bfSmrg	Xfree (dpy->free_funcs);
6760f8248bfSmrg	Xfree (dpy->scratch_buffer);
6771ab64890Smrg	FreeDisplayLock(dpy);
6781ab64890Smrg
6791ab64890Smrg	if (dpy->qfree) {
6801ab64890Smrg	    register _XQEvent *qelt = dpy->qfree;
6811ab64890Smrg
6821ab64890Smrg	    while (qelt) {
6831ab64890Smrg		register _XQEvent *qnxt = qelt->next;
684818534a1Smrg		Xfree (qelt);
6851ab64890Smrg		qelt = qnxt;
6861ab64890Smrg	    }
6871ab64890Smrg	}
6881ab64890Smrg	while (dpy->im_fd_info) {
6891ab64890Smrg	    struct _XConnectionInfo *conni = dpy->im_fd_info;
6901ab64890Smrg	    dpy->im_fd_info = conni->next;
6910f8248bfSmrg	    Xfree (conni->watch_data);
6921ab64890Smrg	    Xfree (conni);
6931ab64890Smrg	}
6941ab64890Smrg	if (dpy->conn_watchers) {
6951ab64890Smrg	    struct _XConnWatchInfo *watcher = dpy->conn_watchers;
6961ab64890Smrg	    dpy->conn_watchers = watcher->next;
6971ab64890Smrg	    Xfree (watcher);
6981ab64890Smrg	}
6990f8248bfSmrg
7000f8248bfSmrg	Xfree (dpy->filedes);
7011ab64890Smrg
7021ab64890Smrg	_XFreeX11XCBStructure(dpy);
7031ab64890Smrg
704818534a1Smrg	Xfree (dpy);
7051ab64890Smrg}
7061ab64890Smrg
7071ab64890Smrg/* OutOfMemory is called if malloc fails.  XOpenDisplay returns NULL
7081ab64890Smrg   after this returns. */
7091ab64890Smrg
710e9fcaa8aSmrgstatic void OutOfMemory(Display *dpy)
7111ab64890Smrg{
712d5e6aabbSmrg	xcb_connection_t *connection = dpy->xcb->connection;
713d5e6aabbSmrg
714d5e6aabbSmrg	_XFreeDisplayStructure (dpy);
715d5e6aabbSmrg
716d5e6aabbSmrg	if (connection)
717d5e6aabbSmrg	    xcb_disconnect(connection);
7181ab64890Smrg}
719