[PATCH] libXrandr: add support for provider objects.

Dave Airlie airlied at gmail.com
Thu Jul 19 22:27:00 PDT 2012


From: Dave Airlie <airlied at redhat.com>

This adds the client side libXrandr support for randr 1.4,
and provider objects.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 include/X11/extensions/Xrandr.h |  101 ++++++++++++
 src/Makefile.am                 |    4 +-
 src/Xrandr.c                    |   65 +++++++-
 src/XrrProvider.c               |  217 +++++++++++++++++++++++++
 src/XrrProviderProperty.c       |  339 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 724 insertions(+), 2 deletions(-)
 create mode 100644 src/XrrProvider.c
 create mode 100644 src/XrrProviderProperty.c

diff --git a/include/X11/extensions/Xrandr.h b/include/X11/extensions/Xrandr.h
index 4b29c3f..b1baf8a 100644
--- a/include/X11/extensions/Xrandr.h
+++ b/include/X11/extensions/Xrandr.h
@@ -39,6 +39,7 @@ _XFUNCPROTOBEGIN
 typedef XID RROutput;
 typedef XID RRCrtc;
 typedef XID RRMode;
+typedef XID RRProvider;
 
 typedef struct {
     int	width, height;
@@ -118,6 +119,41 @@ typedef struct {
     int state;			/* NewValue, Deleted */
 } XRROutputPropertyNotifyEvent;
 
+typedef struct {
+    int type;			/* event base */
+    unsigned long serial;	/* # of last request processed by server */
+    Bool send_event;		/* true if this came from a SendEvent request */
+    Display *display;		/* Display the event was read from */
+    Window window;		/* window which selected for this event */
+    int subtype;		/* RRNotify_ProviderChange */
+    RRProvider provider; 	/* current provider (or None) */
+    Time timestamp;		/* time of change */
+    unsigned int current_role;
+} XRRProviderChangeNotifyEvent;
+
+typedef struct {
+    int type;			/* event base */
+    unsigned long serial;	/* # of last request processed by server */
+    Bool send_event;		/* true if this came from a SendEvent request */
+    Display *display;		/* Display the event was read from */
+    Window window;		/* window which selected for this event */
+    int subtype;		/* RRNotify_ProviderProperty */
+    RRProvider provider;		/* related provider */
+    Atom property;		/* changed property */
+    Time timestamp;		/* time of change */
+    int state;			/* NewValue, Deleted */
+} XRRProviderPropertyNotifyEvent;
+
+typedef struct {
+    int type;			/* event base */
+    unsigned long serial;	/* # of last request processed by server */
+    Bool send_event;		/* true if this came from a SendEvent request */
+    Display *display;		/* Display the event was read from */
+    Window window;		/* window which selected for this event */
+    int subtype;		/* RRNotify_ResourceChange */
+    Time timestamp;		/* time of change */
+} XRRResourceChangeNotifyEvent;
+
 /* internal representation is private to the library */
 typedef struct _XRRScreenConfiguration XRRScreenConfiguration;
 
@@ -451,6 +487,71 @@ RROutput
 XRRGetOutputPrimary(Display *dpy,
 		    Window window);
 
+typedef struct _XRRProviderResources {
+    Time timestamp;
+    int nproviders;
+    RRProvider *providers;
+} XRRProviderResources;
+
+XRRProviderResources *
+XRRGetProviderResources(Display *dpy, Window window);
+
+void
+XRRFreeProviderResources(XRRProviderResources *resources);
+
+typedef struct _XRRProviderInfo {
+    unsigned int capabilities;
+    int ncrtcs;
+    RRCrtc	*crtcs;
+    int noutputs;
+    RROutput    *outputs;
+    char	    *name;
+    int nassociatedproviders;
+    RRProvider *associated_providers;
+    unsigned int *associated_capability;
+    int		    nameLen;
+} XRRProviderInfo;
+  
+XRRProviderInfo *
+XRRGetProviderInfo(Display *dpy, XRRScreenResources *resources, RRProvider provider);
+
+void
+XRRFreeProviderInfo(XRRProviderInfo *provider);
+
+int
+XRRSetProviderOutputSource(Display *dpy, XID provider, XID source_provider);
+
+int
+XRRSetProviderOffloadSink(Display *dpy, XID provider, XID sink_provider);
+
+Atom *
+XRRListProviderProperties (Display *dpy, RRProvider provider, int *nprop);
+
+XRRPropertyInfo *
+XRRQueryProviderProperty (Display *dpy, RRProvider provider, Atom property);
+
+void
+XRRConfigureProviderProperty (Display *dpy, RRProvider provider, Atom property,
+			    Bool pending, Bool range, int num_values,
+			    long *values);
+			
+void
+XRRChangeProviderProperty (Display *dpy, RRProvider provider,
+			 Atom property, Atom type,
+			 int format, int mode,
+			 _Xconst unsigned char *data, int nelements);
+
+void
+XRRDeleteProviderProperty (Display *dpy, RRProvider provider, Atom property);
+
+int
+XRRGetProviderProperty (Display *dpy, RRProvider provider,
+			Atom property, long offset, long length,
+			Bool _delete, Bool pending, Atom req_type,
+			Atom *actual_type, int *actual_format,
+			unsigned long *nitems, unsigned long *bytes_after,
+			unsigned char **prop);
+
 _XFUNCPROTOEND
 
 #endif /* _XRANDR_H_ */
diff --git a/src/Makefile.am b/src/Makefile.am
index d80a3c2..7a47b9c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,7 +8,9 @@ libXrandr_la_SOURCES = 	\
 	XrrMode.c	\
 	XrrOutput.c	\
 	XrrProperty.c	\
-	XrrScreen.c
+	XrrScreen.c     \
+	XrrProvider.c   \
+	XrrProviderProperty.c
 
 libXrandr_la_LIBADD = @RANDR_LIBS@
 
diff --git a/src/Xrandr.c b/src/Xrandr.c
index 2bdbe97..b1e97ec 100644
--- a/src/Xrandr.c
+++ b/src/Xrandr.c
@@ -137,7 +137,46 @@ static Bool XRRWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
 	    aevent->state = awire->state;
 	    return True;
 	}
