summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/X11/extensions/Xrandr.h41
-rw-r--r--src/Makefile.am2
-rw-r--r--src/Xrandr.c24
-rw-r--r--src/XrrCrtc.c193
4 files changed, 245 insertions, 15 deletions
diff --git a/include/X11/extensions/Xrandr.h b/include/X11/extensions/Xrandr.h
index 0a75576..892fae8 100644
--- a/include/X11/extensions/Xrandr.h
+++ b/include/X11/extensions/Xrandr.h
@@ -29,6 +29,7 @@
#define _XRANDR_H_
#include <X11/extensions/randr.h>
+#include <X11/extensions/Xrender.h>
#include <X11/Xfuncproto.h>
@@ -371,18 +372,46 @@ XRRSetCrtcGamma (Display *dpy, RRCrtc crtc, XRRCrtcGamma *gamma);
void
XRRFreeGamma (XRRCrtcGamma *gamma);
-/*
+/* Version 1.3 additions */
+
+XRRScreenResources *
+XRRGetScreenResourcesCurrent (Display *dpy, Window window);
+
+void
+XRRSetCrtcTransform (Display *dpy,
+ RRCrtc crtc,
+ XTransform *transform,
+ char *filter,
+ XFixed *params,
+ int nparams);
+
+typedef struct _XRRCrtcTransformAttributes {
+ XTransform pendingTransform;
+ char *pendingFilter;
+ int pendingNparams;
+ XFixed *pendingParams;
+ XTransform currentTransform;
+ char *currentFilter;
+ int currentNparams;
+ XFixed *currentParams;
+} XRRCrtcTransformAttributes;
+
+/*
+ * Get current crtc transforms and filters.
+ * Pass *attributes to XFree to free
+ */
+Status
+XRRGetCrtcTransform (Display *dpy,
+ RRCrtc crtc,
+ XRRCrtcTransformAttributes **attributes);
+
+/*
* intended to take RRScreenChangeNotify, or
* ConfigureNotify (on the root window)
* returns 1 if it is an event type it understands, 0 if not
*/
int XRRUpdateConfiguration(XEvent *event);
-/* Version 1.3 additions */
-
-XRRScreenResources *
-XRRGetScreenResourcesCurrent (Display *dpy, Window window);
-
_XFUNCPROTOEND
#endif /* _XRANDR_H_ */
diff --git a/src/Makefile.am b/src/Makefile.am
index b884a39..57aa59c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,7 +15,7 @@ AM_CFLAGS = @X_CFLAGS@ @RANDR_CFLAGS@ @MALLOC_ZERO_CFLAGS@
INCLUDES = -I$(top_srcdir)/include/X11/extensions
-libXrandr_la_LDFLAGS = -version-number 2:1:0 -no-undefined
+libXrandr_la_LDFLAGS = -version-number 2:2:0 -no-undefined
libXrandrincludedir = $(includedir)/X11/extensions
libXrandrinclude_HEADERS = $(top_srcdir)/include/X11/extensions/Xrandr.h
diff --git a/src/Xrandr.c b/src/Xrandr.c
index e3f9931..2de995c 100644
--- a/src/Xrandr.c
+++ b/src/Xrandr.c
@@ -86,18 +86,16 @@ static Bool XRRWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
return True;
}
case RRNotify: {
- XRRNotifyEvent *aevent = (XRRNotifyEvent *) event;
- xRRCrtcChangeNotifyEvent *awire = (xRRCrtcChangeNotifyEvent *) wire;
- aevent->type = awire->type & 0x7F;
- aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire);
- aevent->send_event = (awire->type & 0x80) != 0;
- aevent->display = dpy;
- aevent->subtype = awire->subCode;
- switch (aevent->subtype) {
+ switch (wire->u.u.detail) {
case RRNotify_OutputChange: {
XRROutputChangeNotifyEvent *aevent = (XRROutputChangeNotifyEvent *) event;
xRROutputChangeNotifyEvent *awire = (xRROutputChangeNotifyEvent *) 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->output = awire->output;
aevent->crtc = awire->crtc;
aevent->mode = awire->mode;
@@ -109,7 +107,12 @@ static Bool XRRWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
case RRNotify_CrtcChange: {
XRRCrtcChangeNotifyEvent *aevent = (XRRCrtcChangeNotifyEvent *) event;
xRRCrtcChangeNotifyEvent *awire = (xRRCrtcChangeNotifyEvent *) 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->crtc = awire->crtc;
aevent->mode = awire->mode;
aevent->rotation = awire->rotation;
@@ -122,7 +125,12 @@ static Bool XRRWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
case RRNotify_OutputProperty: {
XRROutputPropertyNotifyEvent *aevent = (XRROutputPropertyNotifyEvent *) event;
xRROutputPropertyNotifyEvent *awire = (xRROutputPropertyNotifyEvent *) 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->output = awire->output;
aevent->property = awire->atom;
aevent->timestamp = awire->timestamp;
diff --git a/src/XrrCrtc.c b/src/XrrCrtc.c
index 5e5c813..66dbc67 100644
--- a/src/XrrCrtc.c
+++ b/src/XrrCrtc.c
@@ -270,3 +270,196 @@ XRRFreeGamma (XRRCrtcGamma *crtc_gamma)
{
Xfree (crtc_gamma);
}
+
+/* Version 1.3 additions */
+
+static void
+XTransform_from_xRenderTransform (XTransform *x,
+ xRenderTransform *render)
+{
+ x->matrix[0][0] = render->matrix11;
+ x->matrix[0][1] = render->matrix12;
+ x->matrix[0][2] = render->matrix13;
+
+ x->matrix[1][0] = render->matrix21;
+ x->matrix[1][1] = render->matrix22;
+ x->matrix[1][2] = render->matrix23;
+
+ x->matrix[2][0] = render->matrix31;
+ x->matrix[2][1] = render->matrix32;
+ x->matrix[2][2] = render->matrix33;
+}
+
+static void
+xRenderTransform_from_XTransform (xRenderTransform *render,
+ XTransform *x)
+{
+ render->matrix11 = x->matrix[0][0];
+ render->matrix12 = x->matrix[0][1];
+ render->matrix13 = x->matrix[0][2];
+
+ render->matrix21 = x->matrix[1][0];
+ render->matrix22 = x->matrix[1][1];
+ render->matrix23 = x->matrix[1][2];
+
+ render->matrix31 = x->matrix[2][0];
+ render->matrix32 = x->matrix[2][1];
+ render->matrix33 = x->matrix[2][2];
+}
+
+void
+XRRSetCrtcTransform (Display *dpy,
+ RRCrtc crtc,
+ XTransform *transform,
+ char *filter,
+ XFixed *params,
+ int nparams)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRSetCrtcTransformReq *req;
+ int nbytes = strlen (filter);
+
+ RRSimpleCheckExtension (dpy, info);
+
+ LockDisplay(dpy);
+ GetReq (RRSetCrtcTransform, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRSetCrtcTransform;
+ req->crtc = crtc;
+
+ xRenderTransform_from_XTransform (&req->transform, transform);
+
+ req->nbytesFilter = nbytes;
+ req->length += ((nbytes + 3) >> 2) + nparams;
+ Data (dpy, filter, nbytes);
+ Data32 (dpy, params, nparams << 2);
+
+ UnlockDisplay (dpy);
+ SyncHandle ();
+}
+
+#define CrtcTransformExtra (SIZEOF(xRRGetCrtcTransformReply) - 32)
+
+static const xRenderTransform identity = {
+ 0x10000, 0, 0,
+ 0, 0x10000, 0,
+ 0, 0, 0x10000,
+};
+
+static Bool
+_XRRHasTransform (int major, int minor)
+{
+ return major > 1 || (major == 1 && minor >= 3);
+}
+
+Status
+XRRGetCrtcTransform (Display *dpy,
+ RRCrtc crtc,
+ XRRCrtcTransformAttributes **attributes)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ XRandRInfo *xrri;
+ xRRGetCrtcTransformReply rep;
+ xRRGetCrtcTransformReq *req;
+ int major_version, minor_version;
+ XRRCrtcTransformAttributes *attr;
+ char *extra = NULL, *e;
+ int p;
+
+ *attributes = NULL;
+
+ RRCheckExtension (dpy, info, False);
+
+ if (!XRRQueryVersion (dpy, &major_version, &minor_version) ||
+ !_XRRHasTransform (major_version, minor_version))
+ {
+ /* For pre-1.3 servers, just report identity matrices everywhere */
+ rep.pendingTransform = identity;
+ rep.pendingNbytesFilter = 0;
+ rep.pendingNparamsFilter = 0;
+ rep.currentTransform = identity;
+ rep.currentNbytesFilter = 0;
+ rep.currentNparamsFilter = 0;
+ }
+ else
+ {
+ LockDisplay (dpy);
+ GetReq (RRGetCrtcTransform, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRGetCrtcTransform;
+ req->crtc = crtc;
+
+ if (!_XReply (dpy, (xReply *) &rep, CrtcTransformExtra >> 2, xFalse))
+ {
+ rep.pendingTransform = identity;
+ rep.pendingNbytesFilter = 0;
+ rep.pendingNparamsFilter = 0;
+ rep.currentTransform = identity;
+ rep.currentNbytesFilter = 0;
+ rep.currentNparamsFilter = 0;
+ }
+ else
+ {
+ int extraBytes = rep.length * 4 - CrtcTransformExtra;
+ extra = Xmalloc (extraBytes);
+ if (!extra) {
+ _XEatData (dpy, extraBytes);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return False;
+ }
+ _XRead (dpy, extra, extraBytes);
+ }
+
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ }
+
+ attr = Xmalloc (sizeof (XRRCrtcTransformAttributes) +
+ rep.pendingNparamsFilter * sizeof (XFixed) +
+ rep.currentNparamsFilter * sizeof (XFixed) +
+ rep.pendingNbytesFilter + 1 +
+ rep.currentNbytesFilter + 1);
+
+ if (!attr) {
+ XFree (extra);
+ return False;
+ }
+ XTransform_from_xRenderTransform (&attr->pendingTransform, &rep.pendingTransform);
+ XTransform_from_xRenderTransform (&attr->currentTransform, &rep.currentTransform);
+
+ attr->pendingParams = (XFixed *) (attr + 1);
+ attr->currentParams = attr->pendingParams + rep.pendingNparamsFilter;
+ attr->pendingFilter = (char *) (attr->currentParams + rep.currentNparamsFilter);
+ attr->currentFilter = attr->pendingFilter + rep.pendingNbytesFilter + 1;
+
+ e = extra;
+
+ memcpy (attr->pendingFilter, e, rep.pendingNbytesFilter);
+ attr->pendingFilter[rep.pendingNbytesFilter] = '\0';
+ e += (rep.pendingNbytesFilter + 3) & ~3;
+ for (p = 0; p < rep.pendingNparamsFilter; p++) {
+ INT32 f;
+ memcpy (&f, e, 4);
+ e += 4;
+ attr->pendingParams[p] = (XFixed) f;
+ }
+ attr->pendingNparams = rep.pendingNparamsFilter;
+
+ memcpy (attr->currentFilter, e, rep.currentNbytesFilter);
+ attr->currentFilter[rep.currentNbytesFilter] = '\0';
+ e += (rep.currentNbytesFilter + 3) & ~3;
+ for (p = 0; p < rep.currentNparamsFilter; p++) {
+ INT32 f;
+ memcpy (&f, e, 4);
+ e += 4;
+ attr->currentParams[p] = (XFixed) f;
+ }
+ attr->currentNparams = rep.currentNparamsFilter;
+
+ if (extra)
+ XFree (extra);
+ *attributes = attr;
+
+ return True;
+}