OpenDis.c revision 88de56cc
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#define NEED_REPLIES
281ab64890Smrg#define NEED_EVENTS
291ab64890Smrg#ifdef HAVE_CONFIG_H
301ab64890Smrg#include <config.h>
311ab64890Smrg#endif
321ab64890Smrg#include "Xlibint.h"
331ab64890Smrg#if USE_XCB
341ab64890Smrg#include "Xxcbint.h"
351ab64890Smrg#else /* !USE_XCB */
361ab64890Smrg#include <X11/Xtrans/Xtrans.h>
371ab64890Smrg#include <X11/extensions/bigreqstr.h>
381ab64890Smrg#endif /* USE_XCB */
391ab64890Smrg#include <X11/Xatom.h>
401ab64890Smrg#include <X11/Xresource.h>
411ab64890Smrg#include <stdio.h>
421ab64890Smrg#include "Xintconn.h"
431ab64890Smrg
441ab64890Smrg#ifdef XKB
451ab64890Smrg#include "XKBlib.h"
461ab64890Smrg#endif /* XKB */
471ab64890Smrg
481ab64890Smrg#if !USE_XCB
491ab64890Smrg#ifdef X_NOT_POSIX
501ab64890Smrg#define Size_t unsigned int
511ab64890Smrg#else
521ab64890Smrg#define Size_t size_t
531ab64890Smrg#endif
541ab64890Smrg
551ab64890Smrg#define bignamelen (sizeof(XBigReqExtensionName) - 1)
561ab64890Smrg
571ab64890Smrgtypedef struct {
581ab64890Smrg    unsigned long seq;
591ab64890Smrg    int opcode;
601ab64890Smrg} _XBigReqState;
611ab64890Smrg#endif /* !USE_XCB */
621ab64890Smrg
631ab64890Smrg#ifdef XTHREADS
641ab64890Smrg#include "locking.h"
651ab64890Smrgint  (*_XInitDisplayLock_fn)(Display *dpy) = NULL;
661ab64890Smrgvoid (*_XFreeDisplayLock_fn)(Display *dpy) = NULL;
671ab64890Smrg
681ab64890Smrg#define InitDisplayLock(d)	(_XInitDisplayLock_fn ? (*_XInitDisplayLock_fn)(d) : Success)
691ab64890Smrg#define FreeDisplayLock(d)	if (_XFreeDisplayLock_fn) (*_XFreeDisplayLock_fn)(d)
701ab64890Smrg#else
711ab64890Smrg#define InitDisplayLock(dis) Success
721ab64890Smrg#define FreeDisplayLock(dis)
731ab64890Smrg#endif /* XTHREADS */
741ab64890Smrg
751ab64890Smrgstatic xReq _dummy_request = {
761ab64890Smrg	0, 0, 0
771ab64890Smrg};
781ab64890Smrg
791ab64890Smrgstatic void OutOfMemory(Display *dpy, char *setup);
801ab64890Smrg#if !USE_XCB
811ab64890Smrgstatic Bool _XBigReqHandler(Display *dpy, xReply *rep, char *buf, int len,
821ab64890Smrg				XPointer data);
831ab64890Smrg#endif /* !USE_XCB */
841ab64890Smrg
8561b2299dSmrg/*
861ab64890Smrg * Connects to a server, creates a Display object and returns a pointer to
871ab64890Smrg * the newly created Display back to the caller.
881ab64890Smrg */
891ab64890SmrgDisplay *
901ab64890SmrgXOpenDisplay (
911ab64890Smrg	register _Xconst char *display)
921ab64890Smrg{
931ab64890Smrg	register Display *dpy;		/* New Display object being created. */
941ab64890Smrg	register int i;
951ab64890Smrg	int j, k;			/* random iterator indexes */
961ab64890Smrg	char *display_name;		/* pointer to display name */
9788de56ccSmrg#if !USE_XCB
981ab64890Smrg	int endian;			/* to determine which endian. */
991ab64890Smrg	xConnClientPrefix client;	/* client information */
1001ab64890Smrg	int idisplay;			/* display number */
1011ab64890Smrg	int prefixread = 0;             /* setup prefix already read? */
1021ab64890Smrg	char *conn_auth_name, *conn_auth_data;
1031ab64890Smrg	int conn_auth_namelen, conn_auth_datalen;
1041ab64890Smrg#endif /* !USE_XCB */
1051ab64890Smrg	char *setup = NULL;		/* memory allocated at startup */
1061ab64890Smrg	char *fullname = NULL;		/* expanded name of display */
1071ab64890Smrg	int iscreen;			/* screen number */
1081ab64890Smrg	xConnSetupPrefix prefix;	/* prefix information */
1091ab64890Smrg	int vendorlen;			/* length of vendor string */
1101ab64890Smrg	union {
1111ab64890Smrg		xConnSetup *setup;
1121ab64890Smrg		char *failure;
1131ab64890Smrg		char *vendor;
1141ab64890Smrg		xPixmapFormat *sf;
1151ab64890Smrg		xWindowRoot *rp;
1161ab64890Smrg		xDepth *dp;
1171ab64890Smrg		xVisualType *vp;
1181ab64890Smrg	} u;				/* proto data returned from server */
1191ab64890Smrg	long setuplength;	/* number of bytes in setup message */
1201ab64890Smrg	long usedbytes = 0;     /* number of bytes we have processed */
1211ab64890Smrg	unsigned long mask;
12288de56ccSmrg	long int conn_buf_size;
12388de56ccSmrg	char *xlib_buffer_size;
1241ab64890Smrg
1251ab64890Smrg#if !USE_XCB
1261ab64890Smrg	bzero((char *) &client, sizeof(client));
1271ab64890Smrg	bzero((char *) &prefix, sizeof(prefix));
12888de56ccSmrg#endif /* !USE_XCB */
1291ab64890Smrg
1301ab64890Smrg	/*
13161b2299dSmrg	 * If the display specifier string supplied as an argument to this
1321ab64890Smrg	 * routine is NULL or a pointer to NULL, read the DISPLAY variable.
1331ab64890Smrg	 */
1341ab64890Smrg	if (display == NULL || *display == '\0') {
1351ab64890Smrg		if ((display_name = getenv("DISPLAY")) == NULL) {
1361ab64890Smrg			/* Oops! No DISPLAY environment variable - error. */
1371ab64890Smrg			return(NULL);
1381ab64890Smrg		}
1391ab64890Smrg	}
1401ab64890Smrg	else {
1411ab64890Smrg		/* Display is non-NULL, copy the pointer */
1421ab64890Smrg		display_name = (char *)display;
1431ab64890Smrg	}
1441ab64890Smrg
1451ab64890Smrg/*
1461ab64890Smrg * Set the default error handlers.  This allows the global variables to
1471ab64890Smrg * default to NULL for use with shared libraries.
1481ab64890Smrg */
1491ab64890Smrg	if (_XErrorFunction == NULL) (void) XSetErrorHandler (NULL);
1501ab64890Smrg	if (_XIOErrorFunction == NULL) (void) XSetIOErrorHandler (NULL);
1511ab64890Smrg
1521ab64890Smrg/*
1531ab64890Smrg * Attempt to allocate a display structure. Return NULL if allocation fails.
1541ab64890Smrg */
1551ab64890Smrg	if ((dpy = (Display *)Xcalloc(1, sizeof(Display))) == NULL) {
1561ab64890Smrg		return(NULL);
1571ab64890Smrg	}
1581ab64890Smrg
1591ab64890Smrg/*
1601ab64890Smrg * Call the Connect routine to get the transport connection object.
1611ab64890Smrg * If NULL is returned, the connection failed. The connect routine
1621ab64890Smrg * will set fullname to point to the expanded name.
1631ab64890Smrg */
1641ab64890Smrg
1651ab64890Smrg#if USE_XCB
1661ab64890Smrg	if(!_XConnectXCB(dpy, display, &fullname, &iscreen)) {
16788de56ccSmrg		/* Try falling back on other transports if no transport specified */
16888de56ccSmrg		const char *slash = strrchr(display_name, '/');
16988de56ccSmrg		if(slash == NULL) {
17088de56ccSmrg			const char *protocols[] = {"local", "unix", "tcp", "inet6", "inet", NULL};
17188de56ccSmrg			const char **s;
17288de56ccSmrg			size_t buf_size = strlen(display_name) + 7; // max strlen + 2 (null + /)
17388de56ccSmrg			char *buf = Xmalloc(buf_size * sizeof(char));
17488de56ccSmrg
17588de56ccSmrg			if(buf) {
17688de56ccSmrg				for(s = protocols; buf && *s; s++) {
17788de56ccSmrg					snprintf(buf, buf_size, "%s/%s", *s, display_name);
17888de56ccSmrg					if(_XConnectXCB(dpy, buf, &fullname, &iscreen))
17988de56ccSmrg						goto fallback_success;
18088de56ccSmrg				}
18188de56ccSmrg				Xfree(buf);
18288de56ccSmrg			}
18388de56ccSmrg		}
18488de56ccSmrg
18561b2299dSmrg		dpy->display_name = fullname;
1862e9c7c8cSmrg		OutOfMemory(dpy, NULL);
1872e9c7c8cSmrg		return NULL;
1881ab64890Smrg	}
18988de56ccSmrgfallback_success:
1901ab64890Smrg#else /* !USE_XCB */
1911ab64890Smrg	if ((dpy->trans_conn = _X11TransConnectDisplay (
1921ab64890Smrg					 display_name, &fullname, &idisplay,
1931ab64890Smrg					 &iscreen, &conn_auth_name,
1941ab64890Smrg					 &conn_auth_namelen, &conn_auth_data,
1951ab64890Smrg					 &conn_auth_datalen)) == NULL) {
1961ab64890Smrg		Xfree ((char *) dpy);
1971ab64890Smrg		return(NULL);
1981ab64890Smrg	}
1991ab64890Smrg
2001ab64890Smrg	dpy->fd = _X11TransGetConnectionNumber (dpy->trans_conn);
2011ab64890Smrg#endif /* USE_XCB */
2021ab64890Smrg
2031ab64890Smrg	/* Initialize as much of the display structure as we can.
2041ab64890Smrg	 * Initialize pointers to NULL so that XFreeDisplayStructure will
2051ab64890Smrg	 * work if we run out of memory before we finish initializing.
2061ab64890Smrg	 */
2071ab64890Smrg	dpy->display_name	= fullname;
2081ab64890Smrg	dpy->keysyms		= (KeySym *) NULL;
2091ab64890Smrg	dpy->modifiermap	= NULL;
2101ab64890Smrg	dpy->lock_meaning	= NoSymbol;
2111ab64890Smrg	dpy->keysyms_per_keycode = 0;
2121ab64890Smrg	dpy->xdefaults		= (char *)NULL;
2131ab64890Smrg	dpy->scratch_length	= 0L;
2141ab64890Smrg	dpy->scratch_buffer	= NULL;
2151ab64890Smrg	dpy->key_bindings	= NULL;
2161ab64890Smrg	dpy->ext_procs		= (_XExtension *)NULL;
2171ab64890Smrg	dpy->ext_data		= (XExtData *)NULL;
2181ab64890Smrg	dpy->ext_number 	= 0;
2191ab64890Smrg	dpy->event_vec[X_Error] = _XUnknownWireEvent;
2201ab64890Smrg	dpy->event_vec[X_Reply] = _XUnknownWireEvent;
2211ab64890Smrg	dpy->wire_vec[X_Error]  = _XUnknownNativeEvent;
2221ab64890Smrg	dpy->wire_vec[X_Reply]  = _XUnknownNativeEvent;
2231ab64890Smrg	for (i = KeyPress; i < LASTEvent; i++) {
2241ab64890Smrg	    dpy->event_vec[i] 	= _XWireToEvent;
2251ab64890Smrg	    dpy->wire_vec[i] 	= NULL;
2261ab64890Smrg	}
2271ab64890Smrg	for (i = LASTEvent; i < 128; i++) {
2281ab64890Smrg	    dpy->event_vec[i] 	= _XUnknownWireEvent;
2291ab64890Smrg	    dpy->wire_vec[i] 	= _XUnknownNativeEvent;
2301ab64890Smrg	}
2311ab64890Smrg	dpy->resource_id	= 0;
2321ab64890Smrg	dpy->db 		= (struct _XrmHashBucketRec *)NULL;
2331ab64890Smrg	dpy->cursor_font	= None;
2341ab64890Smrg	dpy->flags		= 0;
2351ab64890Smrg	dpy->async_handlers	= NULL;
2361ab64890Smrg	dpy->screens		= NULL;
2371ab64890Smrg	dpy->vendor		= NULL;
2381ab64890Smrg	dpy->buffer		= NULL;
2391ab64890Smrg	dpy->atoms		= NULL;
2401ab64890Smrg	dpy->error_vec		= NULL;
2411ab64890Smrg	dpy->context_db		= NULL;
2421ab64890Smrg	dpy->free_funcs		= NULL;
2431ab64890Smrg	dpy->pixmap_format	= NULL;
2441ab64890Smrg	dpy->cms.clientCmaps	= NULL;
2451ab64890Smrg	dpy->cms.defaultCCCs	= NULL;
2461ab64890Smrg	dpy->cms.perVisualIntensityMaps = NULL;
2471ab64890Smrg	dpy->im_filters		= NULL;
2481ab64890Smrg 	dpy->bigreq_size	= 0;
2491ab64890Smrg	dpy->lock		= NULL;
2501ab64890Smrg	dpy->lock_fns		= NULL;
2511ab64890Smrg	dpy->qfree		= NULL;
2521ab64890Smrg	dpy->next_event_serial_num = 1;
2531ab64890Smrg	dpy->im_fd_info		= NULL;
2541ab64890Smrg	dpy->im_fd_length	= 0;
2551ab64890Smrg	dpy->conn_watchers	= NULL;
2561ab64890Smrg	dpy->watcher_count	= 0;
2571ab64890Smrg	dpy->filedes		= NULL;
2581ab64890Smrg	dpy->flushes		= NULL;
2591ab64890Smrg	dpy->xcmisc_opcode	= 0;
2601ab64890Smrg	dpy->xkb_info		= NULL;
2611ab64890Smrg
2621ab64890Smrg/*
2631ab64890Smrg * Setup other information in this display structure.
2641ab64890Smrg */
2651ab64890Smrg	dpy->vnumber = X_PROTOCOL;
2661ab64890Smrg	dpy->resource_alloc = _XAllocID;
2671ab64890Smrg	dpy->idlist_alloc = _XAllocIDs;
2681ab64890Smrg	dpy->synchandler = NULL;
2691ab64890Smrg	dpy->savedsynchandler = NULL;
2701ab64890Smrg	dpy->request = 0;
2711ab64890Smrg	dpy->last_request_read = 0;
2721ab64890Smrg	dpy->default_screen = iscreen;  /* Value returned by ConnectDisplay */
2731ab64890Smrg	dpy->last_req = (char *)&_dummy_request;
2741ab64890Smrg
2751ab64890Smrg	/* Initialize the display lock */
2761ab64890Smrg	if (InitDisplayLock(dpy) != 0) {
2771ab64890Smrg	        OutOfMemory (dpy, setup);
2781ab64890Smrg		return(NULL);
2791ab64890Smrg	}
2801ab64890Smrg
2811ab64890Smrg	if (!_XPollfdCacheInit(dpy)) {
2821ab64890Smrg	        OutOfMemory (dpy, setup);
2831ab64890Smrg		return(NULL);
28461b2299dSmrg	}
2851ab64890Smrg
2861ab64890Smrg	/* Set up the output buffers. */
2871ab64890Smrg#ifndef XLIBDEFAULTBUFSIZE
2881ab64890Smrg#define XLIBDEFAULTBUFSIZE 16384 /* 16k */
2891ab64890Smrg#endif
2901ab64890Smrg#ifndef XLIBMINBUFSIZE
2911ab64890Smrg#define XLIBMINBUFSIZE BUFSIZE /* old default buffer size */
2921ab64890Smrg#endif
293b4ee4795Smrg	xlib_buffer_size = getenv("XLIBBUFFERSIZE");
294b4ee4795Smrg
295b4ee4795Smrg#ifdef __sun /* Backwards compatibility for old Solaris libX11 name */
296b4ee4795Smrg	if (xlib_buffer_size == NULL)
297b4ee4795Smrg	    xlib_buffer_size = getenv("XSUNBUFFERSIZE");
298b4ee4795Smrg#endif
299b4ee4795Smrg
300b4ee4795Smrg	if (xlib_buffer_size == NULL)
301b4ee4795Smrg	    conn_buf_size = XLIBDEFAULTBUFSIZE;
302b4ee4795Smrg	else
303b4ee4795Smrg	    conn_buf_size = 1024 * strtol(xlib_buffer_size, NULL, 10);
304b4ee4795Smrg	if (conn_buf_size < XLIBMINBUFSIZE)
305b4ee4795Smrg	    conn_buf_size = XLIBMINBUFSIZE;
306b4ee4795Smrg
307b4ee4795Smrg	if ((dpy->bufptr = dpy->buffer = Xcalloc(1, conn_buf_size)) == NULL) {
308b4ee4795Smrg	    OutOfMemory (dpy, setup);
309b4ee4795Smrg	    return(NULL);
310b4ee4795Smrg	}
311b4ee4795Smrg	dpy->bufmax = dpy->buffer + conn_buf_size;
31261b2299dSmrg#if USE_XCB
313b4ee4795Smrg	dpy->xcb->real_bufmax = dpy->bufmax;
314b4ee4795Smrg	dpy->bufmax = dpy->buffer;
31561b2299dSmrg#endif
31661b2299dSmrg
3171ab64890Smrg	/* Set up the input event queue and input event queue parameters. */
3181ab64890Smrg	dpy->head = dpy->tail = NULL;
3191ab64890Smrg	dpy->qlen = 0;
3201ab64890Smrg
3211ab64890Smrg	/* Set up free-function record */
3221ab64890Smrg	if ((dpy->free_funcs = (_XFreeFuncRec *)Xcalloc(1,
3231ab64890Smrg							sizeof(_XFreeFuncRec)))
3241ab64890Smrg	    == NULL) {
3251ab64890Smrg	    OutOfMemory (dpy, setup);
3261ab64890Smrg	    return(NULL);
3271ab64890Smrg	}
3281ab64890Smrg
3291ab64890Smrg#if !USE_XCB
3301ab64890Smrg/*
3311ab64890Smrg * The xConnClientPrefix describes the initial connection setup information
3321ab64890Smrg * and is followed by the authorization information.  Sites that are interested
33361b2299dSmrg * in security are strongly encouraged to use an authentication and
3341ab64890Smrg * authorization system such as Kerberos.
3351ab64890Smrg */
3361ab64890Smrg	endian = 1;
3371ab64890Smrg	if (*(char *) &endian)
3381ab64890Smrg	    client.byteOrder = '\154'; /* 'l' */
3391ab64890Smrg	else
3401ab64890Smrg	    client.byteOrder = '\102'; /* 'B' */
3411ab64890Smrg	client.majorVersion = X_PROTOCOL;
3421ab64890Smrg	client.minorVersion = X_PROTOCOL_REVISION;
3431ab64890Smrg	client.nbytesAuthProto = conn_auth_namelen;
3441ab64890Smrg	client.nbytesAuthString = conn_auth_datalen;
3451ab64890Smrg	prefixread = _XSendClientPrefix(dpy, &client,
3461ab64890Smrg					conn_auth_name, conn_auth_data,
3471ab64890Smrg					&prefix);
3481ab64890Smrg	if (prefixread < 0)
3491ab64890Smrg	{
3501ab64890Smrg	    _XDisconnectDisplay (dpy->trans_conn);
3511ab64890Smrg	    Xfree ((char *)dpy);
3521ab64890Smrg	    return(NULL);
3531ab64890Smrg	}
3541ab64890Smrg	if (conn_auth_name) Xfree(conn_auth_name);
3551ab64890Smrg	if (conn_auth_data) Xfree(conn_auth_data);
3561ab64890Smrg/*
3571ab64890Smrg * Now see if connection was accepted...
3581ab64890Smrg */
3591ab64890Smrg	/* these internal functions expect the display to be locked */
3601ab64890Smrg	LockDisplay(dpy);
3611ab64890Smrg
3621ab64890Smrg	if (prefixread == 0)
3631ab64890Smrg	    _XRead (dpy, (char *)&prefix,(long)SIZEOF(xConnSetupPrefix));
3641ab64890Smrg
3651ab64890Smrg	/* an Authenticate reply we weren't expecting? */
3661ab64890Smrg	if (prefix.success != xTrue && prefix.success != xFalse) {
3671ab64890Smrg	    fprintf (stderr,
3681ab64890Smrg      "Xlib: unexpected connection setup reply from server, type %d.\r\n",
3691ab64890Smrg		     prefix.success);
3701ab64890Smrg	    _XDisconnectDisplay (dpy->trans_conn);
3711ab64890Smrg	    Xfree ((char *)dpy);
3721ab64890Smrg	    return(NULL);
3731ab64890Smrg	}
3741ab64890Smrg
3751ab64890Smrg	if (prefix.majorVersion != X_PROTOCOL) {
3761ab64890Smrg	    /* XXX - printing messages marks a bad programming interface */
3771ab64890Smrg	    fprintf (stderr,
3781ab64890Smrg     "Xlib: client uses different protocol version (%d) than server (%d)!\r\n",
3791ab64890Smrg		     X_PROTOCOL, prefix.majorVersion);
3801ab64890Smrg	    _XDisconnectDisplay (dpy->trans_conn);
3811ab64890Smrg	    Xfree ((char *)dpy);
3821ab64890Smrg	    return(NULL);
3831ab64890Smrg	}
3841ab64890Smrg#endif /* !USE_XCB */
3851ab64890Smrg
3861ab64890Smrg#if USE_XCB
3871ab64890Smrg	{
3881ab64890Smrg		const struct xcb_setup_t *xcbsetup = xcb_get_setup(dpy->xcb->connection);
3891ab64890Smrg		memcpy(&prefix, xcbsetup, sizeof(prefix));
3901ab64890Smrg		setuplength = prefix.length << 2;
3911ab64890Smrg		setup = (char *) xcbsetup;
3921ab64890Smrg		setup += SIZEOF(xConnSetupPrefix);
3931ab64890Smrg		u.setup = (xConnSetup *) setup;
3941ab64890Smrg	}
3951ab64890Smrg#else /* !USE_XCB */
3961ab64890Smrg	setuplength = prefix.length << 2;
3971ab64890Smrg	if ( (u.setup = (xConnSetup *)
3981ab64890Smrg	      (setup =  Xmalloc ((unsigned) setuplength))) == NULL) {
3991ab64890Smrg		_XDisconnectDisplay (dpy->trans_conn);
4001ab64890Smrg		Xfree ((char *)dpy);
4011ab64890Smrg		return(NULL);
4021ab64890Smrg	}
4031ab64890Smrg	_XRead (dpy, (char *)u.setup, setuplength);
4041ab64890Smrg
4051ab64890Smrg/*
4061ab64890Smrg * If the connection was not accepted by the server due to problems,
4071ab64890Smrg * give error message to the user....
4081ab64890Smrg */
4091ab64890Smrg	if (prefix.success != xTrue) {
4101ab64890Smrg		/* XXX - printing messages marks a bad programming interface */
41161b2299dSmrg		fprintf (stderr,
4121ab64890Smrg		      "Xlib: connection to \"%s\" refused by server\r\nXlib: ",
4131ab64890Smrg			 fullname);
4141ab64890Smrg
4151ab64890Smrg		if (prefix.lengthReason > setuplength) {
4161ab64890Smrg		    fprintf (stderr, "Xlib: Broken initial reply: length of reason > length of packet\r\n");
4171ab64890Smrg		}else{
4181ab64890Smrg		    (void) fwrite (u.failure, (Size_t)sizeof(char),
4191ab64890Smrg			       (Size_t)prefix.lengthReason, stderr);
4201ab64890Smrg		    (void) fwrite ("\r\n", sizeof(char), 2, stderr);
4211ab64890Smrg		}
4221ab64890Smrg
4231ab64890Smrg		OutOfMemory(dpy, setup);
4241ab64890Smrg		return (NULL);
4251ab64890Smrg	}
4261ab64890Smrg#endif /* USE_XCB */
4271ab64890Smrg
4281ab64890Smrg/*
4291ab64890Smrg * Check if the reply was long enough to get any information out of it.
4301ab64890Smrg */
4311ab64890Smrg	usedbytes = sz_xConnSetup;
4321ab64890Smrg	if (setuplength < usedbytes ) {
4331ab64890Smrg	    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
4341ab64890Smrg	    OutOfMemory(dpy, setup);
4351ab64890Smrg	    return (NULL);
4361ab64890Smrg	}
4371ab64890Smrg
4381ab64890Smrg/*
4391ab64890Smrg * We succeeded at authorization, so let us move the data into
4401ab64890Smrg * the display structure.
4411ab64890Smrg */
4421ab64890Smrg	dpy->proto_major_version= prefix.majorVersion;
4431ab64890Smrg	dpy->proto_minor_version= prefix.minorVersion;
4441ab64890Smrg	dpy->release 		= u.setup->release;
4451ab64890Smrg	dpy->resource_base	= u.setup->ridBase;
4461ab64890Smrg	dpy->resource_mask	= u.setup->ridMask;
4471ab64890Smrg	dpy->min_keycode	= u.setup->minKeyCode;
4481ab64890Smrg	dpy->max_keycode	= u.setup->maxKeyCode;
4491ab64890Smrg	dpy->motion_buffer	= u.setup->motionBufferSize;
4501ab64890Smrg	dpy->nformats		= u.setup->numFormats;
4511ab64890Smrg	dpy->nscreens		= u.setup->numRoots;
4521ab64890Smrg	dpy->byte_order		= u.setup->imageByteOrder;
4531ab64890Smrg	dpy->bitmap_unit	= u.setup->bitmapScanlineUnit;
4541ab64890Smrg	dpy->bitmap_pad		= u.setup->bitmapScanlinePad;
4551ab64890Smrg	dpy->bitmap_bit_order   = u.setup->bitmapBitOrder;
4561ab64890Smrg	dpy->max_request_size	= u.setup->maxRequestSize;
4571ab64890Smrg	mask = dpy->resource_mask;
4581ab64890Smrg	dpy->resource_shift	= 0;
4591ab64890Smrg	if (!mask)
4601ab64890Smrg	{
4611ab64890Smrg	    fprintf (stderr, "Xlib: connection to \"%s\" invalid setup\n",
4621ab64890Smrg		     fullname);
4631ab64890Smrg	    OutOfMemory(dpy, setup);
4641ab64890Smrg	    return (NULL);
4651ab64890Smrg	}
46661b2299dSmrg
4671ab64890Smrg	while (!(mask & 1)) {
4681ab64890Smrg	    dpy->resource_shift++;
4691ab64890Smrg	    mask = mask >> 1;
4701ab64890Smrg	}
4711ab64890Smrg	dpy->resource_max = (dpy->resource_mask >> dpy->resource_shift) - 5;
4721ab64890Smrg/*
4731ab64890Smrg * now extract the vendor string...  String must be null terminated,
4741ab64890Smrg * padded to multiple of 4 bytes.
4751ab64890Smrg */
4761ab64890Smrg	/* Check for a sane vendor string length */
4771ab64890Smrg	if (u.setup->nbytesVendor > 256) {
4781ab64890Smrg	    OutOfMemory(dpy, setup);
4791ab64890Smrg	    return (NULL);
4801ab64890Smrg	}
4811ab64890Smrg
4821ab64890Smrg	dpy->vendor = (char *) Xmalloc((unsigned) (u.setup->nbytesVendor + 1));
4831ab64890Smrg	if (dpy->vendor == NULL) {
4841ab64890Smrg	    OutOfMemory(dpy, setup);
4851ab64890Smrg	    return (NULL);
4861ab64890Smrg	}
4871ab64890Smrg	vendorlen = u.setup->nbytesVendor;
4881ab64890Smrg
4891ab64890Smrg/*
4901ab64890Smrg * validate setup length
4911ab64890Smrg */
4921ab64890Smrg	usedbytes += (vendorlen + 3) & ~3;
4931ab64890Smrg	if (setuplength < usedbytes) {
4941ab64890Smrg	    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
4951ab64890Smrg	    OutOfMemory(dpy, setup);
4961ab64890Smrg	    return (NULL);
4971ab64890Smrg	}
4981ab64890Smrg
4991ab64890Smrg 	u.setup = (xConnSetup *) (((char *) u.setup) + sz_xConnSetup);
5001ab64890Smrg  	(void) strncpy(dpy->vendor, u.vendor, vendorlen);
5011ab64890Smrg	dpy->vendor[vendorlen] = '\0';
5021ab64890Smrg 	vendorlen = (vendorlen + 3) & ~3;	/* round up */
5031ab64890Smrg	u.vendor += vendorlen;
5041ab64890Smrg
5051ab64890Smrg/*
5061ab64890Smrg * Now iterate down setup information.....
5071ab64890Smrg */
50861b2299dSmrg	dpy->pixmap_format =
5091ab64890Smrg	    (ScreenFormat *)Xmalloc(
5101ab64890Smrg		(unsigned) (dpy->nformats *sizeof(ScreenFormat)));
5111ab64890Smrg	if (dpy->pixmap_format == NULL) {
5121ab64890Smrg	        OutOfMemory (dpy, setup);
5131ab64890Smrg		return(NULL);
5141ab64890Smrg	}
5151ab64890Smrg/*
5161ab64890Smrg * First decode the Z axis Screen format information.
5171ab64890Smrg */
5181ab64890Smrg	usedbytes += dpy->nformats * sz_xPixmapFormat;
5191ab64890Smrg
5201ab64890Smrg	if (setuplength < usedbytes) {
5211ab64890Smrg	    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
5221ab64890Smrg	    OutOfMemory (dpy, setup);
5231ab64890Smrg	    return(NULL);
5241ab64890Smrg	}
5251ab64890Smrg
5261ab64890Smrg	for (i = 0; i < dpy->nformats; i++) {
5271ab64890Smrg	    register ScreenFormat *fmt = &dpy->pixmap_format[i];
5281ab64890Smrg	    fmt->depth = u.sf->depth;
5291ab64890Smrg	    fmt->bits_per_pixel = u.sf->bitsPerPixel;
5301ab64890Smrg	    fmt->scanline_pad = u.sf->scanLinePad;
5311ab64890Smrg	    fmt->ext_data = NULL;
5321ab64890Smrg	    u.sf = (xPixmapFormat *) (((char *) u.sf) + sz_xPixmapFormat);
5331ab64890Smrg	}
5341ab64890Smrg
5351ab64890Smrg/*
5361ab64890Smrg * next the Screen structures.
5371ab64890Smrg */
53861b2299dSmrg	dpy->screens =
5391ab64890Smrg	    (Screen *)Xmalloc((unsigned) dpy->nscreens*sizeof(Screen));
5401ab64890Smrg	if (dpy->screens == NULL) {
5411ab64890Smrg	        OutOfMemory (dpy, setup);
5421ab64890Smrg		return(NULL);
5431ab64890Smrg	}
5441ab64890Smrg
5451ab64890Smrg/*
5461ab64890Smrg * Now go deal with each screen structure.
5471ab64890Smrg */
5481ab64890Smrg	for (i = 0; i < dpy->nscreens; i++) {
5491ab64890Smrg	    register Screen *sp = &dpy->screens[i];
5501ab64890Smrg	    VisualID root_visualID;
5511ab64890Smrg
5521ab64890Smrg	    usedbytes += sz_xWindowRoot;
5531ab64890Smrg	    if (setuplength < usedbytes) {
5541ab64890Smrg		fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
5551ab64890Smrg		OutOfMemory (dpy, setup);
5561ab64890Smrg		return(NULL);
5571ab64890Smrg	    }
5581ab64890Smrg
55961b2299dSmrg	    root_visualID = u.rp->rootVisualID;
5601ab64890Smrg	    sp->display	    = dpy;
5611ab64890Smrg	    sp->root 	    = u.rp->windowId;
5621ab64890Smrg	    sp->cmap 	    = u.rp->defaultColormap;
5631ab64890Smrg	    sp->white_pixel = u.rp->whitePixel;
5641ab64890Smrg	    sp->black_pixel = u.rp->blackPixel;
5651ab64890Smrg	    sp->root_input_mask = u.rp->currentInputMask;
5661ab64890Smrg	    sp->width	    = u.rp->pixWidth;
5671ab64890Smrg	    sp->height	    = u.rp->pixHeight;
5681ab64890Smrg	    sp->mwidth	    = u.rp->mmWidth;
5691ab64890Smrg	    sp->mheight	    = u.rp->mmHeight;
5701ab64890Smrg	    sp->min_maps    = u.rp->minInstalledMaps;
5711ab64890Smrg	    sp->max_maps    = u.rp->maxInstalledMaps;
5721ab64890Smrg	    sp->backing_store= u.rp->backingStore;
5731ab64890Smrg	    sp->save_unders = u.rp->saveUnders;
5741ab64890Smrg	    sp->root_depth  = u.rp->rootDepth;
5751ab64890Smrg	    sp->ndepths	    = u.rp->nDepths;
5761ab64890Smrg	    sp->ext_data   = NULL;
5771ab64890Smrg	    u.rp = (xWindowRoot *) (((char *) u.rp) + sz_xWindowRoot);
5781ab64890Smrg/*
5791ab64890Smrg * lets set up the depth structures.
5801ab64890Smrg */
5811ab64890Smrg	    sp->depths = (Depth *)Xmalloc(
5821ab64890Smrg			(unsigned)sp->ndepths*sizeof(Depth));
5831ab64890Smrg	    if (sp->depths == NULL) {
5841ab64890Smrg		OutOfMemory (dpy, setup);
5851ab64890Smrg		return(NULL);
5861ab64890Smrg	    }
5871ab64890Smrg	    /*
5881ab64890Smrg	     * for all depths on this screen.
5891ab64890Smrg	     */
5901ab64890Smrg	    for (j = 0; j < sp->ndepths; j++) {
5911ab64890Smrg		Depth *dp = &sp->depths[j];
5921ab64890Smrg
5931ab64890Smrg		usedbytes += sz_xDepth;
5941ab64890Smrg		if (setuplength < usedbytes) {
5951ab64890Smrg		    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
5961ab64890Smrg		    OutOfMemory (dpy, setup);
5971ab64890Smrg		    return(NULL);
5981ab64890Smrg		}
59961b2299dSmrg
6001ab64890Smrg		dp->depth = u.dp->depth;
6011ab64890Smrg		dp->nvisuals = u.dp->nVisuals;
6021ab64890Smrg		u.dp = (xDepth *) (((char *) u.dp) + sz_xDepth);
6031ab64890Smrg		if (dp->nvisuals > 0) {
60461b2299dSmrg		    dp->visuals =
6051ab64890Smrg		      (Visual *)Xmalloc((unsigned)dp->nvisuals*sizeof(Visual));
6061ab64890Smrg		    if (dp->visuals == NULL) {
6071ab64890Smrg			OutOfMemory (dpy, setup);
6081ab64890Smrg			return(NULL);
6091ab64890Smrg		    }
6101ab64890Smrg		    for (k = 0; k < dp->nvisuals; k++) {
6111ab64890Smrg			register Visual *vp = &dp->visuals[k];
6121ab64890Smrg
6131ab64890Smrg			usedbytes += sz_xVisualType;
6141ab64890Smrg			if (setuplength < usedbytes) {
6151ab64890Smrg			    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
6161ab64890Smrg			    OutOfMemory (dpy, setup);
6171ab64890Smrg			    return(NULL);
6181ab64890Smrg			}
61961b2299dSmrg
6201ab64890Smrg			vp->visualid	= u.vp->visualID;
6211ab64890Smrg			vp->class	= u.vp->class;
6221ab64890Smrg			vp->bits_per_rgb= u.vp->bitsPerRGB;
6231ab64890Smrg			vp->map_entries	= u.vp->colormapEntries;
6241ab64890Smrg			vp->red_mask	= u.vp->redMask;
6251ab64890Smrg			vp->green_mask	= u.vp->greenMask;
6261ab64890Smrg			vp->blue_mask	= u.vp->blueMask;
6271ab64890Smrg			vp->ext_data	= NULL;
6281ab64890Smrg			u.vp = (xVisualType *) (((char *) u.vp) +
6291ab64890Smrg						sz_xVisualType);
6301ab64890Smrg		    }
6311ab64890Smrg		    if (dp->depth == 32 && getenv ("XLIB_SKIP_ARGB_VISUALS"))
6321ab64890Smrg		    {
6331ab64890Smrg			Xfree (dp->visuals);
6341ab64890Smrg			dp->visuals = NULL;
6351ab64890Smrg			dp->nvisuals = 0;
6361ab64890Smrg		    }
6371ab64890Smrg		} else {
6381ab64890Smrg		    dp->visuals = (Visual *) NULL;
6391ab64890Smrg		}
6401ab64890Smrg	    }
6411ab64890Smrg	    sp->root_visual = _XVIDtoVisual(dpy, root_visualID);
6421ab64890Smrg	}
6431ab64890Smrg
6441ab64890Smrg	if(usedbytes != setuplength){
6451ab64890Smrg	    /* Sanity check, shouldn't happen. */
6461ab64890Smrg	    fprintf(stderr, "Xlib: Did not parse entire setup message: "
6471ab64890Smrg	                    "parsed: %ld, message: %ld\n",
6481ab64890Smrg		    usedbytes, setuplength);
6491ab64890Smrg	    OutOfMemory(dpy, setup);
6501ab64890Smrg	    return(NULL);
6511ab64890Smrg	}
6521ab64890Smrg
6531ab64890Smrg/*
6541ab64890Smrg * Now start talking to the server to setup all other information...
6551ab64890Smrg */
6561ab64890Smrg
6571ab64890Smrg#if !USE_XCB
6581ab64890Smrg	Xfree (setup);	/* all finished with setup information */
6591ab64890Smrg#endif /* !USE_XCB */
6601ab64890Smrg
6611ab64890Smrg/*
6621ab64890Smrg * Make sure default screen is legal.
6631ab64890Smrg */
6641ab64890Smrg	if (iscreen >= dpy->nscreens) {
6651ab64890Smrg	    OutOfMemory(dpy, (char *) NULL);
6661ab64890Smrg	    return(NULL);
6671ab64890Smrg	}
6681ab64890Smrg
6691ab64890Smrg#if !USE_XCB
6701ab64890Smrg/*
6711ab64890Smrg * finished calling internal routines, now unlock for external routines
6721ab64890Smrg */
6731ab64890Smrg	UnlockDisplay(dpy);
6741ab64890Smrg#endif /* !USE_XCB */
6751ab64890Smrg
67661b2299dSmrg#if USE_XCB
67761b2299dSmrg	dpy->bigreq_size = xcb_get_maximum_request_length(dpy->xcb->connection);
67861b2299dSmrg	if(dpy->bigreq_size <= dpy->max_request_size)
67961b2299dSmrg		dpy->bigreq_size = 0;
68061b2299dSmrg#endif /* USE_XCB */
68161b2299dSmrg
6821ab64890Smrg/*
6831ab64890Smrg * Set up other stuff clients are always going to use.
6841ab64890Smrg */
6851ab64890Smrg	for (i = 0; i < dpy->nscreens; i++) {
6861ab64890Smrg	    register Screen *sp = &dpy->screens[i];
6871ab64890Smrg	    XGCValues values;
6881ab64890Smrg	    values.foreground = sp->black_pixel;
6891ab64890Smrg	    values.background = sp->white_pixel;
6901ab64890Smrg	    if ((sp->default_gc = XCreateGC (dpy, sp->root,
6911ab64890Smrg					     GCForeground|GCBackground,
6921ab64890Smrg					     &values)) == NULL) {
6931ab64890Smrg		OutOfMemory(dpy, (char *) NULL);
6941ab64890Smrg		return (NULL);
6951ab64890Smrg	    }
6961ab64890Smrg	}
6971ab64890Smrg/*
6981ab64890Smrg * call into synchronization routine so that all programs can be
6991ab64890Smrg * forced synchronous
7001ab64890Smrg */
7011ab64890Smrg	(void) XSynchronize(dpy, _Xdebug);
7021ab64890Smrg
7031ab64890Smrg/*
7041ab64890Smrg * get availability of large requests, and
7051ab64890Smrg * get the resource manager database off the root window.
7061ab64890Smrg */
7071ab64890Smrg	LockDisplay(dpy);
7081ab64890Smrg	{
7091ab64890Smrg	    xGetPropertyReply reply;
7101ab64890Smrg	    xGetPropertyReq *req;
7111ab64890Smrg#if !USE_XCB
7121ab64890Smrg	    _XAsyncHandler async;
7131ab64890Smrg	    _XBigReqState async_state;
7141ab64890Smrg	    xQueryExtensionReq *qreq;
7151ab64890Smrg	    xBigReqEnableReq *breq;
7161ab64890Smrg	    xBigReqEnableReply brep;
7171ab64890Smrg
7181ab64890Smrg	    GetReq(QueryExtension, qreq);
7191ab64890Smrg	    async_state.seq = dpy->request;
7201ab64890Smrg	    async_state.opcode = 0;
7211ab64890Smrg	    async.next = dpy->async_handlers;
7221ab64890Smrg	    async.handler = _XBigReqHandler;
7231ab64890Smrg	    async.data = (XPointer)&async_state;
7241ab64890Smrg	    dpy->async_handlers = &async;
7251ab64890Smrg	    qreq->nbytes = bignamelen;
7261ab64890Smrg	    qreq->length += (bignamelen+3)>>2;
7271ab64890Smrg	    Data(dpy, XBigReqExtensionName, bignamelen);
7281ab64890Smrg#endif /* !USE_XCB */
7291ab64890Smrg
7301ab64890Smrg	    GetReq (GetProperty, req);
7311ab64890Smrg	    req->window = RootWindow(dpy, 0);
7321ab64890Smrg	    req->property = XA_RESOURCE_MANAGER;
7331ab64890Smrg	    req->type = XA_STRING;
7341ab64890Smrg	    req->delete = False;
7351ab64890Smrg	    req->longOffset = 0;
7361ab64890Smrg	    req->longLength = 100000000L;
7371ab64890Smrg
7381ab64890Smrg	    if (_XReply (dpy, (xReply *) &reply, 0, xFalse)) {
7391ab64890Smrg		if (reply.format == 8 && reply.propertyType == XA_STRING &&
7401ab64890Smrg		    (reply.nItems + 1 > 0) &&
7411ab64890Smrg		    (reply.nItems <= req->longLength * 4) &&
7421ab64890Smrg		    (dpy->xdefaults = Xmalloc (reply.nItems + 1))) {
7431ab64890Smrg		    _XReadPad (dpy, dpy->xdefaults, reply.nItems);
7441ab64890Smrg		    dpy->xdefaults[reply.nItems] = '\0';
7451ab64890Smrg		}
7461ab64890Smrg		else if (reply.propertyType != None)
7471ab64890Smrg		    _XEatData(dpy, reply.nItems * (reply.format >> 3));
7481ab64890Smrg	    }
7491ab64890Smrg#if !USE_XCB
7501ab64890Smrg	    DeqAsyncHandler(dpy, &async);
7511ab64890Smrg	    if (async_state.opcode) {
7521ab64890Smrg		GetReq(BigReqEnable, breq);
7531ab64890Smrg		breq->reqType = async_state.opcode;
7541ab64890Smrg		breq->brReqType = X_BigReqEnable;
7551ab64890Smrg		if (_XReply(dpy, (xReply *)&brep, 0, xFalse))
7561ab64890Smrg		    dpy->bigreq_size = brep.max_request_size;
7571ab64890Smrg	    }
7581ab64890Smrg#endif /* !USE_XCB */
7591ab64890Smrg	}
7601ab64890Smrg	UnlockDisplay(dpy);
7611ab64890Smrg
7621ab64890Smrg#ifdef MOTIFBC
7631ab64890Smrg	{
7641ab64890Smrg	    extern Display *_XHeadOfDisplayList;
7651ab64890Smrg	    _XHeadOfDisplayList = dpy;
7661ab64890Smrg	}
7671ab64890Smrg#endif
7681ab64890Smrg#ifdef XKB
7691ab64890Smrg	XkbUseExtension(dpy,NULL,NULL);
7701ab64890Smrg#endif
7711ab64890Smrg/*
7721ab64890Smrg * and return successfully
7731ab64890Smrg */
7741ab64890Smrg 	return(dpy);
7751ab64890Smrg}
7761ab64890Smrg
7771ab64890Smrg#if !USE_XCB
7781ab64890Smrgstatic Bool
7791ab64890Smrg_XBigReqHandler(
7801ab64890Smrg    register Display *dpy,
7811ab64890Smrg    register xReply *rep,
7821ab64890Smrg    char *buf,
7831ab64890Smrg    int len,
7841ab64890Smrg    XPointer data)
7851ab64890Smrg{
7861ab64890Smrg    _XBigReqState *state;
7871ab64890Smrg    xQueryExtensionReply replbuf;
7881ab64890Smrg    xQueryExtensionReply *repl;
7891ab64890Smrg
7901ab64890Smrg    state = (_XBigReqState *)data;
7911ab64890Smrg    if (dpy->last_request_read != state->seq)
7921ab64890Smrg	return False;
7931ab64890Smrg    if (rep->generic.type == X_Error)
7941ab64890Smrg	return True;
7951ab64890Smrg    repl = (xQueryExtensionReply *)
7961ab64890Smrg	_XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
7971ab64890Smrg			(SIZEOF(xQueryExtensionReply) - SIZEOF(xReply)) >> 2,
7981ab64890Smrg			True);
7991ab64890Smrg    if (repl->present)
8001ab64890Smrg	state->opcode = repl->major_opcode;
8011ab64890Smrg    return True;
8021ab64890Smrg}
8031ab64890Smrg#endif /* !USE_XCB */
8041ab64890Smrg
8051ab64890Smrg
80661b2299dSmrg/* XFreeDisplayStructure frees all the storage associated with a
8071ab64890Smrg * Display.  It is used by XOpenDisplay if it runs out of memory,
8081ab64890Smrg * and also by XCloseDisplay.   It needs to check whether all pointers
8091ab64890Smrg * are non-NULL before dereferencing them, since it may be called
8101ab64890Smrg * by XOpenDisplay before the Display structure is fully formed.
8111ab64890Smrg * XOpenDisplay must be sure to initialize all the pointers to NULL
8121ab64890Smrg * before the first possible call on this.
8131ab64890Smrg */
8141ab64890Smrg
81561b2299dSmrgvoid _XFreeDisplayStructure(Display *dpy)
8161ab64890Smrg{
817b4ee4795Smrg	/* move all cookies in the EQ to the jar, then free them. */
818b4ee4795Smrg	if (dpy->qfree) {
819b4ee4795Smrg	    _XQEvent *qelt = dpy->qfree;
820b4ee4795Smrg	    while (qelt) {
821b4ee4795Smrg		if (_XIsEventCookie(dpy, &qelt->event))
822b4ee4795Smrg		    _XStoreEventCookie(dpy, &qelt->event);
823b4ee4795Smrg		qelt = qelt->next;
824b4ee4795Smrg	    }
825b4ee4795Smrg        }
826b4ee4795Smrg	if (dpy->cookiejar)
827b4ee4795Smrg	    _XFreeEventCookies(dpy);
8281ab64890Smrg	while (dpy->ext_procs) {
8291ab64890Smrg	    _XExtension *ext = dpy->ext_procs;
8301ab64890Smrg	    dpy->ext_procs = ext->next;
8311ab64890Smrg	    if (ext->name)
8321ab64890Smrg		Xfree (ext->name);
8331ab64890Smrg	    Xfree ((char *)ext);
8341ab64890Smrg	}
8351ab64890Smrg	if (dpy->im_filters)
8361ab64890Smrg	   (*dpy->free_funcs->im_filters)(dpy);
8371ab64890Smrg	if (dpy->cms.clientCmaps)
8381ab64890Smrg	   (*dpy->free_funcs->clientCmaps)(dpy);
8391ab64890Smrg	if (dpy->cms.defaultCCCs)
8401ab64890Smrg	   (*dpy->free_funcs->defaultCCCs)(dpy);
8411ab64890Smrg	if (dpy->cms.perVisualIntensityMaps)
8421ab64890Smrg	   (*dpy->free_funcs->intensityMaps)(dpy);
8431ab64890Smrg	if (dpy->atoms)
8441ab64890Smrg	    (*dpy->free_funcs->atoms)(dpy);
8451ab64890Smrg	if (dpy->modifiermap)
8461ab64890Smrg	   (*dpy->free_funcs->modifiermap)(dpy->modifiermap);
8471ab64890Smrg	if (dpy->key_bindings)
8481ab64890Smrg	   (*dpy->free_funcs->key_bindings)(dpy);
8491ab64890Smrg	if (dpy->context_db)
8501ab64890Smrg	   (*dpy->free_funcs->context_db)(dpy);
8511ab64890Smrg	if (dpy->xkb_info)
8521ab64890Smrg	   (*dpy->free_funcs->xkb)(dpy);
8531ab64890Smrg
8541ab64890Smrg	/* if RM database was allocated by XGetDefault() free it */
8551ab64890Smrg	if (dpy->db && (dpy->flags & XlibDisplayDfltRMDB))
8561ab64890Smrg	    XrmDestroyDatabase(dpy->db);
8571ab64890Smrg
8581ab64890Smrg	if (dpy->screens) {
8591ab64890Smrg	    register int i;
8601ab64890Smrg
8611ab64890Smrg            for (i = 0; i < dpy->nscreens; i++) {
8621ab64890Smrg		Screen *sp = &dpy->screens[i];
8631ab64890Smrg
8641ab64890Smrg		if (sp->depths) {
8651ab64890Smrg		   register int j;
8661ab64890Smrg
8671ab64890Smrg		   for (j = 0; j < sp->ndepths; j++) {
8681ab64890Smrg			Depth *dp = &sp->depths[j];
8691ab64890Smrg
8701ab64890Smrg			if (dp->visuals) {
8711ab64890Smrg			   register int k;
8721ab64890Smrg
8731ab64890Smrg			   for (k = 0; k < dp->nvisuals; k++)
8741ab64890Smrg			     _XFreeExtData (dp->visuals[k].ext_data);
8751ab64890Smrg			   Xfree ((char *) dp->visuals);
8761ab64890Smrg			   }
8771ab64890Smrg			}
8781ab64890Smrg
8791ab64890Smrg		   Xfree ((char *) sp->depths);
8801ab64890Smrg		   }
8811ab64890Smrg
8821ab64890Smrg		_XFreeExtData (sp->ext_data);
8831ab64890Smrg		}
8841ab64890Smrg
8851ab64890Smrg	    Xfree ((char *)dpy->screens);
8861ab64890Smrg	    }
88761b2299dSmrg
8881ab64890Smrg	if (dpy->pixmap_format) {
8891ab64890Smrg	    register int i;
8901ab64890Smrg
8911ab64890Smrg	    for (i = 0; i < dpy->nformats; i++)
8921ab64890Smrg	      _XFreeExtData (dpy->pixmap_format[i].ext_data);
8931ab64890Smrg            Xfree ((char *)dpy->pixmap_format);
8941ab64890Smrg	    }
8951ab64890Smrg
8961ab64890Smrg	if (dpy->display_name)
8971ab64890Smrg	   Xfree (dpy->display_name);
8981ab64890Smrg	if (dpy->vendor)
8991ab64890Smrg	   Xfree (dpy->vendor);
9001ab64890Smrg
9011ab64890Smrg        if (dpy->buffer)
9021ab64890Smrg	   Xfree (dpy->buffer);
9031ab64890Smrg	if (dpy->keysyms)
9041ab64890Smrg	   Xfree ((char *) dpy->keysyms);
9051ab64890Smrg	if (dpy->xdefaults)
9061ab64890Smrg	   Xfree (dpy->xdefaults);
9071ab64890Smrg	if (dpy->error_vec)
9081ab64890Smrg	    Xfree ((char *)dpy->error_vec);
9091ab64890Smrg
9101ab64890Smrg	_XFreeExtData (dpy->ext_data);
9111ab64890Smrg	if (dpy->free_funcs)
9121ab64890Smrg	    Xfree ((char *)dpy->free_funcs);
9131ab64890Smrg 	if (dpy->scratch_buffer)
9141ab64890Smrg 	    Xfree (dpy->scratch_buffer);
9151ab64890Smrg	FreeDisplayLock(dpy);
9161ab64890Smrg
9171ab64890Smrg	if (dpy->qfree) {
9181ab64890Smrg	    register _XQEvent *qelt = dpy->qfree;
9191ab64890Smrg
9201ab64890Smrg	    while (qelt) {
9211ab64890Smrg		register _XQEvent *qnxt = qelt->next;
9221ab64890Smrg		Xfree ((char *) qelt);
9231ab64890Smrg		qelt = qnxt;
9241ab64890Smrg	    }
9251ab64890Smrg	}
9261ab64890Smrg	while (dpy->im_fd_info) {
9271ab64890Smrg	    struct _XConnectionInfo *conni = dpy->im_fd_info;
9281ab64890Smrg	    dpy->im_fd_info = conni->next;
9291ab64890Smrg	    if (conni->watch_data)
9301ab64890Smrg		Xfree (conni->watch_data);
9311ab64890Smrg	    Xfree (conni);
9321ab64890Smrg	}
9331ab64890Smrg	if (dpy->conn_watchers) {
9341ab64890Smrg	    struct _XConnWatchInfo *watcher = dpy->conn_watchers;
9351ab64890Smrg	    dpy->conn_watchers = watcher->next;
9361ab64890Smrg	    Xfree (watcher);
9371ab64890Smrg	}
9381ab64890Smrg	if (dpy->filedes)
9391ab64890Smrg	    Xfree (dpy->filedes);
9401ab64890Smrg
9411ab64890Smrg#if USE_XCB
9421ab64890Smrg	_XFreeX11XCBStructure(dpy);
9431ab64890Smrg#endif /* USE_XCB */
9441ab64890Smrg
9451ab64890Smrg	Xfree ((char *)dpy);
9461ab64890Smrg}
9471ab64890Smrg
9481ab64890Smrg/* OutOfMemory is called if malloc fails.  XOpenDisplay returns NULL
9491ab64890Smrg   after this returns. */
9501ab64890Smrg
95161b2299dSmrgstatic void OutOfMemory(Display *dpy, char *setup)
9521ab64890Smrg{
9531ab64890Smrg#if USE_XCB
9541ab64890Smrg    if(dpy->xcb->connection)
9551ab64890Smrg	xcb_disconnect(dpy->xcb->connection);
9561ab64890Smrg#else /* !USE_XCB */
9571ab64890Smrg    _XDisconnectDisplay (dpy->trans_conn);
9581ab64890Smrg#endif /* USE_XCB */
9591ab64890Smrg    _XFreeDisplayStructure (dpy);
9601ab64890Smrg#if !USE_XCB
9611ab64890Smrg    if (setup) Xfree (setup);
9621ab64890Smrg#endif /* !USE_XCB */
9631ab64890Smrg}
964