Create rrtransform.[ch]. Add RRTransform argument to RRCrtcNotify.
Instead of using a separate function to notify DIX about transform changes, add the transform to RRCrtcNotify so that the whole Crtc state changes atomically.
This commit is contained in:
parent
fa6a1df209
commit
7c61db66a4
|
@ -282,6 +282,7 @@ xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotati
|
||||||
crtc->y = y;
|
crtc->y = y;
|
||||||
crtc->rotation = rotation;
|
crtc->rotation = rotation;
|
||||||
if (transform) {
|
if (transform) {
|
||||||
|
RRTransformCopy (&crtc->transform, transform);
|
||||||
crtc->transform = *transform;
|
crtc->transform = *transform;
|
||||||
crtc->transformPresent = TRUE;
|
crtc->transformPresent = TRUE;
|
||||||
} else
|
} else
|
||||||
|
@ -367,10 +368,6 @@ xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotati
|
||||||
if (output->crtc == crtc)
|
if (output->crtc == crtc)
|
||||||
output->funcs->commit(output);
|
output->funcs->commit(output);
|
||||||
}
|
}
|
||||||
#ifdef RANDR_12_INTERFACE
|
|
||||||
if (crtc->randr_crtc)
|
|
||||||
RRCrtcSetTransform (crtc->randr_crtc, transform);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* XXX free adjustedmode */
|
/* XXX free adjustedmode */
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
|
@ -715,7 +715,9 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret = RRCrtcNotify (randr_crtc, randr_mode, x, y,
|
ret = RRCrtcNotify (randr_crtc, randr_mode, x, y,
|
||||||
rotation, numOutputs, randr_outputs);
|
rotation,
|
||||||
|
crtc->transformPresent ? &crtc->transform : NULL,
|
||||||
|
numOutputs, randr_outputs);
|
||||||
xfree(randr_outputs);
|
xfree(randr_outputs);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -395,7 +395,7 @@ xf86CrtcRotate (xf86CrtcPtr crtc)
|
||||||
if (crtc->transformPresent)
|
if (crtc->transformPresent)
|
||||||
transform = &crtc->transform;
|
transform = &crtc->transform;
|
||||||
|
|
||||||
if (!RRComputeTransform (crtc->x, crtc->y,
|
if (!RRTransformCompute (crtc->x, crtc->y,
|
||||||
crtc->mode.HDisplay, crtc->mode.VDisplay,
|
crtc->mode.HDisplay, crtc->mode.VDisplay,
|
||||||
crtc->rotation,
|
crtc->rotation,
|
||||||
transform,
|
transform,
|
||||||
|
|
|
@ -20,7 +20,9 @@ librandr_la_SOURCES = \
|
||||||
rrpointer.c \
|
rrpointer.c \
|
||||||
rrproperty.c \
|
rrproperty.c \
|
||||||
rrscreen.c \
|
rrscreen.c \
|
||||||
rrsdispatch.c
|
rrsdispatch.c \
|
||||||
|
rrtransform.h \
|
||||||
|
rrtransform.c
|
||||||
|
|
||||||
if XINERAMA
|
if XINERAMA
|
||||||
librandr_la_SOURCES += ${XINERAMA_SRCS}
|
librandr_la_SOURCES += ${XINERAMA_SRCS}
|
||||||
|
|
|
@ -159,7 +159,7 @@ miRandRInit (ScreenPtr pScreen)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (!RROutputSetConnection (output, RR_Connected))
|
if (!RROutputSetConnection (output, RR_Connected))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, 1, &output);
|
RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, NULL, 1, &output);
|
||||||
#endif
|
#endif
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "pixmapstr.h"
|
#include "pixmapstr.h"
|
||||||
#include "extnsionst.h"
|
#include "extnsionst.h"
|
||||||
#include "servermd.h"
|
#include "servermd.h"
|
||||||
|
#include "rrtransform.h"
|
||||||
#include <X11/extensions/randr.h>
|
#include <X11/extensions/randr.h>
|
||||||
#include <X11/extensions/randrproto.h>
|
#include <X11/extensions/randrproto.h>
|
||||||
#ifdef RENDER
|
#ifdef RENDER
|
||||||
|
@ -78,7 +79,6 @@ typedef struct _rrPropertyValue RRPropertyValueRec, *RRPropertyValuePtr;
|
||||||
typedef struct _rrProperty RRPropertyRec, *RRPropertyPtr;
|
typedef struct _rrProperty RRPropertyRec, *RRPropertyPtr;
|
||||||
typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr;
|
typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr;
|
||||||
typedef struct _rrOutput RROutputRec, *RROutputPtr;
|
typedef struct _rrOutput RROutputRec, *RROutputPtr;
|
||||||
typedef struct _rrTransform RRTransformRec, *RRTransformPtr;
|
|
||||||
|
|
||||||
struct _rrMode {
|
struct _rrMode {
|
||||||
int refcnt;
|
int refcnt;
|
||||||
|
@ -105,17 +105,6 @@ struct _rrProperty {
|
||||||
RRPropertyValueRec current, pending;
|
RRPropertyValueRec current, pending;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _rrTransform {
|
|
||||||
PictTransform transform;
|
|
||||||
struct pict_f_transform f_transform;
|
|
||||||
struct pict_f_transform f_inverse;
|
|
||||||
PictFilterPtr filter;
|
|
||||||
xFixed *params;
|
|
||||||
int nparams;
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _rrCrtc {
|
struct _rrCrtc {
|
||||||
RRCrtc id;
|
RRCrtc id;
|
||||||
ScreenPtr pScreen;
|
ScreenPtr pScreen;
|
||||||
|
@ -557,6 +546,7 @@ RRCrtcNotify (RRCrtcPtr crtc,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
Rotation rotation,
|
Rotation rotation,
|
||||||
|
RRTransformPtr transform,
|
||||||
int numOutputs,
|
int numOutputs,
|
||||||
RROutputPtr *outputs);
|
RROutputPtr *outputs);
|
||||||
|
|
||||||
|
@ -618,7 +608,7 @@ RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height);
|
||||||
* Return TRUE if the resulting transform is not a simple translation.
|
* Return TRUE if the resulting transform is not a simple translation.
|
||||||
*/
|
*/
|
||||||
Bool
|
Bool
|
||||||
RRComputeTransform (int x,
|
RRTransformCompute (int x,
|
||||||
int y,
|
int y,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
|
@ -635,12 +625,6 @@ RRComputeTransform (int x,
|
||||||
RRTransformPtr
|
RRTransformPtr
|
||||||
RRCrtcGetTransform (RRCrtcPtr crtc);
|
RRCrtcGetTransform (RRCrtcPtr crtc);
|
||||||
|
|
||||||
/*
|
|
||||||
* Mark the pending transform as current
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
RRCrtcSetTransform (RRCrtcPtr crtc, RRTransformPtr transform);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether the pending and current transforms are the same
|
* Check whether the pending and current transforms are the same
|
||||||
*/
|
*/
|
||||||
|
|
230
randr/rrcrtc.c
230
randr/rrcrtc.c
|
@ -48,69 +48,6 @@ RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
RRTransformInit (RRTransformPtr transform)
|
|
||||||
{
|
|
||||||
PictureTransformInitIdentity (&transform->transform);
|
|
||||||
pict_f_transform_init_identity (&transform->f_transform);
|
|
||||||
pict_f_transform_init_identity (&transform->f_inverse);
|
|
||||||
transform->filter = NULL;
|
|
||||||
transform->params = NULL;
|
|
||||||
transform->nparams = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Bool
|
|
||||||
RRTransformSetFilter (RRTransformPtr dst,
|
|
||||||
PictFilterPtr filter,
|
|
||||||
xFixed *params,
|
|
||||||
int nparams,
|
|
||||||
int width,
|
|
||||||
int height)
|
|
||||||
{
|
|
||||||
xFixed *new_params;
|
|
||||||
|
|
||||||
if (nparams)
|
|
||||||
{
|
|
||||||
new_params = xalloc (nparams * sizeof (xFixed));
|
|
||||||
if (!new_params)
|
|
||||||
return FALSE;
|
|
||||||
memcpy (new_params, params, nparams * sizeof (xFixed));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
new_params = NULL;
|
|
||||||
if (dst->params)
|
|
||||||
xfree (dst->params);
|
|
||||||
dst->filter = filter;
|
|
||||||
dst->params = new_params;
|
|
||||||
dst->nparams = nparams;
|
|
||||||
dst->width = width;
|
|
||||||
dst->height = height;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Bool
|
|
||||||
RRTransformCopy (RRTransformPtr dst, RRTransformPtr src)
|
|
||||||
{
|
|
||||||
if (src)
|
|
||||||
{
|
|
||||||
if (!RRTransformSetFilter (dst, src->filter,
|
|
||||||
src->params, src->nparams, src->width, src->height))
|
|
||||||
return FALSE;
|
|
||||||
dst->transform = src->transform;
|
|
||||||
dst->f_transform = src->f_transform;
|
|
||||||
dst->f_inverse = src->f_inverse;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!RRTransformSetFilter (dst, NULL, NULL, 0, 0, 0))
|
|
||||||
return FALSE;
|
|
||||||
PictureTransformInitIdentity (&dst->transform);
|
|
||||||
pict_f_transform_init_identity (&dst->f_transform);
|
|
||||||
pict_f_transform_init_identity (&dst->f_inverse);
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a CRTC
|
* Create a CRTC
|
||||||
*/
|
*/
|
||||||
|
@ -196,6 +133,7 @@ RRCrtcNotify (RRCrtcPtr crtc,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
Rotation rotation,
|
Rotation rotation,
|
||||||
|
RRTransformPtr transform,
|
||||||
int numOutputs,
|
int numOutputs,
|
||||||
RROutputPtr *outputs)
|
RROutputPtr *outputs)
|
||||||
{
|
{
|
||||||
|
@ -291,6 +229,10 @@ RRCrtcNotify (RRCrtcPtr crtc,
|
||||||
crtc->rotation = rotation;
|
crtc->rotation = rotation;
|
||||||
RRCrtcChanged (crtc, TRUE);
|
RRCrtcChanged (crtc, TRUE);
|
||||||
}
|
}
|
||||||
|
if (!RRTransformEqual (transform, &crtc->client_current_transform)) {
|
||||||
|
RRTransformCopy (&crtc->client_current_transform, transform);
|
||||||
|
RRCrtcChanged (crtc, TRUE);
|
||||||
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,7 +333,7 @@ RRCrtcSet (RRCrtcPtr crtc,
|
||||||
|
|
||||||
if (!mode)
|
if (!mode)
|
||||||
{
|
{
|
||||||
RRCrtcNotify (crtc, NULL, x, y, rotation, 0, NULL);
|
RRCrtcNotify (crtc, NULL, x, y, rotation, NULL, 0, NULL);
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -417,7 +359,7 @@ RRCrtcSet (RRCrtcPtr crtc,
|
||||||
*/
|
*/
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
RRCrtcNotify (crtc, mode, x, y, rotation, 1, outputs);
|
RRCrtcNotify (crtc, mode, x, y, rotation, NULL, 1, outputs);
|
||||||
RRScreenSizeNotify (pScreen);
|
RRScreenSizeNotify (pScreen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -449,27 +391,6 @@ RRCrtcGetTransform (RRCrtcPtr crtc)
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Called when driver applies a transform to a crtc
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
RRCrtcSetTransform (RRCrtcPtr crtc, RRTransformPtr transform)
|
|
||||||
{
|
|
||||||
if (!crtc->mode)
|
|
||||||
return;
|
|
||||||
|
|
||||||
RRTransformCopy (&crtc->client_current_transform, transform);
|
|
||||||
|
|
||||||
RRComputeTransform (crtc->x, crtc->y,
|
|
||||||
crtc->mode->mode.width,
|
|
||||||
crtc->mode->mode.height,
|
|
||||||
crtc->rotation,
|
|
||||||
transform,
|
|
||||||
&crtc->transform,
|
|
||||||
&crtc->f_transform,
|
|
||||||
&crtc->f_inverse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether the pending and current transforms are the same
|
* Check whether the pending and current transforms are the same
|
||||||
*/
|
*/
|
||||||
|
@ -674,141 +595,6 @@ RRCrtcTransformSet (RRCrtcPtr crtc,
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define F(x) IntToxFixed(x)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Compute the complete transformation matrix including
|
|
||||||
* client-specified transform, rotation/reflection values and the crtc
|
|
||||||
* offset.
|
|
||||||
*
|
|
||||||
* Return TRUE if the resulting transform is not a simple translation.
|
|
||||||
*/
|
|
||||||
Bool
|
|
||||||
RRComputeTransform (int x,
|
|
||||||
int y,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
Rotation rotation,
|
|
||||||
RRTransformPtr rr_transform,
|
|
||||||
|
|
||||||
PictTransformPtr transform,
|
|
||||||
struct pict_f_transform *f_transform,
|
|
||||||
struct pict_f_transform *f_inverse)
|
|
||||||
{
|
|
||||||
PictTransform inverse;
|
|
||||||
|
|
||||||
PictureTransformInitIdentity (transform);
|
|
||||||
PictureTransformInitIdentity (&inverse);
|
|
||||||
pict_f_transform_init_identity (f_transform);
|
|
||||||
pict_f_transform_init_identity (f_inverse);
|
|
||||||
if (rotation != RR_Rotate_0)
|
|
||||||
{
|
|
||||||
double f_rot_cos, f_rot_sin, f_rot_dx, f_rot_dy;
|
|
||||||
double f_scale_x, f_scale_y, f_scale_dx, f_scale_dy;
|
|
||||||
xFixed rot_cos, rot_sin, rot_dx, rot_dy;
|
|
||||||
xFixed scale_x, scale_y, scale_dx, scale_dy;
|
|
||||||
|
|
||||||
/* rotation */
|
|
||||||
switch (rotation & 0xf) {
|
|
||||||
default:
|
|
||||||
case RR_Rotate_0:
|
|
||||||
f_rot_cos = 1; f_rot_sin = 0;
|
|
||||||
f_rot_dx = 0; f_rot_dy = 0;
|
|
||||||
rot_cos = F ( 1); rot_sin = F ( 0);
|
|
||||||
rot_dx = F ( 0); rot_dy = F ( 0);
|
|
||||||
break;
|
|
||||||
case RR_Rotate_90:
|
|
||||||
f_rot_cos = 0; f_rot_sin = 1;
|
|
||||||
f_rot_dx = height; f_rot_dy = 0;
|
|
||||||
rot_cos = F ( 0); rot_sin = F ( 1);
|
|
||||||
rot_dx = F ( height); rot_dy = F (0);
|
|
||||||
break;
|
|
||||||
case RR_Rotate_180:
|
|
||||||
f_rot_cos = -1; f_rot_sin = 0;
|
|
||||||
f_rot_dx = width; f_rot_dy = height;
|
|
||||||
rot_cos = F (-1); rot_sin = F ( 0);
|
|
||||||
rot_dx = F (width); rot_dy = F ( height);
|
|
||||||
break;
|
|
||||||
case RR_Rotate_270:
|
|
||||||
f_rot_cos = 0; f_rot_sin = -1;
|
|
||||||
f_rot_dx = 0; f_rot_dy = width;
|
|
||||||
rot_cos = F ( 0); rot_sin = F (-1);
|
|
||||||
rot_dx = F ( 0); rot_dy = F ( width);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
PictureTransformRotate (&inverse, transform, rot_cos, rot_sin);
|
|
||||||
PictureTransformTranslate (&inverse, transform, rot_dx, rot_dy);
|
|
||||||
pict_f_transform_rotate (f_inverse, f_transform, f_rot_cos, f_rot_sin);
|
|
||||||
pict_f_transform_translate (f_inverse, f_transform, f_rot_dx, f_rot_dy);
|
|
||||||
|
|
||||||
/* reflection */
|
|
||||||
f_scale_x = 1;
|
|
||||||
f_scale_dx = 0;
|
|
||||||
f_scale_y = 1;
|
|
||||||
f_scale_dy = 0;
|
|
||||||
scale_x = F (1);
|
|
||||||
scale_dx = 0;
|
|
||||||
scale_y = F (1);
|
|
||||||
scale_dy = 0;
|
|
||||||
if (rotation & RR_Reflect_X)
|
|
||||||
{
|
|
||||||
f_scale_x = -1;
|
|
||||||
scale_x = F(-1);
|
|
||||||
if (rotation & (RR_Rotate_0|RR_Rotate_180)) {
|
|
||||||
f_scale_dx = width;
|
|
||||||
scale_dx = F(width);
|
|
||||||
} else {
|
|
||||||
f_scale_dx = height;
|
|
||||||
scale_dx = F(height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rotation & RR_Reflect_Y)
|
|
||||||
{
|
|
||||||
f_scale_y = -1;
|
|
||||||
scale_y = F(-1);
|
|
||||||
if (rotation & (RR_Rotate_0|RR_Rotate_180)) {
|
|
||||||
f_scale_dy = height;
|
|
||||||
scale_dy = F(height);
|
|
||||||
} else {
|
|
||||||
f_scale_dy = width;
|
|
||||||
scale_dy = F(width);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PictureTransformScale (&inverse, transform, scale_x, scale_y);
|
|
||||||
pict_f_transform_scale (f_inverse, f_transform, f_scale_x, f_scale_y);
|
|
||||||
PictureTransformTranslate (&inverse, transform, scale_dx, scale_dy);
|
|
||||||
pict_f_transform_translate (f_inverse, f_transform, f_scale_dx, f_scale_dy);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef RANDR_12_INTERFACE
|
|
||||||
if (rr_transform)
|
|
||||||
{
|
|
||||||
PictureTransformMultiply (transform, transform, &rr_transform->transform);
|
|
||||||
pict_f_transform_multiply (f_transform, f_transform, &rr_transform->f_transform);
|
|
||||||
pict_f_transform_multiply (f_inverse, &rr_transform->f_inverse, f_inverse);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
* Compute the class of the resulting transform
|
|
||||||
*/
|
|
||||||
if (PictureTransformIsIdentity (transform))
|
|
||||||
{
|
|
||||||
PictureTransformInitTranslate (transform, F ( x), F ( y));
|
|
||||||
|
|
||||||
pict_f_transform_init_translate (f_transform, F( x), F( y));
|
|
||||||
pict_f_transform_init_translate (f_inverse, F(-x), F(-y));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PictureTransformTranslate (&inverse, transform, x, y);
|
|
||||||
pict_f_transform_translate (f_inverse, f_transform, x, y);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize crtc type
|
* Initialize crtc type
|
||||||
*/
|
*/
|
||||||
|
@ -1116,7 +902,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
|
||||||
PictTransform transform;
|
PictTransform transform;
|
||||||
struct pict_f_transform f_transform, f_inverse;
|
struct pict_f_transform f_transform, f_inverse;
|
||||||
|
|
||||||
RRComputeTransform (stuff->x, stuff->y,
|
RRTransformCompute (stuff->x, stuff->y,
|
||||||
mode->mode.width, mode->mode.height,
|
mode->mode.width, mode->mode.height,
|
||||||
rotation,
|
rotation,
|
||||||
&crtc->client_pending_transform,
|
&crtc->client_pending_transform,
|
||||||
|
|
|
@ -170,7 +170,7 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations)
|
||||||
/* notice current mode */
|
/* notice current mode */
|
||||||
if (newMode)
|
if (newMode)
|
||||||
RRCrtcNotify (crtc, newMode, 0, 0, pScrPriv->rotation,
|
RRCrtcNotify (crtc, newMode, 0, 0, pScrPriv->rotation,
|
||||||
1, &output);
|
NULL, 1, &output);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,259 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2007 Keith Packard
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting documentation, and
|
||||||
|
* that the name of the copyright holders not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided "as
|
||||||
|
* is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rrtransform.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
RRTransformInit (RRTransformPtr transform)
|
||||||
|
{
|
||||||
|
PictureTransformInitIdentity (&transform->transform);
|
||||||
|
pict_f_transform_init_identity (&transform->f_transform);
|
||||||
|
pict_f_transform_init_identity (&transform->f_inverse);
|
||||||
|
transform->filter = NULL;
|
||||||
|
transform->params = NULL;
|
||||||
|
transform->nparams = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RRTransformFini (RRTransformPtr transform)
|
||||||
|
{
|
||||||
|
if (transform->params)
|
||||||
|
xfree (transform->params);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
RRTransformEqual (RRTransformPtr a, RRTransformPtr b)
|
||||||
|
{
|
||||||
|
if (a && PictureTransformIsIdentity (&a->transform))
|
||||||
|
a = NULL;
|
||||||
|
if (b && PictureTransformIsIdentity (&b->transform))
|
||||||
|
b = NULL;
|
||||||
|
if (a == NULL && b == NULL)
|
||||||
|
return TRUE;
|
||||||
|
if (a == NULL || b == NULL)
|
||||||
|
return FALSE;
|
||||||
|
if (memcmp (&a->transform, &b->transform, sizeof (a->transform)) != 0)
|
||||||
|
return FALSE;
|
||||||
|
if (a->filter != b->filter)
|
||||||
|
return FALSE;
|
||||||
|
if (a->nparams != b->nparams)
|
||||||
|
return FALSE;
|
||||||
|
if (memcmp (a->params, b->params, a->nparams * sizeof (xFixed)) != 0)
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
RRTransformSetFilter (RRTransformPtr dst,
|
||||||
|
PictFilterPtr filter,
|
||||||
|
xFixed *params,
|
||||||
|
int nparams,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
xFixed *new_params;
|
||||||
|
|
||||||
|
if (nparams)
|
||||||
|
{
|
||||||
|
new_params = xalloc (nparams * sizeof (xFixed));
|
||||||
|
if (!new_params)
|
||||||
|
return FALSE;
|
||||||
|
memcpy (new_params, params, nparams * sizeof (xFixed));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
new_params = NULL;
|
||||||
|
if (dst->params)
|
||||||
|
xfree (dst->params);
|
||||||
|
dst->filter = filter;
|
||||||
|
dst->params = new_params;
|
||||||
|
dst->nparams = nparams;
|
||||||
|
dst->width = width;
|
||||||
|
dst->height = height;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
RRTransformCopy (RRTransformPtr dst, RRTransformPtr src)
|
||||||
|
{
|
||||||
|
if (src && PictureTransformIsIdentity (&src->transform))
|
||||||
|
src = NULL;
|
||||||
|
|
||||||
|
if (src)
|
||||||
|
{
|
||||||
|
if (!RRTransformSetFilter (dst, src->filter,
|
||||||
|
src->params, src->nparams, src->width, src->height))
|
||||||
|
return FALSE;
|
||||||
|
dst->transform = src->transform;
|
||||||
|
dst->f_transform = src->f_transform;
|
||||||
|
dst->f_inverse = src->f_inverse;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!RRTransformSetFilter (dst, NULL, NULL, 0, 0, 0))
|
||||||
|
return FALSE;
|
||||||
|
PictureTransformInitIdentity (&dst->transform);
|
||||||
|
pict_f_transform_init_identity (&dst->f_transform);
|
||||||
|
pict_f_transform_init_identity (&dst->f_inverse);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define F(x) IntToxFixed(x)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute the complete transformation matrix including
|
||||||
|
* client-specified transform, rotation/reflection values and the crtc
|
||||||
|
* offset.
|
||||||
|
*
|
||||||
|
* Return TRUE if the resulting transform is not a simple translation.
|
||||||
|
*/
|
||||||
|
Bool
|
||||||
|
RRTransformCompute (int x,
|
||||||
|
int y,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
Rotation rotation,
|
||||||
|
RRTransformPtr rr_transform,
|
||||||
|
|
||||||
|
PictTransformPtr transform,
|
||||||
|
struct pict_f_transform *f_transform,
|
||||||
|
struct pict_f_transform *f_inverse)
|
||||||
|
{
|
||||||
|
PictTransform t_transform, inverse;
|
||||||
|
struct pict_f_transform tf_transform, tf_inverse;
|
||||||
|
|
||||||
|
if (!transform) transform = &t_transform;
|
||||||
|
if (!f_transform) f_transform = &tf_transform;
|
||||||
|
if (!f_inverse) f_inverse = &tf_inverse;
|
||||||
|
|
||||||
|
PictureTransformInitIdentity (transform);
|
||||||
|
PictureTransformInitIdentity (&inverse);
|
||||||
|
pict_f_transform_init_identity (f_transform);
|
||||||
|
pict_f_transform_init_identity (f_inverse);
|
||||||
|
if (rotation != RR_Rotate_0)
|
||||||
|
{
|
||||||
|
double f_rot_cos, f_rot_sin, f_rot_dx, f_rot_dy;
|
||||||
|
double f_scale_x, f_scale_y, f_scale_dx, f_scale_dy;
|
||||||
|
xFixed rot_cos, rot_sin, rot_dx, rot_dy;
|
||||||
|
xFixed scale_x, scale_y, scale_dx, scale_dy;
|
||||||
|
|
||||||
|
/* rotation */
|
||||||
|
switch (rotation & 0xf) {
|
||||||
|
default:
|
||||||
|
case RR_Rotate_0:
|
||||||
|
f_rot_cos = 1; f_rot_sin = 0;
|
||||||
|
f_rot_dx = 0; f_rot_dy = 0;
|
||||||
|
rot_cos = F ( 1); rot_sin = F ( 0);
|
||||||
|
rot_dx = F ( 0); rot_dy = F ( 0);
|
||||||
|
break;
|
||||||
|
case RR_Rotate_90:
|
||||||
|
f_rot_cos = 0; f_rot_sin = 1;
|
||||||
|
f_rot_dx = height; f_rot_dy = 0;
|
||||||
|
rot_cos = F ( 0); rot_sin = F ( 1);
|
||||||
|
rot_dx = F ( height); rot_dy = F (0);
|
||||||
|
break;
|
||||||
|
case RR_Rotate_180:
|
||||||
|
f_rot_cos = -1; f_rot_sin = 0;
|
||||||
|
f_rot_dx = width; f_rot_dy = height;
|
||||||
|
rot_cos = F (-1); rot_sin = F ( 0);
|
||||||
|
rot_dx = F (width); rot_dy = F ( height);
|
||||||
|
break;
|
||||||
|
case RR_Rotate_270:
|
||||||
|
f_rot_cos = 0; f_rot_sin = -1;
|
||||||
|
f_rot_dx = 0; f_rot_dy = width;
|
||||||
|
rot_cos = F ( 0); rot_sin = F (-1);
|
||||||
|
rot_dx = F ( 0); rot_dy = F ( width);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
PictureTransformRotate (transform, &inverse, rot_cos, rot_sin);
|
||||||
|
PictureTransformTranslate (transform, &inverse, rot_dx, rot_dy);
|
||||||
|
pict_f_transform_rotate (f_transform, f_inverse, f_rot_cos, f_rot_sin);
|
||||||
|
pict_f_transform_translate (f_transform, f_inverse, f_rot_dx, f_rot_dy);
|
||||||
|
|
||||||
|
/* reflection */
|
||||||
|
f_scale_x = 1;
|
||||||
|
f_scale_dx = 0;
|
||||||
|
f_scale_y = 1;
|
||||||
|
f_scale_dy = 0;
|
||||||
|
scale_x = F (1);
|
||||||
|
scale_dx = 0;
|
||||||
|
scale_y = F (1);
|
||||||
|
scale_dy = 0;
|
||||||
|
if (rotation & RR_Reflect_X)
|
||||||
|
{
|
||||||
|
f_scale_x = -1;
|
||||||
|
scale_x = F(-1);
|
||||||
|
if (rotation & (RR_Rotate_0|RR_Rotate_180)) {
|
||||||
|
f_scale_dx = width;
|
||||||
|
scale_dx = F(width);
|
||||||
|
} else {
|
||||||
|
f_scale_dx = height;
|
||||||
|
scale_dx = F(height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rotation & RR_Reflect_Y)
|
||||||
|
{
|
||||||
|
f_scale_y = -1;
|
||||||
|
scale_y = F(-1);
|
||||||
|
if (rotation & (RR_Rotate_0|RR_Rotate_180)) {
|
||||||
|
f_scale_dy = height;
|
||||||
|
scale_dy = F(height);
|
||||||
|
} else {
|
||||||
|
f_scale_dy = width;
|
||||||
|
scale_dy = F(width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PictureTransformScale (transform, &inverse, scale_x, scale_y);
|
||||||
|
pict_f_transform_scale (f_transform, f_inverse, f_scale_x, f_scale_y);
|
||||||
|
PictureTransformTranslate (transform, &inverse, scale_dx, scale_dy);
|
||||||
|
pict_f_transform_translate (f_transform, f_inverse, f_scale_dx, f_scale_dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RANDR_12_INTERFACE
|
||||||
|
if (rr_transform)
|
||||||
|
{
|
||||||
|
PictureTransformMultiply (transform, transform, &rr_transform->transform);
|
||||||
|
pict_f_transform_multiply (f_transform, f_transform, &rr_transform->f_transform);
|
||||||
|
pict_f_transform_multiply (f_inverse, &rr_transform->f_inverse, f_inverse);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Compute the class of the resulting transform
|
||||||
|
*/
|
||||||
|
if (PictureTransformIsIdentity (transform))
|
||||||
|
{
|
||||||
|
PictureTransformInitTranslate (transform, F ( x), F ( y));
|
||||||
|
|
||||||
|
pict_f_transform_init_translate (f_transform, F( x), F( y));
|
||||||
|
pict_f_transform_init_translate (f_inverse, F(-x), F(-y));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PictureTransformTranslate (&inverse, transform, x, y);
|
||||||
|
pict_f_transform_translate (f_inverse, f_transform, x, y);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2007 Keith Packard
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting documentation, and
|
||||||
|
* that the name of the copyright holders not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided "as
|
||||||
|
* is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RRTRANSFORM_H_
|
||||||
|
#define _RRTRANSFORM_H_
|
||||||
|
|
||||||
|
#include <X11/extensions/randr.h>
|
||||||
|
#include "picturestr.h"
|
||||||
|
|
||||||
|
typedef struct _rrTransform RRTransformRec, *RRTransformPtr;
|
||||||
|
|
||||||
|
struct _rrTransform {
|
||||||
|
PictTransform transform;
|
||||||
|
struct pict_f_transform f_transform;
|
||||||
|
struct pict_f_transform f_inverse;
|
||||||
|
PictFilterPtr filter;
|
||||||
|
xFixed *params;
|
||||||
|
int nparams;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
RRTransformInit (RRTransformPtr transform);
|
||||||
|
|
||||||
|
void
|
||||||
|
RRTransformFini (RRTransformPtr transform);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
RRTransformEqual (RRTransformPtr a, RRTransformPtr b);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
RRTransformSetFilter (RRTransformPtr dst,
|
||||||
|
PictFilterPtr filter,
|
||||||
|
xFixed *params,
|
||||||
|
int nparams,
|
||||||
|
int width,
|
||||||
|
int height);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
RRTransformCopy (RRTransformPtr dst, RRTransformPtr src);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
RRTransformCompute (int x,
|
||||||
|
int y,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
Rotation rotation,
|
||||||
|
RRTransformPtr rr_transform,
|
||||||
|
|
||||||
|
PictTransformPtr transform,
|
||||||
|
struct pict_f_transform *f_transform,
|
||||||
|
struct pict_f_transform *f_inverse);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _RRTRANSFORM_H_ */
|
Loading…
Reference in New Issue