diff options
-rw-r--r-- | include/X11/extensions/Xrandr.h | 41 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/Xrandr.c | 24 | ||||
-rw-r--r-- | src/XrrCrtc.c | 193 |
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; +} |