[Xcb] [PATCH] Split xproto out of libxcb into its own library, libxcb-xproto.

Jamey Sharp jamey at minilop.net
Sat Oct 7 02:03:47 PDT 2006


We still don't have some requests encoded ideally, perhaps even
correctly, even in the core protocol. PolyText8 is an example that we're
thinking hard about. Josh and I want the flexibility to bump the xproto
soname without changing libxcb itself.

Since libX11 does not use XCB's core protocol encoding at all, this and
any future changes have no effect on it.
---

Josh and I want to split out the core protocol of XCB from libxcb into
libxcb-xproto, leaving just the transport layer (and xc-misc and bigreq)
in libxcb. This would allow us to fix bugs and deficiencies in the core
protocol code (for example, PolyText8) without bumping the libxcb
soname. The attached patch does exactly this. Comments? Suggestions?
Flames?

 Makefile.am      |    2 ++
 configure.ac     |    2 +-
 src/Makefile.am  |   23 ++++++++++++-----------
 src/xcb.h        |   15 +++++++++------
 src/xcb_auth.c   |    1 +
 src/xcb_conn.c   |   20 ++------------------
 src/xcb_ext.c    |   27 ++++++++++++++++++++++-----
 src/xcb_in.c     |   24 +++++++++++++++++++++---
 src/xcb_out.c    |    5 +++--
 src/xcb_xid.c    |    1 +
 src/xcbint.h     |    2 +-
 xcb-xproto.pc.in |   11 +++++++++++
 12 files changed, 86 insertions(+), 47 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 7f89fba..e913b6b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,6 +5,7 @@ pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = \
 xcb.pc \
 xcb-xlib.pc \
+xcb-xproto.pc \
 xcb-composite.pc \
 xcb-damage.pc \
 xcb-dpms.pc \
@@ -28,6 +29,7 @@ xcb-xvmc.pc
 EXTRA_DIST = \
 xcb.pc.in \
 xcb-xlib.pc.in \
+xcb-xproto.pc.in \
 xcb-composite.pc.in \
 xcb-damage.pc.in \
 xcb-dpms.pc.in \
diff --git a/configure.ac b/configure.ac
index b097759..941194c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -119,6 +119,6 @@ AC_SUBST(CWARNFLAGS)
 GCC_CHECK_VISIBILITY()
 
 AC_CONFIG_FILES([Makefile src/Makefile tests/Makefile])
-AC_CONFIG_FILES([xcb.pc xcb-xlib.pc xcb-composite.pc xcb-damage.pc xcb-dpms.pc xcb-glx.pc xcb-randr.pc xcb-record.pc xcb-render.pc xcb-res.pc xcb-screensaver.pc xcb-shape.pc xcb-shm.pc xcb-sync.pc xcb-xevie.pc xcb-xf86dri.pc xcb-xfixes.pc xcb-xprint.pc xcb-xtest.pc xcb-xv.pc xcb-xvmc.pc])
+AC_CONFIG_FILES([xcb.pc xcb-xlib.pc xcb-xproto.pc xcb-composite.pc xcb-damage.pc xcb-dpms.pc xcb-glx.pc xcb-randr.pc xcb-record.pc xcb-render.pc xcb-res.pc xcb-screensaver.pc xcb-shape.pc xcb-shm.pc xcb-sync.pc xcb-xevie.pc xcb-xf86dri.pc xcb-xfixes.pc xcb-xprint.pc xcb-xtest.pc xcb-xv.pc xcb-xvmc.pc])
 
 AC_OUTPUT
diff --git a/src/Makefile.am b/src/Makefile.am
index 15fda4a..6f3b2bf 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,6 @@
 lib_LTLIBRARIES = libxcb.la \
                   libxcb-xlib.la \
+                  libxcb-xproto.la \
                   libxcb-composite.la \
                   libxcb-damage.la \
                   libxcb-dpms.la \
@@ -21,6 +22,7 @@ lib_LTLIBRARIES = libxcb.la \
                   libxcb-xvmc.la
 
 EXTHEADERS = \
+		xproto.h \
 		bigreq.h \
 		composite.h \
 		damage.h \
@@ -43,6 +45,7 @@ EXTHEADERS = \
 		xv.h \
 		xvmc.h
 EXTSOURCES = \
+		xproto.c \
 		bigreq.c \
 		composite.c \
 		damage.c \
@@ -73,6 +76,7 @@ ESSENTIAL_EXTENSIONS = \
 		xc_misc.c
 
 EXTENSION_XML = \
+		xproto.xml \
 		bigreq.xml \
 		composite.xml \
 		damage.xml \
@@ -95,11 +99,7 @@ EXTENSION_XML = \
 		xvmc.xml \
 		xv.xml
 
