[PATCH] Create rrtransform.[ch]. Add RRTransform argument to RRCrtcNotify.

Keith Packard keithp at keithp.com
Fri Nov 14 14:12:51 PST 2008


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.
---
 hw/xfree86/modes/xf86Crtc.c    |    5 +-
 hw/xfree86/modes/xf86RandR12.c |    4 +-
 hw/xfree86/modes/xf86Rotate.c  |    2 +-
 randr/Makefile.am              |    4 +-
 randr/mirandr.c                |    2 +-
 randr/randrstr.h               |   22 +---
 randr/rrcrtc.c                 |  230 ++----------------------------------
 randr/rrinfo.c                 |    2 +-
 randr/rrtransform.c            |  259 ++++++++++++++++++++++++++++++++++++++++
 randr/rrtransform.h            |   75 ++++++++++++
 10 files changed, 355 insertions(+), 250 deletions(-)
 create mode 100644 randr/rrtransform.c
 create mode 100644 randr/rrtransform.h

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index e3a852e..9d13898 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 49add63..9d7750f 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 7d35c34..75f4a55 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 20b0f72..3d16ede 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 7777853..05375e4 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 d4cfa67..822e377 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 091517a..1b6350e 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 7e77d39..38314de 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 0000000..f9934d7
--- /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 0000000..92d3ee7
--- /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_ */
-- 
1.5.6.5




More information about the xorg mailing list