-
+	case RRNotify_ProviderChange: {
+	    XRRProviderChangeNotifyEvent *aevent = (XRRProviderChangeNotifyEvent *) event;
+	    xRRProviderChangeNotifyEvent *awire = (xRRProviderChangeNotifyEvent *) wire;
+	    aevent->type = awire->type & 0x7F;
+	    aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire);
+	    aevent->send_event = (awire->type & 0x80) != 0;
+	    aevent->display = dpy;
+	    aevent->window = awire->window;
+	    aevent->subtype = awire->subCode;
+	    aevent->provider = awire->provider;
+	    aevent->timestamp = awire->timestamp;
+	    return True;
+	}
+	case RRNotify_ProviderProperty: {
+	    XRRProviderPropertyNotifyEvent *aevent = (XRRProviderPropertyNotifyEvent *) event;
+	    xRRProviderPropertyNotifyEvent *awire = (xRRProviderPropertyNotifyEvent *) wire;
+	    aevent->type = awire->type & 0x7F;
+	    aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire);
+	    aevent->send_event = (awire->type & 0x80) != 0;
+	    aevent->display = dpy;
+	    aevent->window = awire->window;
+	    aevent->subtype = awire->subCode;
+	    aevent->provider = awire->provider;
+	    aevent->property = awire->atom;
+	    aevent->timestamp = awire->timestamp;
+	    aevent->state = awire->state;
+	    return True;
+	}
+	case RRNotify_ResourceChange: {
+	    XRRResourceChangeNotifyEvent *aevent = (XRRResourceChangeNotifyEvent *) event;
+	    xRRResourceChangeNotifyEvent *awire = (xRRResourceChangeNotifyEvent *) wire;
+	    aevent->type = awire->type & 0x7F;
+	    aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire);
+	    aevent->send_event = (awire->type & 0x80) != 0;
+	    aevent->display = dpy;
+	    aevent->window = awire->window;
+	    aevent->subtype = awire->subCode;
+	    aevent->timestamp = awire->timestamp;
+	    return True;
+	}
 	    break;
 	}
       }
