Wire up RandR CRTC transform protocol, bump server to RandR 1.3
This involved removing a pile of matrix code from the DDX, as well as moving a bit of transform logic from DDX to DIX.
This commit is contained in:
parent
ff9d1cd843
commit
e3d6f279d5
|
@ -351,6 +351,10 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef RANDR_12_INTERFACE
|
||||||
|
if (crtc->randr_crtc)
|
||||||
|
RRCrtcPostPendingTransform (crtc->randr_crtc);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* XXX free adjustedmode */
|
/* XXX free adjustedmode */
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
|
@ -755,6 +755,9 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
|
||||||
if (rotation != crtc->rotation)
|
if (rotation != crtc->rotation)
|
||||||
changed = TRUE;
|
changed = TRUE;
|
||||||
|
|
||||||
|
if (RRCrtcPendingTransform (randr_crtc))
|
||||||
|
changed = TRUE;
|
||||||
|
|
||||||
if (x != crtc->x || y != crtc->y)
|
if (x != crtc->x || y != crtc->y)
|
||||||
changed = TRUE;
|
changed = TRUE;
|
||||||
for (o = 0; o < config->num_output; o++)
|
for (o = 0; o < config->num_output; o++)
|
||||||
|
|
|
@ -70,204 +70,8 @@ compWindowFormat (WindowPtr pWin)
|
||||||
|
|
||||||
#define F(x) IntToxFixed(x)
|
#define F(x) IntToxFixed(x)
|
||||||
|
|
||||||
static void
|
|
||||||
PictureTransformIdentity (PictTransformPtr matrix)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
memset (matrix, '\0', sizeof (PictTransform));
|
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
matrix->matrix[i][i] = F(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Bool
|
|
||||||
PictureTransformMultiply (PictTransformPtr dst, PictTransformPtr l, PictTransformPtr r)
|
|
||||||
{
|
|
||||||
PictTransform d;
|
|
||||||
int dx, dy;
|
|
||||||
int o;
|
|
||||||
|
|
||||||
for (dy = 0; dy < 3; dy++)
|
|
||||||
for (dx = 0; dx < 3; dx++)
|
|
||||||
{
|
|
||||||
xFixed_48_16 v;
|
|
||||||
xFixed_32_32 partial;
|
|
||||||
v = 0;
|
|
||||||
for (o = 0; o < 3; o++)
|
|
||||||
{
|
|
||||||
partial = (xFixed_32_32) l->matrix[dy][o] * (xFixed_32_32) r->matrix[o][dx];
|
|
||||||
v += partial >> 16;
|
|
||||||
}
|
|
||||||
if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
|
|
||||||
return FALSE;
|
|
||||||
d.matrix[dy][dx] = (xFixed) v;
|
|
||||||
}
|
|
||||||
*dst = d;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
PictureTransformInitScale (PictTransformPtr t, xFixed sx, xFixed sy)
|
|
||||||
{
|
|
||||||
memset (t, '\0', sizeof (PictTransform));
|
|
||||||
t->matrix[0][0] = sx;
|
|
||||||
t->matrix[1][1] = sy;
|
|
||||||
t->matrix[2][2] = F (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static xFixed
|
|
||||||
fixed_inverse (xFixed x)
|
|
||||||
{
|
|
||||||
return (xFixed) ((((xFixed_48_16) F(1)) * F(1)) / x);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Bool
|
|
||||||
PictureTransformScale (PictTransformPtr forward,
|
|
||||||
PictTransformPtr reverse,
|
|
||||||
xFixed sx, xFixed sy)
|
|
||||||
{
|
|
||||||
PictTransform t;
|
|
||||||
|
|
||||||
PictureTransformInitScale (&t, sx, sy);
|
|
||||||
if (!PictureTransformMultiply (forward, &t, forward))
|
|
||||||
return FALSE;
|
|
||||||
PictureTransformInitScale (&t, fixed_inverse (sx), fixed_inverse (sy));
|
|
||||||
if (!PictureTransformMultiply (reverse, reverse, &t))
|
|
||||||
return FALSE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
PictureTransformInitRotate (PictTransformPtr t, xFixed c, xFixed s)
|
|
||||||
{
|
|
||||||
memset (t, '\0', sizeof (PictTransform));
|
|
||||||
t->matrix[0][0] = c;
|
|
||||||
t->matrix[0][1] = -s;
|
|
||||||
t->matrix[1][0] = s;
|
|
||||||
t->matrix[1][1] = c;
|
|
||||||
t->matrix[2][2] = F (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Bool
|
|
||||||
PictureTransformRotate (PictTransformPtr forward,
|
|
||||||
PictTransformPtr reverse,
|
|
||||||
xFixed c, xFixed s)
|
|
||||||
{
|
|
||||||
PictTransform t;
|
|
||||||
PictureTransformInitRotate (&t, c, s);
|
|
||||||
if (!PictureTransformMultiply (forward, &t, forward))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
PictureTransformInitRotate (&t, c, -s);
|
|
||||||
if (!PictureTransformMultiply (reverse, reverse, &t))
|
|
||||||
return FALSE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
PictureTransformInitTranslate (PictTransformPtr t, xFixed tx, xFixed ty)
|
|
||||||
{
|
|
||||||
memset (t, '\0', sizeof (PictTransform));
|
|
||||||
t->matrix[0][0] = F (1);
|
|
||||||
t->matrix[0][2] = tx;
|
|
||||||
t->matrix[1][1] = F (1);
|
|
||||||
t->matrix[1][2] = ty;
|
|
||||||
t->matrix[2][2] = F (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Bool
|
|
||||||
PictureTransformTranslate (PictTransformPtr forward,
|
|
||||||
PictTransformPtr reverse,
|
|
||||||
xFixed tx, xFixed ty)
|
|
||||||
{
|
|
||||||
PictTransform t;
|
|
||||||
PictureTransformInitTranslate (&t, tx, ty);
|
|
||||||
if (!PictureTransformMultiply (forward, &t, forward))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
PictureTransformInitTranslate (&t, -tx, -ty);
|
|
||||||
if (!PictureTransformMultiply (reverse, reverse, &t))
|
|
||||||
return FALSE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
PictureTransformBounds (BoxPtr b, PictTransformPtr matrix)
|
|
||||||
{
|
|
||||||
PictVector v[4];
|
|
||||||
int i;
|
|
||||||
int x1, y1, x2, y2;
|
|
||||||
|
|
||||||
v[0].vector[0] = F (b->x1); v[0].vector[1] = F (b->y1); v[0].vector[2] = F(1);
|
|
||||||
v[1].vector[0] = F (b->x2); v[1].vector[1] = F (b->y1); v[1].vector[2] = F(1);
|
|
||||||
v[2].vector[0] = F (b->x2); v[2].vector[1] = F (b->y2); v[2].vector[2] = F(1);
|
|
||||||
v[3].vector[0] = F (b->x1); v[3].vector[1] = F (b->y2); v[3].vector[2] = F(1);
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
PictureTransformPoint (matrix, &v[i]);
|
|
||||||
x1 = xFixedToInt (v[i].vector[0]);
|
|
||||||
y1 = xFixedToInt (v[i].vector[1]);
|
|
||||||
x2 = xFixedToInt (xFixedCeil (v[i].vector[0]));
|
|
||||||
y2 = xFixedToInt (xFixedCeil (v[i].vector[1]));
|
|
||||||
if (i == 0)
|
|
||||||
{
|
|
||||||
b->x1 = x1; b->y1 = y1;
|
|
||||||
b->x2 = x2; b->y2 = y2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (x1 < b->x1) b->x1 = x1;
|
|
||||||
if (y1 < b->y1) b->y1 = y1;
|
|
||||||
if (x2 > b->x2) b->x2 = x2;
|
|
||||||
if (y2 > b->y2) b->y2 = y2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Bool
|
|
||||||
PictureTransformIsIdentity(PictTransform *t)
|
|
||||||
{
|
|
||||||
return ((t->matrix[0][0] == t->matrix[1][1]) &&
|
|
||||||
(t->matrix[0][0] == t->matrix[2][2]) &&
|
|
||||||
(t->matrix[0][0] != 0) &&
|
|
||||||
(t->matrix[0][1] == 0) &&
|
|
||||||
(t->matrix[0][2] == 0) &&
|
|
||||||
(t->matrix[1][0] == 0) &&
|
|
||||||
(t->matrix[1][2] == 0) &&
|
|
||||||
(t->matrix[2][0] == 0) &&
|
|
||||||
(t->matrix[2][1] == 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
#define toF(x) ((float) (x) / 65536.0f)
|
#define toF(x) ((float) (x) / 65536.0f)
|
||||||
|
|
||||||
static void
|
|
||||||
PictureTransformErrorF (PictTransform *t)
|
|
||||||
{
|
|
||||||
ErrorF ("{ { %f %f %f } { %f %f %f } { %f %f %f } }",
|
|
||||||
toF(t->matrix[0][0]), toF(t->matrix[0][1]), toF(t->matrix[0][2]),
|
|
||||||
toF(t->matrix[1][0]), toF(t->matrix[1][1]), toF(t->matrix[1][2]),
|
|
||||||
toF(t->matrix[2][0]), toF(t->matrix[2][1]), toF(t->matrix[2][2]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static Bool
|
|
||||||
PictureTransformIsInverse (char *where, PictTransform *a, PictTransform *b)
|
|
||||||
{
|
|
||||||
PictTransform t;
|
|
||||||
|
|
||||||
PictureTransformMultiply (&t, a, b);
|
|
||||||
if (!PictureTransformIsIdentity (&t))
|
|
||||||
{
|
|
||||||
ErrorF ("%s: ", where);
|
|
||||||
PictureTransformErrorF (a);
|
|
||||||
ErrorF (" * ");
|
|
||||||
PictureTransformErrorF (b);
|
|
||||||
ErrorF (" = ");
|
|
||||||
PictureTransformErrorF (&t);
|
|
||||||
ErrorF ("\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
|
xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
|
||||||
{
|
{
|
||||||
|
@ -516,9 +320,8 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
|
||||||
ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
|
ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
|
||||||
PictTransform crtc_to_fb, fb_to_crtc;
|
PictTransform crtc_to_fb, fb_to_crtc;
|
||||||
|
|
||||||
PictureTransformIdentity (&crtc_to_fb);
|
PictureTransformInitIdentity (&crtc_to_fb);
|
||||||
PictureTransformIdentity (&fb_to_crtc);
|
PictureTransformInitIdentity (&fb_to_crtc);
|
||||||
PictureTransformIsInverse ("identity", &crtc_to_fb, &fb_to_crtc);
|
|
||||||
if (rotation != RR_Rotate_0)
|
if (rotation != RR_Rotate_0)
|
||||||
{
|
{
|
||||||
xFixed rot_cos, rot_sin, rot_dx, rot_dy;
|
xFixed rot_cos, rot_sin, rot_dx, rot_dy;
|
||||||
|
@ -548,10 +351,7 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
PictureTransformRotate (&crtc_to_fb, &fb_to_crtc, rot_cos, rot_sin);
|
PictureTransformRotate (&crtc_to_fb, &fb_to_crtc, rot_cos, rot_sin);
|
||||||
PictureTransformIsInverse ("rotate", &crtc_to_fb, &fb_to_crtc);
|
|
||||||
|
|
||||||
PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, rot_dx, rot_dy);
|
PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, rot_dx, rot_dy);
|
||||||
PictureTransformIsInverse ("rotate translate", &crtc_to_fb, &fb_to_crtc);
|
|
||||||
|
|
||||||
/* reflection */
|
/* reflection */
|
||||||
scale_x = F (1);
|
scale_x = F (1);
|
||||||
|
@ -576,19 +376,14 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
PictureTransformScale (&crtc_to_fb, &fb_to_crtc, scale_x, scale_y);
|
PictureTransformScale (&crtc_to_fb, &fb_to_crtc, scale_x, scale_y);
|
||||||
PictureTransformIsInverse ("scale", &crtc_to_fb, &fb_to_crtc);
|
|
||||||
|
|
||||||
PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, scale_dx, scale_dy);
|
PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, scale_dx, scale_dy);
|
||||||
PictureTransformIsInverse ("scale translate", &crtc_to_fb, &fb_to_crtc);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RANDR_12_INTERFACE
|
#ifdef RANDR_12_INTERFACE
|
||||||
{
|
{
|
||||||
PictTransform user_forward, user_reverse;
|
PictTransform user_forward, user_reverse;
|
||||||
if (RRCrtcGetTransform (crtc->randr_crtc, &user_forward, &user_reverse))
|
if (crtc->randr_crtc && RRCrtcGetTransform (crtc->randr_crtc, &user_forward, &user_reverse))
|
||||||
{
|
{
|
||||||
PictureTransformIsInverse ("user", &user_forward, &user_reverse);
|
|
||||||
PictureTransformMultiply (&crtc_to_fb, &user_forward, &crtc_to_fb);
|
PictureTransformMultiply (&crtc_to_fb, &user_forward, &crtc_to_fb);
|
||||||
PictureTransformMultiply (&fb_to_crtc, &fb_to_crtc, &user_reverse);
|
PictureTransformMultiply (&fb_to_crtc, &fb_to_crtc, &user_reverse);
|
||||||
}
|
}
|
||||||
|
@ -614,7 +409,6 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
|
||||||
PixmapPtr shadow;
|
PixmapPtr shadow;
|
||||||
|
|
||||||
PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, F(crtc->x), F(crtc->y));
|
PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, F(crtc->x), F(crtc->y));
|
||||||
PictureTransformIsInverse ("offset", &crtc_to_fb, &fb_to_crtc);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* these are the size of the shadow pixmap, which
|
* these are the size of the shadow pixmap, which
|
||||||
|
|
|
@ -119,6 +119,12 @@ struct _rrCrtc {
|
||||||
CARD16 *gammaBlue;
|
CARD16 *gammaBlue;
|
||||||
CARD16 *gammaGreen;
|
CARD16 *gammaGreen;
|
||||||
void *devPrivate;
|
void *devPrivate;
|
||||||
|
PictTransform client_pending_transform;
|
||||||
|
PictTransform client_pending_inverse;
|
||||||
|
PictTransform client_current_transform;
|
||||||
|
PictTransform client_current_inverse;
|
||||||
|
PictTransform transform;
|
||||||
|
PictTransform inverse;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _rrOutput {
|
struct _rrOutput {
|
||||||
|
@ -586,6 +592,23 @@ RRCrtcGammaSetSize (RRCrtcPtr crtc,
|
||||||
void
|
void
|
||||||
RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height);
|
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.
|
||||||
|
*/
|
||||||
|
Bool
|
||||||
|
RRComputeTransform (RRModePtr mode,
|
||||||
|
Rotation rotation,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
PictTransformPtr client_transform,
|
||||||
|
PictTransformPtr client_inverse,
|
||||||
|
PictTransformPtr transform,
|
||||||
|
PictTransformPtr inverse);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return crtc transform
|
* Return crtc transform
|
||||||
*/
|
*/
|
||||||
|
@ -600,12 +623,28 @@ RRCrtcGetTransform (RRCrtcPtr crtc,
|
||||||
void
|
void
|
||||||
RRCrtcPostPendingTransform (RRCrtcPtr crtc);
|
RRCrtcPostPendingTransform (RRCrtcPtr crtc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check whether the pending and current transforms are the same
|
||||||
|
*/
|
||||||
|
Bool
|
||||||
|
RRCrtcPendingTransform (RRCrtcPtr crtc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Destroy a Crtc at shutdown
|
* Destroy a Crtc at shutdown
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
RRCrtcDestroy (RRCrtcPtr crtc);
|
RRCrtcDestroy (RRCrtcPtr crtc);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the pending CRTC transformation
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
RRCrtcTransformSet (RRCrtcPtr crtc,
|
||||||
|
PictTransformPtr transform,
|
||||||
|
PictTransformPtr inverse);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize crtc type
|
* Initialize crtc type
|
||||||
*/
|
*/
|
||||||
|
@ -631,6 +670,12 @@ ProcRRGetCrtcGamma (ClientPtr client);
|
||||||
int
|
int
|
||||||
ProcRRSetCrtcGamma (ClientPtr client);
|
ProcRRSetCrtcGamma (ClientPtr client);
|
||||||
|
|
||||||
|
int
|
||||||
|
ProcRRSetCrtcTransform (ClientPtr client);
|
||||||
|
|
||||||
|
int
|
||||||
|
ProcRRGetCrtcTransform (ClientPtr client);
|
||||||
|
|
||||||
/* rrdispatch.c */
|
/* rrdispatch.c */
|
||||||
Bool
|
Bool
|
||||||
RRClientKnowsRates (ClientPtr pClient);
|
RRClientKnowsRates (ClientPtr pClient);
|
||||||
|
|
203
randr/rrcrtc.c
203
randr/rrcrtc.c
|
@ -89,6 +89,12 @@ RRCrtcCreate (ScreenPtr pScreen, void *devPrivate)
|
||||||
crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL;
|
crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL;
|
||||||
crtc->changed = FALSE;
|
crtc->changed = FALSE;
|
||||||
crtc->devPrivate = devPrivate;
|
crtc->devPrivate = devPrivate;
|
||||||
|
PictureTransformInitIdentity (&crtc->client_pending_transform);
|
||||||
|
PictureTransformInitIdentity (&crtc->client_pending_inverse);
|
||||||
|
PictureTransformInitIdentity (&crtc->client_current_transform);
|
||||||
|
PictureTransformInitIdentity (&crtc->client_current_inverse);
|
||||||
|
PictureTransformInitIdentity (&crtc->transform);
|
||||||
|
PictureTransformInitIdentity (&crtc->inverse);
|
||||||
|
|
||||||
if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc))
|
if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -290,7 +296,8 @@ RRCrtcSet (RRCrtcPtr crtc,
|
||||||
crtc->rotation == rotation &&
|
crtc->rotation == rotation &&
|
||||||
crtc->numOutputs == numOutputs &&
|
crtc->numOutputs == numOutputs &&
|
||||||
!memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) &&
|
!memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) &&
|
||||||
!RRCrtcPendingProperties (crtc))
|
!RRCrtcPendingProperties (crtc) &&
|
||||||
|
!RRCrtcPendingTransform (crtc))
|
||||||
{
|
{
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -366,7 +373,9 @@ RRCrtcGetTransform (RRCrtcPtr crtc,
|
||||||
PictTransformPtr crtc_to_fb,
|
PictTransformPtr crtc_to_fb,
|
||||||
PictTransformPtr fb_to_crtc)
|
PictTransformPtr fb_to_crtc)
|
||||||
{
|
{
|
||||||
return FALSE;
|
*crtc_to_fb = crtc->client_pending_transform;
|
||||||
|
*fb_to_crtc = crtc->client_pending_inverse;
|
||||||
|
return !PictureTransformIsIdentity (crtc_to_fb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -375,6 +384,24 @@ RRCrtcGetTransform (RRCrtcPtr crtc,
|
||||||
void
|
void
|
||||||
RRCrtcPostPendingTransform (RRCrtcPtr crtc)
|
RRCrtcPostPendingTransform (RRCrtcPtr crtc)
|
||||||
{
|
{
|
||||||
|
crtc->client_current_transform = crtc->client_pending_transform;
|
||||||
|
crtc->client_current_inverse = crtc->client_pending_inverse;
|
||||||
|
RRComputeTransform (crtc->mode, crtc->rotation, crtc->x, crtc->y,
|
||||||
|
&crtc->client_current_transform,
|
||||||
|
&crtc->client_current_inverse,
|
||||||
|
&crtc->transform,
|
||||||
|
&crtc->inverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check whether the pending and current transforms are the same
|
||||||
|
*/
|
||||||
|
Bool
|
||||||
|
RRCrtcPendingTransform (RRCrtcPtr crtc)
|
||||||
|
{
|
||||||
|
return memcmp (&crtc->client_current_transform,
|
||||||
|
&crtc->client_pending_transform,
|
||||||
|
sizeof (PictTransform)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -512,6 +539,122 @@ RRCrtcGammaSetSize (RRCrtcPtr crtc,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the pending CRTC transformation
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
RRCrtcTransformSet (RRCrtcPtr crtc,
|
||||||
|
PictTransformPtr transform,
|
||||||
|
PictTransformPtr inverse)
|
||||||
|
{
|
||||||
|
if (!PictureTransformIsInverse (transform, inverse))
|
||||||
|
return BadMatch;
|
||||||
|
crtc->client_pending_transform = *transform;
|
||||||
|
crtc->client_pending_inverse = *inverse;
|
||||||
|
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 (RRModePtr mode,
|
||||||
|
Rotation rotation,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
PictTransformPtr client_transform,
|
||||||
|
PictTransformPtr client_inverse,
|
||||||
|
PictTransformPtr transform,
|
||||||
|
PictTransformPtr inverse)
|
||||||
|
{
|
||||||
|
PictureTransformInitIdentity (transform);
|
||||||
|
PictureTransformInitIdentity (inverse);
|
||||||
|
if (rotation != RR_Rotate_0)
|
||||||
|
{
|
||||||
|
xFixed rot_cos, rot_sin, rot_dx, rot_dy;
|
||||||
|
xFixed scale_x, scale_y, scale_dx, scale_dy;
|
||||||
|
int mode_w = mode->mode.width;
|
||||||
|
int mode_h = mode->mode.height;
|
||||||
|
|
||||||
|
/* rotation */
|
||||||
|
switch (rotation & 0xf) {
|
||||||
|
default:
|
||||||
|
case RR_Rotate_0:
|
||||||
|
rot_cos = F ( 1); rot_sin = F ( 0);
|
||||||
|
rot_dx = F ( 0); rot_dy = F ( 0);
|
||||||
|
break;
|
||||||
|
case RR_Rotate_90:
|
||||||
|
rot_cos = F ( 0); rot_sin = F ( 1);
|
||||||
|
rot_dx = F ( mode_h); rot_dy = F (0);
|
||||||
|
break;
|
||||||
|
case RR_Rotate_180:
|
||||||
|
rot_cos = F (-1); rot_sin = F ( 0);
|
||||||
|
rot_dx = F (mode_w); rot_dy = F ( mode_h);
|
||||||
|
break;
|
||||||
|
case RR_Rotate_270:
|
||||||
|
rot_cos = F ( 0); rot_sin = F (-1);
|
||||||
|
rot_dx = F ( 0); rot_dy = F ( mode_w);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
PictureTransformRotate (inverse, transform, rot_cos, rot_sin);
|
||||||
|
PictureTransformTranslate (inverse, transform, rot_dx, rot_dy);
|
||||||
|
|
||||||
|
/* reflection */
|
||||||
|
scale_x = F (1);
|
||||||
|
scale_dx = 0;
|
||||||
|
scale_y = F (1);
|
||||||
|
scale_dy = 0;
|
||||||
|
if (rotation & RR_Reflect_X)
|
||||||
|
{
|
||||||
|
scale_x = F(-1);
|
||||||
|
if (rotation & (RR_Rotate_0|RR_Rotate_180))
|
||||||
|
scale_dx = F(mode_w);
|
||||||
|
else
|
||||||
|
scale_dx = F(mode_h);
|
||||||
|
}
|
||||||
|
if (rotation & RR_Reflect_Y)
|
||||||
|
{
|
||||||
|
scale_y = F(-1);
|
||||||
|
if (rotation & (RR_Rotate_0|RR_Rotate_180))
|
||||||
|
scale_dy = F(mode_h);
|
||||||
|
else
|
||||||
|
scale_dy = F(mode_w);
|
||||||
|
}
|
||||||
|
|
||||||
|
PictureTransformScale (inverse, transform, scale_x, scale_y);
|
||||||
|
PictureTransformTranslate (inverse, transform, scale_dx, scale_dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RANDR_12_INTERFACE
|
||||||
|
{
|
||||||
|
PictureTransformMultiply (inverse, client_inverse, inverse);
|
||||||
|
PictureTransformMultiply (transform, transform, client_transform);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Compute the class of the resulting transform
|
||||||
|
*/
|
||||||
|
if (PictureTransformIsIdentity (transform))
|
||||||
|
{
|
||||||
|
PictureTransformInitTranslate (inverse, F (-x), F (-y));
|
||||||
|
PictureTransformInitTranslate (transform, F ( x), F ( y));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PictureTransformTranslate (inverse, transform, x, y);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize crtc type
|
* Initialize crtc type
|
||||||
*/
|
*/
|
||||||
|
@ -977,3 +1120,59 @@ ProcRRSetCrtcGamma (ClientPtr client)
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Version 1.3 additions */
|
||||||
|
|
||||||
|
int
|
||||||
|
ProcRRSetCrtcTransform (ClientPtr client)
|
||||||
|
{
|
||||||
|
REQUEST(xRRSetCrtcTransformReq);
|
||||||
|
RRCrtcPtr crtc;
|
||||||
|
PictTransform transform, inverse;
|
||||||
|
|
||||||
|
REQUEST_SIZE_MATCH (xRRSetCrtcTransformReq);
|
||||||
|
crtc = LookupCrtc (client, stuff->crtc, DixWriteAccess);
|
||||||
|
if (!crtc)
|
||||||
|
return RRErrorBase + BadRRCrtc;
|
||||||
|
|
||||||
|
PictTransform_from_xRenderTransform (&transform, &stuff->transform);
|
||||||
|
PictTransform_from_xRenderTransform (&inverse, &stuff->inverse);
|
||||||
|
|
||||||
|
return RRCrtcTransformSet (crtc, &transform, &inverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define CrtcTransformExtra (SIZEOF(xRRGetCrtcTransformReply) - 32)
|
||||||
|
|
||||||
|
int
|
||||||
|
ProcRRGetCrtcTransform (ClientPtr client)
|
||||||
|
{
|
||||||
|
REQUEST(xRRGetCrtcTransformReq);
|
||||||
|
xRRGetCrtcTransformReply reply;
|
||||||
|
RRCrtcPtr crtc;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
REQUEST_SIZE_MATCH (xRRGetCrtcTransformReq);
|
||||||
|
crtc = LookupCrtc (client, stuff->crtc, DixWriteAccess);
|
||||||
|
if (!crtc)
|
||||||
|
return RRErrorBase + BadRRCrtc;
|
||||||
|
|
||||||
|
reply.type = X_Reply;
|
||||||
|
reply.sequenceNumber = client->sequence;
|
||||||
|
reply.length = CrtcTransformExtra >> 2;
|
||||||
|
|
||||||
|
xRenderTransform_from_PictTransform (&reply.pendingTransform,
|
||||||
|
&crtc->client_pending_transform);
|
||||||
|
xRenderTransform_from_PictTransform (&reply.pendingInverse,
|
||||||
|
&crtc->client_pending_inverse);
|
||||||
|
xRenderTransform_from_PictTransform (&reply.currentTransform,
|
||||||
|
&crtc->client_current_transform);
|
||||||
|
xRenderTransform_from_PictTransform (&reply.currentInverse,
|
||||||
|
&crtc->client_current_inverse);
|
||||||
|
if (client->swapped) {
|
||||||
|
swaps (&reply.sequenceNumber, n);
|
||||||
|
swapl (&reply.length, n);
|
||||||
|
SwapLongs ((CARD32 *) &reply.pendingTransform, 40);
|
||||||
|
}
|
||||||
|
WriteToClient (client, sizeof (xRRGetCrtcTransformReply), (char *) &reply);
|
||||||
|
return client->noClientException;
|
||||||
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include "randrstr.h"
|
#include "randrstr.h"
|
||||||
|
|
||||||
#define SERVER_RANDR_MAJOR 1
|
#define SERVER_RANDR_MAJOR 1
|
||||||
#define SERVER_RANDR_MINOR 2
|
#define SERVER_RANDR_MINOR 3
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
RRClientKnowsRates (ClientPtr pClient)
|
RRClientKnowsRates (ClientPtr pClient)
|
||||||
|
@ -211,5 +211,8 @@ int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = {
|
||||||
ProcRRGetCrtcGammaSize, /* 22 */
|
ProcRRGetCrtcGammaSize, /* 22 */
|
||||||
ProcRRGetCrtcGamma, /* 23 */
|
ProcRRGetCrtcGamma, /* 23 */
|
||||||
ProcRRSetCrtcGamma, /* 24 */
|
ProcRRSetCrtcGamma, /* 24 */
|
||||||
|
/* V1.3 additions */
|
||||||
|
ProcRRSetCrtcTransform, /* 25 */
|
||||||
|
ProcRRGetCrtcTransform, /* 26 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -364,6 +364,26 @@ SProcRRSetCrtcGamma (ClientPtr client)
|
||||||
return (*ProcRandrVector[stuff->randrReqType]) (client);
|
return (*ProcRandrVector[stuff->randrReqType]) (client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SProcRRSetCrtcTransform (ClientPtr client)
|
||||||
|
{
|
||||||
|
REQUEST(xRRSetCrtcTransformReq);
|
||||||
|
|
||||||
|
REQUEST_SIZE_MATCH(xRRSetCrtcTransformReq);
|
||||||
|
(void) stuff;
|
||||||
|
return BadImplementation;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SProcRRGetCrtcTransform (ClientPtr client)
|
||||||
|
{
|
||||||
|
REQUEST(xRRGetCrtcTransformReq);
|
||||||
|
|
||||||
|
REQUEST_SIZE_MATCH(xRRGetCrtcTransformReq);
|
||||||
|
(void) stuff;
|
||||||
|
return BadImplementation;
|
||||||
|
}
|
||||||
|
|
||||||
int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = {
|
int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = {
|
||||||
SProcRRQueryVersion, /* 0 */
|
SProcRRQueryVersion, /* 0 */
|
||||||
/* we skip 1 to make old clients fail pretty immediately */
|
/* we skip 1 to make old clients fail pretty immediately */
|
||||||
|
@ -394,5 +414,8 @@ int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = {
|
||||||
SProcRRGetCrtcGammaSize, /* 22 */
|
SProcRRGetCrtcGammaSize, /* 22 */
|
||||||
SProcRRGetCrtcGamma, /* 23 */
|
SProcRRGetCrtcGamma, /* 23 */
|
||||||
SProcRRSetCrtcGamma, /* 24 */
|
SProcRRSetCrtcGamma, /* 24 */
|
||||||
|
/* V1.3 additions */
|
||||||
|
SProcRRSetCrtcTransform, /* 25 */
|
||||||
|
SProcRRGetCrtcTransform, /* 26 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue