From 25b9dbb15f0dc98cfc6b5585e7efebf3250f64d3 Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Tue, 7 Dec 2010 15:49:06 +0000
Subject: xserver pixman git update 7-12-2010

---
 xorg-server/randr/Makefile.am   |    6 +-
 xorg-server/randr/mirrcrtc.c    |  174 ++++++
 xorg-server/randr/randr.c       |   15 +
 xorg-server/randr/randrstr.h    |  207 ++++++-
 xorg-server/randr/rrcrtc.c      |  562 +++++++++++++++++--
 xorg-server/randr/rrdispatch.c  |    6 +
 xorg-server/randr/rrinfo.c      |    2 +-
 xorg-server/randr/rrpixmap.c    |  154 ++++++
 xorg-server/randr/rrscreen.c    |   32 +-
 xorg-server/randr/rrsdispatch.c | 1138 ++++++++++++++++++++++-----------------
 xorg-server/randr/rrsprite.c    |  104 ++++
 xorg-server/randr/rrtransform.c |   64 ++-
 xorg-server/randr/rrtransform.h |  161 +++---
 13 files changed, 1955 insertions(+), 670 deletions(-)
 create mode 100644 xorg-server/randr/mirrcrtc.c
 create mode 100644 xorg-server/randr/rrpixmap.c
 create mode 100644 xorg-server/randr/rrsprite.c

(limited to 'xorg-server/randr')

diff --git a/xorg-server/randr/Makefile.am b/xorg-server/randr/Makefile.am
index 4842df89c..2b0b3a984 100644
--- a/xorg-server/randr/Makefile.am
+++ b/xorg-server/randr/Makefile.am
@@ -16,12 +16,16 @@ librandr_la_SOURCES =	\
 	rrinfo.c	\
 	rrmode.c	\
 	rroutput.c	\
+	rrpixmap.c	\
 	rrpointer.c	\
 	rrproperty.c	\
 	rrscreen.c	\
 	rrsdispatch.c	\
+	rrsprite.c	\
 	rrtransform.h	\
-	rrtransform.c
+	rrtransform.c	\
+	mirrcrtc.c
+
 
 if XINERAMA
 librandr_la_SOURCES += ${XINERAMA_SRCS}
diff --git a/xorg-server/randr/mirrcrtc.c b/xorg-server/randr/mirrcrtc.c
new file mode 100644
index 000000000..812b2b68b
--- /dev/null
+++ b/xorg-server/randr/mirrcrtc.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright © 2010 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 "randrstr.h"
+
+Bool
+miRRSetScreenConfig(ScreenPtr screen,
+		    RRScreenConfigPtr screen_config)
+{
+    RRScreenConfigRec	old_screen_config;
+
+    RRScreenCurrentConfig(screen, &old_screen_config);
+
+    /* Check and see if nothing has changed */
+    if (old_screen_config.screen_width == screen_config->screen_width &&
+	old_screen_config.screen_height == screen_config->screen_height &&
+	old_screen_config.screen_pixmap_width == screen_config->screen_pixmap_width &&
+	old_screen_config.screen_pixmap_height == screen_config->screen_pixmap_height &&
+	old_screen_config.mm_width == screen_config->mm_width &&
+	old_screen_config.mm_height == screen_config->mm_height)
+	return TRUE;
+
+    return RRScreenSizeSet(screen,
+			   screen_config->screen_width,
+			   screen_config->screen_height,
+			   screen_config->screen_pixmap_width,
+			   screen_config->screen_pixmap_height,
+			   screen_config->mm_width,
+			   screen_config->mm_height);
+}
+
+Bool
+miRRSetCrtcConfig(RRCrtcConfigPtr crtc_config)
+{
+    int	x = crtc_config->x, y = crtc_config->y;
+
+    if (crtc_config->pixmap) {
+	x = crtc_config->pixmap_x;
+	y = crtc_config->pixmap_y;
+    }
+    if (!RRCrtcSet(crtc_config->crtc,
+		   crtc_config->mode,
+		   x,
+		   y,
+		   crtc_config->rotation,
+		   crtc_config->numOutputs,
+		   crtc_config->outputs,
+		   crtc_config->pixmap))
+	return FALSE;
+    RRCrtcSpriteTransformSet(crtc_config->crtc,
+			     &crtc_config->sprite_position_transform,
+			     &crtc_config->sprite_image_transform,
+			     &crtc_config->sprite_position_f_transform,
+			     &crtc_config->sprite_image_f_transform);
+    return TRUE;
+}
+
+Bool
+miRRDisableCrtc(RRCrtcPtr crtc)
+{
+    RRCrtcConfigRec	off_config;
+
+    memset(&off_config, '\0', sizeof (RRCrtcConfigRec));
+    off_config.crtc = crtc;
+    return miRRSetCrtcConfig(&off_config);
+}
+
+/*
+ * If the current crtc configuration doesn't fit
+ * with the new screen config, disable it
+ */
+Bool
+miRRCheckDisableCrtc(RRScreenConfigPtr new_screen_config,
+		     RRCrtcConfigPtr old_crtc_config)
+{
+    RRCrtcPtr crtc = old_crtc_config->crtc;
+
+    /* If it's already disabled, we're done */
+    if (!old_crtc_config->mode)
+	return TRUE;
+
+    /* If the crtc isn't scanning from the screen pixmap,
+     * we're done
+     */
+    if (old_crtc_config->pixmap)
+	return TRUE;
+
+    /* If the new screen configuration covers the existing CRTC space,
+     * we're done
+     */
+    if (RRScreenCoversCrtc(new_screen_config, old_crtc_config,
+			   &crtc->client_current_transform, NULL))
+	return TRUE;
+
+    /* Disable the crtc and let it get re-enabled */
+    return miRRDisableCrtc(crtc);
+}
+
+Bool
+miRRSetCrtcConfigs(ScreenPtr screen,
+		   RRScreenConfigPtr screen_config,
+		   RRCrtcConfigPtr crtc_configs,
+		   int num_configs)
+{
+    RRScreenConfigRec	old_screen_config;
+    RRCrtcConfigPtr	old_crtc_configs;
+    int			i;
+
+    /*
+     * Save existing state
+     */
+
+    RRScreenCurrentConfig(screen, &old_screen_config);
+    old_crtc_configs = calloc(num_configs, sizeof (RRCrtcConfigRec));
+    if (!old_crtc_configs)
+	return FALSE;
+
+    for (i = 0; i < num_configs; i++)
+	if (!RRCrtcCurrentConfig(crtc_configs[i].crtc, &old_crtc_configs[i]))
+	    goto fail_save;
+    /*
+     * Set the new configuration. If anything goes wrong,
+     * bail and restore the old configuration
+     */
+    for (i = 0; i < num_configs; i++)
+	if (!miRRCheckDisableCrtc(screen_config, &old_crtc_configs[i]))
+	    goto fail_disable;
+
+    if (!miRRSetScreenConfig(screen, screen_config))
+	goto fail_set_screen;
+
+    for (i = 0; i < num_configs; i++)
+	if (!miRRSetCrtcConfig(&crtc_configs[i]))
+	    goto fail_set_crtc;
+
+    RRFreeCrtcConfigs(old_crtc_configs, num_configs);
+    return TRUE;
+
+fail_set_crtc:
+    /*
+     * Restore the previous configuration. Ignore any errors
+     * as we just need to hope that the driver can manage to
+     * get back to the previous state without trouble.
+     */
+    for (i = 0; i < num_configs; i++)
+	(void) miRRDisableCrtc(old_crtc_configs[i].crtc);
+    (void) miRRSetScreenConfig(screen, &old_screen_config);
+fail_set_screen:
+fail_disable:
+    for (i = 0; i < num_configs; i++)
+	(void) miRRSetCrtcConfig(&old_crtc_configs[i]);
+fail_save:
+    RRFreeCrtcConfigs(old_crtc_configs, num_configs);
+    return FALSE;
+}
diff --git a/xorg-server/randr/randr.c b/xorg-server/randr/randr.c
index aa1e71dcf..1346d1e9c 100644
--- a/xorg-server/randr/randr.c
+++ b/xorg-server/randr/randr.c
@@ -98,6 +98,7 @@ RRCloseScreen (int i, ScreenPtr pScreen)
     
     free(pScrPriv->crtcs);
     free(pScrPriv->outputs);
+    free(pScrPriv->scanout_info);
     free(pScrPriv);
     RRNScreens -= 1;	/* ok, one fewer screen with RandR running */
     return (*pScreen->CloseScreen) (i, pScreen);    
@@ -248,6 +249,8 @@ Bool RRScreenInit(ScreenPtr pScreen)
     pScrPriv->rrCrtcSet = NULL;
     pScrPriv->rrCrtcSetGamma = NULL;
 #endif
+    pScrPriv->scanout_info = NULL;
+    pScrPriv->n_scanout_info = 0;
 #if RANDR_10_INTERFACE    
     pScrPriv->rrSetConfig = 0;
     pScrPriv->rotations = RR_Rotate_0;
@@ -482,6 +485,18 @@ RRVerticalRefresh (xRRModeInfo *mode)
     return (CARD16) refresh;
 }
 
+RRScanoutPixmapInfo *
+RRQueryScanoutPixmapInfo(ScreenPtr screen, int *n_info)
+{
+    rrScrPriv(screen);
+
+    if (!pScrPriv->scanout_info && pScrPriv->rrQueryScanoutPixmaps)
+	pScrPriv->scanout_info = pScrPriv->rrQueryScanoutPixmaps(screen,
+								 &pScrPriv->n_scanout_info);
+    *n_info = pScrPriv->n_scanout_info;
+    return pScrPriv->scanout_info;
+}
+
 static int
 ProcRRDispatch (ClientPtr client)
 {
diff --git a/xorg-server/randr/randrstr.h b/xorg-server/randr/randrstr.h
index b4acfe12a..ee208f569 100644
--- a/xorg-server/randr/randrstr.h
+++ b/xorg-server/randr/randrstr.h
@@ -55,9 +55,10 @@
 #define RANDR_10_INTERFACE 1
 #define RANDR_12_INTERFACE 1
 #define RANDR_13_INTERFACE 1 /* requires RANDR_12_INTERFACE */
+#define RANDR_14_INTERFACE 1 /* requires RANDR_13_INTERFACE */
 #define RANDR_GET_CRTC_INTERFACE 1
 
-#define RANDR_INTERFACE_VERSION 0x0103
+#define RANDR_INTERFACE_VERSION 0x0104
 
 typedef XID	RRMode;
 typedef XID	RROutput;
@@ -77,6 +78,8 @@ typedef struct _rrMode		RRModeRec, *RRModePtr;
 typedef struct _rrPropertyValue	RRPropertyValueRec, *RRPropertyValuePtr;
 typedef struct _rrProperty	RRPropertyRec, *RRPropertyPtr;
 typedef struct _rrCrtc		RRCrtcRec, *RRCrtcPtr;
+typedef struct _rrScreenConfig	RRScreenConfigRec, *RRScreenConfigPtr;
+typedef struct _rrCrtcConfig	RRCrtcConfigRec, *RRCrtcConfigPtr;
 typedef struct _rrOutput	RROutputRec, *RROutputPtr;
 
 struct _rrMode {
@@ -120,11 +123,43 @@ struct _rrCrtc {
     CARD16	    *gammaGreen;
     void	    *devPrivate;
     Bool	    transforms;
+    PixmapPtr	    scanoutPixmap;
     RRTransformRec  client_pending_transform;
     RRTransformRec  client_current_transform;
+    PictTransform   client_sprite_position_transform;
+    PictTransform   client_sprite_image_transform;
+    struct pict_f_transform	client_sprite_f_position_transform;
+    struct pict_f_transform	client_sprite_f_image_transform;
+
     PictTransform   transform;
     struct pict_f_transform f_transform;
     struct pict_f_transform f_inverse;
+    struct pict_f_transform f_sprite_position;		/* crtc from screen */
+    struct pict_f_transform f_sprite_image_inverse;	/* image from crtc */
+};
+
+struct _rrScreenConfig {
+    CARD16			screen_pixmap_width;
+    CARD16			screen_pixmap_height;
+    CARD16			screen_width;
+    CARD16			screen_height;
+    CARD32			mm_width;
+    CARD32			mm_height;
+};
+
+struct _rrCrtcConfig {
+    RRCrtcPtr			crtc;
+    int				x, y;
+    RRModePtr			mode;
+    Rotation			rotation;
+    int				numOutputs;
+    RROutputPtr			*outputs;
+    PictTransform		sprite_position_transform;
+    PictTransform		sprite_image_transform;
+    struct pict_f_transform	sprite_position_f_transform;
+    struct pict_f_transform	sprite_image_f_transform;
+    PixmapPtr			pixmap;
+    int				pixmap_x, pixmap_y;
 };
 
 struct _rrOutput {
@@ -156,6 +191,8 @@ struct _rrOutput {
 typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr	pScreen,
 					CARD16		width,
 					CARD16		height,
+					CARD16		pixWidth,
+					CARD16		pixHeight,
 					CARD32		mmWidth,
 					CARD32		mmHeight);
 					
@@ -166,7 +203,8 @@ typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr		pScreen,
 				  int			y,
 				  Rotation		rotation,
 				  int			numOutputs,
-				  RROutputPtr		*outputs);
+				  RROutputPtr		*outputs,
+				  PixmapPtr		scanout_pixmap);
 
 typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr	pScreen,
 				       RRCrtcPtr	crtc);
@@ -232,6 +270,35 @@ typedef Bool (*RRSetConfigProcPtr) (ScreenPtr		pScreen,
 
 #endif
 	
+typedef struct {
+    PictFormatPtr	format;
+    int			maxWidth, maxHeight;
+    int			depth;
+    Rotation		rotations;
+} RRScanoutPixmapInfo;
+
+typedef RRScanoutPixmapInfo *(*RRQueryScanoutPixmapsPtr) (ScreenPtr pScreen,
+							  int *num_info);
+
+typedef PixmapPtr (*RRCreateScanoutPixmapPtr) (ScreenPtr pScreen,
+					       int width, int height, int depth,
+					       Rotation rotations,
+					       PictFormatPtr format);
+
+typedef void (*RRSetCrtcSpriteTransformPtr) (ScreenPtr pScreen,
+					     RRCrtcPtr randr_crtc,
+					     struct pict_f_transform *position_transform,
+					     struct pict_f_transform *image_transform);
+
+typedef void (*RRGetCrtcSpriteTransformPtr) (ScreenPtr pScreen,
+					     RRCrtcPtr randr_crtc,
+					     struct pict_f_transform *position_transform,
+					     struct pict_f_transform *image_transform);
+
+typedef Bool (*RRSetCrtcConfigsPtr) (ScreenPtr screen,
+				     RRScreenConfigPtr screen_config,
+				     RRCrtcConfigPtr crtc_configs,
+				     int num_configs);
 
 typedef struct _rrScrPriv {
     /*
@@ -256,7 +323,12 @@ typedef struct _rrScrPriv {
     RRGetPanningProcPtr	rrGetPanning;
     RRSetPanningProcPtr	rrSetPanning;
 #endif
-    
+    RRQueryScanoutPixmapsPtr	rrQueryScanoutPixmaps;
+    RRCreateScanoutPixmapPtr	rrCreateScanoutPixmap;
+    RRSetCrtcSpriteTransformPtr	rrSetCrtcSpriteTransform;
+    RRGetCrtcSpriteTransformPtr	rrGetCrtcSpriteTransform;
+    RRSetCrtcConfigsPtr rrSetCrtcConfigs;
+
     /*
      * Private part of the structure; not considered part of the ABI
      */
@@ -283,6 +355,8 @@ typedef struct _rrScrPriv {
     /* Last known pointer position */
     RRCrtcPtr		    pointerCrtc;
 
+    RRScanoutPixmapInfo	    *scanout_info;
+    int			    n_scanout_info;
 #ifdef RANDR_10_INTERFACE
     /*
      * Configuration information
@@ -297,6 +371,7 @@ typedef struct _rrScrPriv {
     int			    rate;
     int			    size;
 #endif
+
 } rrScrPrivRec, *rrScrPrivPtr;
 
 extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec;
@@ -405,9 +480,15 @@ extern _X_EXPORT Bool
 RRScreenSizeSet (ScreenPtr  pScreen,
 		 CARD16	    width,
 		 CARD16	    height,
+		 CARD16	    pixWidth,
+		 CARD16	    pixHeight,
 		 CARD32	    mmWidth,
 		 CARD32	    mmHeight);
 
+extern _X_EXPORT void
+RRScreenCurrentConfig(ScreenPtr screen,
+		      RRScreenConfigPtr screen_config);
+
 /*
  * Send ConfigureNotify event to root window when 'something' happens
  */
@@ -467,6 +548,9 @@ RRGetRotation (ScreenPtr pScreen);
 extern _X_EXPORT CARD16
 RRVerticalRefresh (xRRModeInfo *mode);
 
+extern _X_EXPORT RRScanoutPixmapInfo *
+RRQueryScanoutPixmapInfo(ScreenPtr screen, int *n_info);
+
 #ifdef RANDR_10_INTERFACE					
 /*
  * This is the old interface, deprecated but left
@@ -545,7 +629,8 @@ RRCrtcNotify (RRCrtcPtr	    crtc,
 	      Rotation	    rotation,
 	      RRTransformPtr transform,
 	      int	    numOutputs,
-	      RROutputPtr   *outputs);
+	      RROutputPtr   *outputs,
+	      PixmapPtr	    scanoutPixmap);
 
 extern _X_EXPORT void
 RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc);
@@ -560,7 +645,8 @@ RRCrtcSet (RRCrtcPtr    crtc,
 	   int		y,
 	   Rotation	rotation,
 	   int		numOutput,
-	   RROutputPtr  *outputs);
+	   RROutputPtr  *outputs,
+	   PixmapPtr	scanout_pixmap);
 
 /*
  * Request that the Crtc gamma be changed
@@ -589,6 +675,10 @@ RRCrtcGammaGet(RRCrtcPtr crtc);
 extern _X_EXPORT Bool
 RRCrtcGammaNotify (RRCrtcPtr	crtc);
 
+void
+RRModeGetScanoutSize (RRModePtr mode, struct pixman_f_transform *transform,
+		      int *width, int *height);
+
 /*
  * Set the size of the gamma table at server startup time
  */
@@ -605,25 +695,6 @@ RRCrtcGammaSetSize (RRCrtcPtr	crtc,
 extern _X_EXPORT void
 RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height);
 
-/*
- * 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.
- */
-extern _X_EXPORT 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);
-
 /*
  * Return crtc transform
  */
@@ -669,6 +740,38 @@ RRCrtcInit (void);
 extern _X_EXPORT void
 RRCrtcInitErrorValue (void);
 
+/*
+ * Free a set of crtc configs and their attached output arrays
+ */
+void
+RRFreeCrtcConfigs(RRCrtcConfigPtr configs, int num_configs);
+
+/*
+ * Convert the current crtc configuration into an RRCrtcConfig
+ */
+extern _X_EXPORT Bool
+RRCrtcCurrentConfig(RRCrtcPtr crtc,
+		    RRCrtcConfigPtr crtc_config);
+
+/*
+ * Figure out whether the specific crtc_config can fit
+ * within the screen_config
+ */
+Bool
+RRScreenCoversCrtc(RRScreenConfigPtr screen_config,
+		   RRCrtcConfigPtr crtc_config,
+		   RRTransformPtr client_transform,
+		   XID *errorValue);
+
+/*
+ * Set a screen and set of crtc configurations in one operation
+ */
+Bool
+RRSetCrtcConfigs(ScreenPtr screen,
+		 RRScreenConfigPtr screen_config,
+		 RRCrtcConfigPtr crtc_configs,
+		 int num_configs);
+
 /*
  * Crtc dispatch
  */
@@ -694,12 +797,40 @@ ProcRRSetCrtcTransform (ClientPtr client);
 extern _X_EXPORT int
 ProcRRGetCrtcTransform (ClientPtr client);
 
+extern _X_EXPORT int
+ProcRRSetCrtcConfigs (ClientPtr client);
+
 int
 ProcRRGetPanning (ClientPtr client);
 
 int
 ProcRRSetPanning (ClientPtr client);
 
+void
+RRCrtcSpriteTransformSet(RRCrtcPtr crtc,
+			 PictTransform *position_transform,
+			 PictTransform *image_transform,
+			 struct pict_f_transform *f_position_transform,
+			 struct pict_f_transform *f_image_transform);
+
+int
+ProcRRQueryScanoutPixmaps (ClientPtr client);
+
+int
+ProcRRCreateScanoutPixmap (ClientPtr client);
+
+int
+ProcRRSetCrtcPixmapConfig (ClientPtr client);
+
+int
+ProcRRSetCrtcSpriteTransform (ClientPtr client);
+
+int
+ProcRRGetCrtcSpriteTransform (ClientPtr client);
+
+int
+ProcRRSetCrtcConfigs (ClientPtr client);
+
 /* rrdispatch.c */
 extern _X_EXPORT Bool
 RRClientKnowsRates (ClientPtr	pClient);
@@ -889,12 +1020,40 @@ ProcRRConfigureOutputProperty (ClientPtr client);
 extern _X_EXPORT int
 ProcRRDeleteOutputProperty (ClientPtr client);
 
+/* rrsprite.c */
+extern _X_EXPORT int
+ProcRRSetCrtcSpriteTransform (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRGetCrtcSpriteTransform (ClientPtr client);
+
 /* rrxinerama.c */
 #ifdef XINERAMA
 extern _X_EXPORT void
 RRXineramaExtensionInit(void);
 #endif
 
+/* mirrcrtc.c */
+Bool
+miRRSetScreenConfig(ScreenPtr screen,
+		    RRScreenConfigPtr screen_config);
+
+Bool
+miRRSetCrtcConfig(RRCrtcConfigPtr crtc_config);
+
+Bool
+miRRDisableCrtc(RRCrtcPtr crtc);
+
+Bool
+miRRCheckDisableCrtc(RRScreenConfigPtr new_screen_config,
+		     RRCrtcConfigPtr old_crtc_config);
+
+Bool
+miRRSetCrtcConfigs(ScreenPtr screen,
+		   RRScreenConfigPtr screen_config,
+		   RRCrtcConfigPtr crtc_configs,
+		   int num_configs);
+
 #endif /* _RANDRSTR_H_ */
 
 /*
diff --git a/xorg-server/randr/rrcrtc.c b/xorg-server/randr/rrcrtc.c
index fba9f4805..524fcd266 100644
--- a/xorg-server/randr/rrcrtc.c
+++ b/xorg-server/randr/rrcrtc.c
@@ -37,7 +37,7 @@ RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged)
     if (pScreen)
     {
 	rrScrPriv(pScreen);
-    
+
 	pScrPriv->changed = TRUE;
 	/*
 	 * Send ConfigureNotify on any layout change
@@ -59,19 +59,19 @@ RRCrtcCreate (ScreenPtr pScreen, void *devPrivate)
 
     if (!RRInit())
 	return NULL;
-    
+
     pScrPriv = rrGetScrPriv(pScreen);
 
     /* make space for the crtc pointer */
     if (pScrPriv->numCrtcs)
-	crtcs = realloc(pScrPriv->crtcs, 
+	crtcs = realloc(pScrPriv->crtcs,
 			  (pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr));
     else
 	crtcs = malloc(sizeof (RRCrtcPtr));
     if (!crtcs)
 	return FALSE;
     pScrPriv->crtcs = crtcs;
-    
+
     crtc = calloc(1, sizeof (RRCrtcRec));
     if (!crtc)
 	return NULL;
@@ -90,9 +90,13 @@ RRCrtcCreate (ScreenPtr pScreen, void *devPrivate)
     crtc->devPrivate = devPrivate;
     RRTransformInit (&crtc->client_pending_transform);
     RRTransformInit (&crtc->client_current_transform);
+    pixman_transform_init_identity (&crtc->client_sprite_position_transform);
+    pixman_transform_init_identity (&crtc->client_sprite_image_transform);
     pixman_transform_init_identity (&crtc->transform);
     pixman_f_transform_init_identity (&crtc->f_transform);
     pixman_f_transform_init_identity (&crtc->f_inverse);
+    pixman_f_transform_init_identity (&crtc->f_sprite_position);
+    pixman_f_transform_init_identity (&crtc->f_sprite_image_inverse);
 
     if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc))
 	return NULL;
@@ -100,7 +104,7 @@ RRCrtcCreate (ScreenPtr pScreen, void *devPrivate)
     /* attach the screen and crtc together */
     crtc->pScreen = pScreen;
     pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc;
-    
+
     return crtc;
 }
 
@@ -134,10 +138,11 @@ RRCrtcNotify (RRCrtcPtr	    crtc,
 	      Rotation	    rotation,
 	      RRTransformPtr transform,
 	      int	    numOutputs,
-	      RROutputPtr   *outputs)
+	      RROutputPtr   *outputs,
+	      PixmapPtr	    scanoutPixmap)
 {
     int	    i, j;
-    
+
     /*
      * Check to see if any of the new outputs were
      * not in the old list and mark them as changed
@@ -177,7 +182,7 @@ RRCrtcNotify (RRCrtcPtr	    crtc,
     if (numOutputs != crtc->numOutputs)
     {
 	RROutputPtr *newoutputs;
-	
+
 	if (numOutputs)
 	{
 	    if (crtc->numOutputs)
@@ -231,15 +236,30 @@ RRCrtcNotify (RRCrtcPtr	    crtc,
 	RRTransformCopy (&crtc->client_current_transform, transform);
 	RRCrtcChanged (crtc, TRUE);
     }
+
+    if (scanoutPixmap != crtc->scanoutPixmap)
+    {
+	if (scanoutPixmap)
+	    ++scanoutPixmap->refcnt;
+	if (crtc->scanoutPixmap)
+	    (*crtc->scanoutPixmap->drawable.pScreen->DestroyPixmap) (crtc->scanoutPixmap);
+	crtc->scanoutPixmap = scanoutPixmap;
+    }
+
     if (crtc->changed && mode)
     {
 	RRTransformCompute (x, y,
 			    mode->mode.width, mode->mode.height,
 			    rotation,
 			    &crtc->client_current_transform,
+			    &crtc->client_sprite_f_position_transform,
+			    &crtc->client_sprite_f_image_transform,
 			    &crtc->transform, &crtc->f_transform,
-			    &crtc->f_inverse);
+			    &crtc->f_inverse, &crtc->f_sprite_position,
+			    &crtc->f_sprite_image_inverse,
+			    NULL);
     }
+
     return TRUE;
 }
 
@@ -250,7 +270,7 @@ RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc)
     rrScrPriv (pScreen);
     xRRCrtcChangeNotifyEvent	ce;
     RRModePtr	mode = crtc->mode;
-    
+
     ce.type = RRNotify + RREventBase;
     ce.subCode = RRNotify_CrtcChange;
     ce.timestamp = pScrPriv->lastSetTime.milliseconds;
@@ -302,7 +322,8 @@ RRCrtcSet (RRCrtcPtr    crtc,
 	   int		y,
 	   Rotation	rotation,
 	   int		numOutputs,
-	   RROutputPtr  *outputs)
+	   RROutputPtr  *outputs,
+	   PixmapPtr	scanout_pixmap)
 {
     ScreenPtr	pScreen = crtc->pScreen;
     Bool	ret = FALSE;
@@ -316,7 +337,8 @@ RRCrtcSet (RRCrtcPtr    crtc,
 	crtc->numOutputs == numOutputs &&
 	!memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) &&
 	!RRCrtcPendingProperties (crtc) &&
-	!RRCrtcPendingTransform (crtc))
+	!RRCrtcPendingTransform (crtc) &&
+	crtc->scanoutPixmap == scanout_pixmap)
     {
 	ret = TRUE;
     }
@@ -325,8 +347,8 @@ RRCrtcSet (RRCrtcPtr    crtc,
 #if RANDR_12_INTERFACE
 	if (pScrPriv->rrCrtcSet)
 	{
-	    ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, 
-					  rotation, numOutputs, outputs);
+	    ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y,
+					  rotation, numOutputs, outputs, scanout_pixmap);
 	}
 	else
 #endif
@@ -339,7 +361,7 @@ RRCrtcSet (RRCrtcPtr    crtc,
 
 		if (!mode)
 		{
-		    RRCrtcNotify (crtc, NULL, x, y, rotation, NULL, 0, NULL);
+		    RRCrtcNotify (crtc, NULL, x, y, rotation, NULL, 0, NULL, scanout_pixmap);
 		    ret = TRUE;
 		}
 		else
@@ -365,7 +387,7 @@ RRCrtcSet (RRCrtcPtr    crtc,
 		     */
 		    if (ret)
 		    {
-			RRCrtcNotify (crtc, mode, x, y, rotation, NULL, 1, outputs);
+			RRCrtcNotify (crtc, mode, x, y, rotation, NULL, 1, outputs, scanout_pixmap);
 			RRScreenSizeNotify (pScreen);
 		    }
 		}