@@ -214,6 +253,30 @@ static Status XRREventToWire(Display *dpy, XEvent *event, xEvent *wire)
 	    awire->state = aevent->state;
 	    return True;
 	}
+	case RRNotify_ProviderChange: {
+	    xRRProviderChangeNotifyEvent *awire = (xRRProviderChangeNotifyEvent *) wire;
+	    XRRProviderChangeNotifyEvent *aevent = (XRRProviderChangeNotifyEvent *) event;
+	    awire->window = aevent->window;
+	    awire->provider = aevent->provider;
+	    return True;
+	}
+	case RRNotify_ProviderProperty: {
+	    xRRProviderPropertyNotifyEvent *awire = (xRRProviderPropertyNotifyEvent *) wire;
+	    XRRProviderPropertyNotifyEvent *aevent = (XRRProviderPropertyNotifyEvent *) event;
+	    awire->window = aevent->window;
+	    awire->provider = aevent->provider;
+	    awire->atom = aevent->property;
+	    awire->timestamp = aevent->timestamp;
+	    awire->state = aevent->state;
+	    return True;
+	}
+	case RRNotify_ResourceChange: {
+	    xRRResourceChangeNotifyEvent *awire = (xRRResourceChangeNotifyEvent *) wire;
+	    XRRResourceChangeNotifyEvent *aevent = (XRRResourceChangeNotifyEvent *) event;
+	    awire->window = aevent->window;
+	    awire->timestamp = aevent->timestamp;
+	    return True;
+	}
 	}
       }
     }
