[RFC] [PATCH v2 11/12] [libXRes] Implemented first part of XResource extension v1.2: XResQueryClientIds

Erkki Seppälä erkki.seppala at vincit.fi
Fri Dec 31 05:32:49 PST 2010


Signed-off-by: Erkki Seppälä <erkki.seppala at vincit.fi>
Reviewed-by: Rami Ylimäki <rami.ylimaki at vincit.fi>
Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>
---
 include/X11/extensions/XRes.h |   47 ++++++++++++++++
 src/XRes.c                    |  118 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 162 insertions(+), 3 deletions(-)

diff --git a/include/X11/extensions/XRes.h b/include/X11/extensions/XRes.h
index ed4b2b8..b9759e3 100644
--- a/include/X11/extensions/XRes.h
+++ b/include/X11/extensions/XRes.h
@@ -7,6 +7,8 @@
 
 #include <X11/Xfuncproto.h>
 
+/* v1.0 */
+
 typedef struct {
   XID resource_base;
   XID resource_mask;
@@ -17,8 +19,33 @@ typedef struct {
   unsigned int count;
 } XResType;
 
+/* v1.2 */
+
+typedef enum {
+  XRES_CLIENT_ID_XID,
+  XRES_CLIENT_ID_PID,
+  XRES_CLIENT_ID_NR
+} XResClientIdType;
+
+typedef enum {
+  XRES_CLIENT_ID_XID_MASK = 1 << XRES_CLIENT_ID_XID,
+  XRES_CLIENT_ID_PID_MASK = 1 << XRES_CLIENT_ID_PID
+} XResClientIdMask;
+
+typedef struct {
+  XID           client;
+  unsigned int  mask;
+} XResClientIdSpec;
+
+typedef struct {
+  XResClientIdSpec spec;
+  long          length;
+  void         *value;
+} XResClientIdValue;
+
 _XFUNCPROTOBEGIN
 
+/* v1.0 */
 
 Bool XResQueryExtension (
    Display *dpy,
@@ -51,6 +78,26 @@ Status XResQueryClientPixmapBytes (
    unsigned long *bytes
 );
 
+/* v1.2 */
+
+Status XResQueryClientIds (
+   Display            *dpy,
+   long                num_specs,
+   XResClientIdSpec   *client_specs,   /* in */
+   long               *num_ids,        /* out */
+   XResClientIdValue **client_ids      /* out */
+);
+
+XResClientIdType XResGetClientIdType(XResClientIdValue* value);
+
+/* return -1 if no pid associated to the value */
+pid_t XResGetClientPid(XResClientIdValue* value);
+
+void XResClientIdsDestroy (
+   long                num_ids,
+   XResClientIdValue  *client_ids
+);
+
 _XFUNCPROTOEND
 
 #endif /* _XRES_H */
diff --git a/src/XRes.c b/src/XRes.c
index 518ad01..5c903a5 100644
--- a/src/XRes.c
+++ b/src/XRes.c
@@ -12,7 +12,7 @@
 #include <X11/extensions/extutil.h>
 #include <X11/extensions/XResproto.h>
 #include <X11/extensions/XRes.h>
-
+#include <assert.h>
 
 static XExtensionInfo _xres_ext_info_data;
 static XExtensionInfo *xres_ext_info = &_xres_ext_info_data;
@@ -38,7 +38,7 @@ static XExtensionHooks xres_extension_hooks = {
 };
 
 static XEXT_GENERATE_FIND_DISPLAY (find_display, xres_ext_info,
-                                   xres_extension_name, 
+                                   xres_extension_name,
                                    &xres_extension_hooks,
                                    0, NULL)
 
@@ -186,7 +186,7 @@ Status XResQueryClientResources (
             _XEatData(dpy, rep.length << 2);
         }
     }
-    
+
     UnlockDisplay (dpy);
     SyncHandle ();
     return result;
@@ -228,3 +228,115 @@ Status XResQueryClientPixmapBytes (
     return 1;
 }
 
+static Bool ReadClientValues(
+   Display              *dpy,
+   long                 num_ids,
+   XResClientIdValue   *client_ids /* out */
+)
+{
+    int c;
+    for (c = 0; c < num_ids; ++c) {
+        XResClientIdValue* client = client_ids + c;
+        _XRead32 (dpy, &client->spec.client, 4);
+        _XRead32 (dpy, &client->spec.mask, 4);
+        _XRead32 (dpy, &client->length, 4);
+        client->value = malloc(client->length);
+        _XRead32 (dpy, client->value, client->length);
+    }
+    return True;
+}
+
+Status XResQueryClientIds (
+   Display            *dpy,
+   long                num_specs,
+   XResClientIdSpec   *client_specs,   /* in */
+   long               *num_ids,        /* out */
+   XResClientIdValue **client_ids      /* out */
+)
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXResQueryClientIdsReq *req;
+    xXResQueryClientIdsReply rep;
+    int c;
+
+    *num_ids = 0;
+
+    XResCheckExtension (dpy, info, 0);
+    LockDisplay (dpy);
+    GetReq (XResQueryClientIds, req);
+    req->reqType = info->codes->major_opcode;
+    req->XResReqType = X_XResQueryClientIds;
+    req->length += num_specs * 2; /* 2 longs per client id spec */
+    req->numSpecs = num_specs;
+
+    for (c = 0; c < num_specs; ++c) {
+        Data32(dpy, &client_specs[c].client, 4);
+        Data32(dpy, &client_specs[c].mask, 4);
+    }
+
+    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
+        goto error;
+    }
+
+    *client_ids = calloc(rep.numIds, sizeof(**client_ids));
+    *num_ids = rep.numIds;
+
+    if (!ReadClientValues(dpy, *num_ids, *client_ids)) {
+        goto error;
+    }
+
+    UnlockDisplay (dpy);
+    SyncHandle ();
+    return Success;
+
+ error:
+    XResClientIdsDestroy (*num_ids, *client_ids);
+    *client_ids = NULL;
+
+    UnlockDisplay (dpy);
+    SyncHandle ();
+    return !Success;
+}
+
+void XResClientIdsDestroy (
+   long                num_ids,
+   XResClientIdValue  *client_ids
+)
+{
+    int c;
+    for (c = 0; c < num_ids; ++c) {
+        free(client_ids[c].value);
+    }
+    free(client_ids);
+}
+
+XResClientIdType XResGetClientIdType(
+    XResClientIdValue* value
+)
+{
+    int bit;
+    XResClientIdType idType = 0;
+    Bool found = False;
+    for (bit = 0; bit < XRES_CLIENT_ID_NR; ++bit) {
+        if (value->spec.mask & (1 << bit)) {
+            assert(!found);
+            found = True;
+            idType = bit;
+        }
+    }
+
+    assert(found);
+
+    return idType;
+}
+
+pid_t XResGetClientPid(
+    XResClientIdValue* value
+)
+{
+    if (value->spec.mask & XRES_CLIENT_ID_PID_MASK && value->length >= 4) {
+        return (pid_t) * (CARD32*) value->value;
+    } else {
+        return (pid_t) -1;
+    }
+}
-- 
1.7.0.4



More information about the xorg-devel mailing list