@@ -384,6 +406,60 @@ RRCrtcSet (RRCrtcPtr    crtc,
     return ret;
 }
 
+void
+RRFreeCrtcConfigs(RRCrtcConfigPtr configs, int num_configs)
+{
+    int	i;
+
+    for (i = 0; i < num_configs; i++)
+	free(configs[i].outputs);
+    free(configs);
+}
+
+Bool
+RRCrtcCurrentConfig(RRCrtcPtr crtc,
+		    RRCrtcConfigPtr crtc_config)
+{
+    crtc_config->crtc = crtc;
+    crtc_config->x = crtc->x;
+    crtc_config->y = crtc->y;
+    crtc_config->mode = crtc->mode;
+    crtc_config->rotation = crtc->rotation;
+    crtc_config->numOutputs = crtc->numOutputs;
+    crtc_config->outputs = calloc(crtc->numOutputs, sizeof (RROutputPtr));
+    if (!crtc_config->outputs)
+	return FALSE;
+    memcpy(crtc_config->outputs, crtc->outputs, crtc->numOutputs * sizeof (RROutputPtr));
+    crtc_config->sprite_position_transform = crtc->client_sprite_position_transform;
+    crtc_config->sprite_image_transform = crtc->client_sprite_image_transform;
+    crtc_config->sprite_position_f_transform = crtc->client_sprite_f_position_transform;
+    crtc_config->sprite_image_f_transform = crtc->client_sprite_f_image_transform;
+
+    crtc_config->pixmap = crtc->scanoutPixmap;
+    crtc_config->pixmap_x = crtc->x;
+    crtc_config->pixmap_y = crtc->y;
+    return TRUE;
+}
+
+
+/*
+ * Request that a set of crtcs be configured at the same
+ * time on a single screen
+ */
+
+Bool
+RRSetCrtcConfigs(ScreenPtr screen,
+		 RRScreenConfigPtr screen_config,
+		 RRCrtcConfigPtr crtc_configs,
+		 int num_configs)
+{
+    rrScrPrivPtr	scr_priv = rrGetScrPriv(screen);
+
+    if (!scr_priv)
+	return FALSE;
+    return (*scr_priv->rrSetCrtcConfigs)(screen, screen_config, crtc_configs, num_configs);
+}
+
 /*
  * Return crtc transform
  */
@@ -427,7 +503,7 @@ RRCrtcDestroyResource (pointer value, XID pid)
     {
 	rrScrPriv(pScreen);
 	int		i;
-    
+
 	for (i = 0; i < pScrPriv->numCrtcs; i++)
 	{
 	    if (pScrPriv->crtcs[i] == crtc)
@@ -460,7 +536,7 @@ RRCrtcGammaSet (RRCrtcPtr   crtc,
 #if RANDR_12_INTERFACE
     ScreenPtr	pScreen = crtc->pScreen;
 #endif
-    
+
     memcpy (crtc->gammaRed, red, crtc->gammaSize * sizeof (CARD16));
     memcpy (crtc->gammaGreen, green, crtc->gammaSize * sizeof (CARD16));
     memcpy (crtc->gammaBlue, blue, crtc->gammaSize * sizeof (CARD16));
@@ -510,8 +586,11 @@ RRCrtcGammaNotify (RRCrtcPtr	crtc)
     return TRUE;    /* not much going on here */
 }
 
-static void
-RRModeGetScanoutSize (RRModePtr mode, PictTransformPtr transform,
+/*
+ * Compute overall scanout buffer requirements for the specified mode
+ */
+void
+RRModeGetScanoutSize (RRModePtr mode, struct pixman_f_transform *transform,
 		      int *width, int *height)
 {
     BoxRec  box;
@@ -527,7 +606,7 @@ RRModeGetScanoutSize (RRModePtr mode, PictTransformPtr transform,
     box.x2 = mode->mode.width;
     box.y2 = mode->mode.height;
 
-    pixman_transform_bounds (transform, &box);
+    pixman_f_transform_bounds (transform, &box);
     *width = box.x2 - box.x1;
     *height = box.y2 - box.y1;
 }
@@ -538,7 +617,7 @@ RRModeGetScanoutSize (RRModePtr mode, PictTransformPtr transform,
 void
 RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height)
 {
-    return RRModeGetScanoutSize (crtc->mode, &crtc->transform, width, height);
+    RRModeGetScanoutSize (crtc->mode, &crtc->f_transform, width, height);
 }
 
 /*
@@ -622,6 +701,44 @@ RRCrtcTransformSet (RRCrtcPtr		crtc,
     return Success;
 }
 
+/*
+ * Figure out whether the specific crtc_config can fit
+ * within the screen_config
+ */
+Bool
+RRScreenCoversCrtc(RRScreenConfigPtr screen_config,
+		   RRCrtcConfigPtr crtc_config,
+		   RRTransformPtr client_transform,
+		   XID *errorValue)
+{
+    int source_width;
+    int	source_height;
+    struct pixman_f_transform f_transform;
+
+    RRTransformCompute (crtc_config->x, crtc_config->y,
+			crtc_config->mode->mode.width, crtc_config->mode->mode.height,
+			crtc_config->rotation,
+			client_transform,
+			&crtc_config->sprite_position_f_transform,
+			&crtc_config->sprite_image_f_transform,
+			NULL, &f_transform, NULL, NULL, NULL, NULL);
+
+    RRModeGetScanoutSize (crtc_config->mode, &f_transform,
+			  &source_width, &source_height);
+    if (crtc_config->x + source_width > screen_config->screen_pixmap_width) {
+	if (errorValue)
+	    *errorValue = crtc_config->x;
+	return FALSE;
+    }
+
+    if (crtc_config->y + source_height > screen_config->screen_pixmap_height) {
+	if (errorValue)
+	    *errorValue = crtc_config->y;
+	return FALSE;
+    }
+    return TRUE;
+}
+
 /*
  * Initialize crtc type
  */
@@ -631,7 +748,7 @@ RRCrtcInit (void)
     RRCrtcType = CreateNewResourceType (RRCrtcDestroyResource, "CRTC");
     if (!RRCrtcType)
 	return FALSE;
-    
+
     return TRUE;
 }
 
@@ -660,7 +777,7 @@ ProcRRGetCrtcInfo (ClientPtr client)
     int				i, j, k, n;
     int				width, height;
     BoxRec			panned_area;
-    
+
     REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq);
     VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
 
@@ -671,7 +788,7 @@ ProcRRGetCrtcInfo (ClientPtr client)
     pScrPriv = rrGetScrPriv(pScreen);
 
     mode = crtc->mode;
-    
+
     rep.type = X_Reply;
     rep.status = RRSetConfigSuccess;
     rep.sequenceNumber = client->sequence;
@@ -704,7 +821,7 @@ ProcRRGetCrtcInfo (ClientPtr client)
 	    if (pScrPriv->outputs[i]->crtcs[j] == crtc)
 		k++;
     rep.nPossibleOutput = k;
-    
+
     rep.length = rep.nOutput + rep.nPossibleOutput;
 
     extraLen = rep.length << 2;
@@ -719,7 +836,7 @@ ProcRRGetCrtcInfo (ClientPtr client)
 
     outputs = (RROutput *) extra;
     possible = (RROutput *) (outputs + rep.nOutput);
-    
+
     for (i = 0; i < crtc->numOutputs; i++)
     {
 	outputs[i] = crtc->outputs[i]->id;
@@ -736,7 +853,7 @@ ProcRRGetCrtcInfo (ClientPtr client)
 		    swapl (&possible[k], n);
 		k++;
 	    }
-    
+
     if (client->swapped) {
 	swaps(&rep.sequenceNumber, n);
 	swapl(&rep.length, n);
@@ -757,7 +874,7 @@ ProcRRGetCrtcInfo (ClientPtr client)
 	WriteToClient (client, extraLen, (char *) extra);
 	free(extra);
     }
-    
+
     return Success;
 }
 
@@ -777,10 +894,10 @@ ProcRRSetCrtcConfig (ClientPtr client)
     TimeStamp		    time;
     Rotation		    rotation;
     int			    rc, i, j;
-    
+
     REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq);
     numOutputs = (stuff->length - bytes_to_int32(SIZEOF (xRRSetCrtcConfigReq)));
-    
+
     VERIFY_RR_CRTC(stuff->crtc, crtc, DixSetAttrAccess);
 
     if (stuff->mode == None)
@@ -803,7 +920,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
     }
     else
 	outputs = NULL;
-    
+
     outputIds = (RROutput *) (stuff + 1);
     for (i = 0; i < numOutputs; i++)
     {
@@ -826,7 +943,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
 	/* validate mode for this output */
 	for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++)
 	{
-	    RRModePtr	m = (j < outputs[i]->numModes ? 
+	    RRModePtr	m = (j < outputs[i]->numModes ?
 			     outputs[i]->modes[j] :
 			     outputs[i]->userModes[j - outputs[i]->numModes]);
 	    if (m == mode)
@@ -861,17 +978,17 @@ ProcRRSetCrtcConfig (ClientPtr client)
 
     pScreen = crtc->pScreen;
     pScrPriv = rrGetScrPriv(pScreen);
-    
+
     time = ClientTimeToServerTime(stuff->timestamp);
     configTime = ClientTimeToServerTime(stuff->configTimestamp);
-    
+
     if (!pScrPriv)
     {
 	time = currentTime;
 	rep.status = RRSetConfigFailed;
 	goto sendReply;
     }
-    
+
     /*
      * Validate requested rotation
      */
@@ -904,7 +1021,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
 	    free(outputs);
 	    return BadMatch;
 	}
-    
+
 #ifdef RANDR_12_INTERFACE
 	/*
 	 * Check screen size bounds if the DDX provides a 1.2 interface
@@ -924,16 +1041,19 @@ ProcRRSetCrtcConfig (ClientPtr client)
 				mode->mode.width, mode->mode.height,
 				rotation,
 				&crtc->client_pending_transform,
-				&transform, &f_transform, &f_inverse);
+				&crtc->client_sprite_f_position_transform,
+				&crtc->client_sprite_f_image_transform,
+				&transform, &f_transform, &f_inverse, NULL, NULL, NULL);
 
-	    RRModeGetScanoutSize (mode, &transform, &source_width, &source_height);
+	    RRModeGetScanoutSize (mode, &f_transform,
+				  &source_width, &source_height);
 	    if (stuff->x + source_width > pScreen->width)
 	    {
 		client->errorValue = stuff->x;
 		free(outputs);
 		return BadValue;
 	    }
-	    
+
 	    if (stuff->y + source_height > pScreen->height)
 	    {
 		client->errorValue = stuff->y;
@@ -943,26 +1063,26 @@ ProcRRSetCrtcConfig (ClientPtr client)
 	}
 #endif
     }
-    
+
     if (!RRCrtcSet (crtc, mode, stuff->x, stuff->y,
-		   rotation, numOutputs, outputs))
+		    rotation, numOutputs, outputs, NULL))
     {
 	rep.status = RRSetConfigFailed;
 	goto sendReply;
     }
     rep.status = RRSetConfigSuccess;
     pScrPriv->lastSetTime = time;
-    
+
 sendReply:
     free(outputs);
-    
+
     rep.type = X_Reply;
     /* rep.status has already been filled in */
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
     rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
 
-    if (client->swapped) 
+    if (client->swapped)
     {
 	int n;
     	swaps(&rep.sequenceNumber, n);
@@ -970,7 +1090,7 @@ sendReply:
 	swapl(&rep.newTimestamp, n);
     }
     WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *)&rep);
-    
+
     return Success;
 }
 
@@ -986,7 +1106,7 @@ ProcRRGetPanning (ClientPtr client)
     BoxRec		tracking;
     INT16		border[4];
     int			n;
-    
+
     REQUEST_SIZE_MATCH(xRRGetPanningReq);
     VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
 
@@ -1056,7 +1176,7 @@ ProcRRSetPanning (ClientPtr client)
     BoxRec		tracking;
     INT16		border[4];
     int			n;
-    
+
     REQUEST_SIZE_MATCH(xRRSetPanningReq);
     VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
 
@@ -1071,9 +1191,9 @@ ProcRRSetPanning (ClientPtr client)
 	rep.status = RRSetConfigFailed;
 	goto sendReply;
     }
-    
+
     time = ClientTimeToServerTime(stuff->timestamp);
-    
+
     if (!pScrPriv->rrGetPanning)
 	return RRErrorBase + BadRRCrtc;
 
@@ -1149,7 +1269,7 @@ ProcRRGetCrtcGamma (ClientPtr client)
     int				n;
     unsigned long		len;
     char			*extra = NULL;
-    
+
     REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq);
     VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
 
@@ -1158,7 +1278,7 @@ ProcRRGetCrtcGamma (ClientPtr client)
         return RRErrorBase + BadRRCrtc;
 
     len = crtc->gammaSize * 3 * 2;
-    
+
     if (crtc->gammaSize) {
 	extra = malloc(len);
 	if (!extra)
@@ -1192,21 +1312,21 @@ ProcRRSetCrtcGamma (ClientPtr client)
     RRCrtcPtr			crtc;
     unsigned long		len;
     CARD16			*red, *green, *blue;
-    
+
     REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq);
     VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
-    
+
     len = client->req_len - bytes_to_int32(sizeof (xRRSetCrtcGammaReq));
     if (len < (stuff->size * 3 + 1) >> 1)
 	return BadLength;
 
     if (stuff->size != crtc->gammaSize)
 	return BadMatch;
-    
+
     red = (CARD16 *) (stuff + 1);
     green = red + crtc->gammaSize;
     blue = green + crtc->gammaSize;
-    
+
     RRCrtcGammaSet (crtc, red, green, blue);
 
     return Success;
@@ -1247,7 +1367,7 @@ ProcRRSetCrtcTransform (ClientPtr client)
 
 
 #define CrtcTransformExtra	(SIZEOF(xRRGetCrtcTransformReply) - 32)
-				
+
 static int
 transform_filter_length (RRTransformPtr transform)
 {
@@ -1349,3 +1469,331 @@ ProcRRGetCrtcTransform (ClientPtr client)
     free(reply);
     return Success;
 }
+
+static int
+RRConvertCrtcConfig(ClientPtr client, ScreenPtr screen,
+		    RRScreenConfigPtr screen_config,
+		    RRCrtcConfigPtr config, xRRCrtcConfig *x,
+		    RROutput *outputIds)
+{
+    RRCrtcPtr		crtc;
+    RROutputPtr		*outputs;
+    rrScrPrivPtr	scr_priv;
+    RRModePtr		mode;
+    PixmapPtr		pixmap;
+    int			rc, i, j;
+    Rotation		rotation;
+
+    VERIFY_RR_CRTC(x->crtc, crtc, DixSetAttrAccess);
+
+    if (x->mode == None)
+    {
+	mode = NULL;
+	if (x->nOutput > 0)
+	    return BadMatch;
+    }
+    else
+    {
+	VERIFY_RR_MODE(x->mode, mode, DixSetAttrAccess);
+	if (x->nOutput == 0)
+	    return BadMatch;
+    }
+    if (x->nOutput)
+    {
+	outputs = malloc(x->nOutput * sizeof (RROutputPtr));
+	if (!outputs)
+	    return BadAlloc;
+    }
+    else
+	outputs = NULL;
+
+    if (x->pixmap == None)
+	pixmap = NULL;
+    else if (x->pixmap == RR_CurrentScanoutPixmap)
+	pixmap = crtc->scanoutPixmap;
+    else
+    {
+	rc = dixLookupResourceByType((pointer *) &pixmap, x->pixmap,
+				     RT_PIXMAP, client, DixWriteAccess);
+	if (rc != Success) {
+	    free(outputs);
+	    return rc;
+	}
+	/* XXX check to make sure this is a scanout pixmap */
+    }
+
+    for (i = 0; i < x->nOutput; i++)
+    {
+	rc = dixLookupResourceByType((pointer *)(outputs + i), outputIds[i],
+				     RROutputType, client, DixSetAttrAccess);
+	if (rc != Success)
+	{
+	    free(outputs);
+	    return rc;
+	}
+	/* validate crtc for this output */
+	for (j = 0; j < outputs[i]->numCrtcs; j++)
+	    if (outputs[i]->crtcs[j] == crtc)
+		break;
+	if (j == outputs[i]->numCrtcs)
+	{
+	    free(outputs);
+	    return BadMatch;
+	}
+	/* validate mode for this output */
+	for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++)
+	{
+	    RRModePtr	m = (j < outputs[i]->numModes ?
+			     outputs[i]->modes[j] :
+			     outputs[i]->userModes[j - outputs[i]->numModes]);
+	    if (m == mode)
+		break;
+	}
+	if (j == outputs[i]->numModes + outputs[i]->numUserModes)
+	{
+	    free(outputs);
+	    return BadMatch;
+	}
+    }
+    /* validate clones */
+    for (i = 0; i < x->nOutput; i++)
+    {
+	for (j = 0; j < x->nOutput; j++)
+	{
+	    int k;
+	    if (i == j)
+		continue;
+	    for (k = 0; k < outputs[i]->numClones; k++)
+	    {
+		if (outputs[i]->clones[k] == outputs[j])
+		    break;
+	    }
+	    if (k == outputs[i]->numClones)
+	    {
+		free(outputs);
+		return BadMatch;
+	    }
+	}
+    }
+
+    if (crtc->pScreen != screen)
+	return BadMatch;
+
+    scr_priv = rrGetScrPriv(screen);
+
+    config->crtc = crtc;
+    config->x = x->x;
+    config->y = x->y;
+    config->mode = mode;
+    config->rotation = x->rotation;
+    config->numOutputs = x->nOutput;
+    config->outputs = outputs;
+    PictTransform_from_xRenderTransform(&config->sprite_position_transform,
+					     &x->spritePositionTransform);
+    PictTransform_from_xRenderTransform(&config->sprite_image_transform,
+					     &x->spriteImageTransform);
+    pixman_f_transform_from_pixman_transform(&config->sprite_position_f_transform,
+					     &config->sprite_position_transform);
+    pixman_f_transform_from_pixman_transform(&config->sprite_image_f_transform,
+					     &config->sprite_image_transform);
+    config->pixmap = pixmap;
+    config->pixmap_x = x->xPixmap;
+    config->pixmap_y = x->yPixmap;
+
+    /*
+     * Validate requested rotation
+     */
+    rotation = (Rotation) x->rotation;
+
+    /* test the rotation bits only! */
+    switch (rotation & 0xf) {
+    case RR_Rotate_0:
+    case RR_Rotate_90:
+    case RR_Rotate_180:
+    case RR_Rotate_270:
+	break;
+    default:
+	/*
+	 * Invalid rotation
+	 */
+	client->errorValue = x->rotation;
+	free(outputs);
+	return BadValue;
+    }
+
+    if (mode)
+    {
+	if ((~crtc->rotations) & rotation)
+	{
+	    /*
+	     * requested rotation or reflection not supported by screen
+	     */
+	    client->errorValue = x->rotation;
+	    free(outputs);
+	    return BadMatch;
+	}
+
+	/*
+	 * If scanning out from another pixmap, make sure the mode
+	 * fits
+	 */
+	if (pixmap)
+	{
+	    if (x->xPixmap + mode->mode.width > pixmap->drawable.width) {
+		client->errorValue = x->xPixmap;
+		free(outputs);
+		return BadValue;
+	    }
+	    if (x->yPixmap + mode->mode.height > pixmap->drawable.height) {
+		client->errorValue = x->yPixmap;
+		free(outputs);
+		return BadValue;
+	    }
+	}
+	/*
+	 * Check screen size bounds if the DDX provides a 1.2 interface
+	 * for setting screen size. Else, assume the CrtcSet sets
+	 * the size along with the mode. If the driver supports transforms,
+	 * then it must allow crtcs to display a subset of the screen, so
+	 * only do this check for drivers without transform support.
+	 */
+	else if (scr_priv->rrScreenSetSize && !crtc->transforms)
+	{
+	    if (!RRScreenCoversCrtc(screen_config, config,
+				    &crtc->client_pending_transform,
+				    &client->errorValue))
+	    {
+		free(outputs);
+		return BadValue;
+	    }
+	}
+    }
+
+    return Success;
+}
+
+int
+ProcRRSetCrtcConfigs (ClientPtr client)
+{
+    REQUEST(xRRSetCrtcConfigsReq);
+    xRRSetCrtcConfigsReply  rep;
+    DrawablePtr		    drawable;
+    ScreenPtr		    screen;
+    rrScrPrivPtr	    scr_priv;
+    xRRCrtcConfig	    *x_configs;
+    RRScreenConfigRec	    screen_config;
+    RRCrtcConfigPtr	    configs = NULL;
+    RROutput		    *output_ids;
+    int			    num_configs = 0;
+    int			    rc, i;
+    int			    extra_len;
+    int			    num_output_ids;
+
+    REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigsReq);
+
+    extra_len = client->req_len - bytes_to_int32(sizeof(xRRSetCrtcConfigsReq));
+
+    num_configs = stuff->nConfigs;
+
+    /* Check request length against number of configs specified */
+    if (num_configs * (sizeof (xRRCrtcConfig) >> 2) > extra_len)
+	return BadLength;
+
+    extra_len -= num_configs * (sizeof (xRRCrtcConfig) >> 2);
+    x_configs = (xRRCrtcConfig *) (stuff + 1);
+
+    /* Check remaining request length against number of outputs */
+    num_output_ids = 0;
+    for (i = 0; i < num_configs; i++)
+	num_output_ids += x_configs[i].nOutput;
+
+    if (extra_len != num_output_ids)
+	return BadLength;
+
+    rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixGetAttrAccess);
+    if (rc != Success)
+	return rc;
+
+    screen = drawable->pScreen;
+
+    scr_priv = rrGetScrPriv(screen);
+
+    if (!scr_priv)
+    {
+	rep.status = RRSetConfigFailed;
+	goto sendReply;
+    }
+
+    if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0)
+    {
+	client->errorValue = 0;
+	return BadValue;
+    }
+
+    if (stuff->screenPixmapWidth < scr_priv->minWidth ||
+	scr_priv->maxWidth < stuff->screenPixmapWidth)
+    {
+	client->errorValue = stuff->screenPixmapWidth;
+	return BadValue;
+    }
+    if (stuff->screenPixmapHeight < scr_priv->minHeight ||
+	scr_priv->maxHeight < stuff->screenPixmapHeight)
+    {
+	client->errorValue = stuff->screenPixmapHeight;
+	return BadValue;
+    }
+
+    screen_config.screen_pixmap_width = stuff->screenPixmapWidth;
+    screen_config.screen_pixmap_height = stuff->screenPixmapHeight;
+    screen_config.screen_width = stuff->screenWidth;
+    screen_config.screen_height = stuff->screenHeight;
+    screen_config.mm_width = stuff->widthInMillimeters;
+    screen_config.mm_height = stuff->heightInMillimeters;
+
+    output_ids = (RROutput *) (x_configs + num_configs);
+
+    /*
+     * Convert protocol crtc configurations into
+     * server crtc configurations
+     */
+    configs = calloc(num_configs, sizeof (RRCrtcConfigRec));
+    if (num_configs > 0 && configs == NULL)
+	return BadAlloc;
+    for (i = 0; i < num_configs; i++) {
+	rc = RRConvertCrtcConfig(client, screen, &screen_config,
+				 &configs[i],
+				 &x_configs[i], output_ids);
+	if (rc != Success) {
+	    rep.status = RRSetConfigFailed;
+	    goto sendReply;
+	}
+	output_ids += x_configs[i].nOutput;
+    }
+
+    if (num_configs &&
+	!RRSetCrtcConfigs (screen, &screen_config, configs, num_configs))
+    {
+	rep.status = RRSetConfigFailed;
+	goto sendReply;
+    }
+    rep.status = RRSetConfigSuccess;
+    scr_priv->lastSetTime = currentTime;
+
+sendReply:
+    RRFreeCrtcConfigs(configs, num_configs);
+
+    rep.type = X_Reply;
+    /* rep.status has already been filled in */
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+
+    if (client->swapped)
+    {
+	int n;
+	swaps(&rep.sequenceNumber, n);
+	swapl(&rep.length, n);
+    }
+    WriteToClient(client, sizeof(xRRSetCrtcConfigsReply), (char *)&rep);
+
+    return Success;
+}
diff --git a/xorg-server/randr/rrdispatch.c b/xorg-server/randr/rrdispatch.c
index b54086bcb..7540b4d35 100644
--- a/xorg-server/randr/rrdispatch.c
+++ b/xorg-server/randr/rrdispatch.c
@@ -224,5 +224,11 @@ int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = {
     ProcRRSetPanning,		/* 29 */
     ProcRRSetOutputPrimary,	/* 30 */
     ProcRRGetOutputPrimary,	/* 31 */
+/* V1.4 additions */
+    ProcRRQueryScanoutPixmaps,	/* 32 */
+    ProcRRCreateScanoutPixmap,	/* 33 */
+    ProcRRSetCrtcSpriteTransform,/* 34 */
+    ProcRRGetCrtcSpriteTransform,/* 35 */
+    ProcRRSetCrtcConfigs,	 /* 36 */
 };
 