-COREHEADERS = xproto.h
-CORESOURCES = xproto.c
-COREPROTO   = $(CORESOURCES) $(COREHEADERS)
-
-xcbinclude_HEADERS = xcb.h xcbext.h xcbxlib.h $(COREHEADERS) $(EXTHEADERS)
+xcbinclude_HEADERS = xcb.h xcbext.h xcbxlib.h $(EXTHEADERS)
 noinst_HEADERS = xcbint.h
 
 AM_CFLAGS = $(COPTFLAGS) $(CWARNFLAGS) $(CDEBUGFLAGS) $(XCBPROTO_CFLAGS) $(XAU_CFLAGS) $(XDMCP_CFLAGS)
@@ -107,7 +107,7 @@ libxcb_la_LIBADD = $(XCBPROTO_LIBS) $(XA
 libxcb_la_SOURCES = \
 		xcb_conn.c xcb_out.c xcb_in.c xcb_ext.c xcb_xid.c \
 		xcb_list.c xcb_util.c xcb_auth.c \
-		$(COREPROTO) $(ESSENTIAL_EXTENSIONS) c-client.xsl
+		$(ESSENTIAL_EXTENSIONS) c-client.xsl
 
 # Explanation for -version-info:
 # -version-info current:revision:age
@@ -118,8 +118,8 @@ # * If you change or remove an interface
 #   and age to 0.
 libxcb_la_LDFLAGS = -version-info 0:0:0
 
-BUILT_SOURCES = $(COREPROTO) $(EXTENSIONS)
-CLEANFILES = $(COREPROTO) $(EXTENSIONS)
+BUILT_SOURCES = $(EXTENSIONS)
+CLEANFILES = $(EXTENSIONS)
 
 XCB_LIBS = libxcb.la
 
@@ -129,6 +129,10 @@ libxcb_xlib_la_SOURCES = xcb_xlib.c
 
 # FIXME: find a way to autogenerate this from the XML files.
 
+libxcb_xproto_la_LDFLAGS = -version-info 0:0:0
+libxcb_xproto_la_LIBADD = $(XCB_LIBS)
+libxcb_xproto_la_SOURCES = xproto.c xproto.h
+
 libxcb_composite_la_LDFLAGS = -version-info 0:0:0
 libxcb_composite_la_LIBADD = $(XCB_LIBS)
 libxcb_composite_la_SOURCES = composite.c composite.h
@@ -223,9 +227,6 @@ SUFFIXES = .xml
 	            --stringparam extension-path $(XCBPROTO_XCBINCLUDEDIR)/ \
 	            -o $@ $(srcdir)/c-client.xsl $< 
 
-xproto.xml: $(XCBPROTO_XCBINCLUDEDIR)/xproto.xml
-	$(LN_S) $(XCBPROTO_XCBINCLUDEDIR)/xproto.xml $@
-
 $(EXTENSION_XML):
 	for i in $(EXTENSION_XML) ; do \
            rm -f $$i ; \
diff --git a/src/xcb.h b/src/xcb.h
index 4b5b349..e5f33f6 100644
--- a/src/xcb.h
+++ b/src/xcb.h
@@ -138,10 +138,6 @@ typedef struct {
 } xcb_void_cookie_t;
 
 
-/* Include the generated xproto header. */
-#include "xproto.h"
-
-
 /** XCB_NONE is the universal null resource or null atom parameter value for many core X requests */
 #define XCB_NONE 0L
 
@@ -255,6 +251,13 @@ xcb_generic_error_t *xcb_request_check(x
  */
 typedef struct xcb_extension_t xcb_extension_t;  /**< Opaque structure used as key for xcb_get_extension_data_t. */
 
+typedef struct xcb_extension_status_t {
+	uint8_t present;
+	uint8_t major_opcode;
+	uint8_t first_event;
+	uint8_t first_error;
+} xcb_extension_status_t;
+
 /**
  * @brief Caches reply information from QueryExtension requests.
  * @param c: The connection.
@@ -271,7 +274,7 @@ typedef struct xcb_extension_t xcb_exten
  * The result must not be freed. This storage is managed by the cache
  * itself.
  */
-const xcb_query_extension_reply_t *xcb_get_extension_data(xcb_connection_t *c, xcb_extension_t *ext);
+const xcb_extension_status_t *xcb_get_extension_data(xcb_connection_t *c, xcb_extension_t *ext);
 
 /**
  * @brief Prefetch of extension data into the extension cache
@@ -307,7 +310,7 @@ void xcb_prefetch_extension_data(xcb_con
  *
  * The result must not be freed.
  */
-const xcb_setup_t *xcb_get_setup(xcb_connection_t *c);
+const struct xcb_setup_t *xcb_get_setup(xcb_connection_t *c);
 
 /**
  * @brief Access the file descriptor of the connection.
diff --git a/src/xcb_auth.c b/src/xcb_auth.c
index 4c9f7d6..9710aaf 100644
--- a/src/xcb_auth.c
+++ b/src/xcb_auth.c
@@ -36,6 +36,7 @@ #include <stdlib.h>
 
 #include "xcb.h"
 #include "xcbint.h"
+#include "xproto.h"
 
 #ifdef HASXDMAUTH
 #include <X11/Xdmcp.h>
diff --git a/src/xcb_conn.c b/src/xcb_conn.c
index 239d71b..de85d50 100644
--- a/src/xcb_conn.c
+++ b/src/xcb_conn.c
@@ -37,6 +37,7 @@ #include <errno.h>
 
 #include "xcb.h"
 #include "xcbint.h"
+#include "xproto.h"
 
 typedef struct {
     uint8_t  status;
@@ -139,24 +140,7 @@ static int read_setup(xcb_connection_t *
         return 0;
 
     /* 0 = failed, 2 = authenticate, 1 = success */
-    switch(c->setup->status)
-    {
-    case 0: /* failed */
-        {
-            xcb_setup_failed_t *setup = (xcb_setup_failed_t *) c->setup;
-            write(STDERR_FILENO, xcb_setup_failed_reason(setup), xcb_setup_failed_reason_length(setup));
-            return 0;
-        }
-
-    case 2: /* authenticate */
-        {
-            xcb_setup_authenticate_t *setup = (xcb_setup_authenticate_t *) c->setup;
-            write(STDERR_FILENO, xcb_setup_authenticate_reason(setup), xcb_setup_authenticate_reason_length(setup));
-            return 0;
-        }
-    }
-
-    return 1;
+    return c->setup->status == 1;
 }
 
 /* precondition: there must be something for us to write. */
diff --git a/src/xcb_ext.c b/src/xcb_ext.c
index 9655dd8..a37b718 100644
--- a/src/xcb_ext.c
+++ b/src/xcb_ext.c
@@ -35,8 +35,8 @@ #include "xcbint.h"
 typedef struct lazyreply {
     enum { LAZY_NONE = 0, LAZY_COOKIE, LAZY_FORCED } tag;
     union {
-        xcb_query_extension_cookie_t cookie;
-        xcb_query_extension_reply_t *reply;
+        unsigned long cookie;
+        xcb_extension_status_t *reply;
     } value;
 } lazyreply;
 
@@ -71,8 +71,23 @@ static lazyreply *get_lazyreply(xcb_conn
     if(data && data->tag == LAZY_NONE)
     {
         /* cache miss: query the server */
+        static const xcb_protocol_request_t xcb_req = {
+            /* count */ 3,
+            /* ext */ 0,
+            /* opcode */ 98,
+            /* isvoid */ 0
+        };
+        uint16_t req[4];
+        struct iovec vec[5];
+        req[2] = strlen(ext->name);
+        vec[2].iov_base = req;
+        vec[2].iov_len = sizeof(req);
+        vec[3].iov_base = (char *) ext->name;
+        vec[3].iov_len = req[2];
+        vec[4].iov_base = req;
+        vec[4].iov_len = -req[2] & 3;
         data->tag = LAZY_COOKIE;
-        data->value.cookie = xcb_query_extension(c, strlen(ext->name), ext->name);
+        data->value.cookie = xcb_send_request(c, XCB_REQUEST_CHECKED, vec + 2, &xcb_req);
     }
     return data;
 }
@@ -81,7 +96,7 @@ static lazyreply *get_lazyreply(xcb_conn
 
 /* Do not free the returned xcb_query_extension_reply_t - on return, it's aliased
  * from the cache. */
-const xcb_query_extension_reply_t *xcb_get_extension_data(xcb_connection_t *c, xcb_extension_t *ext)
+const xcb_extension_status_t *xcb_get_extension_data(xcb_connection_t *c, xcb_extension_t *ext)
 {
     lazyreply *data;
     if(c->has_error)
@@ -92,7 +107,9 @@ const xcb_query_extension_reply_t *xcb_g
     if(data && data->tag == LAZY_COOKIE)
     {
         data->tag = LAZY_FORCED;
-        data->value.reply = xcb_query_extension_reply(c, data->value.cookie, 0);
+        data->value.reply = xcb_wait_for_reply(c, data->value.cookie, 0);
+        if(data->value.reply)
+            memcpy(data->value.reply, data->value.reply + 2, sizeof(data->value.reply));
     }
     pthread_mutex_unlock(&c->ext.lock);
 
diff --git a/src/xcb_in.c b/src/xcb_in.c
index b252ffc..cd4801a 100644
--- a/src/xcb_in.c
+++ b/src/xcb_in.c
@@ -36,6 +36,7 @@ #include <errno.h>
 #include "xcb.h"
 #include "xcbext.h"
 #include "xcbint.h"
+#include "xproto.h"
 
 #define XCB_ERROR 0
 #define XCB_REPLY 1
@@ -412,8 +413,8 @@ xcb_generic_event_t *xcb_poll_for_event(
 xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t cookie)
 {
     /* FIXME: this could hold the lock to avoid syncing unnecessarily, but
-     * that would require factoring the locking out of xcb_get_input_focus,
-     * xcb_get_input_focus_reply, and xcb_wait_for_reply. */
+     * that would require factoring the locking out of xcb_send_request and
+     * xcb_wait_for_reply. */
     xcb_generic_error_t *ret;
     void *reply;
     if(c->has_error)
@@ -421,7 +422,24 @@ xcb_generic_error_t *xcb_request_check(x
     if(XCB_SEQUENCE_COMPARE(cookie.sequence,>,c->in.request_expected)
        && XCB_SEQUENCE_COMPARE(cookie.sequence,>,c->in.request_completed))
     {
-        free(xcb_get_input_focus_reply(c, xcb_get_input_focus(c), &ret));
+        static const xcb_protocol_request_t xcb_req = {
+            /* count */ 1,
+            /* ext */ 0,
+            /* opcode */ 43,
+            /* isvoid */ 0
+        };
+        static const union {
+            struct {
+                uint8_t major;
+                uint8_t pad;
+                uint16_t len;
+            } fields;
+            uint32_t packet;
+        } sync = { { /* GetInputFocus */ 43, 0, 1 } };
+        struct iovec vec[3];
+        vec[2].iov_base = (char *) &sync;
+        vec[2].iov_len = sizeof(sync);
+        free(xcb_wait_for_reply(c, xcb_send_request(c, XCB_REQUEST_CHECKED | XCB_REQUEST_RAW, vec + 2, &xcb_req), &ret));
         assert(!ret);
     }
     reply = xcb_wait_for_reply(c, cookie.sequence, &ret);
diff --git a/src/xcb_out.c b/src/xcb_out.c
index 74787e3..23e5ce2 100644
--- a/src/xcb_out.c
+++ b/src/xcb_out.c
@@ -33,6 +33,7 @@ #include <string.h>
 #include "xcb.h"
 #include "xcbext.h"
 #include "xcbint.h"
+#include "xproto.h"
 #include "bigreq.h"
 
 static int write_block(xcb_connection_t *c, struct iovec *vector, int count)
@@ -64,7 +65,7 @@ uint32_t xcb_get_maximum_request_length(
     pthread_mutex_lock(&c->out.reqlenlock);
     if(!c->out.maximum_request_length)
     {
-        const xcb_query_extension_reply_t *ext;
+        const xcb_extension_status_t *ext;
         c->out.maximum_request_length = c->setup->maximum_request_length;
         ext = xcb_get_extension_data(c, &xcb_big_requests_id);
         if(ext && ext->present)
@@ -110,7 +111,7 @@ unsigned int xcb_send_request(xcb_connec
         /* set the major opcode, and the minor opcode for extensions */
         if(req->ext)
         {
-            const xcb_query_extension_reply_t *extension = xcb_get_extension_data(c, req->ext);
+            const xcb_extension_status_t *extension = xcb_get_extension_data(c, req->ext);
             if(!(extension && extension->present))
             {
                 _xcb_conn_shutdown(c);
diff --git a/src/xcb_xid.c b/src/xcb_xid.c
index 7ff0c5f..c9fa74a 100644
--- a/src/xcb_xid.c
+++ b/src/xcb_xid.c
@@ -30,6 +30,7 @@ #include "xcb.h"
 #include "xcbext.h"
 #include "xcbint.h"
 #include "xc_misc.h"
+#include "xproto.h"
 
 /* Public interface */
 
diff --git a/src/xcbint.h b/src/xcbint.h
index d81e787..0d3051c 100644
--- a/src/xcbint.h
+++ b/src/xcbint.h
@@ -154,7 +154,7 @@ struct xcb_connection_t {
     int has_error;
 
     /* constant data */
-    xcb_setup_t *setup;
+    struct xcb_setup_t *setup;
     int fd;
 
     /* I/O data */
diff --git a/xcb-xproto.pc.in b/xcb-xproto.pc.in
new file mode 100644
index 0000000..534e79c
--- /dev/null
+++ b/xcb-xproto.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: XCB Core X Protocol
+Description: XCB Core X Protocol
+Version: @PACKAGE_VERSION@
+Requires: xcb
+Libs: -L${libdir} -lxcb-xproto
+Cflags: -I${includedir}
-- 
1.4.1.1


More information about the Xcb mailing list