[Xcb] [RFC] X generic event integration

Peter Hutterer mailinglists at who-t.net
Thu Feb 28 23:39:19 PST 2008


I think I sent this some 12 months ago already, but with mpx getting 
closer to being merged I'd like to propose the following patch for xge.

XGE is the Generic Event extension, allowing for events to re-use a 
single opcode and also to be longer than 32 bytes. It's pretty 
straightforward, this code was written ages ago and since I haven't 
really had the need to change anything in libxcb.

All we need in libxcb is to detect GenericEvent (opcode 35), then check 
the length field of the event and pull in a few more bytes.

I'll be happy to polish it up if needed. Any comments welcome.

Cheers,
   Peter


diff --git a/src/xcb.h b/src/xcb.h
index 5a1c01a..d24ef95 100644
--- a/src/xcb.h
+++ b/src/xcb.h
@@ -116,6 +116,23 @@ typedef struct {
  } xcb_generic_event_t;

  /**
+ * @brief GE event
+ *
+ * An event as sent by the XGE extension. The length field specifies the
+ * number of 4-byte blocks trailing the struct.
+ */
+typedef struct {
+    uint8_t  response_type;  /**< Type of the response */
+    uint8_t  pad0;           /**< Padding */
+    uint16_t sequence;       /**< Sequence number */
+    uint32_t length;
+    uint16_t event_type;
+    uint16_t pad1;
+    uint32_t pad[5];         /**< Padding */
+    uint32_t full_sequence;  /**< full sequence */
+} xcb_ge_event_t;
+
+/**
   * @brief Generic error.
   *
   * A generic error structure.
diff --git a/src/xcb_in.c b/src/xcb_in.c
index 2997de4..6fb5b6d 100644
--- a/src/xcb_in.c
+++ b/src/xcb_in.c
@@ -39,6 +39,7 @@

  #define XCB_ERROR 0
  #define XCB_REPLY 1
+#define XCB_XGE_EVENT 35

  struct event_list {
      xcb_generic_event_t *event;
@@ -76,7 +77,8 @@ static void wake_up_next_reader(xcb_connection_t *c)
  static int read_packet(xcb_connection_t *c)
  {
      xcb_generic_reply_t genrep;
-    int length = 32;
+    int length = 32,
+        eventlength = 0; /* length after first 32 bytes for 
GenericEvents */
      void *buf;
      pending_reply *pend = 0;
      struct event_list *event;
@@ -141,17 +143,36 @@ static int read_packet(xcb_connection_t *c)
          length += genrep.length * 4;
      }

-    buf = malloc(length + (genrep.response_type == XCB_REPLY ? 0 : 
sizeof(uint32_t)));
+    /* XGE events may have sizes > 32 */
+    if (genrep.response_type == XCB_XGE_EVENT)
+    {
+        eventlength = ((xcb_ge_event_t*)&genrep)->length * 4;
+    }
+
+    buf = malloc(length + eventlength +
+            (genrep.response_type == XCB_REPLY ? 0 : sizeof(uint32_t)));
      if(!buf)
      {
          _xcb_conn_shutdown(c);
          return 0;
      }
+
      if(_xcb_in_read_block(c, buf, length) <= 0)
      {
          free(buf);
          return 0;
      }
+
+    /* pull in XGE event data if available, append after event struct */
+    if (eventlength)
+    {
+        if(_xcb_in_read_block(c, &((xcb_generic_event_t*)buf)[1], 
eventlength) <= 0)
+        {
+            free(buf);
+            return 0;
+        }
+    }
+
      if(pend && (pend->flags & XCB_REQUEST_DISCARD_REPLY))
      {
          free(buf);


More information about the Xcb mailing list