diff --git a/xorg-server/randr/rrinfo.c b/xorg-server/randr/rrinfo.c
index 04c1a6c98..faac15afb 100644
--- a/xorg-server/randr/rrinfo.c
+++ b/xorg-server/randr/rrinfo.c
@@ -168,7 +168,7 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations)
     /* notice current mode */
     if (newMode)
 	RRCrtcNotify (crtc, newMode, 0, 0, pScrPriv->rotation,
-		      NULL, 1, &output);
+		      NULL, 1, &output, NULL);
 }
 #endif
 
diff --git a/xorg-server/randr/rrpixmap.c b/xorg-server/randr/rrpixmap.c
new file mode 100644
index 000000000..5949309c9
--- /dev/null
+++ b/xorg-server/randr/rrpixmap.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright © 2010 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 "randrstr.h"
+#include "xace.h"
+
+int
+ProcRRQueryScanoutPixmaps (ClientPtr client)
+{
+    REQUEST(xRRQueryScanoutPixmapsReq);
+    xRRQueryScanoutPixmapsReply	rep;
+    RRScanoutPixmapInfo		*info;
+    xRRScanoutPixmapInfo	*x_info;
+    int				n_info;
+    int				rc;
+    DrawablePtr			drawable;
+    ScreenPtr			screen;
+    rrScrPrivPtr		screen_priv;
+    int 			n, s;
+
+    REQUEST_SIZE_MATCH(xRRQueryScanoutPixmapsReq);
+    rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixGetAttrAccess);
+    if (rc != Success) {
+	client->errorValue = stuff->drawable;
+	return rc;
+    }
+
+    screen = drawable->pScreen;
+    screen_priv = rrGetScrPriv(screen);
+
+    rep.type = X_Reply;
+    /* rep.status has already been filled in */
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+
+    info = RRQueryScanoutPixmapInfo(screen, &n_info);
+    x_info = calloc(n_info, sizeof (xRRScanoutPixmapInfo));
+    if (n_info && !x_info)
+	return BadAlloc;
+    rep.length += (n_info * sizeof (xRRScanoutPixmapInfo)) >> 2;
+    if (client->swapped) {
+	swaps(&rep.sequenceNumber, n);
+	swapl(&rep.length, n);
+    }
+
+    for (s = 0; s < n_info; s++) {
+	x_info[s].format = info[s].format->id;
+	x_info[s].maxWidth = info[s].maxWidth;
+	x_info[s].maxHeight = info[s].maxHeight;
+	x_info[s].rotations = info[s].rotations;
+	if (client->swapped) {
+	    swapl(&x_info[s].format, n);
+	    swaps(&x_info[s].maxWidth, n);
+	    swaps(&x_info[s].maxHeight, n);
+	    swaps(&x_info[s].rotations, n);
+	}
+    }
+
+    WriteToClient(client, sizeof(rep), (char *)&rep);
+    if (n_info)
+	WriteToClient(client, n_info * sizeof (xRRScanoutPixmapInfo),
+		      (char *) x_info);
+    return Success;
+}
+
+int
+ProcRRCreateScanoutPixmap (ClientPtr client)
+{
+    REQUEST(xRRCreateScanoutPixmapReq);
+    int 		rc;
+    DrawablePtr		drawable;
+    ScreenPtr		screen;
+    rrScrPrivPtr	screen_priv;
+    PixmapPtr		pixmap;
+    int			n_info;
+    RRScanoutPixmapInfo	*info;
+    int			s;
+
+    REQUEST_SIZE_MATCH(xRRCreateScanoutPixmapReq);
+    client->errorValue = stuff->pid;
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+    rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixGetAttrAccess);
+    if (rc != Success) {
+	client->errorValue = stuff->drawable;
+	return rc;
+    }
+    screen = drawable->pScreen;
+    screen_priv = rrGetScrPriv(screen);
+    if (!screen_priv)
+	return BadValue;
+
+    info = RRQueryScanoutPixmapInfo(screen, &n_info);
+    for (s = 0; s < n_info; s++) {
+	if (info[s].format->id == stuff->format)
+	    break;
+    }
+    if (s == n_info || !screen_priv->rrCreateScanoutPixmap) {
+	client->errorValue = stuff->format;
+	return BadValue;
+    }
+    info = &info[s];
+    if (!stuff->width || stuff->width > info->maxWidth) {
+	client->errorValue = stuff->width;
+	return BadValue;
+    }
+    if (!stuff->height || stuff->height > info->maxHeight) {
+	client->errorValue = stuff->height;
+	return BadValue;
+    }
+    if ((stuff->rotations & info->rotations) != stuff->rotations) {
+	client->errorValue = stuff->rotations;
+	return BadValue;
+    }
+
+    pixmap = screen_priv->rrCreateScanoutPixmap (screen,
+						 stuff->width, stuff->height,
+						 info->depth,
+						 stuff->rotations,
+						 info->format);
+    if (!pixmap)
+	return BadAlloc;
+
+    pixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+    pixmap->drawable.id = stuff->pid;
+    rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP,
+		  pixmap, RT_NONE, NULL, DixCreateAccess);
+    if (rc != Success) {
+	screen->DestroyPixmap(pixmap);
+	return rc;
+    }
+    if (!AddResource(stuff->pid, RT_PIXMAP, pixmap))
+	return BadAlloc;
+    return Success;
+}
diff --git a/xorg-server/randr/rrscreen.c b/xorg-server/randr/rrscreen.c
index 6f842fe62..318dfaa91 100644
--- a/xorg-server/randr/rrscreen.c
+++ b/xorg-server/randr/rrscreen.c
@@ -168,6 +168,8 @@ Bool
 RRScreenSizeSet (ScreenPtr  pScreen,
 		 CARD16	    width,
 		 CARD16	    height,
+		 CARD16	    pixWidth,
+		 CARD16	    pixHeight,
 		 CARD32	    mmWidth,
 		 CARD32	    mmHeight)
 {
@@ -178,6 +180,7 @@ RRScreenSizeSet (ScreenPtr  pScreen,
     {
 	return (*pScrPriv->rrScreenSetSize) (pScreen,
 					     width, height,
+					     pixWidth, pixHeight,
 					     mmWidth, mmHeight);
     }
 #endif
@@ -190,6 +193,24 @@ RRScreenSizeSet (ScreenPtr  pScreen,
     return FALSE;
 }
 
+/*
+ * Compute an RRScreenConfig from the current screen information
+ */
+void
+RRScreenCurrentConfig(ScreenPtr screen,
+		      RRScreenConfigPtr screen_config)
+{
+    PixmapPtr		screen_pixmap = screen->GetScreenPixmap(screen);
+    WindowPtr		root = screen->root;
+
+    screen_config->screen_pixmap_width = screen_pixmap->drawable.width;
+    screen_config->screen_pixmap_height = screen_pixmap->drawable.height;
+    screen_config->screen_width = root->drawable.width;
+    screen_config->screen_height = root->drawable.height;
+    screen_config->mm_width = screen->mmWidth;
+    screen_config->mm_height = screen->mmHeight;
+}
+
 /*
  * Retrieve valid screen size range
  */
@@ -299,6 +320,7 @@ ProcRRSetScreenSize (ClientPtr client)
 	return BadValue;
     }
     if (!RRScreenSizeSet (pScreen, 
+			  stuff->width, stuff->height,
 			  stuff->width, stuff->height,
 			  stuff->widthInMillimeters,
 			  stuff->heightInMillimeters))
@@ -776,8 +798,10 @@ ProcRRSetScreenConfig (ClientPtr client)
     }
     
     rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess);
-    if (rc != Success)
+    if (rc != Success) {
+	client->errorValue = stuff->drawable;
 	return rc;
+    }
 
     pScreen = pDraw->pScreen;
 
