Commit c7cda56e authored by Jamey Sharp's avatar Jamey Sharp
Browse files

Land XCB support on X.org HEAD.

parent 881467b3
2006-02-14 Jamey Sharp <jamey@minilop.net>
* configure.ac:
* include/Makefile.am:
* include/X11/Xlibint.h:
* include/X11/xcl.h (new):
* src/Makefile.am:
* src/ClDisplay.c:
* src/OpenDis.c:
* src/Xintconn.h:
* src/XlibInt.c:
* src/locking.c:
* src/locking.h:
* src/xclint.h (new):
* src/xcl/display.c (new):
* src/xcl/io.c (new):
* src/xcl/xcblock.c (new):
Land XCB support on X.org HEAD.
2006-02-14 Jamey Sharp <jamey@minilop.net>
* configure.ac:
......
......@@ -20,15 +20,32 @@ AC_PROG_CC
XORG_PROG_RAWCPP
# Build XCL? or traditional Xlib?
AC_ARG_WITH(xcb,
AC_HELP_STRING([--with-xcb], [use XCB for low-level protocol implementation]),
[ac_cv_use_xcb=$withval], [ac_cv_use_xcb=yes])
AC_CACHE_CHECK([whether to use XCB], [ac_cv_use_xcb], [ac_cv_use_xcb=yes])
AM_CONDITIONAL(XCB, test x$ac_cv_use_xcb != xno)
# Checks for pkg-config packages
PKG_CHECK_MODULES(XPROTO, xproto)
AC_SUBST(XPROTO_CFLAGS)
PKG_CHECK_MODULES(X11, xextproto xtrans xau xcmiscproto bigreqsproto)
PKG_CHECK_MODULES(XDMCP, xdmcp)
AC_SUBST(XDMCP_CFLAGS)
AC_SUBST(XDMCP_LIBS)
case "$ac_cv_use_xcb" in
no)
X11_REQUIRES="xau xcmiscproto bigreqsproto"
PKG_CHECK_MODULES(XDMCP, xdmcp)
AC_CHECK_LIB(Xdmcp, XdmcpWrap, [xdmauth="yes"], [xdmauth="no"], [$XDMCP_LIBS])
AC_DEFINE(USE_XCB, 0, [Use XCB for low-level protocol implementation])
;;
*)
X11_REQUIRES="xcb"
xdmauth="no" # XCB handles all auth
AC_CHECK_HEADERS([features.h])
AC_DEFINE(USE_XCB, 1, [Use XCB for low-level protocol implementation])
;;
esac
PKG_CHECK_MODULES(X11, xextproto xtrans $X11_REQUIRES)
dnl Issue an error if xtrans.m4 was not found and XTRANS_CONNECTION_FLAGS macro
dnl was not expanded, since libX11 with no transport types is rather useless.
......@@ -166,8 +183,6 @@ AC_SUBST(XTHREADLIB)
AC_SUBST(XTHREAD_CFLAGS)
X11_CFLAGS="$X11_CFLAGS $XTHREAD_CFLAGS"
AC_CHECK_LIB(Xdmcp, XdmcpWrap, [xdmauth="yes"], [xdmauth="no"], [$XDMCP_LIBS])
case x$xdmauth in
xyes)
XDMCP_CFLAGS="$XDMCP_CFLAGS -DHASXDMAUTH"
......@@ -408,6 +423,7 @@ echo ""
echo "X11 will be built with the following settings:"
echo " Loadable i18n module support: "$XLIB_LOADABLE_I18N
echo " Loadable xcursor library support: "$XLIB_LOADABLE_XCURSOR
echo " Use XCB: "$ac_cv_use_xcb
echo " Threading support: "$xthreads
echo " Use Threads safe API: "$mtsafeapi
echo " Threads stubs in libX11: "$thrstubs
......
......@@ -14,3 +14,7 @@ x11include_HEADERS=\
EXTRA_DIST=\
X11/XlibConf.h.in
if XCB
x11include_HEADERS += X11/xcl.h
endif
......@@ -184,6 +184,7 @@ struct _XDisplay
int xcmisc_opcode; /* major opcode for XC-MISC */
struct _XkbInfoRec *xkb_info; /* XKB info */
struct _XtransConnInfo *trans_conn; /* transport connection object */
struct XCLPrivate *xcl; /* XCB glue private data */
};
#define XAllocIDs(dpy,ids,n) (*(dpy)->idlist_alloc)(dpy,ids,n)
......@@ -958,6 +959,9 @@ extern void _XGetAsyncData(
int /* datalen */,
int /* discardtotal */
);
extern void _XSetSeqSyncFunction(
Display* /* dpy */
);
extern void _XFlush(
Display* /* dpy */
);
......@@ -1214,6 +1218,11 @@ extern void _XUnregisterInternalConnection(
int /* fd */
);
extern void _XProcessInternalConnection(
Display* /* dpy */,
struct _XConnectionInfo* /* conn_info */
);
/* Display structure has pointers to these */
struct _XConnectionInfo { /* info from _XRegisterInternalConnection */
......
/* Copyright (C) 2003 Jamey Sharp.
* This file is licensed under the MIT license. See the file COPYING. */
#ifndef XCL_H
#define XCL_H
#include <X11/XCB/xcb.h>
#include <X11/Xlib.h>
/* Coercions from Xlib XID types to XCB XID types.
* On GCC/x86 with optimizations turned on, these compile to zero
* instructions. */
#define XCLCASTDECL(src_t, dst_t, field) \
static inline XCB##dst_t XCL##dst_t(src_t src) \
{ \
XCB##dst_t dst; \
dst.field = src; \
return dst; \
}
#define XCLXIDCASTDECL(src_t, dst_t) XCLCASTDECL(src_t, dst_t, xid)
#define XCLIDCASTDECL(src_t, dst_t) XCLCASTDECL(src_t, dst_t, id)
XCLXIDCASTDECL(Window, WINDOW)
XCLXIDCASTDECL(Pixmap, PIXMAP)
XCLXIDCASTDECL(Cursor, CURSOR)
XCLXIDCASTDECL(Font, FONT)
XCLXIDCASTDECL(GContext, GCONTEXT)
XCLXIDCASTDECL(Colormap, COLORMAP)
XCLXIDCASTDECL(Atom, ATOM)
/* For the union types, pick an arbitrary field of the union to hold the
* Xlib XID. Assumes the bit pattern is the same regardless of the field. */
XCLCASTDECL(Drawable, DRAWABLE, window.xid)
XCLCASTDECL(Font, FONTABLE, font.xid)
XCLIDCASTDECL(VisualID, VISUALID)
XCLIDCASTDECL(Time, TIMESTAMP)
XCLIDCASTDECL(KeySym, KEYSYM)
XCLIDCASTDECL(KeyCode, KEYCODE)
XCLIDCASTDECL(CARD8, BUTTON)
/* xcl/display.c */
XCBConnection *XCBConnectionOfDisplay(Display *dpy);
/* xcl/io.c */
enum XEventQueueOwner { XlibOwnsEventQueue = 0, XCBOwnsEventQueue };
void XSetEventQueueOwner(Display *dpy, enum XEventQueueOwner owner);
#endif /* XCL_H */
......@@ -32,7 +32,11 @@ from The Open Group.
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if USE_XCB
#include "xclint.h"
#else /* !USE_XCB */
#include <X11/Xtrans/Xtrans.h>
#endif /* USE_XCB */
#include "Xlib.h"
#include "Xlibint.h"
#include "Xintconn.h"
......@@ -70,7 +74,11 @@ XCloseDisplay (
if (dpy->request != dpy->last_request_read)
XSync(dpy, 1);
}
#if USE_XCB
XCBDisconnect(XCBConnectionOfDisplay(dpy));
#else /* !USE_XCB */
_XDisconnectDisplay(dpy->trans_conn);
#endif /* USE_XCB */
_XFreeDisplayStructure (dpy);
return 0;
}
......@@ -77,7 +77,6 @@ libX11_la_SOURCES = \
Clear.c \
Cmap.h \
ConfWind.c \
ConnDis.c \
Context.c \
ConvSel.c \
CopyArea.c \
......@@ -184,7 +183,6 @@ libX11_la_SOURCES = \
LiProps.c \
ListExt.c \
LoadFont.c \
LockDis.c \
locking.c \
locking.h \
LookupCol.c \
......@@ -303,7 +301,6 @@ libX11_la_SOURCES = \
WMGeom.c \
WMProps.c \
WrBitF.c \
x11_trans.c \
Xatomtype.h \
Xintatom.h \
Xintconn.h \
......@@ -339,6 +336,18 @@ EXTRA_DIST = \
udcInf.c \
UIThrStubs.c
if XCB
libX11_la_SOURCES += \
xcl/xcblock.c \
xcl/display.c \
xcl/io.c
else
libX11_la_SOURCES += \
ConnDis.c \
LockDis.c \
x11_trans.c
endif
#
# Figure out which sub-libraries to link into Xlib
#
......
......@@ -32,10 +32,14 @@ in this Software without prior written authorization from The Open Group.
#include <config.h>
#endif
#include "Xlibint.h"
#if USE_XCB
#include "xclint.h"
#else /* !USE_XCB */
#include <X11/Xtrans/Xtrans.h>
#include <X11/extensions/bigreqstr.h>
#endif /* USE_XCB */
#include <X11/Xatom.h>
#include <X11/Xresource.h>
#include <X11/extensions/bigreqstr.h>
#include <stdio.h>
#include "Xintconn.h"
......@@ -43,6 +47,7 @@ in this Software without prior written authorization from The Open Group.
#include "XKBlib.h"
#endif /* XKB */
#if !USE_XCB
#ifdef X_NOT_POSIX
#define Size_t unsigned int
#else
......@@ -55,14 +60,21 @@ typedef struct {
unsigned long seq;
int opcode;
} _XBigReqState;
#endif /* !USE_XCB */
#ifdef XTHREADS
#include "locking.h"
int (*_XInitDisplayLock_fn)(Display *dpy) = NULL;
void (*_XFreeDisplayLock_fn)(Display *dpy) = NULL;
#if USE_XCB
#define InitDisplayLock(d) _XInitDisplayLock(d)
#define FreeDisplayLock(d) _XFreeDisplayLock(d)
#else /* if !USE_XCB */
#define InitDisplayLock(d) (_XInitDisplayLock_fn ? (*_XInitDisplayLock_fn)(d) : Success)
#define FreeDisplayLock(d) if (_XFreeDisplayLock_fn) (*_XFreeDisplayLock_fn)(d)
#endif /* !USE_XCB */
#else
#define InitDisplayLock(dis) Success
#define FreeDisplayLock(dis)
......@@ -73,8 +85,10 @@ static xReq _dummy_request = {
};
static void OutOfMemory(Display *dpy, char *setup);
#if !USE_XCB
static Bool _XBigReqHandler(Display *dpy, xReply *rep, char *buf, int len,
XPointer data);
#endif /* !USE_XCB */
/*
* Connects to a server, creates a Display object and returns a pointer to
......@@ -87,16 +101,20 @@ XOpenDisplay (
register Display *dpy; /* New Display object being created. */
register int i;
int j, k; /* random iterator indexes */
#if !USE_XCB
char *display_name; /* pointer to display name */
int endian; /* to determine which endian. */
xConnClientPrefix client; /* client information */
xConnSetupPrefix prefix; /* prefix information */
int vendorlen; /* length of vendor string */
int idisplay; /* display number */
int prefixread = 0; /* setup prefix already read? */
char *conn_auth_name, *conn_auth_data;
int conn_auth_namelen, conn_auth_datalen;
#endif /* !USE_XCB */
char *setup = NULL; /* memory allocated at startup */
char *fullname = NULL; /* expanded name of display */
int idisplay; /* display number */
int iscreen; /* screen number */
int prefixread = 0; /* setup prefix already read? */
xConnSetupPrefix prefix; /* prefix information */
int vendorlen; /* length of vendor string */
union {
xConnSetup *setup;
char *failure;
......@@ -108,12 +126,11 @@ XOpenDisplay (
} u; /* proto data returned from server */
long setuplength; /* number of bytes in setup message */
long usedbytes = 0; /* number of bytes we have processed */
char *conn_auth_name, *conn_auth_data;
int conn_auth_namelen, conn_auth_datalen;
unsigned long mask;
long int conn_buf_size;
char *xlib_buffer_size;
#if !USE_XCB
bzero((char *) &client, sizeof(client));
bzero((char *) &prefix, sizeof(prefix));
......@@ -131,6 +148,8 @@ XOpenDisplay (
/* Display is non-NULL, copy the pointer */
display_name = (char *)display;
}
#endif /* !USE_XCB */
/*
* Set the default error handlers. This allows the global variables to
* default to NULL for use with shared libraries.
......@@ -151,6 +170,12 @@ XOpenDisplay (
* will set fullname to point to the expanded name.
*/
#if USE_XCB
if(!_XConnectXCB(dpy, display, &fullname, &iscreen)) {
OutOfMemory(dpy, 0);
return 0;
}
#else /* !USE_XCB */
if ((dpy->trans_conn = _X11TransConnectDisplay (
display_name, &fullname, &idisplay,
&iscreen, &conn_auth_name,
......@@ -161,6 +186,7 @@ XOpenDisplay (
}
dpy->fd = _X11TransGetConnectionNumber (dpy->trans_conn);
#endif /* USE_XCB */
/* Initialize as much of the display structure as we can.
* Initialize pointers to NULL so that XFreeDisplayStructure will
......@@ -277,6 +303,7 @@ XOpenDisplay (
return(NULL);
}
#if !USE_XCB
/*
* The xConnClientPrefix describes the initial connection setup information
* and is followed by the authorization information. Sites that are interested
......@@ -331,7 +358,18 @@ XOpenDisplay (
Xfree ((char *)dpy);
return(NULL);
}
#endif /* !USE_XCB */
#if USE_XCB
{
XCBConnSetupSuccessRep *xcbsetup = XCBGetSetup(XCBConnectionOfDisplay(dpy));
setuplength = xcbsetup->length << 2;
memcpy(&prefix, xcbsetup, sizeof(prefix));
setup = (char *) xcbsetup;
setup += SIZEOF(xConnSetupPrefix);
u.setup = (xConnSetup *) setup;
}
#else /* !USE_XCB */
setuplength = prefix.length << 2;
if ( (u.setup = (xConnSetup *)
(setup = Xmalloc ((unsigned) setuplength))) == NULL) {
......@@ -362,6 +400,7 @@ XOpenDisplay (
OutOfMemory(dpy, setup);
return (NULL);
}
#endif /* USE_XCB */
/*
* Check if the reply was long enough to get any information out of it.
......@@ -595,7 +634,9 @@ XOpenDisplay (
* Now start talking to the server to setup all other information...
*/
#if !USE_XCB
Xfree (setup); /* all finished with setup information */
#endif /* !USE_XCB */
/*
* Make sure default screen is legal.
......@@ -605,10 +646,12 @@ XOpenDisplay (
return(NULL);
}
#if !USE_XCB
/*
* finished calling internal routines, now unlock for external routines
*/
UnlockDisplay(dpy);
#endif /* !USE_XCB */
/*
* Set up other stuff clients are always going to use.
......@@ -631,17 +674,24 @@ XOpenDisplay (
*/
(void) XSynchronize(dpy, _Xdebug);
#if USE_XCB
dpy->bigreq_size = XCBGetMaximumRequestLength(XCBConnectionOfDisplay(dpy));
if(dpy->bigreq_size <= dpy->max_request_size)
dpy->bigreq_size = 0;
#endif /* USE_XCB */
/*
* get availability of large requests, and
* get the resource manager database off the root window.
*/
LockDisplay(dpy);
{
xGetPropertyReply reply;
xGetPropertyReq *req;
#if !USE_XCB
_XAsyncHandler async;
_XBigReqState async_state;
xQueryExtensionReq *qreq;
xGetPropertyReply reply;
xGetPropertyReq *req;
xBigReqEnableReq *breq;
xBigReqEnableReply brep;
......@@ -655,6 +705,7 @@ XOpenDisplay (
qreq->nbytes = bignamelen;
qreq->length += (bignamelen+3)>>2;
Data(dpy, XBigReqExtensionName, bignamelen);
#endif /* !USE_XCB */
GetReq (GetProperty, req);
req->window = RootWindow(dpy, 0);
......@@ -675,6 +726,7 @@ XOpenDisplay (
else if (reply.propertyType != None)
_XEatData(dpy, reply.nItems * (reply.format >> 3));
}
#if !USE_XCB
DeqAsyncHandler(dpy, &async);
if (async_state.opcode) {
GetReq(BigReqEnable, breq);
......@@ -683,6 +735,7 @@ XOpenDisplay (
if (_XReply(dpy, (xReply *)&brep, 0, xFalse))
dpy->bigreq_size = brep.max_request_size;
}
#endif /* !USE_XCB */
}
UnlockDisplay(dpy);
......@@ -701,6 +754,7 @@ XOpenDisplay (
return(dpy);
}
#if !USE_XCB
static Bool
_XBigReqHandler(dpy, rep, buf, len, data)
register Display *dpy;
......@@ -726,6 +780,7 @@ _XBigReqHandler(dpy, rep, buf, len, data)
state->opcode = repl->major_opcode;
return True;
}
#endif /* !USE_XCB */
/* XFreeDisplayStructure frees all the storage associated with a
......@@ -853,6 +908,10 @@ void _XFreeDisplayStructure(dpy)
if (dpy->filedes)
Xfree (dpy->filedes);
#if USE_XCB
_XFreeXCLStructure(dpy);
#endif /* USE_XCB */
Xfree ((char *)dpy);
}
......@@ -863,7 +922,13 @@ static void OutOfMemory (dpy, setup)
Display *dpy;
char *setup;
{
#if USE_XCB
XCBDisconnect(XCBConnectionOfDisplay(dpy));
#else /* !USE_XCB */
_XDisconnectDisplay (dpy->trans_conn);
#endif /* USE_XCB */
_XFreeDisplayStructure (dpy);
#if !USE_XCB
if (setup) Xfree (setup);
#endif /* !USE_XCB */
}
......@@ -7,6 +7,7 @@
_XFUNCPROTOBEGIN
#if !USE_XCB
/* ConnDis.c */
int _XConnectDisplay (
......@@ -27,6 +28,7 @@ extern XtransConnInfo _X11TransConnectDisplay(char *display_name,
int *screenp, char **auth_namep,
int *auth_namelenp, char **auth_datap,
int *auth_datalenp);
#endif /* !USE_XCB */
/* OpenDis.c */
extern void _XFreeDisplayStructure(Display *dpy);
......
......@@ -43,8 +43,10 @@ from The Open Group.
#endif
#include "Xlibint.h"
#include <X11/Xpoll.h>
#if !USE_XCB
#include <X11/Xtrans/Xtrans.h>
#include <X11/extensions/xcmiscstr.h>
#endif /* !USE_XCB */
#include <stdio.h>
#ifdef WIN32
#include <direct.h>
......@@ -76,6 +78,7 @@ xthread_t (*_Xthread_self_fn)(void) = NULL;
#define XThread_Self() ((*_Xthread_self_fn)())
#if !USE_XCB
#define UnlockNextReplyReader(d) if ((d)->lock) \
(*(d)->lock->pop_reader)((d),&(d)->lock->reply_awaiters,&(d)->lock->reply_awaiters_tail)
......@@ -91,12 +94,15 @@ xthread_t (*_Xthread_self_fn)(void) = NULL;
#define InternalLockDisplay(d,wskip) if ((d)->lock) \
(*(d)->lock->internal_lock_display)(d,wskip)
#endif
#endif /* !USE_XCB */
#else /* XTHREADS else */
#if !USE_XCB
#define UnlockNextReplyReader(d)
#define UnlockNextEventReader(d)
#define InternalLockDisplay(d,wskip)
#endif /* !USE_XCB */
#endif /* XTHREADS else */
......@@ -151,11 +157,14 @@ xthread_t (*_Xthread_self_fn)(void) = NULL;
#endif
#ifdef __UNIXOS2__
#if !USE_XCB
#define select(n,r,w,x,t) os2ClientSelect(n,r,w,x,t)
#endif /* !USE_XCB */
#include <limits.h>
#define MAX_PATH _POSIX_PATH_MAX
#endif
#if !USE_XCB
#ifdef MUSTCOPY
#define STARTITERATE(tpvar,type,start,endcond) \
......@@ -190,10 +199,7 @@ static char *_XAsyncReply(
char *buf,
register int *lenp,
Bool discard);
static void _XProcessInternalConnection(
Display *dpy,
struct _XConnectionInfo *conn_info);
#endif /* !USE_XCB */
#define SEQLIMIT (65535 - (BUFSIZE / SIZEOF(xReq)) - 10)
......@@ -215,6 +221,7 @@ static void _XProcessInternalConnection(
* the object they have created.
*/
#if !USE_XCB
static xReq _dummy_request = {
0, 0, 0
};
......@@ -368,6 +375,7 @@ _XWaitForWritable(
}
}
}
#endif /* !USE_XCB */
#define POLLFD_CACHE_SIZE 5
......@@ -425,6 +433,7 @@ void _XPollfdCacheDel(
#endif
}
#if !USE_XCB
/* returns True iff there is an event in the queue newer than serial_num */
static Bool
......@@ -554,6 +563,7 @@ _XWaitForReadable(
#endif
return 0;
}
#endif /* !USE_XCB */
static
int _XSeqSyncFunction(
......@@ -577,7 +587,6 @@ int _XSeqSyncFunction(
return 0;
}
static
void _XSetSeqSyncFunction(
register Display *dpy)
{
......@@ -589,6 +598,7 @@ void _XSetSeqSyncFunction(
}
}
#if !USE_XCB
#ifdef XTHREADS
static void _XFlushInt(
register Display *dpy,
......@@ -1118,6 +1128,7 @@ int _XRead(
#endif /* XTHREADS*/
return 0;
}
#endif /* !USE_XCB */
#ifdef LONG64
void _XRead32(
......@@ -1259,6 +1270,7 @@ void _XRead16Pad(
#endif /* WORD64 */
#if !USE_XCB
/*
* _XReadPad - Read bytes from the socket taking into account incomplete
* reads. If the number of bytes is not 0 mod 4, read additional pad
......@@ -1908,6 +1920,7 @@ _XAsyncReply(
}
return nbuf;
}
#endif /* !USE_XCB */
/*
* Support for internal connections, such as an IM might use.
......@@ -2053,12 +2066,12 @@ XInternalConnectionNumbers(
return 1;
}
static void _XProcessInternalConnection(
void _XProcessInternalConnection(
Display *dpy,
struct _XConnectionInfo *conn_info)
{
dpy->flags |= XlibDisplayProcConni;
#ifdef XTHREADS
#if defined(XTHREADS) && !USE_XCB
if (dpy->lock) {
/* check cache to avoid call to thread_self */
if (xthread_have_id(dpy->lock->reading_thread))
......@@ -2066,14 +2079,14 @@ static void _XProcessInternalConnection(
else
dpy->lock->conni_thread = XThread_Self();