summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErkki Seppälä <erkki.seppala@vincit.fi>2010-11-29 12:43:51 +0200
committerAlan Coopersmith <alan.coopersmith@oracle.com>2012-04-23 19:04:43 -0700
commit0f38938a27df1f865dcdda35f4d2ef191092ba42 (patch)
tree1de739bfbd00bbecaafd2dfd89ce9ab46f99ce51
parente6e0e02e4bf764fa58798540793bdeb44a60cc7f (diff)
downloadxorg-lib-libXRes-0f38938a27df1f865dcdda35f4d2ef191092ba42.tar.gz
Implemented first part of XResource extension v1.2: XResQueryClientIds
Signed-off-by: Erkki Seppälä <erkki.seppala@vincit.fi> Reviewed-by: Rami Ylimäki <rami.ylimaki@vincit.fi> Reviewed-by: Tiago Vignatti <tiago.vignatti@nokia.com> Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
-rw-r--r--include/X11/extensions/XRes.h47
-rw-r--r--src/XRes.c118
2 files changed, 164 insertions, 1 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 6091c96..0781666 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;
@@ -228,3 +228,119 @@ 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;
+ CARD32 value;
+ _XRead32 (dpy, &value, 4);
+ client->spec.client = value;
+ _XRead32 (dpy, &value, 4);
+ client->spec.mask = value;
+ _XRead32 (dpy, &value, 4);
+ client->length = value;
+ 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;
+ }
+}