@@ -922,14 +946,14 @@ ProcRRSetScreenConfig (ClientPtr client)
 	for (c = 0; c < pScrPriv->numCrtcs; c++)
 	{
 	    if (!RRCrtcSet (pScrPriv->crtcs[c], NULL, 0, 0, RR_Rotate_0,
-			    0, NULL))
+			    0, NULL, NULL))
 	    {
 		rep.status = RRSetConfigFailed;
 		/* XXX recover from failure */
 		goto sendReply;
 	    }
 	}
-	if (!RRScreenSizeSet (pScreen, width, height,
+	if (!RRScreenSizeSet (pScreen, width, height, width, height,
 			      pScreen->mmWidth, pScreen->mmHeight))
 	{
 	    rep.status = RRSetConfigFailed;
@@ -938,7 +962,7 @@ ProcRRSetScreenConfig (ClientPtr client)
 	}
     }
 
-    if (!RRCrtcSet (crtc, mode, 0, 0, stuff->rotation, 1, &output))
+    if (!RRCrtcSet (crtc, mode, 0, 0, stuff->rotation, 1, &output, NULL))
 	rep.status = RRSetConfigFailed;
     else {
 	pScrPriv->lastSetTime = time;
diff --git a/xorg-server/randr/rrsdispatch.c b/xorg-server/randr/rrsdispatch.c
index e16090a41..5c6978aa1 100644
--- a/xorg-server/randr/rrsdispatch.c
+++ b/xorg-server/randr/rrsdispatch.c
@@ -1,503 +1,635 @@
-/*
- * 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.
- */
-
-#include "randrstr.h"
-
-static int
-SProcRRQueryVersion (ClientPtr client)
-{
-    register int n;
-    REQUEST(xRRQueryVersionReq);
-
-    swaps(&stuff->length, n);
-    swapl(&stuff->majorVersion, n);
-    swapl(&stuff->minorVersion, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRGetScreenInfo (ClientPtr client)
-{
-    register int n;
-    REQUEST(xRRGetScreenInfoReq);
-
-    swaps(&stuff->length, n);
-    swapl(&stuff->window, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRSetScreenConfig (ClientPtr client)
-{
-    register int n;
-    REQUEST(xRRSetScreenConfigReq);
-
-    if (RRClientKnowsRates (client))
-    {
-	REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
-	swaps (&stuff->rate, n);
-    }
-    else
-    {
-	REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
-    }
-    
-    swaps(&stuff->length, n);
-    swapl(&stuff->drawable, n);
-    swapl(&stuff->timestamp, n);
-    swaps(&stuff->sizeID, n);
-    swaps(&stuff->rotation, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRSelectInput (ClientPtr client)
-{
-    register int n;
-    REQUEST(xRRSelectInputReq);
-
-    swaps(&stuff->length, n);
-    swapl(&stuff->window, n);
-    swaps(&stuff->enable, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRGetScreenSizeRange (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRGetScreenSizeRangeReq);
-
-    REQUEST_SIZE_MATCH(xRRGetScreenSizeRangeReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->window, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRSetScreenSize (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRSetScreenSizeReq);
-
-    REQUEST_SIZE_MATCH(xRRSetScreenSizeReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->window, n);
-    swaps(&stuff->width, n);
-    swaps(&stuff->height, n);
-    swapl(&stuff->widthInMillimeters, n);
-    swapl(&stuff->heightInMillimeters, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRGetScreenResources (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRGetScreenResourcesReq);
-
-    REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->window, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRGetOutputInfo (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRGetOutputInfoReq);
-
-    REQUEST_SIZE_MATCH(xRRGetOutputInfoReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->output, n);
-    swapl(&stuff->configTimestamp, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRListOutputProperties (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRListOutputPropertiesReq);
-
-    REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->output, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRQueryOutputProperty (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRQueryOutputPropertyReq);
-
-    REQUEST_SIZE_MATCH(xRRQueryOutputPropertyReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->output, n);
-    swapl(&stuff->property, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRConfigureOutputProperty (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRConfigureOutputPropertyReq);
-
-    swaps(&stuff->length, n);
-    swapl(&stuff->output, n);
-    swapl(&stuff->property, n);
-    SwapRestL(stuff);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRChangeOutputProperty (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRChangeOutputPropertyReq);
-
-    REQUEST_AT_LEAST_SIZE (xRRChangeOutputPropertyReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->output, n);
-    swapl(&stuff->property, n);
-    swapl(&stuff->type, n);
-    swapl(&stuff->nUnits, n);
-    switch(stuff->format) {
-	case 8:
-	    break;
-	case 16:
-	    SwapRestS(stuff);
-	    break;
-	case 32:
-	    SwapRestL(stuff);
-	    break;
-	default:
-	    client->errorValue = stuff->format;
-	    return BadValue;
-    }
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRDeleteOutputProperty (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRDeleteOutputPropertyReq);
-    
-    REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->output, n);
-    swapl(&stuff->property, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRGetOutputProperty (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRGetOutputPropertyReq);
-
-    REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->output, n);
-    swapl(&stuff->property, n);
-    swapl(&stuff->type, n);
-    swapl(&stuff->longOffset, n);
-    swapl(&stuff->longLength, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRCreateMode (ClientPtr client)
-{
-    int n;
-    xRRModeInfo *modeinfo;
-    REQUEST(xRRCreateModeReq);
-
-    REQUEST_AT_LEAST_SIZE(xRRCreateModeReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->window, n);
-
-    modeinfo = &stuff->modeInfo;
-    swapl(&modeinfo->id, n);
-    swaps(&modeinfo->width, n);
-    swaps(&modeinfo->height, n);
-    swapl(&modeinfo->dotClock, n);
-    swaps(&modeinfo->hSyncStart, n);
-    swaps(&modeinfo->hSyncEnd, n);
-    swaps(&modeinfo->hTotal, n);
-    swaps(&modeinfo->vSyncStart, n);
-    swaps(&modeinfo->vSyncEnd, n);
-    swaps(&modeinfo->vTotal, n);
-    swaps(&modeinfo->nameLength, n);
-    swapl(&modeinfo->modeFlags, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRDestroyMode (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRDestroyModeReq);
-
-    REQUEST_SIZE_MATCH(xRRDestroyModeReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->mode, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRAddOutputMode (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRAddOutputModeReq);
-
-    REQUEST_SIZE_MATCH(xRRAddOutputModeReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->output, n);
-    swapl(&stuff->mode, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRDeleteOutputMode (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRDeleteOutputModeReq);
-
-    REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->output, n);
-    swapl(&stuff->mode, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRGetCrtcInfo (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRGetCrtcInfoReq);
-
-    REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->crtc, n);
-    swapl(&stuff->configTimestamp, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRSetCrtcConfig (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRSetCrtcConfigReq);
-
-    REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->crtc, n);
-    swapl(&stuff->timestamp, n);
-    swapl(&stuff->configTimestamp, n);
-    swaps(&stuff->x, n);
-    swaps(&stuff->y, n);
-    swapl(&stuff->mode, n);
-    swaps(&stuff->rotation, n);
-    SwapRestL(stuff);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRGetCrtcGammaSize (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRGetCrtcGammaSizeReq);
-
-    REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->crtc, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRGetCrtcGamma (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRGetCrtcGammaReq);
-
-    REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->crtc, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRSetCrtcGamma (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRSetCrtcGammaReq);
-
-    REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->crtc, n);
-    swaps(&stuff->size, n);
-    SwapRestS(stuff);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRSetCrtcTransform (ClientPtr client)
-{
-    int n, nparams;
-    char *filter;
-    CARD32 *params;
-    REQUEST(xRRSetCrtcTransformReq);
-
-    REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->crtc, n);
-    SwapLongs((CARD32 *)&stuff->transform, bytes_to_int32(sizeof(xRenderTransform)));
-    swaps(&stuff->nbytesFilter, n);
-    filter = (char *)(stuff + 1);
-    params = (CARD32 *) (filter + pad_to_int32(stuff->nbytesFilter));
-    nparams = ((CARD32 *) stuff + client->req_len) - params;
-    if (nparams < 0)
-	return BadLength;
-
-    SwapLongs(params, nparams);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRGetCrtcTransform (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRGetCrtcTransformReq);
-
-    REQUEST_SIZE_MATCH(xRRGetCrtcTransformReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->crtc, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRGetPanning (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRGetPanningReq);
-    
-    REQUEST_SIZE_MATCH(xRRGetPanningReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->crtc, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRSetPanning (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRSetPanningReq);
-    
-    REQUEST_SIZE_MATCH(xRRSetPanningReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->crtc, n);
-    swapl(&stuff->timestamp, n);
-    swaps(&stuff->left, n);
-    swaps(&stuff->top, n);
-    swaps(&stuff->width, n);
-    swaps(&stuff->height, n);
-    swaps(&stuff->track_left, n);
-    swaps(&stuff->track_top, n);
-    swaps(&stuff->track_width, n);
-    swaps(&stuff->track_height, n);
-    swaps(&stuff->border_left, n);
-    swaps(&stuff->border_top, n);
-    swaps(&stuff->border_right, n);
-    swaps(&stuff->border_bottom, n);
-    return (*ProcRandrVector[stuff->randrReqType]) (client);
-}
-
-static int
-SProcRRSetOutputPrimary (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRSetOutputPrimaryReq);
-
-    REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->window, n);
-    swapl(&stuff->output, n);
-    return ProcRandrVector[stuff->randrReqType](client);
-}
-
-static int
-SProcRRGetOutputPrimary (ClientPtr client)
-{
-    int n;
-    REQUEST(xRRGetOutputPrimaryReq);
-
-    REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq);
-    swaps(&stuff->length, n);
-    swapl(&stuff->window, n);
-    return ProcRandrVector[stuff->randrReqType](client);
-}
-
-int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = {
-    SProcRRQueryVersion,	/* 0 */
-/* we skip 1 to make old clients fail pretty immediately */
-    NULL,			/* 1 SProcRandrOldGetScreenInfo */
-/* V1.0 apps share the same set screen config request id */
-    SProcRRSetScreenConfig,	/* 2 */
-    NULL,			/* 3 SProcRandrOldScreenChangeSelectInput */
-/* 3 used to be ScreenChangeSelectInput; deprecated */
-    SProcRRSelectInput,		/* 4 */
-    SProcRRGetScreenInfo,    	/* 5 */
-/* V1.2 additions */
-    SProcRRGetScreenSizeRange,	/* 6 */
-    SProcRRSetScreenSize,	/* 7 */
-    SProcRRGetScreenResources,	/* 8 */
-    SProcRRGetOutputInfo,	/* 9 */
-    SProcRRListOutputProperties,/* 10 */
-    SProcRRQueryOutputProperty,	/* 11 */
-    SProcRRConfigureOutputProperty,  /* 12 */
-    SProcRRChangeOutputProperty,/* 13 */
-    SProcRRDeleteOutputProperty,/* 14 */
-    SProcRRGetOutputProperty,	/* 15 */
-    SProcRRCreateMode,		/* 16 */
-    SProcRRDestroyMode,		/* 17 */
-    SProcRRAddOutputMode,	/* 18 */
-    SProcRRDeleteOutputMode,	/* 19 */
-    SProcRRGetCrtcInfo,		/* 20 */
-    SProcRRSetCrtcConfig,	/* 21 */
-    SProcRRGetCrtcGammaSize,	/* 22 */
-    SProcRRGetCrtcGamma,	/* 23 */
-    SProcRRSetCrtcGamma,	/* 24 */
-/* V1.3 additions */
-    SProcRRGetScreenResources,	/* 25 GetScreenResourcesCurrent */
-    SProcRRSetCrtcTransform,	/* 26 */
-    SProcRRGetCrtcTransform,	/* 27 */
-    SProcRRGetPanning,		/* 28 */
-    SProcRRSetPanning,		/* 29 */
-    SProcRRSetOutputPrimary,	/* 30 */
-    SProcRRGetOutputPrimary,	/* 31 */
-};
-
+/*
+ * 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.
+ */
+
+#include "randrstr.h"
+
+static int
+SProcRRQueryVersion (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRRQueryVersionReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->majorVersion, n);
+    swapl(&stuff->minorVersion, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetScreenInfo (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRRGetScreenInfoReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->window, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSetScreenConfig (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRRSetScreenConfigReq);
+
+    if (RRClientKnowsRates (client))
+    {
+	REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
+	swaps (&stuff->rate, n);
+    }
+    else
+    {
+	REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
+    }
+    
+    swaps(&stuff->length, n);
+    swapl(&stuff->drawable, n);
+    swapl(&stuff->timestamp, n);
+    swaps(&stuff->sizeID, n);
+    swaps(&stuff->rotation, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSelectInput (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRRSelectInputReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->window, n);
+    swaps(&stuff->enable, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetScreenSizeRange (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRGetScreenSizeRangeReq);
+
+    REQUEST_SIZE_MATCH(xRRGetScreenSizeRangeReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->window, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSetScreenSize (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRSetScreenSizeReq);
+
+    REQUEST_SIZE_MATCH(xRRSetScreenSizeReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->window, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    swapl(&stuff->widthInMillimeters, n);
+    swapl(&stuff->heightInMillimeters, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetScreenResources (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRGetScreenResourcesReq);
+
+    REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->window, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetOutputInfo (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRGetOutputInfoReq);
+
+    REQUEST_SIZE_MATCH(xRRGetOutputInfoReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->output, n);
+    swapl(&stuff->configTimestamp, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRListOutputProperties (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRListOutputPropertiesReq);
+
+    REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->output, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRQueryOutputProperty (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRQueryOutputPropertyReq);
+
+    REQUEST_SIZE_MATCH(xRRQueryOutputPropertyReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->output, n);
+    swapl(&stuff->property, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRConfigureOutputProperty (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRConfigureOutputPropertyReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->output, n);
+    swapl(&stuff->property, n);
+    SwapRestL(stuff);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRChangeOutputProperty (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRChangeOutputPropertyReq);
+
+    REQUEST_AT_LEAST_SIZE (xRRChangeOutputPropertyReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->output, n);
+    swapl(&stuff->property, n);
+    swapl(&stuff->type, n);
+    swapl(&stuff->nUnits, n);
+    switch(stuff->format) {
+	case 8:
+	    break;
+	case 16:
+	    SwapRestS(stuff);
+	    break;
+	case 32:
+	    SwapRestL(stuff);
+	    break;
+	default:
+	    client->errorValue = stuff->format;
+	    return BadValue;
+    }
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRDeleteOutputProperty (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRDeleteOutputPropertyReq);
+    
+    REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->output, n);
+    swapl(&stuff->property, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetOutputProperty (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRGetOutputPropertyReq);
+
+    REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->output, n);
+    swapl(&stuff->property, n);
+    swapl(&stuff->type, n);
+    swapl(&stuff->longOffset, n);
+    swapl(&stuff->longLength, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRCreateMode (ClientPtr client)
+{
+    int n;
+    xRRModeInfo *modeinfo;
+    REQUEST(xRRCreateModeReq);
+
+    REQUEST_AT_LEAST_SIZE(xRRCreateModeReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->window, n);
+
+    modeinfo = &stuff->modeInfo;
+    swapl(&modeinfo->id, n);
+    swaps(&modeinfo->width, n);
+    swaps(&modeinfo->height, n);
+    swapl(&modeinfo->dotClock, n);
+    swaps(&modeinfo->hSyncStart, n);
+    swaps(&modeinfo->hSyncEnd, n);
+    swaps(&modeinfo->hTotal, n);
+    swaps(&modeinfo->vSyncStart, n);
+    swaps(&modeinfo->vSyncEnd, n);
+    swaps(&modeinfo->vTotal, n);
+    swaps(&modeinfo->nameLength, n);
+    swapl(&modeinfo->modeFlags, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRDestroyMode (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRDestroyModeReq);
+
+    REQUEST_SIZE_MATCH(xRRDestroyModeReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->mode, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRAddOutputMode (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRAddOutputModeReq);
+
+    REQUEST_SIZE_MATCH(xRRAddOutputModeReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->output, n);
+    swapl(&stuff->mode, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRDeleteOutputMode (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRDeleteOutputModeReq);
+
+    REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->output, n);
+    swapl(&stuff->mode, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetCrtcInfo (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRGetCrtcInfoReq);
+
+    REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->crtc, n);
+    swapl(&stuff->configTimestamp, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSetCrtcConfig (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRSetCrtcConfigReq);
+
+    REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->crtc, n);
+    swapl(&stuff->timestamp, n);
+    swapl(&stuff->configTimestamp, n);
+    swaps(&stuff->x, n);
+    swaps(&stuff->y, n);
+    swapl(&stuff->mode, n);
+    swaps(&stuff->rotation, n);
+    SwapRestL(stuff);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetCrtcGammaSize (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRGetCrtcGammaSizeReq);
+
+    REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->crtc, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetCrtcGamma (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRGetCrtcGammaReq);
+
+    REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->crtc, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSetCrtcGamma (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRSetCrtcGammaReq);
+
+    REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->crtc, n);
+    swaps(&stuff->size, n);
+    SwapRestS(stuff);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSetCrtcTransform (ClientPtr client)
+{
+    int n, nparams;
+    char *filter;
+    CARD32 *params;
+    REQUEST(xRRSetCrtcTransformReq);
+
+    REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->crtc, n);
+    SwapLongs((CARD32 *)&stuff->transform, bytes_to_int32(sizeof(xRenderTransform)));
+    swaps(&stuff->nbytesFilter, n);
+    filter = (char *)(stuff + 1);
+    params = (CARD32 *) (filter + pad_to_int32(stuff->nbytesFilter));
+    nparams = ((CARD32 *) stuff + client->req_len) - params;
+    if (nparams < 0)
+	return BadLength;
+
+    SwapLongs(params, nparams);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetCrtcTransform (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRGetCrtcTransformReq);
+
+    REQUEST_SIZE_MATCH(xRRGetCrtcTransformReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->crtc, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetPanning (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRGetPanningReq);
+    
+    REQUEST_SIZE_MATCH(xRRGetPanningReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->crtc, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSetPanning (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRSetPanningReq);
+    
+    REQUEST_SIZE_MATCH(xRRSetPanningReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->crtc, n);
+    swapl(&stuff->timestamp, n);
+    swaps(&stuff->left, n);
+    swaps(&stuff->top, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    swaps(&stuff->track_left, n);
+    swaps(&stuff->track_top, n);
+    swaps(&stuff->track_width, n);
+    swaps(&stuff->track_height, n);
+    swaps(&stuff->border_left, n);
+    swaps(&stuff->border_top, n);
+    swaps(&stuff->border_right, n);
+    swaps(&stuff->border_bottom, n);
+    return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSetOutputPrimary (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRSetOutputPrimaryReq);
+
+    REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->window, n);
+    swapl(&stuff->output, n);
+    return ProcRandrVector[stuff->randrReqType](client);
+}
+
+static int
+SProcRRGetOutputPrimary (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRGetOutputPrimaryReq);
+
+    REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->window, n);
+    return ProcRandrVector[stuff->randrReqType](client);
+}
+
+static int
+SProcRRQueryScanoutPixmaps (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRQueryScanoutPixmapsReq);
+
+    REQUEST_SIZE_MATCH(xRRQueryScanoutPixmapsReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->drawable, n);
+    return ProcRandrVector[stuff->randrReqType](client);
+}
+
+static int
+SProcRRCreateScanoutPixmap (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRCreateScanoutPixmapReq);
+
+    REQUEST_SIZE_MATCH(xRRCreateScanoutPixmapReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->pid, n);
+    swapl(&stuff->drawable, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    swapl(&stuff->format, n);
+    swaps(&stuff->rotations, n);
+    return ProcRandrVector[stuff->randrReqType](client);
+}
+
+static void
+swap_transform(xRenderTransform *t)
+{
+    int n;
+    swapl(&t->matrix11, n);
+    swapl(&t->matrix12, n);
+    swapl(&t->matrix13, n);
+    swapl(&t->matrix21, n);
+    swapl(&t->matrix22, n);
+    swapl(&t->matrix23, n);
+    swapl(&t->matrix31, n);
+    swapl(&t->matrix32, n);
+    swapl(&t->matrix33, n);
+}
+
+static int
+SProcRRSetCrtcSpriteTransform (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRSetCrtcSpriteTransformReq);
+
+    REQUEST_SIZE_MATCH(xRRSetCrtcSpriteTransformReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->crtc, n);
+    swap_transform(&stuff->positionTransform);
+    swap_transform(&stuff->imageTransform);
+    return ProcRandrVector[stuff->randrReqType](client);
+}
+
+static int
+SProcRRGetCrtcSpriteTransform (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRGetCrtcSpriteTransformReq);
+
+    REQUEST_SIZE_MATCH(xRRGetCrtcSpriteTransformReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->crtc, n);
+    return ProcRandrVector[stuff->randrReqType](client);
+}
+
+static int
+SProcRRSetCrtcConfigs (ClientPtr client)
+{
+    int n;
+    REQUEST(xRRSetCrtcConfigsReq);
+    int c;
+    int extra_len;
+    int num_configs;
+    int num_output_ids;
+    xRRCrtcConfig *x_configs;
+
+    REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigsReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->drawable, n);
+    swaps(&stuff->screenPixmapWidth, n);
+    swaps(&stuff->screenPixmapHeight, n);
+    swaps(&stuff->screenWidth, n);
+    swaps(&stuff->screenHeight, n);
+    swapl(&stuff->widthInMillimeters, n);
+    swapl(&stuff->heightInMillimeters, n);
+    swaps(&stuff->nConfigs, n);
+
+    extra_len = client->req_len - bytes_to_int32(sizeof(xRRSetCrtcConfigsReq));
+
+    num_configs = stuff->nConfigs;
+
+    /* Check request length against number of configs specified */
+    if (num_configs * (sizeof (xRRCrtcConfig) >> 2) > extra_len)
+	return BadLength;
+
+    x_configs = (xRRCrtcConfig *) (stuff + 1);
+    for (c = 0; c < num_configs; c++) {
+	swapl(&x_configs->crtc, n);
+	swaps(&x_configs->x, n);
+	swaps(&x_configs->y, n);
+	swapl(&x_configs->mode, n);
+	swaps(&x_configs->rotation, n);
+	swaps(&x_configs->nOutput, n);
+	swap_transform(&x_configs->spritePositionTransform);
+	swap_transform(&x_configs->spriteImageTransform);
+	swapl(&x_configs->pixmap, n);
+	swaps(&x_configs->xPixmap, n);
+	swaps(&x_configs->yPixmap, n);
+	x_configs++;
+    }
+
+    /* Let the other dispatch function deal with verifying that
+     * the right number of output ids are present, just
+     * swap whatever is here
+     */
+    num_output_ids = extra_len - (num_configs * (sizeof (xRRCrtcConfig)) >> 2);
+    SwapLongs((CARD32 *) x_configs, num_output_ids);
+
+    return ProcRandrVector[stuff->randrReqType](client);
+}
+
+int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = {
+    SProcRRQueryVersion,	/* 0 */
+/* we skip 1 to make old clients fail pretty immediately */
+    NULL,			/* 1 SProcRandrOldGetScreenInfo */
+/* V1.0 apps share the same set screen config request id */
+    SProcRRSetScreenConfig,	/* 2 */
+    NULL,			/* 3 SProcRandrOldScreenChangeSelectInput */
+/* 3 used to be ScreenChangeSelectInput; deprecated */
+    SProcRRSelectInput,		/* 4 */
+    SProcRRGetScreenInfo,    	/* 5 */
+/* V1.2 additions */
+    SProcRRGetScreenSizeRange,	/* 6 */
+    SProcRRSetScreenSize,	/* 7 */
+    SProcRRGetScreenResources,	/* 8 */
+    SProcRRGetOutputInfo,	/* 9 */
+    SProcRRListOutputProperties,/* 10 */
+    SProcRRQueryOutputProperty,	/* 11 */
+    SProcRRConfigureOutputProperty,  /* 12 */
+    SProcRRChangeOutputProperty,/* 13 */
+    SProcRRDeleteOutputProperty,/* 14 */
+    SProcRRGetOutputProperty,	/* 15 */
+    SProcRRCreateMode,		/* 16 */
+    SProcRRDestroyMode,		/* 17 */
+    SProcRRAddOutputMode,	/* 18 */
+    SProcRRDeleteOutputMode,	/* 19 */
+    SProcRRGetCrtcInfo,		/* 20 */
+    SProcRRSetCrtcConfig,	/* 21 */
+    SProcRRGetCrtcGammaSize,	/* 22 */
+    SProcRRGetCrtcGamma,	/* 23 */
+    SProcRRSetCrtcGamma,	/* 24 */
+/* V1.3 additions */
+    SProcRRGetScreenResources,	/* 25 GetScreenResourcesCurrent */
+    SProcRRSetCrtcTransform,	/* 26 */
+    SProcRRGetCrtcTransform,	/* 27 */
+    SProcRRGetPanning,		/* 28 */
+    SProcRRSetPanning,		/* 29 */
+    SProcRRSetOutputPrimary,	/* 30 */
+    SProcRRGetOutputPrimary,	/* 31 */
+/* V1.4 additions */
+    SProcRRQueryScanoutPixmaps,	/* 32 */
+    SProcRRCreateScanoutPixmap,	/* 33 */
+    SProcRRSetCrtcSpriteTransform,/* 34 */
+    SProcRRGetCrtcSpriteTransform,/* 35 */
+    SProcRRSetCrtcConfigs,	/* 36 */
+};
+
diff --git a/xorg-server/randr/rrsprite.c b/xorg-server/randr/rrsprite.c
new file mode 100644
index 000000000..c441e0396
--- /dev/null
+++ b/xorg-server/randr/rrsprite.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright © 2010 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 "randrstr.h"
+#include "swaprep.h"
+
+void
+RRCrtcSpriteTransformSet(RRCrtcPtr crtc,
+			 PictTransform *position_transform,
+			 PictTransform *image_transform,
+			 struct pict_f_transform *f_position_transform,
+			 struct pict_f_transform *f_image_transform)
+{
+    ScreenPtr			pScreen;
+    rrScrPrivPtr		pScrPriv;
+
+    pScreen = crtc->pScreen;
+    pScrPriv = rrGetScrPriv(pScreen);
+    crtc->client_sprite_position_transform = *position_transform;
+    crtc->client_sprite_image_transform = *image_transform;
+    crtc->client_sprite_f_position_transform = *f_position_transform;
+    crtc->client_sprite_f_image_transform = *f_image_transform;
+    if (pScrPriv->rrSetCrtcSpriteTransform)
+	(*pScrPriv->rrSetCrtcSpriteTransform) (pScreen, crtc,
+					       &crtc->client_sprite_f_position_transform,
+					       &crtc->client_sprite_f_image_transform);
+}
+
+int
+ProcRRSetCrtcSpriteTransform (ClientPtr client)
+{
+    REQUEST(xRRSetCrtcSpriteTransformReq);
+    RRCrtcPtr		    crtc;
+    PictTransform	    position_transform, image_transform;
+    struct pixman_f_transform f_position_transform, f_image_transform;
+
+    REQUEST_AT_LEAST_SIZE(xRRSetCrtcSpriteTransformReq);
+    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+    PictTransform_from_xRenderTransform (&position_transform, &stuff->positionTransform);
+    PictTransform_from_xRenderTransform (&image_transform, &stuff->imageTransform);
+    pixman_f_transform_from_pixman_transform (&f_position_transform, &position_transform);
+    pixman_f_transform_from_pixman_transform (&f_image_transform, &image_transform);
+
+    RRCrtcSpriteTransformSet (crtc, &position_transform, &image_transform,
+			      &f_position_transform, &f_image_transform);
+    return Success;
+}
+
+#define CrtcSpriteTransformExtra	(SIZEOF(xRRGetCrtcSpriteTransformReply) - 32)
+
+int
+ProcRRGetCrtcSpriteTransform (ClientPtr client)
+{
+    REQUEST(xRRGetCrtcSpriteTransformReq);
+    xRRGetCrtcSpriteTransformReply	*reply;
+    RRCrtcPtr			crtc;
+    int				n;
+    char			*extra;
+
+    REQUEST_SIZE_MATCH (xRRGetCrtcSpriteTransformReq);
+    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+    reply = malloc(sizeof (xRRGetCrtcSpriteTransformReply));
+    if (!reply)
+	return BadAlloc;
+
+    extra = (char *) (reply + 1);
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = bytes_to_int32(CrtcSpriteTransformExtra);
+
+    xRenderTransform_from_PictTransform(&reply->positionTransform, &crtc->client_sprite_position_transform);
+    xRenderTransform_from_PictTransform(&reply->imageTransform, &crtc->client_sprite_image_transform);
+
+    if (client->swapped) {
+	swaps (&reply->sequenceNumber, n);
+	swapl (&reply->length, n);
+	SwapLongs((CARD32 *) &reply->positionTransform, bytes_to_int32(sizeof(xRenderTransform)));
+	SwapLongs((CARD32 *) &reply->imageTransform, bytes_to_int32(sizeof(xRenderTransform)));
+    }
+    WriteToClient (client, sizeof (xRRGetCrtcSpriteTransformReply), (char *) reply);
+    free(reply);
+    return Success;
+}
diff --git a/xorg-server/randr/rrtransform.c b/xorg-server/randr/rrtransform.c
index 102a0f48e..f78d5f913 100644
--- a/xorg-server/randr/rrtransform.c
+++ b/xorg-server/randr/rrtransform.c
@@ -134,6 +134,24 @@ RRTransformRescale(struct pixman_f_transform *f_transform, double limit)
 	    f_transform->m[j][i] *= scale;
 }
 
+#define EPSILON (1e-20)
+#define IS_F_SAME(a,b)	(fabs((a)-(b)) < EPSILON)
+#define IS_F_ZERO(a)	(fabs(a) < EPSILON)
+
+static Bool
+pict_f_transform_is_identity (const struct pixman_f_transform *t)
+{
+    return (IS_F_SAME (t->m[0][0], t->m[1][1]) &&
+	    IS_F_SAME (t->m[0][0], t->m[2][2]) &&
+	    !IS_F_ZERO (t->m[0][0]) &&
+	    IS_F_ZERO (t->m[0][1]) &&
+	    IS_F_ZERO (t->m[0][2]) &&
+	    IS_F_ZERO (t->m[1][0]) &&
+	    IS_F_ZERO (t->m[1][2]) &&
+	    IS_F_ZERO (t->m[2][0]) &&
+	    IS_F_ZERO (t->m[2][1]));
+}
+
 /*
  * Compute the complete transformation matrix including
  * client-specified transform, rotation/reflection values and the crtc 
@@ -148,23 +166,39 @@ RRTransformCompute (int			    x,
 		    int			    height,
 		    Rotation		    rotation,
 		    RRTransformPtr	    rr_transform,
+		    struct pixman_f_transform *sprite_position_transform,
+		    struct pixman_f_transform *sprite_image_transform,
 
 		    PictTransformPtr	    transform,
 		    struct pixman_f_transform *f_transform,
-		    struct pixman_f_transform *f_inverse)
+		    struct pixman_f_transform *f_inverse,
+		    struct pixman_f_transform *f_fb_to_sprite,
+		    struct pixman_f_transform *f_sprite_to_image,
+		    Bool		      *sprite_transform_in_use)
 {
     PictTransform	    t_transform, inverse;
     struct pixman_f_transform tf_transform, tf_inverse;
+    struct pixman_f_transform sf_position_transform, sf_image_transform;
+    struct pixman_f_transform f_image_to_sprite;
     Bool		    overflow = FALSE;
+    Bool		    ret = TRUE;
 
     if (!transform) transform = &t_transform;
     if (!f_transform) f_transform = &tf_transform;
     if (!f_inverse) f_inverse = &tf_inverse;
+    if (!f_fb_to_sprite) f_fb_to_sprite = &sf_position_transform;
+    if (!f_sprite_to_image) f_sprite_to_image = &sf_image_transform;
+
+    /* invert the sprite image transform to have it go from dest to source */
+    if (!pixman_f_transform_invert (&f_image_to_sprite, f_sprite_to_image))
+	pixman_f_transform_init_identity(&f_image_to_sprite);
 
     pixman_transform_init_identity (transform);
     pixman_transform_init_identity (&inverse);
     pixman_f_transform_init_identity (f_transform);
     pixman_f_transform_init_identity (f_inverse);
+    pixman_f_transform_init_identity (f_fb_to_sprite);
+    pixman_f_transform_init_identity (f_sprite_to_image);
     if (rotation != RR_Rotate_0)
     {
 	double	f_rot_cos, f_rot_sin, f_rot_dx, f_rot_dy;
@@ -246,7 +280,14 @@ RRTransformCompute (int			    x,
 	pixman_f_transform_translate (f_transform, f_inverse, f_scale_dx, f_scale_dy);
     }
     
-#ifdef RANDR_12_INTERFACE
+    /*
+     * Sprite position is affected by the transform matrix,
+     * but the image is not
+     */
+    pixman_f_transform_multiply(f_sprite_to_image,
+				f_transform,
+				&f_image_to_sprite);
+
     if (rr_transform)
     {
         if (!pixman_transform_multiply (transform, &rr_transform->transform, transform))
@@ -254,7 +295,7 @@ RRTransformCompute (int			    x,
 	pixman_f_transform_multiply (f_transform, &rr_transform->f_transform, f_transform);
 	pixman_f_transform_multiply (f_inverse, f_inverse, &rr_transform->f_inverse);
     }
-#endif
+
     /*
      * Compute the class of the resulting transform
      */
@@ -264,7 +305,7 @@ RRTransformCompute (int			    x,
 
 	pixman_f_transform_init_translate (f_transform,  x,  y);
 	pixman_f_transform_init_translate (f_inverse,   -x, -y);
-	return FALSE;
+	ret = FALSE;
     }
     else
     {
@@ -278,6 +319,19 @@ RRTransformCompute (int			    x,
 	    RRTransformRescale(&f_scaled, 16384.0);
 	    pixman_transform_from_pixman_f_transform(transform, &f_scaled);
 	}
-	return TRUE;
+	ret = TRUE;
     }
+
+    /*
+     * Sprite position is affected by the transform matrix,
+     * but the image is not
+     */
+    pixman_f_transform_multiply(f_fb_to_sprite,
+				f_inverse,
+				sprite_position_transform);
+    if (sprite_transform_in_use)
+	*sprite_transform_in_use = ret || !pict_f_transform_is_identity(f_fb_to_sprite);
+    return ret;
 }
+
+
diff --git a/xorg-server/randr/rrtransform.h b/xorg-server/randr/rrtransform.h
index 561762dfe..eaced0d3e 100644
--- a/xorg-server/randr/rrtransform.h
+++ b/xorg-server/randr/rrtransform.h
@@ -1,75 +1,86 @@
-/*
- * 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;
-};
-
-extern _X_EXPORT void
-RRTransformInit (RRTransformPtr transform);
-
-extern _X_EXPORT void
-RRTransformFini (RRTransformPtr transform);
-
-extern _X_EXPORT Bool
-RRTransformEqual (RRTransformPtr a, RRTransformPtr b);
-
-extern _X_EXPORT Bool
-RRTransformSetFilter (RRTransformPtr	dst,
-		      PictFilterPtr	filter,
-		      xFixed		*params,
-		      int		nparams,
-		      int		width,
-		      int		height);
-
-extern _X_EXPORT Bool
-RRTransformCopy (RRTransformPtr dst, RRTransformPtr src);
-
-extern _X_EXPORT 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_ */
+/*
+ * 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;
+};
+
+extern _X_EXPORT void
+RRTransformInit (RRTransformPtr transform);
+
+extern _X_EXPORT void
+RRTransformFini (RRTransformPtr transform);
+
+extern _X_EXPORT Bool
+RRTransformEqual (RRTransformPtr a, RRTransformPtr b);
+
+extern _X_EXPORT Bool
+RRTransformSetFilter (RRTransformPtr	dst,
+		      PictFilterPtr	filter,
+		      xFixed		*params,
+		      int		nparams,
+		      int		width,
+		      int		height);
+
+extern _X_EXPORT Bool
+RRTransformCopy (RRTransformPtr dst, RRTransformPtr src);
+
+/*
+ * 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.
+ */
+extern _X_EXPORT Bool
+RRTransformCompute (int			    x,
+		    int			    y,
+		    int			    width,
+		    int			    height,
+		    Rotation		    rotation,
+		    RRTransformPtr	    rr_transform,
+		    struct pict_f_transform *sprite_position_transform,
+		    struct pict_f_transform *sprite_image_transform,
+
+		    PictTransformPtr	    transform,
+		    struct pict_f_transform *f_transform,
+		    struct pict_f_transform *f_inverse,
+		    struct pict_f_transform *f_fb_to_sprite,
+		    struct pict_f_transform *f_sprite_to_image,
+		    Bool		    *sprite_transform_in_use);
+
+#endif /* _RRTRANSFORM_H_ */
-- 
cgit v1.2.3