diff options
Diffstat (limited to 'randr')
-rw-r--r-- | randr/Makefile.am | 4 | ||||
-rw-r--r-- | randr/mirandr.c | 2 | ||||
-rw-r--r-- | randr/randrstr.h | 22 | ||||
-rw-r--r-- | randr/rrcrtc.c | 230 | ||||
-rw-r--r-- | randr/rrinfo.c | 2 | ||||
-rw-r--r-- | randr/rrtransform.c | 259 | ||||
-rw-r--r-- | randr/rrtransform.h | 75 |
7 files changed, 350 insertions, 244 deletions
diff --git a/randr/Makefile.am b/randr/Makefile.am index 20b0f72e0..3d16ede72 100644 --- a/randr/Makefile.am +++ b/randr/Makefile.am @@ -20,7 +20,9 @@ librandr_la_SOURCES = \ rrpointer.c \ rrproperty.c \ rrscreen.c \ - rrsdispatch.c + rrsdispatch.c \ + rrtransform.h \ + rrtransform.c if XINERAMA librandr_la_SOURCES += ${XINERAMA_SRCS} diff --git a/randr/mirandr.c b/randr/mirandr.c index 777785380..05375e46c 100644 --- a/randr/mirandr.c +++ b/randr/mirandr.c @@ -159,7 +159,7 @@ miRandRInit (ScreenPtr pScreen) return FALSE; if (!RROutputSetConnection (output, RR_Connected)) return FALSE; - RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, 1, &output); + RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, NULL, 1, &output); #endif return TRUE; } diff --git a/randr/randrstr.h b/randr/randrstr.h index d4cfa67e6..822e37747 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -43,6 +43,7 @@ #include "pixmapstr.h" #include "extnsionst.h" #include "servermd.h" +#include "rrtransform.h" #include <X11/extensions/randr.h> #include <X11/extensions/randrproto.h> #ifdef RENDER @@ -78,7 +79,6 @@ typedef struct _rrPropertyValue RRPropertyValueRec, *RRPropertyValuePtr; typedef struct _rrProperty RRPropertyRec, *RRPropertyPtr; typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr; typedef struct _rrOutput RROutputRec, *RROutputPtr; -typedef struct _rrTransform RRTransformRec, *RRTransformPtr; struct _rrMode { int refcnt; @@ -105,17 +105,6 @@ struct _rrProperty { RRPropertyValueRec current, pending; }; -struct _rrTransform { - PictTransform transform; - struct pict_f_transform f_transform; - struct pict_f_transform f_inverse; - PictFilterPtr filter; - xFixed *params; - int nparams; - int width; - int height; -}; - struct _rrCrtc { RRCrtc id; ScreenPtr pScreen; @@ -557,6 +546,7 @@ RRCrtcNotify (RRCrtcPtr crtc, int x, int y, Rotation rotation, + RRTransformPtr transform, int numOutputs, RROutputPtr *outputs); @@ -618,7 +608,7 @@ RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height); * Return TRUE if the resulting transform is not a simple translation. */ Bool -RRComputeTransform (int x, +RRTransformCompute (int x, int y, int width, int height, @@ -636,12 +626,6 @@ RRTransformPtr RRCrtcGetTransform (RRCrtcPtr crtc); /* - * Mark the pending transform as current - */ -void -RRCrtcSetTransform (RRCrtcPtr crtc, RRTransformPtr transform); - -/* * Check whether the pending and current transforms are the same */ Bool diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index 091517a05..1b6350eff 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -48,69 +48,6 @@ RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged) } } -static void -RRTransformInit (RRTransformPtr transform) -{ - PictureTransformInitIdentity (&transform->transform); - pict_f_transform_init_identity (&transform->f_transform); - pict_f_transform_init_identity (&transform->f_inverse); - transform->filter = NULL; - transform->params = NULL; - transform->nparams = 0; -} - -static Bool -RRTransformSetFilter (RRTransformPtr dst, - PictFilterPtr filter, - xFixed *params, - int nparams, - int width, - int height) -{ - xFixed *new_params; - - if (nparams) - { - new_params = xalloc (nparams * sizeof (xFixed)); - if (!new_params) - return FALSE; - memcpy (new_params, params, nparams * sizeof (xFixed)); - } - else - new_params = NULL; - if (dst->params) - xfree (dst->params); - dst->filter = filter; - dst->params = new_params; - dst->nparams = nparams; - dst->width = width; - dst->height = height; - return TRUE; -} - -static Bool -RRTransformCopy (RRTransformPtr dst, RRTransformPtr src) -{ - if (src) - { - if (!RRTransformSetFilter (dst, src->filter, - src->params, src->nparams, src->width, src->height)) - return FALSE; - dst->transform = src->transform; - dst->f_transform = src->f_transform; - dst->f_inverse = src->f_inverse; - } - else - { - if (!RRTransformSetFilter (dst, NULL, NULL, 0, 0, 0)) - return FALSE; - PictureTransformInitIdentity (&dst->transform); - pict_f_transform_init_identity (&dst->f_transform); - pict_f_transform_init_identity (&dst->f_inverse); - } - return TRUE; -} - /* * Create a CRTC */ @@ -196,6 +133,7 @@ RRCrtcNotify (RRCrtcPtr crtc, int x, int y, Rotation rotation, + RRTransformPtr transform, int numOutputs, RROutputPtr *outputs) { @@ -291,6 +229,10 @@ RRCrtcNotify (RRCrtcPtr crtc, crtc->rotation = rotation; RRCrtcChanged (crtc, TRUE); } + if (!RRTransformEqual (transform, &crtc->client_current_transform)) { + RRTransformCopy (&crtc->client_current_transform, transform); + RRCrtcChanged (crtc, TRUE); + } return TRUE; } @@ -391,7 +333,7 @@ RRCrtcSet (RRCrtcPtr crtc, if (!mode) { - RRCrtcNotify (crtc, NULL, x, y, rotation, 0, NULL); + RRCrtcNotify (crtc, NULL, x, y, rotation, NULL, 0, NULL); ret = TRUE; } else @@ -417,7 +359,7 @@ RRCrtcSet (RRCrtcPtr crtc, */ if (ret) { - RRCrtcNotify (crtc, mode, x, y, rotation, 1, outputs); + RRCrtcNotify (crtc, mode, x, y, rotation, NULL, 1, outputs); RRScreenSizeNotify (pScreen); } } @@ -450,27 +392,6 @@ RRCrtcGetTransform (RRCrtcPtr crtc) } /* - * Called when driver applies a transform to a crtc - */ -void -RRCrtcSetTransform (RRCrtcPtr crtc, RRTransformPtr transform) -{ - if (!crtc->mode) - return; - - RRTransformCopy (&crtc->client_current_transform, transform); - - RRComputeTransform (crtc->x, crtc->y, - crtc->mode->mode.width, - crtc->mode->mode.height, - crtc->rotation, - transform, - &crtc->transform, - &crtc->f_transform, - &crtc->f_inverse); -} - -/* * Check whether the pending and current transforms are the same */ Bool @@ -674,141 +595,6 @@ RRCrtcTransformSet (RRCrtcPtr crtc, return Success; } -#define F(x) IntToxFixed(x) - -/* - * Compute the complete transformation matrix including - * client-specified transform, rotation/reflection values and the crtc - * offset. - * - * Return TRUE if the resulting transform is not a simple translation. - */ -Bool -RRComputeTransform (int x, - int y, - int width, - int height, - Rotation rotation, - RRTransformPtr rr_transform, - - PictTransformPtr transform, - struct pict_f_transform *f_transform, - struct pict_f_transform *f_inverse) -{ - PictTransform inverse; - - PictureTransformInitIdentity (transform); - PictureTransformInitIdentity (&inverse); - pict_f_transform_init_identity (f_transform); - pict_f_transform_init_identity (f_inverse); - if (rotation != RR_Rotate_0) - { - double f_rot_cos, f_rot_sin, f_rot_dx, f_rot_dy; - double f_scale_x, f_scale_y, f_scale_dx, f_scale_dy; - xFixed rot_cos, rot_sin, rot_dx, rot_dy; - xFixed scale_x, scale_y, scale_dx, scale_dy; - - /* rotation */ - switch (rotation & 0xf) { - default: - case RR_Rotate_0: - f_rot_cos = 1; f_rot_sin = 0; - f_rot_dx = 0; f_rot_dy = 0; - rot_cos = F ( 1); rot_sin = F ( 0); - rot_dx = F ( 0); rot_dy = F ( 0); - break; - case RR_Rotate_90: - f_rot_cos = 0; f_rot_sin = 1; - f_rot_dx = height; f_rot_dy = 0; - rot_cos = F ( 0); rot_sin = F ( 1); - rot_dx = F ( height); rot_dy = F (0); - break; - case RR_Rotate_180: - f_rot_cos = -1; f_rot_sin = 0; - f_rot_dx = width; f_rot_dy = height; - rot_cos = F (-1); rot_sin = F ( 0); - rot_dx = F (width); rot_dy = F ( height); - break; - case RR_Rotate_270: - f_rot_cos = 0; f_rot_sin = -1; - f_rot_dx = 0; f_rot_dy = width; - rot_cos = F ( 0); rot_sin = F (-1); - rot_dx = F ( 0); rot_dy = F ( width); - break; - } - - PictureTransformRotate (&inverse, transform, rot_cos, rot_sin); - PictureTransformTranslate (&inverse, transform, rot_dx, rot_dy); - pict_f_transform_rotate (f_inverse, f_transform, f_rot_cos, f_rot_sin); - pict_f_transform_translate (f_inverse, f_transform, f_rot_dx, f_rot_dy); - - /* reflection */ - f_scale_x = 1; - f_scale_dx = 0; - f_scale_y = 1; - f_scale_dy = 0; - scale_x = F (1); - scale_dx = 0; - scale_y = F (1); - scale_dy = 0; - if (rotation & RR_Reflect_X) - { - f_scale_x = -1; - scale_x = F(-1); - if (rotation & (RR_Rotate_0|RR_Rotate_180)) { - f_scale_dx = width; - scale_dx = F(width); - } else { - f_scale_dx = height; - scale_dx = F(height); - } - } - if (rotation & RR_Reflect_Y) - { - f_scale_y = -1; - scale_y = F(-1); - if (rotation & (RR_Rotate_0|RR_Rotate_180)) { - f_scale_dy = height; - scale_dy = F(height); - } else { - f_scale_dy = width; - scale_dy = F(width); - } - } - - PictureTransformScale (&inverse, transform, scale_x, scale_y); - pict_f_transform_scale (f_inverse, f_transform, f_scale_x, f_scale_y); - PictureTransformTranslate (&inverse, transform, scale_dx, scale_dy); - pict_f_transform_translate (f_inverse, f_transform, f_scale_dx, f_scale_dy); - } - -#ifdef RANDR_12_INTERFACE - if (rr_transform) - { - PictureTransformMultiply (transform, transform, &rr_transform->transform); - pict_f_transform_multiply (f_transform, f_transform, &rr_transform->f_transform); - pict_f_transform_multiply (f_inverse, &rr_transform->f_inverse, f_inverse); - } -#endif - /* - * Compute the class of the resulting transform - */ - if (PictureTransformIsIdentity (transform)) - { - PictureTransformInitTranslate (transform, F ( x), F ( y)); - - pict_f_transform_init_translate (f_transform, F( x), F( y)); - pict_f_transform_init_translate (f_inverse, F(-x), F(-y)); - return FALSE; - } - else - { - PictureTransformTranslate (&inverse, transform, x, y); - pict_f_transform_translate (f_inverse, f_transform, x, y); - return TRUE; - } -} - /* * Initialize crtc type */ @@ -1116,7 +902,7 @@ ProcRRSetCrtcConfig (ClientPtr client) PictTransform transform; struct pict_f_transform f_transform, f_inverse; - RRComputeTransform (stuff->x, stuff->y, + RRTransformCompute (stuff->x, stuff->y, mode->mode.width, mode->mode.height, rotation, &crtc->client_pending_transform, diff --git a/randr/rrinfo.c b/randr/rrinfo.c index 7e77d393d..38314defd 100644 --- a/randr/rrinfo.c +++ b/randr/rrinfo.c @@ -170,7 +170,7 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) /* notice current mode */ if (newMode) RRCrtcNotify (crtc, newMode, 0, 0, pScrPriv->rotation, - 1, &output); + NULL, 1, &output); } #endif diff --git a/randr/rrtransform.c b/randr/rrtransform.c new file mode 100644 index 000000000..f9934d766 --- /dev/null +++ b/randr/rrtransform.c @@ -0,0 +1,259 @@ +/* + * Copyright © 2007 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "rrtransform.h" + +void +RRTransformInit (RRTransformPtr transform) +{ + PictureTransformInitIdentity (&transform->transform); + pict_f_transform_init_identity (&transform->f_transform); + pict_f_transform_init_identity (&transform->f_inverse); + transform->filter = NULL; + transform->params = NULL; + transform->nparams = 0; +} + +void +RRTransformFini (RRTransformPtr transform) +{ + if (transform->params) + xfree (transform->params); +} + +Bool +RRTransformEqual (RRTransformPtr a, RRTransformPtr b) +{ + if (a && PictureTransformIsIdentity (&a->transform)) + a = NULL; + if (b && PictureTransformIsIdentity (&b->transform)) + b = NULL; + if (a == NULL && b == NULL) + return TRUE; + if (a == NULL || b == NULL) + return FALSE; + if (memcmp (&a->transform, &b->transform, sizeof (a->transform)) != 0) + return FALSE; + if (a->filter != b->filter) + return FALSE; + if (a->nparams != b->nparams) + return FALSE; + if (memcmp (a->params, b->params, a->nparams * sizeof (xFixed)) != 0) + return FALSE; + return TRUE; +} + +Bool +RRTransformSetFilter (RRTransformPtr dst, + PictFilterPtr filter, + xFixed *params, + int nparams, + int width, + int height) +{ + xFixed *new_params; + + if (nparams) + { + new_params = xalloc (nparams * sizeof (xFixed)); + if (!new_params) + return FALSE; + memcpy (new_params, params, nparams * sizeof (xFixed)); + } + else + new_params = NULL; + if (dst->params) + xfree (dst->params); + dst->filter = filter; + dst->params = new_params; + dst->nparams = nparams; + dst->width = width; + dst->height = height; + return TRUE; +} + +Bool +RRTransformCopy (RRTransformPtr dst, RRTransformPtr src) +{ + if (src && PictureTransformIsIdentity (&src->transform)) + src = NULL; + + if (src) + { + if (!RRTransformSetFilter (dst, src->filter, + src->params, src->nparams, src->width, src->height)) + return FALSE; + dst->transform = src->transform; + dst->f_transform = src->f_transform; + dst->f_inverse = src->f_inverse; + } + else + { + if (!RRTransformSetFilter (dst, NULL, NULL, 0, 0, 0)) + return FALSE; + PictureTransformInitIdentity (&dst->transform); + pict_f_transform_init_identity (&dst->f_transform); + pict_f_transform_init_identity (&dst->f_inverse); + } + return TRUE; +} + +#define F(x) IntToxFixed(x) + +/* + * Compute the complete transformation matrix including + * client-specified transform, rotation/reflection values and the crtc + * offset. + * + * Return TRUE if the resulting transform is not a simple translation. + */ +Bool +RRTransformCompute (int x, + int y, + int width, + int height, + Rotation rotation, + RRTransformPtr rr_transform, + + PictTransformPtr transform, + struct pict_f_transform *f_transform, + struct pict_f_transform *f_inverse) +{ + PictTransform t_transform, inverse; + struct pict_f_transform tf_transform, tf_inverse; + + if (!transform) transform = &t_transform; + if (!f_transform) f_transform = &tf_transform; + if (!f_inverse) f_inverse = &tf_inverse; + + PictureTransformInitIdentity (transform); + PictureTransformInitIdentity (&inverse); + pict_f_transform_init_identity (f_transform); + pict_f_transform_init_identity (f_inverse); + if (rotation != RR_Rotate_0) + { + double f_rot_cos, f_rot_sin, f_rot_dx, f_rot_dy; + double f_scale_x, f_scale_y, f_scale_dx, f_scale_dy; + xFixed rot_cos, rot_sin, rot_dx, rot_dy; + xFixed scale_x, scale_y, scale_dx, scale_dy; + + /* rotation */ + switch (rotation & 0xf) { + default: + case RR_Rotate_0: + f_rot_cos = 1; f_rot_sin = 0; + f_rot_dx = 0; f_rot_dy = 0; + rot_cos = F ( 1); rot_sin = F ( 0); + rot_dx = F ( 0); rot_dy = F ( 0); + break; + case RR_Rotate_90: + f_rot_cos = 0; f_rot_sin = 1; + f_rot_dx = height; f_rot_dy = 0; + rot_cos = F ( 0); rot_sin = F ( 1); + rot_dx = F ( height); rot_dy = F (0); + break; + case RR_Rotate_180: + f_rot_cos = -1; f_rot_sin = 0; + f_rot_dx = width; f_rot_dy = height; + rot_cos = F (-1); rot_sin = F ( 0); + rot_dx = F (width); rot_dy = F ( height); + break; + case RR_Rotate_270: + f_rot_cos = 0; f_rot_sin = -1; + f_rot_dx = 0; f_rot_dy = width; + rot_cos = F ( 0); rot_sin = F (-1); + rot_dx = F ( 0); rot_dy = F ( width); + break; + } + + PictureTransformRotate (transform, &inverse, rot_cos, rot_sin); + PictureTransformTranslate (transform, &inverse, rot_dx, rot_dy); + pict_f_transform_rotate (f_transform, f_inverse, f_rot_cos, f_rot_sin); + pict_f_transform_translate (f_transform, f_inverse, f_rot_dx, f_rot_dy); + + /* reflection */ + f_scale_x = 1; + f_scale_dx = 0; + f_scale_y = 1; + f_scale_dy = 0; + scale_x = F (1); + scale_dx = 0; + scale_y = F (1); + scale_dy = 0; + if (rotation & RR_Reflect_X) + { + f_scale_x = -1; + scale_x = F(-1); + if (rotation & (RR_Rotate_0|RR_Rotate_180)) { + f_scale_dx = width; + scale_dx = F(width); + } else { + f_scale_dx = height; + scale_dx = F(height); + } + } + if (rotation & RR_Reflect_Y) + { + f_scale_y = -1; + scale_y = F(-1); + if (rotation & (RR_Rotate_0|RR_Rotate_180)) { + f_scale_dy = height; + scale_dy = F(height); + } else { + f_scale_dy = width; + scale_dy = F(width); + } + } + + PictureTransformScale (transform, &inverse, scale_x, scale_y); + pict_f_transform_scale (f_transform, f_inverse, f_scale_x, f_scale_y); + PictureTransformTranslate (transform, &inverse, scale_dx, scale_dy); + pict_f_transform_translate (f_transform, f_inverse, f_scale_dx, f_scale_dy); + } + +#ifdef RANDR_12_INTERFACE + if (rr_transform) + { + PictureTransformMultiply (transform, transform, &rr_transform->transform); + pict_f_transform_multiply (f_transform, f_transform, &rr_transform->f_transform); + pict_f_transform_multiply (f_inverse, &rr_transform->f_inverse, f_inverse); + } +#endif + /* + * Compute the class of the resulting transform + */ + if (PictureTransformIsIdentity (transform)) + { + PictureTransformInitTranslate (transform, F ( x), F ( y)); + + pict_f_transform_init_translate (f_transform, F( x), F( y)); + pict_f_transform_init_translate (f_inverse, F(-x), F(-y)); + return FALSE; + } + else + { + PictureTransformTranslate (&inverse, transform, x, y); + pict_f_transform_translate (f_inverse, f_transform, x, y); + return TRUE; + } +} + diff --git a/randr/rrtransform.h b/randr/rrtransform.h new file mode 100644 index 000000000..92d3ee7be --- /dev/null +++ b/randr/rrtransform.h @@ -0,0 +1,75 @@ +/* + * Copyright © 2007 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _RRTRANSFORM_H_ +#define _RRTRANSFORM_H_ + +#include <X11/extensions/randr.h> +#include "picturestr.h" + +typedef struct _rrTransform RRTransformRec, *RRTransformPtr; + +struct _rrTransform { + PictTransform transform; + struct pict_f_transform f_transform; + struct pict_f_transform f_inverse; + PictFilterPtr filter; + xFixed *params; + int nparams; + int width; + int height; +}; + +void +RRTransformInit (RRTransformPtr transform); + +void +RRTransformFini (RRTransformPtr transform); + +Bool +RRTransformEqual (RRTransformPtr a, RRTransformPtr b); + +Bool +RRTransformSetFilter (RRTransformPtr dst, + PictFilterPtr filter, + xFixed *params, + int nparams, + int width, + int height); + +Bool +RRTransformCopy (RRTransformPtr dst, RRTransformPtr src); + +Bool +RRTransformCompute (int x, + int y, + int width, + int height, + Rotation rotation, + RRTransformPtr rr_transform, + + PictTransformPtr transform, + struct pict_f_transform *f_transform, + struct pict_f_transform *f_inverse); + + +#endif /* _RRTRANSFORM_H_ */ |