diff --git a/src/XrrProvider.c b/src/XrrProvider.c
new file mode 100644
index 0000000..fcd06ff
--- /dev/null
+++ b/src/XrrProvider.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright © 2011 Dave Airlie
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/Xlib.h>
+/* we need to be able to manipulate the Display structure on events */
+#include <X11/Xlibint.h>
+#include <X11/extensions/render.h>
+#include <X11/extensions/Xrender.h>
+#include "Xrandrint.h"
+
+XRRProviderResources *
+XRRGetProviderResources(Display *dpy, Window window)
+{
+    XExtDisplayInfo		*info = XRRFindDisplay(dpy);
+    xRRGetProvidersReply rep;
+    xRRGetProvidersReq *req;
+    XRRProviderResources *xrpr;
+    long nbytes, nbytesRead;
+    int rbytes;
+
+    RRCheckExtension (dpy, info, NULL);
+
+    LockDisplay (dpy);
+
+    GetReq(RRGetProviders, req);
+    req->reqType = info->codes->major_opcode;
+    req->randrReqType = X_RRGetProviders;
+    req->window = window;
+    
+    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
+    {
+      UnlockDisplay (dpy);
+      SyncHandle ();
+      return NULL;
+    }
+
+    nbytes = (long) rep.length << 2;
+
+    nbytesRead = (long) (rep.nProviders * 4);
+
+    rbytes = (sizeof(XRRProviderResources) + rep.nProviders * sizeof(RRProvider));
+    xrpr = (XRRProviderResources *) Xmalloc(rbytes);
+
+    if (xrpr == NULL) {
+       _XEatData (dpy, (unsigned long) nbytes);
+       UnlockDisplay (dpy);
+       SyncHandle ();
+       return NULL;
+    }
+
+    xrpr->timestamp = rep.timestamp;
+    xrpr->nproviders = rep.nProviders;
+    xrpr->providers = (RRProvider *)(xrpr + 1);
+
+    _XRead32(dpy, xrpr->providers, rep.nProviders << 2);
+
+    if (nbytes > nbytesRead)
+      _XEatData (dpy, (unsigned long) (nbytes - nbytesRead));
+
+
+    UnlockDisplay (dpy);
+    SyncHandle();
+
+    return (XRRProviderResources *) xrpr;
+}
+
+void
+XRRFreeProviderResources(XRRProviderResources *provider_resources)
+{
+    free(provider_resources);
+}
+
+#define ProviderInfoExtra	(SIZEOF(xRRGetProviderInfoReply) - 32)  
+XRRProviderInfo *
+XRRGetProviderInfo(Display *dpy, XRRScreenResources *resources, RRProvider provider)
+{
+    XExtDisplayInfo	    *info = XRRFindDisplay(dpy);
+    xRRGetProviderInfoReply rep;
+    xRRGetProviderInfoReq *req;
+    int nbytes, nbytesRead, rbytes;
+    XRRProviderInfo *xpi;
+
+    RRCheckExtension (dpy, info, NULL);
+
+    LockDisplay (dpy);
+    GetReq (RRGetProviderInfo, req);
+    req->reqType = info->codes->major_opcode;
+    req->randrReqType = X_RRGetProviderInfo;
+    req->provider = provider;
+    req->configTimestamp = resources->configTimestamp;
+
+    if (!_XReply (dpy, (xReply *) &rep, ProviderInfoExtra >> 2, xFalse))
+    {
+	UnlockDisplay (dpy);
+	SyncHandle ();
+	return NULL;
+    }
+
+    nbytes = ((long) rep.length << 2) - ProviderInfoExtra;
+
+    nbytesRead = (long)(rep.nCrtcs * 4 +
+			rep.nOutputs * 4 +
+			rep.nAssociatedProviders * 8 +
+			((rep.nameLength + 3) & ~3));
+
+    rbytes = (sizeof(XRRProviderInfo) +
+	      rep.nCrtcs * sizeof(RRCrtc) +
+	      rep.nOutputs * sizeof(RROutput) +
+	      rep.nAssociatedProviders * (sizeof(RRProvider) + sizeof(unsigned int))+
+	      rep.nameLength + 1);
+
+    xpi = (XRRProviderInfo *)Xmalloc(rbytes);
+    if (xpi == NULL) {
+	_XEatData (dpy, (unsigned long) nbytes);
+	UnlockDisplay (dpy);
+	SyncHandle ();
+	return NULL;
+    }
+
+    xpi->capabilities = rep.capabilities;
+    xpi->ncrtcs = rep.nCrtcs;
+    xpi->noutputs = rep.nOutputs;
+    xpi->nassociatedproviders = rep.nAssociatedProviders;
+    xpi->crtcs = (RRCrtc *)(xpi + 1);
+    xpi->outputs = (RROutput *)(xpi->crtcs + rep.nCrtcs);
+    xpi->associated_providers = (RRProvider *)(xpi->outputs + rep.nOutputs);
+    xpi->associated_capability = (unsigned int *)(xpi->associated_providers + rep.nAssociatedProviders);
+    xpi->name = (char *)(xpi->associated_capability + rep.nAssociatedProviders);
+
+    _XRead32(dpy, xpi->crtcs, rep.nCrtcs << 2);
+    _XRead32(dpy, xpi->outputs, rep.nOutputs << 2);
+
+    _XRead32(dpy, xpi->associated_providers, rep.nAssociatedProviders << 2);
+    _XRead32(dpy, xpi->associated_capability, rep.nAssociatedProviders << 2);
+
+    _XReadPad(dpy, xpi->name, rep.nameLength);
+    xpi->name[rep.nameLength] = '\0';
+
+    /*
+     * Skip any extra data
+     */
+    if (nbytes > nbytesRead)
+	_XEatData (dpy, (unsigned long) (nbytes - nbytesRead));
+
+    UnlockDisplay (dpy);
+    SyncHandle ();
+    return (XRRProviderInfo *) xpi;
+}
+
+void
+XRRFreeProviderInfo(XRRProviderInfo *provider)
+{
+    free(provider);
+}
+
+int
+XRRSetProviderOutputSource(Display *dpy, XID provider,
+			   XID source_provider)
+{
+    XExtDisplayInfo	    *info = XRRFindDisplay(dpy);
+    xRRSetProviderOutputSourceReq *req;
+
+    RRCheckExtension (dpy, info, 0);
+    LockDisplay (dpy);
+    GetReq (RRSetProviderOutputSource, req);
+    req->reqType = info->codes->major_opcode;
+    req->randrReqType = X_RRSetProviderOutputSource;
+    req->provider = provider;
+    req->source_provider = source_provider;
+    UnlockDisplay (dpy);
+    SyncHandle ();
+    return 0;
+}
+
+int
+XRRSetProviderOffloadSink(Display *dpy, XID provider,
+			  XID sink_provider)
+{
+    XExtDisplayInfo	    *info = XRRFindDisplay(dpy);
+    xRRSetProviderOffloadSinkReq *req;
+
+    RRCheckExtension (dpy, info, 0);
+    LockDisplay (dpy);
+    GetReq (RRSetProviderOffloadSink, req);
+    req->reqType = info->codes->major_opcode;
+    req->randrReqType = X_RRSetProviderOffloadSink;
+    req->provider = provider;
+    req->sink_provider = sink_provider;
+    UnlockDisplay (dpy);
+    SyncHandle ();
+    return 0;
+}
diff --git a/src/XrrProviderProperty.c b/src/XrrProviderProperty.c
new file mode 100644
index 0000000..c8c08e9
--- /dev/null
+++ b/src/XrrProviderProperty.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/Xlib.h>
+/* we need to be able to manipulate the Display structure on events */
+#include <X11/Xlibint.h>
+#include <X11/extensions/render.h>
+#include <X11/extensions/Xrender.h>
+#include "Xrandrint.h"
+
+Atom *
+XRRListProviderProperties (Display *dpy, RRProvider provider, int *nprop)
+{
+    XExtDisplayInfo		*info = XRRFindDisplay(dpy);
+    xRRListProviderPropertiesReply rep;
+    xRRListProviderPropertiesReq	*req;
+    int				nbytes, rbytes;
+    Atom			*props = NULL;
+
+    RRCheckExtension (dpy, info, NULL);
+
+    LockDisplay (dpy);
+    GetReq (RRListProviderProperties, req);
+    req->reqType = info->codes->major_opcode;
+    req->randrReqType = X_RRListProviderProperties;
+    req->provider = provider;
+
+    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
+	UnlockDisplay (dpy);
+	SyncHandle ();
+	*nprop = 0;
+	return NULL;
+    }
+
+    if (rep.nAtoms) {
+	rbytes = rep.nAtoms * sizeof (Atom);
+	nbytes = rep.nAtoms << 2;
+
+	props = (Atom *) Xmalloc (rbytes);
+	if (props == NULL) {
+	    _XEatData (dpy, nbytes);
+	    UnlockDisplay (dpy);
+	    SyncHandle ();
+	    *nprop = 0;
+	    return NULL;
+	}
+
+	_XRead32 (dpy, props, nbytes);
+    }
+
+    *nprop = rep.nAtoms;
+    UnlockDisplay (dpy);
+    SyncHandle ();
+    return props;
+}
+
+XRRPropertyInfo *
+XRRQueryProviderProperty (Display *dpy, RRProvider provider, Atom property)
+{
+    XExtDisplayInfo		*info = XRRFindDisplay(dpy);
+    xRRQueryProviderPropertyReply rep;
+    xRRQueryProviderPropertyReq	*req;
+    int				rbytes, nbytes;
+    XRRPropertyInfo		*prop_info;
+
+    RRCheckExtension (dpy, info, NULL);
+
+    LockDisplay (dpy);
+    GetReq (RRQueryProviderProperty, req);
+    req->reqType = info->codes->major_opcode;
+    req->randrReqType = X_RRQueryProviderProperty;
+    req->provider = provider;
+    req->property = property;
+
+    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
+	UnlockDisplay (dpy);
+	SyncHandle ();
+	return NULL;
+    }
+
+    rbytes = sizeof (XRRPropertyInfo) + rep.length * sizeof (long);
+    nbytes = rep.length << 2;
+
+    prop_info = (XRRPropertyInfo *) Xmalloc (rbytes);
+    if (prop_info == NULL) {
+	_XEatData (dpy, nbytes);
+	UnlockDisplay (dpy);
+	SyncHandle ();
+	return NULL;
+    }
+
+    prop_info->pending = rep.pending;
+    prop_info->range = rep.range;
+    prop_info->immutable = rep.immutable;
+    prop_info->num_values = rep.length;
+    if (rep.length != 0) {
+	prop_info->values = (long *) (prop_info + 1);
+	_XRead32 (dpy, prop_info->values, nbytes);
+    } else {
+	prop_info->values = NULL;
+    }
+
+    UnlockDisplay (dpy);
+    SyncHandle ();
+    return prop_info;
+}
+
+void
+XRRConfigureProviderProperty (Display *dpy, RRProvider provider, Atom property,
+			    Bool pending, Bool range, int num_values,
+			    long *values)
+{
+    XExtDisplayInfo		    *info = XRRFindDisplay(dpy);
+    xRRConfigureProviderPropertyReq   *req;
+    long len;
+
+    RRSimpleCheckExtension (dpy, info);
+
+    LockDisplay(dpy);
+    GetReq (RRConfigureProviderProperty, req);
+    req->reqType = info->codes->major_opcode;
+    req->randrReqType = X_RRConfigureProviderProperty;
+    req->provider = provider;
+    req->property = property;
+    req->pending = pending;
+    req->range = range;
+
+    len = num_values;
+    if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) {
+	SetReqLen(req, len, len);
+	len = (long)num_values << 2;
+	Data32 (dpy, values, len);
+    } /* else force BadLength */
+
+    UnlockDisplay(dpy);
+    SyncHandle();
+}
+			
+void
+XRRChangeProviderProperty (Display *dpy, RRProvider provider,
+			 Atom property, Atom type,
+			 int format, int mode,
+			 _Xconst unsigned char *data, int nelements)
+{
+    XExtDisplayInfo		*info = XRRFindDisplay(dpy);
+    xRRChangeProviderPropertyReq	*req;
+    long len;
+
+    RRSimpleCheckExtension (dpy, info);
+
+    LockDisplay(dpy);
+    GetReq (RRChangeProviderProperty, req);
+    req->reqType = info->codes->major_opcode;
+    req->randrReqType = X_RRChangeProviderProperty;
+    req->provider = provider;
+    req->property = property;
+    req->type = type;
+    req->mode = mode;
+    if (nelements < 0) {
+	req->nUnits = 0;
+	req->format = 0; /* ask for garbage, get garbage */
+    } else {
+	req->nUnits = nelements;
+	req->format = format;
+    }
+
+    switch (req->format) {
+    case 8:
+	len = ((long)nelements + 3) >> 2;
+	if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) {
+	    SetReqLen(req, len, len);
+	    Data (dpy, (char *)data, nelements);
+	} /* else force BadLength */
+	break;
+
+    case 16:
+	len = ((long)nelements + 1) >> 1;
+	if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) {
+	    SetReqLen(req, len, len);
+	    len = (long)nelements << 1;
+	    Data16 (dpy, (short *) data, len);
+	} /* else force BadLength */
+	break;
+
+    case 32:
+	len = nelements;
+	if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) {
+	    SetReqLen(req, len, len);
+	    len = (long)nelements << 2;
+	    Data32 (dpy, (long *) data, len);
+	} /* else force BadLength */
+	break;
+
+    default:
+	/* BadValue will be generated */ ;
+    }
+
+    UnlockDisplay(dpy);
+    SyncHandle();
+}
+
+void
+XRRDeleteProviderProperty (Display *dpy, RRProvider provider, Atom property)
+{
+    XExtDisplayInfo		*info = XRRFindDisplay(dpy);
+    xRRDeleteProviderPropertyReq *req;
+
+    RRSimpleCheckExtension (dpy, info);
+
+    LockDisplay(dpy);
+    GetReq(RRDeleteProviderProperty, req);
+    req->reqType = info->codes->major_opcode;
+    req->randrReqType = X_RRDeleteProviderProperty;
+    req->provider = provider;
+    req->property = property;
+    UnlockDisplay(dpy);
+    SyncHandle();
+}
+
+int
+XRRGetProviderProperty (Display *dpy, RRProvider provider,
+		      Atom property, long offset, long length,
+		      Bool delete, Bool pending, Atom req_type, 
+		      Atom *actual_type, int *actual_format,
+		      unsigned long *nitems, unsigned long *bytes_after,
+		      unsigned char **prop)
+{
+    XExtDisplayInfo		*info = XRRFindDisplay(dpy);
+    xRRGetProviderPropertyReply	rep;
+    xRRGetProviderPropertyReq	*req;
+    long    			nbytes, rbytes;
+
+    RRCheckExtension (dpy, info, 1);
+
+    LockDisplay (dpy);
+    GetReq (RRGetProviderProperty, req);
+    req->reqType = info->codes->major_opcode;
+    req->randrReqType = X_RRGetProviderProperty;
+    req->provider = provider;
+    req->property = property;
+    req->type = req_type;
+    req->longOffset = offset;
+    req->longLength = length;
+    req->delete = delete;
+    req->pending = pending;
+
+    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
+    {
+	UnlockDisplay (dpy);
+	SyncHandle ();
+	return ((xError *)&rep)->errorCode;
+    }
+
+    *prop = (unsigned char *) NULL;
+    if (rep.propertyType != None) {
+	/*
+	 * One extra byte is malloced than is needed to contain the property
+	 * data, but this last byte is null terminated and convenient for
+	 * returning string properties, so the client doesn't then have to
+	 * recopy the string to make it null terminated.
+	 */
+	switch (rep.format) {
+	case 8:
+	    nbytes = rep.nItems;
+	    rbytes = rep.nItems + 1;
+	    if (rbytes > 0 &&
+		(*prop = (unsigned char *) Xmalloc ((unsigned)rbytes)))
+		_XReadPad (dpy, (char *) *prop, nbytes);
+	    break;
+
+	case 16:
+	    nbytes = rep.nItems << 1;
+	    rbytes = rep.nItems * sizeof (short) + 1;
+	    if (rbytes > 0 &&
+		(*prop = (unsigned char *) Xmalloc ((unsigned)rbytes)))
+		_XRead16Pad (dpy, (short *) *prop, nbytes);
+	    break;
+
+	case 32:
+	    nbytes = rep.nItems << 2;
+	    rbytes = rep.nItems * sizeof (long) + 1;
+	    if (rbytes > 0 &&
+		(*prop = (unsigned char *) Xmalloc ((unsigned)rbytes)))
+		_XRead32 (dpy, (long *) *prop, nbytes);
+	    break;
+
+	default:
+	    /*
+	     * This part of the code should never be reached.  If it is,
+	     * the server sent back a property with an invalid format.
+	     */
+	    nbytes = rep.length << 2;
+	    _XEatData(dpy, (unsigned long) nbytes);
+	    UnlockDisplay(dpy);
+	    SyncHandle();
+	    return(BadImplementation);
+	}
+	if (! *prop) {
+	    _XEatData(dpy, (unsigned long) nbytes);
+	    UnlockDisplay(dpy);
+	    SyncHandle();
+	    return(BadAlloc);
+	}
+	(*prop)[rbytes - 1] = '\0';
+    }
+
+    *actual_type = rep.propertyType;
+    *actual_format = rep.format;
+    *nitems = rep.nItems;
+    *bytes_after = rep.bytesAfter;
+    UnlockDisplay (dpy);
+    SyncHandle ();
+
+    return Success;
+}
-- 
1.7.10.2



More information about the xorg-devel mailing list