OpenDis.c revision b4ee4795
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#if !USE_XCB
971ab64890Smrg	char *display_name;		/* pointer to display name */
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;
1221ab64890Smrg       long int conn_buf_size;
1231ab64890Smrg       char *xlib_buffer_size;
1241ab64890Smrg
1251ab64890Smrg#if !USE_XCB
1261ab64890Smrg	bzero((char *) &client, sizeof(client));
1271ab64890Smrg	bzero((char *) &prefix, sizeof(prefix));
1281ab64890Smrg
1291ab64890Smrg	/*
13061b2299dSmrg	 * If the display specifier string supplied as an argument to this
1311ab64890Smrg	 * routine is NULL or a pointer to NULL, read the DISPLAY variable.
1321ab64890Smrg	 */
1331ab64890Smrg	if (display == NULL || *display == '\0') {
1341ab64890Smrg		if ((display_name = getenv("DISPLAY")) == NULL) {
1351ab64890Smrg			/* Oops! No DISPLAY environment variable - error. */
1361ab64890Smrg			return(NULL);
1371ab64890Smrg		}
1381ab64890Smrg	}
1391ab64890Smrg	else {
1401ab64890Smrg		/* Display is non-NULL, copy the pointer */
1411ab64890Smrg		display_name = (char *)display;
1421ab64890Smrg	}
1431ab64890Smrg#endif /* !USE_XCB */
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)) {
16761b2299dSmrg		dpy->display_name = fullname;
1682e9c7c8cSmrg		OutOfMemory(dpy, NULL);
1692e9c7c8cSmrg		return NULL;
1701ab64890Smrg	}
1711ab64890Smrg#else /* !USE_XCB */
1721ab64890Smrg	if ((dpy->trans_conn = _X11TransConnectDisplay (
1731ab64890Smrg					 display_name, &fullname, &idisplay,
1741ab64890Smrg					 &iscreen, &conn_auth_name,
1751ab64890Smrg					 &conn_auth_namelen, &conn_auth_data,
1761ab64890Smrg					 &conn_auth_datalen)) == NULL) {
1771ab64890Smrg		Xfree ((char *) dpy);
1781ab64890Smrg		return(NULL);
1791ab64890Smrg	}
1801ab64890Smrg
1811ab64890Smrg	dpy->fd = _X11TransGetConnectionNumber (dpy->trans_conn);
1821ab64890Smrg#endif /* USE_XCB */
1831ab64890Smrg
1841ab64890Smrg	/* Initialize as much of the display structure as we can.
1851ab64890Smrg	 * Initialize pointers to NULL so that XFreeDisplayStructure will
1861ab64890Smrg	 * work if we run out of memory before we finish initializing.
1871ab64890Smrg	 */
1881ab64890Smrg	dpy->display_name	= fullname;
1891ab64890Smrg	dpy->keysyms		= (KeySym *) NULL;
1901ab64890Smrg	dpy->modifiermap	= NULL;
1911ab64890Smrg	dpy->lock_meaning	= NoSymbol;
1921ab64890Smrg	dpy->keysyms_per_keycode = 0;
1931ab64890Smrg	dpy->xdefaults		= (char *)NULL;
1941ab64890Smrg	dpy->scratch_length	= 0L;
1951ab64890Smrg	dpy->scratch_buffer	= NULL;
1961ab64890Smrg	dpy->key_bindings	= NULL;
1971ab64890Smrg	dpy->ext_procs		= (_XExtension *)NULL;
1981ab64890Smrg	dpy->ext_data		= (XExtData *)NULL;
1991ab64890Smrg	dpy->ext_number 	= 0;
2001ab64890Smrg	dpy->event_vec[X_Error] = _XUnknownWireEvent;
2011ab64890Smrg	dpy->event_vec[X_Reply] = _XUnknownWireEvent;
2021ab64890Smrg	dpy->wire_vec[X_Error]  = _XUnknownNativeEvent;
2031ab64890Smrg	dpy->wire_vec[X_Reply]  = _XUnknownNativeEvent;
2041ab64890Smrg	for (i = KeyPress; i < LASTEvent; i++) {
2051ab64890Smrg	    dpy->event_vec[i] 	= _XWireToEvent;
2061ab64890Smrg	    dpy->wire_vec[i] 	= NULL;
2071ab64890Smrg	}
2081ab64890Smrg	for (i = LASTEvent; i < 128; i++) {
2091ab64890Smrg	    dpy->event_vec[i] 	= _XUnknownWireEvent;
2101ab64890Smrg	    dpy->wire_vec[i] 	= _XUnknownNativeEvent;
2111ab64890Smrg	}
2121ab64890Smrg	dpy->resource_id	= 0;
2131ab64890Smrg	dpy->db 		= (struct _XrmHashBucketRec *)NULL;
2141ab64890Smrg	dpy->cursor_font	= None;
2151ab64890Smrg	dpy->flags		= 0;
2161ab64890Smrg	dpy->async_handlers	= NULL;
2171ab64890Smrg	dpy->screens		= NULL;
2181ab64890Smrg	dpy->vendor		= NULL;
2191ab64890Smrg	dpy->buffer		= NULL;
2201ab64890Smrg	dpy->atoms		= NULL;
2211ab64890Smrg	dpy->error_vec		= NULL;
2221ab64890Smrg	dpy->context_db		= NULL;
2231ab64890Smrg	dpy->free_funcs		= NULL;
2241ab64890Smrg	dpy->pixmap_format	= NULL;
2251ab64890Smrg	dpy->cms.clientCmaps	= NULL;
2261ab64890Smrg	dpy->cms.defaultCCCs	= NULL;
2271ab64890Smrg	dpy->cms.perVisualIntensityMaps = NULL;
2281ab64890Smrg	dpy->im_filters		= NULL;
2291ab64890Smrg 	dpy->bigreq_size	= 0;
2301ab64890Smrg	dpy->lock		= NULL;
2311ab64890Smrg	dpy->lock_fns		= NULL;
2321ab64890Smrg	dpy->qfree		= NULL;
2331ab64890Smrg	dpy->next_event_serial_num = 1;
2341ab64890Smrg	dpy->im_fd_info		= NULL;
2351ab64890Smrg	dpy->im_fd_length	= 0;
2361ab64890Smrg	dpy->conn_watchers	= NULL;
2371ab64890Smrg	dpy->watcher_count	= 0;
2381ab64890Smrg	dpy->filedes		= NULL;
2391ab64890Smrg	dpy->flushes		= NULL;
2401ab64890Smrg	dpy->xcmisc_opcode	= 0;
2411ab64890Smrg	dpy->xkb_info		= NULL;
2421ab64890Smrg
2431ab64890Smrg/*
2441ab64890Smrg * Setup other information in this display structure.
2451ab64890Smrg */
2461ab64890Smrg	dpy->vnumber = X_PROTOCOL;
2471ab64890Smrg	dpy->resource_alloc = _XAllocID;
2481ab64890Smrg	dpy->idlist_alloc = _XAllocIDs;
2491ab64890Smrg	dpy->synchandler = NULL;
2501ab64890Smrg	dpy->savedsynchandler = NULL;
2511ab64890Smrg	dpy->request = 0;
2521ab64890Smrg	dpy->last_request_read = 0;
2531ab64890Smrg	dpy->default_screen = iscreen;  /* Value returned by ConnectDisplay */
2541ab64890Smrg	dpy->last_req = (char *)&_dummy_request;
2551ab64890Smrg
2561ab64890Smrg	/* Initialize the display lock */
2571ab64890Smrg	if (InitDisplayLock(dpy) != 0) {
2581ab64890Smrg	        OutOfMemory (dpy, setup);
2591ab64890Smrg		return(NULL);
2601ab64890Smrg	}
2611ab64890Smrg
2621ab64890Smrg	if (!_XPollfdCacheInit(dpy)) {
2631ab64890Smrg	        OutOfMemory (dpy, setup);
2641ab64890Smrg		return(NULL);
26561b2299dSmrg	}
2661ab64890Smrg
2671ab64890Smrg	/* Set up the output buffers. */
2681ab64890Smrg#ifndef XLIBDEFAULTBUFSIZE
2691ab64890Smrg#define XLIBDEFAULTBUFSIZE 16384 /* 16k */
2701ab64890Smrg#endif
2711ab64890Smrg#ifndef XLIBMINBUFSIZE
2721ab64890Smrg#define XLIBMINBUFSIZE BUFSIZE /* old default buffer size */
2731ab64890Smrg#endif
274b4ee4795Smrg	xlib_buffer_size = getenv("XLIBBUFFERSIZE");
275b4ee4795Smrg
276b4ee4795Smrg#ifdef __sun /* Backwards compatibility for old Solaris libX11 name */
277b4ee4795Smrg	if (xlib_buffer_size == NULL)
278b4ee4795Smrg	    xlib_buffer_size = getenv("XSUNBUFFERSIZE");
279b4ee4795Smrg#endif
280b4ee4795Smrg
281b4ee4795Smrg	if (xlib_buffer_size == NULL)
282b4ee4795Smrg	    conn_buf_size = XLIBDEFAULTBUFSIZE;
283b4ee4795Smrg	else
284b4ee4795Smrg	    conn_buf_size = 1024 * strtol(xlib_buffer_size, NULL, 10);
285b4ee4795Smrg	if (conn_buf_size < XLIBMINBUFSIZE)
286b4ee4795Smrg	    conn_buf_size = XLIBMINBUFSIZE;
287b4ee4795Smrg
288b4ee4795Smrg	if ((dpy->bufptr = dpy->buffer = Xcalloc(1, conn_buf_size)) == NULL) {
289b4ee4795Smrg	    OutOfMemory (dpy, setup);
290b4ee4795Smrg	    return(NULL);
291b4ee4795Smrg	}
292b4ee4795Smrg	dpy->bufmax = dpy->buffer + conn_buf_size;
29361b2299dSmrg#if USE_XCB
294b4ee4795Smrg	dpy->xcb->real_bufmax = dpy->bufmax;
295b4ee4795Smrg	dpy->bufmax = dpy->buffer;
29661b2299dSmrg#endif
29761b2299dSmrg
2981ab64890Smrg	/* Set up the input event queue and input event queue parameters. */
2991ab64890Smrg	dpy->head = dpy->tail = NULL;
3001ab64890Smrg	dpy->qlen = 0;
3011ab64890Smrg
3021ab64890Smrg	/* Set up free-function record */
3031ab64890Smrg	if ((dpy->free_funcs = (_XFreeFuncRec *)Xcalloc(1,
3041ab64890Smrg							sizeof(_XFreeFuncRec)))
3051ab64890Smrg	    == NULL) {
3061ab64890Smrg	    OutOfMemory (dpy, setup);
3071ab64890Smrg	    return(NULL);
3081ab64890Smrg	}
3091ab64890Smrg
3101ab64890Smrg#if !USE_XCB
3111ab64890Smrg/*
3121ab64890Smrg * The xConnClientPrefix describes the initial connection setup information
3131ab64890Smrg * and is followed by the authorization information.  Sites that are interested
31461b2299dSmrg * in security are strongly encouraged to use an authentication and
3151ab64890Smrg * authorization system such as Kerberos.
3161ab64890Smrg */
3171ab64890Smrg	endian = 1;
3181ab64890Smrg	if (*(char *) &endian)
3191ab64890Smrg	    client.byteOrder = '\154'; /* 'l' */
3201ab64890Smrg	else
3211ab64890Smrg	    client.byteOrder = '\102'; /* 'B' */
3221ab64890Smrg	client.majorVersion = X_PROTOCOL;
3231ab64890Smrg	client.minorVersion = X_PROTOCOL_REVISION;
3241ab64890Smrg	client.nbytesAuthProto = conn_auth_namelen;
3251ab64890Smrg	client.nbytesAuthString = conn_auth_datalen;
3261ab64890Smrg	prefixread = _XSendClientPrefix(dpy, &client,
3271ab64890Smrg					conn_auth_name, conn_auth_data,
3281ab64890Smrg					&prefix);
3291ab64890Smrg	if (prefixread < 0)
3301ab64890Smrg	{
3311ab64890Smrg	    _XDisconnectDisplay (dpy->trans_conn);
3321ab64890Smrg	    Xfree ((char *)dpy);
3331ab64890Smrg	    return(NULL);
3341ab64890Smrg	}
3351ab64890Smrg	if (conn_auth_name) Xfree(conn_auth_name);
3361ab64890Smrg	if (conn_auth_data) Xfree(conn_auth_data);
3371ab64890Smrg/*
3381ab64890Smrg * Now see if connection was accepted...
3391ab64890Smrg */
3401ab64890Smrg	/* these internal functions expect the display to be locked */
3411ab64890Smrg	LockDisplay(dpy);
3421ab64890Smrg
3431ab64890Smrg	if (prefixread == 0)
3441ab64890Smrg	    _XRead (dpy, (char *)&prefix,(long)SIZEOF(xConnSetupPrefix));
3451ab64890Smrg
3461ab64890Smrg	/* an Authenticate reply we weren't expecting? */
3471ab64890Smrg	if (prefix.success != xTrue && prefix.success != xFalse) {
3481ab64890Smrg	    fprintf (stderr,
3491ab64890Smrg      "Xlib: unexpected connection setup reply from server, type %d.\r\n",
3501ab64890Smrg		     prefix.success);
3511ab64890Smrg	    _XDisconnectDisplay (dpy->trans_conn);
3521ab64890Smrg	    Xfree ((char *)dpy);
3531ab64890Smrg	    return(NULL);
3541ab64890Smrg	}
3551ab64890Smrg
3561ab64890Smrg	if (prefix.majorVersion != X_PROTOCOL) {
3571ab64890Smrg	    /* XXX - printing messages marks a bad programming interface */
3581ab64890Smrg	    fprintf (stderr,
3591ab64890Smrg     "Xlib: client uses different protocol version (%d) than server (%d)!\r\n",
3601ab64890Smrg		     X_PROTOCOL, prefix.majorVersion);
3611ab64890Smrg	    _XDisconnectDisplay (dpy->trans_conn);
3621ab64890Smrg	    Xfree ((char *)dpy);
3631ab64890Smrg	    return(NULL);
3641ab64890Smrg	}
3651ab64890Smrg#endif /* !USE_XCB */
3661ab64890Smrg
3671ab64890Smrg#if USE_XCB
3681ab64890Smrg	{
3691ab64890Smrg		const struct xcb_setup_t *xcbsetup = xcb_get_setup(dpy->xcb->connection);
3701ab64890Smrg		memcpy(&prefix, xcbsetup, sizeof(prefix));
3711ab64890Smrg		setuplength = prefix.length << 2;
3721ab64890Smrg		setup = (char *) xcbsetup;
3731ab64890Smrg		setup += SIZEOF(xConnSetupPrefix);
3741ab64890Smrg		u.setup = (xConnSetup *) setup;
3751ab64890Smrg	}
3761ab64890Smrg#else /* !USE_XCB */
3771ab64890Smrg	setuplength = prefix.length << 2;
3781ab64890Smrg	if ( (u.setup = (xConnSetup *)
3791ab64890Smrg	      (setup =  Xmalloc ((unsigned) setuplength))) == NULL) {
3801ab64890Smrg		_XDisconnectDisplay (dpy->trans_conn);
3811ab64890Smrg		Xfree ((char *)dpy);
3821ab64890Smrg		return(NULL);
3831ab64890Smrg	}
3841ab64890Smrg	_XRead (dpy, (char *)u.setup, setuplength);
3851ab64890Smrg
3861ab64890Smrg/*
3871ab64890Smrg * If the connection was not accepted by the server due to problems,
3881ab64890Smrg * give error message to the user....
3891ab64890Smrg */
3901ab64890Smrg	if (prefix.success != xTrue) {
3911ab64890Smrg		/* XXX - printing messages marks a bad programming interface */
39261b2299dSmrg		fprintf (stderr,
3931ab64890Smrg		      "Xlib: connection to \"%s\" refused by server\r\nXlib: ",
3941ab64890Smrg			 fullname);
3951ab64890Smrg
3961ab64890Smrg		if (prefix.lengthReason > setuplength) {
3971ab64890Smrg		    fprintf (stderr, "Xlib: Broken initial reply: length of reason > length of packet\r\n");
3981ab64890Smrg		}else{
3991ab64890Smrg		    (void) fwrite (u.failure, (Size_t)sizeof(char),
4001ab64890Smrg			       (Size_t)prefix.lengthReason, stderr);
4011ab64890Smrg		    (void) fwrite ("\r\n", sizeof(char), 2, stderr);
4021ab64890Smrg		}
4031ab64890Smrg
4041ab64890Smrg		OutOfMemory(dpy, setup);
4051ab64890Smrg		return (NULL);
4061ab64890Smrg	}
4071ab64890Smrg#endif /* USE_XCB */
4081ab64890Smrg
4091ab64890Smrg/*
4101ab64890Smrg * Check if the reply was long enough to get any information out of it.
4111ab64890Smrg */
4121ab64890Smrg	usedbytes = sz_xConnSetup;
4131ab64890Smrg	if (setuplength < usedbytes ) {
4141ab64890Smrg	    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
4151ab64890Smrg	    OutOfMemory(dpy, setup);
4161ab64890Smrg	    return (NULL);
4171ab64890Smrg	}
4181ab64890Smrg
4191ab64890Smrg/*
4201ab64890Smrg * We succeeded at authorization, so let us move the data into
4211ab64890Smrg * the display structure.
4221ab64890Smrg */
4231ab64890Smrg	dpy->proto_major_version= prefix.majorVersion;
4241ab64890Smrg	dpy->proto_minor_version= prefix.minorVersion;
4251ab64890Smrg	dpy->release 		= u.setup->release;
4261ab64890Smrg	dpy->resource_base	= u.setup->ridBase;
4271ab64890Smrg	dpy->resource_mask	= u.setup->ridMask;
4281ab64890Smrg	dpy->min_keycode	= u.setup->minKeyCode;
4291ab64890Smrg	dpy->max_keycode	= u.setup->maxKeyCode;
4301ab64890Smrg	dpy->motion_buffer	= u.setup->motionBufferSize;
4311ab64890Smrg	dpy->nformats		= u.setup->numFormats;
4321ab64890Smrg	dpy->nscreens		= u.setup->numRoots;
4331ab64890Smrg	dpy->byte_order		= u.setup->imageByteOrder;
4341ab64890Smrg	dpy->bitmap_unit	= u.setup->bitmapScanlineUnit;
4351ab64890Smrg	dpy->bitmap_pad		= u.setup->bitmapScanlinePad;
4361ab64890Smrg	dpy->bitmap_bit_order   = u.setup->bitmapBitOrder;
4371ab64890Smrg	dpy->max_request_size	= u.setup->maxRequestSize;
4381ab64890Smrg	mask = dpy->resource_mask;
4391ab64890Smrg	dpy->resource_shift	= 0;
4401ab64890Smrg	if (!mask)
4411ab64890Smrg	{
4421ab64890Smrg	    fprintf (stderr, "Xlib: connection to \"%s\" invalid setup\n",
4431ab64890Smrg		     fullname);
4441ab64890Smrg	    OutOfMemory(dpy, setup);
4451ab64890Smrg	    return (NULL);
4461ab64890Smrg	}
44761b2299dSmrg
4481ab64890Smrg	while (!(mask & 1)) {
4491ab64890Smrg	    dpy->resource_shift++;
4501ab64890Smrg	    mask = mask >> 1;
4511ab64890Smrg	}
4521ab64890Smrg	dpy->resource_max = (dpy->resource_mask >> dpy->resource_shift) - 5;
4531ab64890Smrg/*
4541ab64890Smrg * now extract the vendor string...  String must be null terminated,
4551ab64890Smrg * padded to multiple of 4 bytes.
4561ab64890Smrg */
4571ab64890Smrg	/* Check for a sane vendor string length */
4581ab64890Smrg	if (u.setup->nbytesVendor > 256) {
4591ab64890Smrg	    OutOfMemory(dpy, setup);
4601ab64890Smrg	    return (NULL);
4611ab64890Smrg	}
4621ab64890Smrg
4631ab64890Smrg	dpy->vendor = (char *) Xmalloc((unsigned) (u.setup->nbytesVendor + 1));
4641ab64890Smrg	if (dpy->vendor == NULL) {
4651ab64890Smrg	    OutOfMemory(dpy, setup);
4661ab64890Smrg	    return (NULL);
4671ab64890Smrg	}
4681ab64890Smrg	vendorlen = u.setup->nbytesVendor;
4691ab64890Smrg
4701ab64890Smrg/*
4711ab64890Smrg * validate setup length
4721ab64890Smrg */
4731ab64890Smrg	usedbytes += (vendorlen + 3) & ~3;
4741ab64890Smrg	if (setuplength < usedbytes) {
4751ab64890Smrg	    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
4761ab64890Smrg	    OutOfMemory(dpy, setup);
4771ab64890Smrg	    return (NULL);
4781ab64890Smrg	}
4791ab64890Smrg
4801ab64890Smrg 	u.setup = (xConnSetup *) (((char *) u.setup) + sz_xConnSetup);
4811ab64890Smrg  	(void) strncpy(dpy->vendor, u.vendor, vendorlen);
4821ab64890Smrg	dpy->vendor[vendorlen] = '\0';
4831ab64890Smrg 	vendorlen = (vendorlen + 3) & ~3;	/* round up */
4841ab64890Smrg	u.vendor += vendorlen;
4851ab64890Smrg
4861ab64890Smrg/*
4871ab64890Smrg * Now iterate down setup information.....
4881ab64890Smrg */
48961b2299dSmrg	dpy->pixmap_format =
4901ab64890Smrg	    (ScreenFormat *)Xmalloc(
4911ab64890Smrg		(unsigned) (dpy->nformats *sizeof(ScreenFormat)));
4921ab64890Smrg	if (dpy->pixmap_format == NULL) {
4931ab64890Smrg	        OutOfMemory (dpy, setup);
4941ab64890Smrg		return(NULL);
4951ab64890Smrg	}
4961ab64890Smrg/*
4971ab64890Smrg * First decode the Z axis Screen format information.
4981ab64890Smrg */
4991ab64890Smrg	usedbytes += dpy->nformats * sz_xPixmapFormat;
5001ab64890Smrg
5011ab64890Smrg	if (setuplength < usedbytes) {
5021ab64890Smrg	    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
5031ab64890Smrg	    OutOfMemory (dpy, setup);
5041ab64890Smrg	    return(NULL);
5051ab64890Smrg	}
5061ab64890Smrg
5071ab64890Smrg	for (i = 0; i < dpy->nformats; i++) {
5081ab64890Smrg	    register ScreenFormat *fmt = &dpy->pixmap_format[i];
5091ab64890Smrg	    fmt->depth = u.sf->depth;
5101ab64890Smrg	    fmt->bits_per_pixel = u.sf->bitsPerPixel;
5111ab64890Smrg	    fmt->scanline_pad = u.sf->scanLinePad;
5121ab64890Smrg	    fmt->ext_data = NULL;
5131ab64890Smrg	    u.sf = (xPixmapFormat *) (((char *) u.sf) + sz_xPixmapFormat);
5141ab64890Smrg	}
5151ab64890Smrg
5161ab64890Smrg/*
5171ab64890Smrg * next the Screen structures.
5181ab64890Smrg */
51961b2299dSmrg	dpy->screens =
5201ab64890Smrg	    (Screen *)Xmalloc((unsigned) dpy->nscreens*sizeof(Screen));
5211ab64890Smrg	if (dpy->screens == NULL) {
5221ab64890Smrg	        OutOfMemory (dpy, setup);
5231ab64890Smrg		return(NULL);
5241ab64890Smrg	}
5251ab64890Smrg
5261ab64890Smrg/*
5271ab64890Smrg * Now go deal with each screen structure.
5281ab64890Smrg */
5291ab64890Smrg	for (i = 0; i < dpy->nscreens; i++) {
5301ab64890Smrg	    register Screen *sp = &dpy->screens[i];
5311ab64890Smrg	    VisualID root_visualID;
5321ab64890Smrg
5331ab64890Smrg	    usedbytes += sz_xWindowRoot;
5341ab64890Smrg	    if (setuplength < usedbytes) {
5351ab64890Smrg		fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
5361ab64890Smrg		OutOfMemory (dpy, setup);
5371ab64890Smrg		return(NULL);
5381ab64890Smrg	    }
5391ab64890Smrg
54061b2299dSmrg	    root_visualID = u.rp->rootVisualID;
5411ab64890Smrg	    sp->display	    = dpy;
5421ab64890Smrg	    sp->root 	    = u.rp->windowId;
5431ab64890Smrg	    sp->cmap 	    = u.rp->defaultColormap;
5441ab64890Smrg	    sp->white_pixel = u.rp->whitePixel;
5451ab64890Smrg	    sp->black_pixel = u.rp->blackPixel;
5461ab64890Smrg	    sp->root_input_mask = u.rp->currentInputMask;
5471ab64890Smrg	    sp->width	    = u.rp->pixWidth;
5481ab64890Smrg	    sp->height	    = u.rp->pixHeight;
5491ab64890Smrg	    sp->mwidth	    = u.rp->mmWidth;
5501ab64890Smrg	    sp->mheight	    = u.rp->mmHeight;
5511ab64890Smrg	    sp->min_maps    = u.rp->minInstalledMaps;
5521ab64890Smrg	    sp->max_maps    = u.rp->maxInstalledMaps;
5531ab64890Smrg	    sp->backing_store= u.rp->backingStore;
5541ab64890Smrg	    sp->save_unders = u.rp->saveUnders;
5551ab64890Smrg	    sp->root_depth  = u.rp->rootDepth;
5561ab64890Smrg	    sp->ndepths	    = u.rp->nDepths;
5571ab64890Smrg	    sp->ext_data   = NULL;
5581ab64890Smrg	    u.rp = (xWindowRoot *) (((char *) u.rp) + sz_xWindowRoot);
5591ab64890Smrg/*
5601ab64890Smrg * lets set up the depth structures.
5611ab64890Smrg */
5621ab64890Smrg	    sp->depths = (Depth *)Xmalloc(
5631ab64890Smrg			(unsigned)sp->ndepths*sizeof(Depth));
5641ab64890Smrg	    if (sp->depths == NULL) {
5651ab64890Smrg		OutOfMemory (dpy, setup);
5661ab64890Smrg		return(NULL);
5671ab64890Smrg	    }
5681ab64890Smrg	    /*
5691ab64890Smrg	     * for all depths on this screen.
5701ab64890Smrg	     */
5711ab64890Smrg	    for (j = 0; j < sp->ndepths; j++) {
5721ab64890Smrg		Depth *dp = &sp->depths[j];
5731ab64890Smrg
5741ab64890Smrg		usedbytes += sz_xDepth;
5751ab64890Smrg		if (setuplength < usedbytes) {
5761ab64890Smrg		    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
5771ab64890Smrg		    OutOfMemory (dpy, setup);
5781ab64890Smrg		    return(NULL);
5791ab64890Smrg		}
58061b2299dSmrg
5811ab64890Smrg		dp->depth = u.dp->depth;
5821ab64890Smrg		dp->nvisuals = u.dp->nVisuals;
5831ab64890Smrg		u.dp = (xDepth *) (((char *) u.dp) + sz_xDepth);
5841ab64890Smrg		if (dp->nvisuals > 0) {
58561b2299dSmrg		    dp->visuals =
5861ab64890Smrg		      (Visual *)Xmalloc((unsigned)dp->nvisuals*sizeof(Visual));
5871ab64890Smrg		    if (dp->visuals == NULL) {
5881ab64890Smrg			OutOfMemory (dpy, setup);
5891ab64890Smrg			return(NULL);
5901ab64890Smrg		    }
5911ab64890Smrg		    for (k = 0; k < dp->nvisuals; k++) {
5921ab64890Smrg			register Visual *vp = &dp->visuals[k];
5931ab64890Smrg
5941ab64890Smrg			usedbytes += sz_xVisualType;
5951ab64890Smrg			if (setuplength < usedbytes) {
5961ab64890Smrg			    fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);
5971ab64890Smrg			    OutOfMemory (dpy, setup);
5981ab64890Smrg			    return(NULL);
5991ab64890Smrg			}
60061b2299dSmrg
6011ab64890Smrg			vp->visualid	= u.vp->visualID;
6021ab64890Smrg			vp->class	= u.vp->class;
6031ab64890Smrg			vp->bits_per_rgb= u.vp->bitsPerRGB;
6041ab64890Smrg			vp->map_entries	= u.vp->colormapEntries;
6051ab64890Smrg			vp->red_mask	= u.vp->redMask;
6061ab64890Smrg			vp->green_mask	= u.vp->greenMask;
6071ab64890Smrg			vp->blue_mask	= u.vp->blueMask;
6081ab64890Smrg			vp->ext_data	= NULL;
6091ab64890Smrg			u.vp = (xVisualType *) (((char *) u.vp) +
6101ab64890Smrg						sz_xVisualType);
6111ab64890Smrg		    }
6121ab64890Smrg		    if (dp->depth == 32 && getenv ("XLIB_SKIP_ARGB_VISUALS"))
6131ab64890Smrg		    {
6141ab64890Smrg			Xfree (dp->visuals);
6151ab64890Smrg			dp->visuals = NULL;
6161ab64890Smrg			dp->nvisuals = 0;
6171ab64890Smrg		    }
6181ab64890Smrg		} else {
6191ab64890Smrg		    dp->visuals = (Visual *) NULL;
6201ab64890Smrg		}
6211ab64890Smrg	    }
6221ab64890Smrg	    sp->root_visual = _XVIDtoVisual(dpy, root_visualID);
6231ab64890Smrg	}
6241ab64890Smrg
6251ab64890Smrg	if(usedbytes != setuplength){
6261ab64890Smrg	    /* Sanity check, shouldn't happen. */
6271ab64890Smrg	    fprintf(stderr, "Xlib: Did not parse entire setup message: "
6281ab64890Smrg	                    "parsed: %ld, message: %ld\n",
6291ab64890Smrg		    usedbytes, setuplength);
6301ab64890Smrg	    OutOfMemory(dpy, setup);
6311ab64890Smrg	    return(NULL);
6321ab64890Smrg	}
6331ab64890Smrg
6341ab64890Smrg/*
6351ab64890Smrg * Now start talking to the server to setup all other information...
6361ab64890Smrg */
6371ab64890Smrg
6381ab64890Smrg#if !USE_XCB
6391ab64890Smrg	Xfree (setup);	/* all finished with setup information */
6401ab64890Smrg#endif /* !USE_XCB */
6411ab64890Smrg
6421ab64890Smrg/*
6431ab64890Smrg * Make sure default screen is legal.
6441ab64890Smrg */
6451ab64890Smrg	if (iscreen >= dpy->nscreens) {
6461ab64890Smrg	    OutOfMemory(dpy, (char *) NULL);
6471ab64890Smrg	    return(NULL);
6481ab64890Smrg	}
6491ab64890Smrg
6501ab64890Smrg#if !USE_XCB
6511ab64890Smrg/*
6521ab64890Smrg * finished calling internal routines, now unlock for external routines
6531ab64890Smrg */
6541ab64890Smrg	UnlockDisplay(dpy);
6551ab64890Smrg#endif /* !USE_XCB */
6561ab64890Smrg
65761b2299dSmrg#if USE_XCB
65861b2299dSmrg	dpy->bigreq_size = xcb_get_maximum_request_length(dpy->xcb->connection);
65961b2299dSmrg	if(dpy->bigreq_size <= dpy->max_request_size)
66061b2299dSmrg		dpy->bigreq_size = 0;
66161b2299dSmrg#endif /* USE_XCB */
66261b2299dSmrg
6631ab64890Smrg/*
6641ab64890Smrg * Set up other stuff clients are always going to use.
6651ab64890Smrg */
6661ab64890Smrg	for (i = 0; i < dpy->nscreens; i++) {
6671ab64890Smrg	    register Screen *sp = &dpy->screens[i];
6681ab64890Smrg	    XGCValues values;
6691ab64890Smrg	    values.foreground = sp->black_pixel;
6701ab64890Smrg	    values.background = sp->white_pixel;
6711ab64890Smrg	    if ((sp->default_gc = XCreateGC (dpy, sp->root,
6721ab64890Smrg					     GCForeground|GCBackground,
6731ab64890Smrg					     &values)) == NULL) {
6741ab64890Smrg		OutOfMemory(dpy, (char *) NULL);
6751ab64890Smrg		return (NULL);
6761ab64890Smrg	    }
6771ab64890Smrg	}
6781ab64890Smrg/*
6791ab64890Smrg * call into synchronization routine so that all programs can be
6801ab64890Smrg * forced synchronous
6811ab64890Smrg */
6821ab64890Smrg	(void) XSynchronize(dpy, _Xdebug);
6831ab64890Smrg
6841ab64890Smrg/*
6851ab64890Smrg * get availability of large requests, and
6861ab64890Smrg * get the resource manager database off the root window.
6871ab64890Smrg */
6881ab64890Smrg	LockDisplay(dpy);
6891ab64890Smrg	{
6901ab64890Smrg	    xGetPropertyReply reply;
6911ab64890Smrg	    xGetPropertyReq *req;
6921ab64890Smrg#if !USE_XCB
6931ab64890Smrg	    _XAsyncHandler async;
6941ab64890Smrg	    _XBigReqState async_state;
6951ab64890Smrg	    xQueryExtensionReq *qreq;
6961ab64890Smrg	    xBigReqEnableReq *breq;
6971ab64890Smrg	    xBigReqEnableReply brep;
6981ab64890Smrg
6991ab64890Smrg	    GetReq(QueryExtension, qreq);
7001ab64890Smrg	    async_state.seq = dpy->request;
7011ab64890Smrg	    async_state.opcode = 0;
7021ab64890Smrg	    async.next = dpy->async_handlers;
7031ab64890Smrg	    async.handler = _XBigReqHandler;
7041ab64890Smrg	    async.data = (XPointer)&async_state;
7051ab64890Smrg	    dpy->async_handlers = &async;
7061ab64890Smrg	    qreq->nbytes = bignamelen;
7071ab64890Smrg	    qreq->length += (bignamelen+3)>>2;
7081ab64890Smrg	    Data(dpy, XBigReqExtensionName, bignamelen);
7091ab64890Smrg#endif /* !USE_XCB */
7101ab64890Smrg
7111ab64890Smrg	    GetReq (GetProperty, req);
7121ab64890Smrg	    req->window = RootWindow(dpy, 0);
7131ab64890Smrg	    req->property = XA_RESOURCE_MANAGER;
7141ab64890Smrg	    req->type = XA_STRING;
7151ab64890Smrg	    req->delete = False;
7161ab64890Smrg	    req->longOffset = 0;
7171ab64890Smrg	    req->longLength = 100000000L;
7181ab64890Smrg
7191ab64890Smrg	    if (_XReply (dpy, (xReply *) &reply, 0, xFalse)) {
7201ab64890Smrg		if (reply.format == 8 && reply.propertyType == XA_STRING &&
7211ab64890Smrg		    (reply.nItems + 1 > 0) &&
7221ab64890Smrg		    (reply.nItems <= req->longLength * 4) &&
7231ab64890Smrg		    (dpy->xdefaults = Xmalloc (reply.nItems + 1))) {
7241ab64890Smrg		    _XReadPad (dpy, dpy->xdefaults, reply.nItems);
7251ab64890Smrg		    dpy->xdefaults[reply.nItems] = '\0';
7261ab64890Smrg		}
7271ab64890Smrg		else if (reply.propertyType != None)
7281ab64890Smrg		    _XEatData(dpy, reply.nItems * (reply.format >> 3));
7291ab64890Smrg	    }
7301ab64890Smrg#if !USE_XCB
7311ab64890Smrg	    DeqAsyncHandler(dpy, &async);
7321ab64890Smrg	    if (async_state.opcode) {
7331ab64890Smrg		GetReq(BigReqEnable, breq);
7341ab64890Smrg		breq->reqType = async_state.opcode;
7351ab64890Smrg		breq->brReqType = X_BigReqEnable;
7361ab64890Smrg		if (_XReply(dpy, (xReply *)&brep, 0, xFalse))
7371ab64890Smrg		    dpy->bigreq_size = brep.max_request_size;
7381ab64890Smrg	    }
7391ab64890Smrg#endif /* !USE_XCB */
7401ab64890Smrg	}
7411ab64890Smrg	UnlockDisplay(dpy);
7421ab64890Smrg
7431ab64890Smrg#ifdef MOTIFBC
7441ab64890Smrg	{
7451ab64890Smrg	    extern Display *_XHeadOfDisplayList;
7461ab64890Smrg	    _XHeadOfDisplayList = dpy;
7471ab64890Smrg	}
7481ab64890Smrg#endif
7491ab64890Smrg#ifdef XKB
7501ab64890Smrg	XkbUseExtension(dpy,NULL,NULL);
7511ab64890Smrg#endif
7521ab64890Smrg/*
7531ab64890Smrg * and return successfully
7541ab64890Smrg */
7551ab64890Smrg 	return(dpy);
7561ab64890Smrg}
7571ab64890Smrg
7581ab64890Smrg#if !USE_XCB
7591ab64890Smrgstatic Bool
7601ab64890Smrg_XBigReqHandler(
7611ab64890Smrg    register Display *dpy,
7621ab64890Smrg    register xReply *rep,
7631ab64890Smrg    char *buf,
7641ab64890Smrg    int len,
7651ab64890Smrg    XPointer data)
7661ab64890Smrg{
7671ab64890Smrg    _XBigReqState *state;
7681ab64890Smrg    xQueryExtensionReply replbuf;
7691ab64890Smrg    xQueryExtensionReply *repl;
7701ab64890Smrg
7711ab64890Smrg    state = (_XBigReqState *)data;
7721ab64890Smrg    if (dpy->last_request_read != state->seq)
7731ab64890Smrg	return False;
7741ab64890Smrg    if (rep->generic.type == X_Error)
7751ab64890Smrg	return True;
7761ab64890Smrg    repl = (xQueryExtensionReply *)
7771ab64890Smrg	_XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
7781ab64890Smrg			(SIZEOF(xQueryExtensionReply) - SIZEOF(xReply)) >> 2,
7791ab64890Smrg			True);
7801ab64890Smrg    if (repl->present)
7811ab64890Smrg	state->opcode = repl->major_opcode;
7821ab64890Smrg    return True;
7831ab64890Smrg}
7841ab64890Smrg#endif /* !USE_XCB */
7851ab64890Smrg
7861ab64890Smrg
78761b2299dSmrg/* XFreeDisplayStructure frees all the storage associated with a
7881ab64890Smrg * Display.  It is used by XOpenDisplay if it runs out of memory,
7891ab64890Smrg * and also by XCloseDisplay.   It needs to check whether all pointers
7901ab64890Smrg * are non-NULL before dereferencing them, since it may be called
7911ab64890Smrg * by XOpenDisplay before the Display structure is fully formed.
7921ab64890Smrg * XOpenDisplay must be sure to initialize all the pointers to NULL
7931ab64890Smrg * before the first possible call on this.
7941ab64890Smrg */
7951ab64890Smrg
79661b2299dSmrgvoid _XFreeDisplayStructure(Display *dpy)
7971ab64890Smrg{
798b4ee4795Smrg	/* move all cookies in the EQ to the jar, then free them. */
799b4ee4795Smrg	if (dpy->qfree) {
800b4ee4795Smrg	    _XQEvent *qelt = dpy->qfree;
801b4ee4795Smrg	    while (qelt) {
802b4ee4795Smrg		if (_XIsEventCookie(dpy, &qelt->event))
803b4ee4795Smrg		    _XStoreEventCookie(dpy, &qelt->event);
804b4ee4795Smrg		qelt = qelt->next;
805b4ee4795Smrg	    }
806b4ee4795Smrg        }
807b4ee4795Smrg	if (dpy->cookiejar)
808b4ee4795Smrg	    _XFreeEventCookies(dpy);
8091ab64890Smrg	while (dpy->ext_procs) {
8101ab64890Smrg	    _XExtension *ext = dpy->ext_procs;
8111ab64890Smrg	    dpy->ext_procs = ext->next;
8121ab64890Smrg	    if (ext->name)
8131ab64890Smrg		Xfree (ext->name);
8141ab64890Smrg	    Xfree ((char *)ext);
8151ab64890Smrg	}
8161ab64890Smrg	if (dpy->im_filters)
8171ab64890Smrg	   (*dpy->free_funcs->im_filters)(dpy);
8181ab64890Smrg	if (dpy->cms.clientCmaps)
8191ab64890Smrg	   (*dpy->free_funcs->clientCmaps)(dpy);
8201ab64890Smrg	if (dpy->cms.defaultCCCs)
8211ab64890Smrg	   (*dpy->free_funcs->defaultCCCs)(dpy);
8221ab64890Smrg	if (dpy->cms.perVisualIntensityMaps)
8231ab64890Smrg	   (*dpy->free_funcs->intensityMaps)(dpy);
8241ab64890Smrg	if (dpy->atoms)
8251ab64890Smrg	    (*dpy->free_funcs->atoms)(dpy);
8261ab64890Smrg	if (dpy->modifiermap)
8271ab64890Smrg	   (*dpy->free_funcs->modifiermap)(dpy->modifiermap);
8281ab64890Smrg	if (dpy->key_bindings)
8291ab64890Smrg	   (*dpy->free_funcs->key_bindings)(dpy);
8301ab64890Smrg	if (dpy->context_db)
8311ab64890Smrg	   (*dpy->free_funcs->context_db)(dpy);
8321ab64890Smrg	if (dpy->xkb_info)
8331ab64890Smrg	   (*dpy->free_funcs->xkb)(dpy);
8341ab64890Smrg
8351ab64890Smrg	/* if RM database was allocated by XGetDefault() free it */
8361ab64890Smrg	if (dpy->db && (dpy->flags & XlibDisplayDfltRMDB))
8371ab64890Smrg	    XrmDestroyDatabase(dpy->db);
8381ab64890Smrg
8391ab64890Smrg	if (dpy->screens) {
8401ab64890Smrg	    register int i;
8411ab64890Smrg
8421ab64890Smrg            for (i = 0; i < dpy->nscreens; i++) {
8431ab64890Smrg		Screen *sp = &dpy->screens[i];
8441ab64890Smrg
8451ab64890Smrg		if (sp->depths) {
8461ab64890Smrg		   register int j;
8471ab64890Smrg
8481ab64890Smrg		   for (j = 0; j < sp->ndepths; j++) {
8491ab64890Smrg			Depth *dp = &sp->depths[j];
8501ab64890Smrg
8511ab64890Smrg			if (dp->visuals) {
8521ab64890Smrg			   register int k;
8531ab64890Smrg
8541ab64890Smrg			   for (k = 0; k < dp->nvisuals; k++)
8551ab64890Smrg			     _XFreeExtData (dp->visuals[k].ext_data);
8561ab64890Smrg			   Xfree ((char *) dp->visuals);
8571ab64890Smrg			   }
8581ab64890Smrg			}
8591ab64890Smrg
8601ab64890Smrg		   Xfree ((char *) sp->depths);
8611ab64890Smrg		   }
8621ab64890Smrg
8631ab64890Smrg		_XFreeExtData (sp->ext_data);
8641ab64890Smrg		}
8651ab64890Smrg
8661ab64890Smrg	    Xfree ((char *)dpy->screens);
8671ab64890Smrg	    }
86861b2299dSmrg
8691ab64890Smrg	if (dpy->pixmap_format) {
8701ab64890Smrg	    register int i;
8711ab64890Smrg
8721ab64890Smrg	    for (i = 0; i < dpy->nformats; i++)
8731ab64890Smrg	      _XFreeExtData (dpy->pixmap_format[i].ext_data);
8741ab64890Smrg            Xfree ((char *)dpy->pixmap_format);
8751ab64890Smrg	    }
8761ab64890Smrg
8771ab64890Smrg	if (dpy->display_name)
8781ab64890Smrg	   Xfree (dpy->display_name);
8791ab64890Smrg	if (dpy->vendor)
8801ab64890Smrg	   Xfree (dpy->vendor);
8811ab64890Smrg
8821ab64890Smrg        if (dpy->buffer)
8831ab64890Smrg	   Xfree (dpy->buffer);
8841ab64890Smrg	if (dpy->keysyms)
8851ab64890Smrg	   Xfree ((char *) dpy->keysyms);
8861ab64890Smrg	if (dpy->xdefaults)
8871ab64890Smrg	   Xfree (dpy->xdefaults);
8881ab64890Smrg	if (dpy->error_vec)
8891ab64890Smrg	    Xfree ((char *)dpy->error_vec);
8901ab64890Smrg
8911ab64890Smrg	_XFreeExtData (dpy->ext_data);
8921ab64890Smrg	if (dpy->free_funcs)
8931ab64890Smrg	    Xfree ((char *)dpy->free_funcs);
8941ab64890Smrg 	if (dpy->scratch_buffer)
8951ab64890Smrg 	    Xfree (dpy->scratch_buffer);
8961ab64890Smrg	FreeDisplayLock(dpy);
8971ab64890Smrg
8981ab64890Smrg	if (dpy->qfree) {
8991ab64890Smrg	    register _XQEvent *qelt = dpy->qfree;
9001ab64890Smrg
9011ab64890Smrg	    while (qelt) {
9021ab64890Smrg		register _XQEvent *qnxt = qelt->next;
9031ab64890Smrg		Xfree ((char *) qelt);
9041ab64890Smrg		qelt = qnxt;
9051ab64890Smrg	    }
9061ab64890Smrg	}
9071ab64890Smrg	while (dpy->im_fd_info) {
9081ab64890Smrg	    struct _XConnectionInfo *conni = dpy->im_fd_info;
9091ab64890Smrg	    dpy->im_fd_info = conni->next;
9101ab64890Smrg	    if (conni->watch_data)
9111ab64890Smrg		Xfree (conni->watch_data);
9121ab64890Smrg	    Xfree (conni);
9131ab64890Smrg	}
9141ab64890Smrg	if (dpy->conn_watchers) {
9151ab64890Smrg	    struct _XConnWatchInfo *watcher = dpy->conn_watchers;
9161ab64890Smrg	    dpy->conn_watchers = watcher->next;
9171ab64890Smrg	    Xfree (watcher);
9181ab64890Smrg	}
9191ab64890Smrg	if (dpy->filedes)
9201ab64890Smrg	    Xfree (dpy->filedes);
9211ab64890Smrg
9221ab64890Smrg#if USE_XCB
9231ab64890Smrg	_XFreeX11XCBStructure(dpy);
9241ab64890Smrg#endif /* USE_XCB */
9251ab64890Smrg
9261ab64890Smrg	Xfree ((char *)dpy);
9271ab64890Smrg}
9281ab64890Smrg
9291ab64890Smrg/* OutOfMemory is called if malloc fails.  XOpenDisplay returns NULL
9301ab64890Smrg   after this returns. */
9311ab64890Smrg
93261b2299dSmrgstatic void OutOfMemory(Display *dpy, char *setup)
9331ab64890Smrg{
9341ab64890Smrg#if USE_XCB
9351ab64890Smrg    if(dpy->xcb->connection)
9361ab64890Smrg	xcb_disconnect(dpy->xcb->connection);
9371ab64890Smrg#else /* !USE_XCB */
9381ab64890Smrg    _XDisconnectDisplay (dpy->trans_conn);
9391ab64890Smrg#endif /* USE_XCB */
9401ab64890Smrg    _XFreeDisplayStructure (dpy);
9411ab64890Smrg#if !USE_XCB
9421ab64890Smrg    if (setup) Xfree (setup);
9431ab64890Smrg#endif /* !USE_XCB */
9441ab64890Smrg}
945