summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-03-21 02:39:49 -0700
committerKeith Packard <keithp@keithp.com>2008-11-24 13:24:40 -0800
commit7c61db66a470a8306e346ed8bf8934f014dada42 (patch)
tree27215d0f0fa4a2823222fb37fc0ae5cff541780a
parentfa6a1df209bd74da1d545982cca437afc2198cc1 (diff)
Create rrtransform.[ch]. Add RRTransform argument to RRCrtcNotify.
Instead of using a separate function to notify DIX about transform changes, add the transform to RRCrtcNotify so that the whole Crtc state changes atomically.
-rw-r--r--hw/xfree86/modes/xf86Crtc.c5
-rw-r--r--hw/xfree86/modes/xf86RandR12.c4
-rw-r--r--hw/xfree86/modes/xf86Rotate.c2
-rw-r--r--randr/Makefile.am4
-rw-r--r--randr/mirandr.c2
-rw-r--r--randr/randrstr.h22
-rw-r--r--randr/rrcrtc.c230
-rw-r--r--randr/rrinfo.c2
-rw-r--r--randr/rrtransform.c259
-rw-r--r--randr/rrtransform.h75
10 files changed, 355 insertions, 250 deletions
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index bccda0ee9..d24fc86f0 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -282,6 +282,7 @@ xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotati
crtc->y = y;
crtc->rotation = rotation;
if (transform) {
+ RRTransformCopy (&crtc->transform, transform);
crtc->transform = *transform;
crtc->transformPresent = TRUE;
} else
@@ -367,10 +368,6 @@ xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotati
if (output->crtc == crtc)
output->funcs->commit(output);
}
-#ifdef RANDR_12_INTERFACE
- if (crtc->randr_crtc)
- RRCrtcSetTransform (crtc->randr_crtc, transform);
-#endif
/* XXX free adjustedmode */
ret = TRUE;
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 49add634a..9d7750fbd 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -715,7 +715,9 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
}
}
ret = RRCrtcNotify (randr_crtc, randr_mode, x, y,
- rotation, numOutputs, randr_outputs);
+ rotation,
+ crtc->transformPresent ? &crtc->transform : NULL,
+ numOutputs, randr_outputs);
xfree(randr_outputs);
return ret;
}
diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
index 7d35c3494..75f4a55bb 100644
--- a/hw/xfree86/modes/xf86Rotate.c
+++ b/hw/xfree86/modes/xf86Rotate.c
@@ -395,7 +395,7 @@ xf86CrtcRotate (xf86CrtcPtr crtc)
if (crtc->transformPresent)
transform = &crtc->transform;
- if (!RRComputeTransform (crtc->x, crtc->y,
+ if (!RRTransformCompute (crtc->x, crtc->y,
crtc->mode.HDisplay, crtc->mode.VDisplay,
crtc->rotation,
transform,
diff --git a/randr/Makefile.am b/randr/Makefile.am
index 20b0f72e0..3d16ede72 100644
--- a/randr/Makefile.am
+++ b/randr/Makefile.am
@@ -20,7 +20,9 @@ librandr_la_SOURCES = \
rrpointer.c \
rrproperty.c \
rrscreen.c \
- rrsdispatch.c
+ rrsdispatch.c \
+ rrtransform.h \
+ rrtransform.c
if XINERAMA
librandr_la_SOURCES += ${XINERAMA_SRCS}
diff --git a/randr/mirandr.c b/randr/mirandr.c
index 777785380..05375e46c 100644
--- a/randr/mirandr.c
+++ b/randr/mirandr.c
@@ -159,7 +159,7 @@ miRandRInit (ScreenPtr pScreen)
return FALSE;
if (!RROutputSetConnection (output, RR_Connected))
return FALSE;
- RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, 1, &output);
+ RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, NULL, 1, &output);
#endif
return TRUE;
}
diff --git a/randr/randrstr.h b/randr/randrstr.h
index d4cfa67e6..822e37747 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -43,6 +43,7 @@
#include "pixmapstr.h"
#include "extnsionst.h"
#include "servermd.h"
+#include "rrtransform.h"
#include <X11/extensions/randr.h>
#include <X11/extensions/randrproto.h>
#ifdef RENDER
@@ -78,7 +79,6 @@ typedef struct _rrPropertyValue RRPropertyValueRec, *RRPropertyValuePtr;
typedef struct _rrProperty RRPropertyRec, *RRPropertyPtr;
typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr;
typedef struct _rrOutput RROutputRec, *RROutputPtr;
-typedef struct _rrTransform RRTransformRec, *RRTransformPtr;
struct _rrMode {
int refcnt;
@@ -105,17 +105,6 @@ struct _rrProperty {
RRPropertyValueRec current, pending;
};
-struct _rrTransform {
- PictTransform transform;
- struct pict_f_transform f_transform;
- struct pict_f_transform f_inverse;
- PictFilterPtr filter;
- xFixed *params;
- int nparams;
- int width;
- int height;
-};
-
struct _rrCrtc {
RRCrtc id;
ScreenPtr pScreen;
@@ -557,6 +546,7 @@ RRCrtcNotify (RRCrtcPtr crtc,
int x,
int y,
Rotation rotation,
+ RRTransformPtr transform,
int numOutputs,
RROutputPtr *outputs);
@@ -618,7 +608,7 @@ RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height);
* Return TRUE if the resulting transform is not a simple translation.
*/
Bool
-RRComputeTransform (int x,
+RRTransformCompute (int x,
int y,
int width,
int height,
@@ -636,12 +626,6 @@ RRTransformPtr
RRCrtcGetTransform (RRCrtcPtr crtc);
/*
- * Mark the pending transform as current
- */
-void
-RRCrtcSetTransform (RRCrtcPtr crtc, RRTransformPtr transform);
-
-/*
* Check whether the pending and current transforms are the same
*/
Bool
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 091517a05..1b6350eff 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -48,69 +48,6 @@ RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged)
}
}
-static void
-RRTransformInit (RRTransformPtr transform)
-{
- PictureTransformInitIdentity (&transform->transform);
- pict_f_transform_init_identity (&transform->f_transform);
- pict_f_transform_init_identity (&transform->f_inverse);
- transform->filter = NULL;
- transform->params = NULL;
- transform->nparams = 0;
-}
-
-static Bool
-RRTransformSetFilter (RRTransformPtr dst,
- PictFilterPtr filter,
- xFixed *params,
- int nparams,
- int width,
- int height)
-{
- xFixed *new_params;
-
- if (nparams)
- {
- new_params = xalloc (nparams * sizeof (xFixed));
- if (!new_params)
- return FALSE;
- memcpy (new_params, params, nparams * sizeof (xFixed));
- }
- else
- new_params = NULL;
- if (dst->params)
- xfree (dst->params);
- dst->filter = filter;
- dst->params = new_params;
- dst->nparams = nparams;
- dst->width = width;
- dst->height = height;
- return TRUE;
-}
-
-static Bool
-RRTransformCopy (RRTransformPtr dst, RRTransformPtr src)
-{
- if (src)
- {
- if (!RRTransformSetFilter (dst, src->filter,
- src->params, src->nparams, src->width, src->height))
- return FALSE;
- dst->transform = src->transform;
- dst->f_transform = src->f_transform;
- dst->f_inverse = src->f_inverse;
- }
- else
- {
- if (!RRTransformSetFilter (dst, NULL, NULL, 0, 0, 0))
- return FALSE;
- PictureTransformInitIdentity (&dst->transform);
- pict_f_transform_init_identity (&dst->f_transform);
- pict_f_transform_init_identity (&dst->f_inverse);
- }
- return TRUE;
-}
-
/*
* Create a CRTC
*/
@@ -196,6 +133,7 @@ RRCrtcNotify (RRCrtcPtr crtc,
int x,
int y,
Rotation rotation,
+ RRTransformPtr transform,
int numOutputs,
RROutputPtr *outputs)
{
@@ -291,6 +229,10 @@ RRCrtcNotify (RRCrtcPtr crtc,
crtc->rotation = rotation;
RRCrtcChanged (crtc, TRUE);
}
+ if (!RRTransformEqual (transform, &crtc->client_current_transform)) {
+ RRTransformCopy (&crtc->client_current_transform, transform);
+ RRCrtcChanged (crtc, TRUE);
+ }
return TRUE;
}
@@ -391,7 +333,7 @@ RRCrtcSet (RRCrtcPtr crtc,
if (!mode)
{
- RRCrtcNotify (crtc, NULL, x, y, rotation, 0, NULL);
+ RRCrtcNotify (crtc, NULL, x, y, rotation, NULL, 0, NULL);
ret = TRUE;
}
else
@@ -417,7 +359,7 @@ RRCrtcSet (RRCrtcPtr crtc,
*/
if (ret)
{
- RRCrtcNotify (crtc, mode, x, y, rotation, 1, outputs);
+ RRCrtcNotify (crtc, mode, x, y, rotation, NULL, 1, outputs);
RRScreenSizeNotify (pScreen);
}
}
@@ -450,27 +392,6 @@ RRCrtcGetTransform (RRCrtcPtr crtc)
}
/*
- * Called when driver applies a transform to a crtc
- */
-void
-RRCrtcSetTransform (RRCrtcPtr crtc, RRTransformPtr transform)
-{
- if (!crtc->mode)
- return;
-
- RRTransformCopy (&crtc->client_current_transform, transform);
-
- RRComputeTransform (crtc->x, crtc->y,
- crtc->mode->mode.width,
- crtc->mode->mode.height,
- crtc->rotation,
- transform,
- &crtc->transform,
- &crtc->f_transform,
- &crtc->f_inverse);
-}
-
-/*
* Check whether the pending and current transforms are the same
*/
Bool
@@ -674,141 +595,6 @@ RRCrtcTransformSet (RRCrtcPtr crtc,
return Success;
}
-#define F(x) IntToxFixed(x)
-
-/*
- * Compute the complete transformation matrix including
- * client-specified transform, rotation/reflection values and the crtc
- * offset.
- *
- * Return TRUE if the resulting transform is not a simple translation.
- */
-Bool
-RRComputeTransform (int x,
- int y,
- int width,
- int height,
- Rotation rotation,
- RRTransformPtr rr_transform,
-
- PictTransformPtr transform,
- struct pict_f_transform *f_transform,
- struct pict_f_transform *f_inverse)
-{
- PictTransform inverse;
-
- PictureTransformInitIdentity (transform);
- PictureTransformInitIdentity (&inverse);
- pict_f_transform_init_identity (f_transform);
- pict_f_transform_init_identity (f_inverse);
- if (rotation != RR_Rotate_0)
- {
- double f_rot_cos, f_rot_sin, f_rot_dx, f_rot_dy;
- double f_scale_x, f_scale_y, f_scale_dx, f_scale_dy;
- xFixed rot_cos, rot_sin, rot_dx, rot_dy;
- xFixed scale_x, scale_y, scale_dx, scale_dy;
-
- /* rotation */
- switch (rotation & 0xf) {
- default:
- case RR_Rotate_0:
- f_rot_cos = 1; f_rot_sin = 0;
- f_rot_dx = 0; f_rot_dy = 0;
- rot_cos = F ( 1); rot_sin = F ( 0);
- rot_dx = F ( 0); rot_dy = F ( 0);
- break;
- case RR_Rotate_90:
- f_rot_cos = 0; f_rot_sin = 1;
- f_rot_dx = height; f_rot_dy = 0;
- rot_cos = F ( 0); rot_sin = F ( 1);
- rot_dx = F ( height); rot_dy = F (0);
- break;
- case RR_Rotate_180:
- f_rot_cos = -1; f_rot_sin = 0;
- f_rot_dx = width; f_rot_dy = height;
- rot_cos = F (-1); rot_sin = F ( 0);
- rot_dx = F (width); rot_dy = F ( height);
- break;
- case RR_Rotate_270:
- f_rot_cos = 0; f_rot_sin = -1;
- f_rot_dx = 0; f_rot_dy = width;
- rot_cos = F ( 0); rot_sin = F (-1);
- rot_dx = F ( 0); rot_dy = F ( width);
- break;
- }
-
- PictureTransformRotate (&inverse, transform, rot_cos, rot_sin);
- PictureTransformTranslate (&inverse, transform, rot_dx, rot_dy);
- pict_f_transform_rotate (f_inverse, f_transform, f_rot_cos, f_rot_sin);
- pict_f_transform_translate (f_inverse, f_transform, f_rot_dx, f_rot_dy);
-
- /* reflection */
- f_scale_x = 1;
- f_scale_dx = 0;
- f_scale_y = 1;
- f_scale_dy = 0;
- scale_x = F (1);
- scale_dx = 0;
- scale_y = F (1);
- scale_dy = 0;
- if (rotation & RR_Reflect_X)
- {
- f_scale_x = -1;
- scale_x = F(-1);
- if (rotation & (RR_Rotate_0|RR_Rotate_180)) {
- f_scale_dx = width;
- scale_dx = F(width);
- } else {
- f_scale_dx = height;
- scale_dx = F(height);
- }
- }
- if (rotation & RR_Reflect_Y)
- {
- f_scale_y = -1;
- scale_y = F(-1);
- if (rotation & (RR_Rotate_0|RR_Rotate_180)) {
- f_scale_dy = height;
- scale_dy = F(height);
- } else {
- f_scale_dy = width;
- scale_dy = F(width);
- }
- }
-
- PictureTransformScale (&inverse, transform, scale_x, scale_y);
- pict_f_transform_scale (f_inverse, f_transform, f_scale_x, f_scale_y);
- PictureTransformTranslate (&inverse, transform, scale_dx, scale_dy);
- pict_f_transform_translate (f_inverse, f_transform, f_scale_dx, f_scale_dy);
- }
-
-#ifdef RANDR_12_INTERFACE
- if (rr_transform)
- {
- PictureTransformMultiply (transform, transform, &rr_transform->transform);
- pict_f_transform_multiply (f_transform, f_transform, &rr_transform->f_transform);
- pict_f_transform_multiply (f_inverse, &rr_transform->f_inverse, f_inverse);
- }
-#endif
- /*
- * Compute the class of the resulting transform
- */
- if (PictureTransformIsIdentity (transform))
- {
- PictureTransformInitTranslate (transform, F ( x), F ( y));
-
- pict_f_transform_init_translate (f_transform, F( x), F( y));
- pict_f_transform_init_translate (f_inverse, F(-x), F(-y));
- return FALSE;
- }
- else
- {
- PictureTransformTranslate (&inverse, transform, x, y);
- pict_f_transform_translate (f_inverse, f_transform, x, y);
- return TRUE;
- }
-}
-
/*
* Initialize crtc type
*/
@@ -1116,7 +902,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
PictTransform transform;
struct pict_f_transform f_transform, f_inverse;
- RRComputeTransform (stuff->x, stuff->y,
+ RRTransformCompute (stuff->x, stuff->y,
mode->mode.width, mode->mode.height,
rotation,
&crtc->client_pending_transform,
diff --git a/randr/rrinfo.c b/randr/rrinfo.c
index 7e77d393d..38314defd 100644
--- a/randr/rrinfo.c
+++ b/randr/rrinfo.c
@@ -170,7 +170,7 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations)
/* notice current mode */
if (newMode)
RRCrtcNotify (crtc, newMode, 0, 0, pScrPriv->rotation,
- 1, &output);
+ NULL, 1, &output);
}
#endif
diff --git a/randr/rrtransform.c b/randr/rrtransform.c
new file mode 100644
index 000000000..f9934d766
--- /dev/null
+++ b/randr/rrtransform.c
@@ -0,0 +1,259 @@
+/*
+ * Copyright © 2007 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.
+ */
+
+#include "rrtransform.h"
+
+void
+RRTransformInit (RRTransformPtr transform)
+{
+ PictureTransformInitIdentity (&transform->transform);
+ pict_f_transform_init_identity (&transform->f_transform);
+ pict_f_transform_init_identity (&transform->f_inverse);
+ transform->filter = NULL;
+ transform->params = NULL;
+ transform->nparams = 0;
+}
+
+void
+RRTransformFini (RRTransformPtr transform)
+{
+ if (transform->params)
+ xfree (transform->params);
+}
+
+Bool
+RRTransformEqual (RRTransformPtr a, RRTransformPtr b)
+{
+ if (a && PictureTransformIsIdentity (&a->transform))
+ a = NULL;
+ if (b && PictureTransformIsIdentity (&b->transform))
+ b = NULL;
+ if (a == NULL && b == NULL)
+ return TRUE;
+ if (a == NULL || b == NULL)
+ return FALSE;
+ if (memcmp (&a->transform, &b->transform, sizeof (a->transform)) != 0)
+ return FALSE;
+ if (a->filter != b->filter)
+ return FALSE;
+ if (a->nparams != b->nparams)
+ return FALSE;
+ if (memcmp (a->params, b->params, a->nparams * sizeof (xFixed)) != 0)
+ return FALSE;
+ return TRUE;
+}
+
+Bool
+RRTransformSetFilter (RRTransformPtr dst,
+ PictFilterPtr filter,
+ xFixed *params,
+ int nparams,
+ int width,
+ int height)
+{
+ xFixed *new_params;
+
+ if (nparams)
+ {
+ new_params = xalloc (nparams * sizeof (xFixed));
+ if (!new_params)
+ return FALSE;
+ memcpy (new_params, params, nparams * sizeof (xFixed));
+ }
+ else
+ new_params = NULL;
+ if (dst->params)
+ xfree (dst->params);
+ dst->filter = filter;
+ dst->params = new_params;
+ dst->nparams = nparams;
+ dst->width = width;
+ dst->height = height;
+ return TRUE;
+}
+
+Bool
+RRTransformCopy (RRTransformPtr dst, RRTransformPtr src)
+{
+ if (src && PictureTransformIsIdentity (&src->transform))
+ src = NULL;
+
+ if (src)
+ {
+ if (!RRTransformSetFilter (dst, src->filter,
+ src->params, src->nparams, src->width, src->height))
+ return FALSE;
+ dst->transform = src->transform;
+ dst->f_transform = src->f_transform;
+ dst->f_inverse = src->f_inverse;
+ }
+ else
+ {
+ if (!RRTransformSetFilter (dst, NULL, NULL, 0, 0, 0))
+ return FALSE;
+ PictureTransformInitIdentity (&dst->transform);
+ pict_f_transform_init_identity (&dst->f_transform);
+ pict_f_transform_init_identity (&dst->f_inverse);
+ }
+ return TRUE;
+}
+
+#define F(x) IntToxFixed(x)
+
+/*
+ * Compute the complete transformation matrix including
+ * client-specified transform, rotation/reflection values and the crtc
+ * offset.
+ *
+ * Return TRUE if the resulting transform is not a simple translation.
+ */
+Bool
+RRTransformCompute (int x,
+ int y,
+ int width,
+ int height,
+ Rotation rotation,
+ RRTransformPtr rr_transform,
+
+ PictTransformPtr transform,
+ struct pict_f_transform *f_transform,
+ struct pict_f_transform *f_inverse)
+{
+ PictTransform t_transform, inverse;
+ struct pict_f_transform tf_transform, tf_inverse;
+
+ if (!transform) transform = &t_transform;
+ if (!f_transform) f_transform = &tf_transform;
+ if (!f_inverse) f_inverse = &tf_inverse;
+
+ PictureTransformInitIdentity (transform);
+ PictureTransformInitIdentity (&inverse);
+ pict_f_transform_init_identity (f_transform);
+ pict_f_transform_init_identity (f_inverse);
+ if (rotation != RR_Rotate_0)
+ {
+ double f_rot_cos, f_rot_sin, f_rot_dx, f_rot_dy;
+ double f_scale_x, f_scale_y, f_scale_dx, f_scale_dy;
+ xFixed rot_cos, rot_sin, rot_dx, rot_dy;
+ xFixed scale_x, scale_y, scale_dx, scale_dy;
+
+ /* rotation */
+ switch (rotation & 0xf) {
+ default:
+ case RR_Rotate_0:
+ f_rot_cos = 1; f_rot_sin = 0;
+ f_rot_dx = 0; f_rot_dy = 0;
+ rot_cos = F ( 1); rot_sin = F ( 0);
+ rot_dx = F ( 0); rot_dy = F ( 0);
+ break;
+ case RR_Rotate_90:
+ f_rot_cos = 0; f_rot_sin = 1;
+ f_rot_dx = height; f_rot_dy = 0;
+ rot_cos = F ( 0); rot_sin = F ( 1);
+ rot_dx = F ( height); rot_dy = F (0);
+ break;
+ case RR_Rotate_180:
+ f_rot_cos = -1; f_rot_sin = 0;
+ f_rot_dx = width; f_rot_dy = height;
+ rot_cos = F (-1); rot_sin = F ( 0);
+ rot_dx = F (width); rot_dy = F ( height);
+ break;
+ case RR_Rotate_270:
+ f_rot_cos = 0; f_rot_sin = -1;
+ f_rot_dx = 0; f_rot_dy = width;
+ rot_cos = F ( 0); rot_sin = F (-1);
+ rot_dx = F ( 0); rot_dy = F ( width);
+ break;
+ }
+
+ PictureTransformRotate (transform, &inverse, rot_cos, rot_sin);
+ PictureTransformTranslate (transform, &inverse, rot_dx, rot_dy);
+ pict_f_transform_rotate (f_transform, f_inverse, f_rot_cos, f_rot_sin);
+ pict_f_transform_translate (f_transform, f_inverse, f_rot_dx, f_rot_dy);
+
+ /* reflection */
+ f_scale_x = 1;
+ f_scale_dx = 0;
+ f_scale_y = 1;
+ f_scale_dy = 0;
+ scale_x = F (1);
+ scale_dx = 0;
+ scale_y = F (1);
+ scale_dy = 0;
+ if (rotation & RR_Reflect_X)
+ {
+ f_scale_x = -1;
+ scale_x = F(-1);
+ if (rotation & (RR_Rotate_0|RR_Rotate_180)) {
+ f_scale_dx = width;
+ scale_dx = F(width);
+ } else {
+ f_scale_dx = height;
+ scale_dx = F(height);
+ }
+ }
+ if (rotation & RR_Reflect_Y)
+ {
+ f_scale_y = -1;
+ scale_y = F(-1);
+ if (rotation & (RR_Rotate_0|RR_Rotate_180)) {
+ f_scale_dy = height;
+ scale_dy = F(height);
+ } else {
+ f_scale_dy = width;
+ scale_dy = F(width);
+ }
+ }
+
+ PictureTransformScale (transform, &inverse, scale_x, scale_y);
+ pict_f_transform_scale (f_transform, f_inverse, f_scale_x, f_scale_y);
+ PictureTransformTranslate (transform, &inverse, scale_dx, scale_dy);
+ pict_f_transform_translate (f_transform, f_inverse, f_scale_dx, f_scale_dy);
+ }
+
+#ifdef RANDR_12_INTERFACE
+ if (rr_transform)
+ {
+ PictureTransformMultiply (transform, transform, &rr_transform->transform);
+ pict_f_transform_multiply (f_transform, f_transform, &rr_transform->f_transform);
+ pict_f_transform_multiply (f_inverse, &rr_transform->f_inverse, f_inverse);
+ }
+#endif
+ /*
+ * Compute the class of the resulting transform
+ */
+ if (PictureTransformIsIdentity (transform))
+ {
+ PictureTransformInitTranslate (transform, F ( x), F ( y));
+
+ pict_f_transform_init_translate (f_transform, F( x), F( y));
+ pict_f_transform_init_translate (f_inverse, F(-x), F(-y));
+ return FALSE;
+ }
+ else
+ {
+ PictureTransformTranslate (&inverse, transform, x, y);
+ pict_f_transform_translate (f_inverse, f_transform, x, y);
+ return TRUE;
+ }
+}
+
diff --git a/randr/rrtransform.h b/randr/rrtransform.h
new file mode 100644
index 000000000..92d3ee7be
--- /dev/null
+++ b/randr/rrtransform.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright © 2007 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.
+ */
+
+#ifndef _RRTRANSFORM_H_
+#define _RRTRANSFORM_H_
+
+#include <X11/extensions/randr.h>
+#include "picturestr.h"
+
+typedef struct _rrTransform RRTransformRec, *RRTransformPtr;
+
+struct _rrTransform {
+ PictTransform transform;
+ struct pict_f_transform f_transform;
+ struct pict_f_transform f_inverse;
+ PictFilterPtr filter;
+ xFixed *params;
+ int nparams;
+ int width;
+ int height;
+};
+
+void
+RRTransformInit (RRTransformPtr transform);
+
+void
+RRTransformFini (RRTransformPtr transform);
+
+Bool
+RRTransformEqual (RRTransformPtr a, RRTransformPtr b);
+
+Bool
+RRTransformSetFilter (RRTransformPtr dst,
+ PictFilterPtr filter,
+ xFixed *params,
+ int nparams,
+ int width,
+ int height);
+
+Bool
+RRTransformCopy (RRTransformPtr dst, RRTransformPtr src);
+
+Bool
+RRTransformCompute (int x,
+ int y,
+ int width,
+ int height,
+ Rotation rotation,
+ RRTransformPtr rr_transform,
+
+ PictTransformPtr transform,
+ struct pict_f_transform *f_transform,
+ struct pict_f_transform *f_inverse);
+
+
+#endif /* _RRTRANSFORM_H_ */