summaryrefslogtreecommitdiff
path: root/driver/xf86-video-nv/compat
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2009-05-03 16:42:24 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2009-05-03 16:42:24 +0000
commitf28ebb124cd8286ec4b90fb357af9c5e2b1cfca2 (patch)
treeb8a76c1621500408ef70c59ce0cc70907a66f3a1 /driver/xf86-video-nv/compat
parentdeb713453d2ae91b63221fc0c30696cc5a7828f9 (diff)
update to xf86-video-nv 2.1.13.
Diffstat (limited to 'driver/xf86-video-nv/compat')
-rw-r--r--driver/xf86-video-nv/compat/Makefile.in14
-rw-r--r--driver/xf86-video-nv/compat/modes/xf86Crtc.c423
-rw-r--r--driver/xf86-video-nv/compat/modes/xf86Crtc.h86
-rw-r--r--driver/xf86-video-nv/compat/modes/xf86Cursors.c49
-rw-r--r--driver/xf86-video-nv/compat/modes/xf86EdidModes.c4
-rw-r--r--driver/xf86-video-nv/compat/modes/xf86Modes.c16
-rw-r--r--driver/xf86-video-nv/compat/modes/xf86Modes.h15
-rw-r--r--driver/xf86-video-nv/compat/modes/xf86RandR12.c531
-rw-r--r--driver/xf86-video-nv/compat/modes/xf86RandR12.h1
-rw-r--r--driver/xf86-video-nv/compat/modes/xf86Rename.h1
-rw-r--r--driver/xf86-video-nv/compat/modes/xf86Rotate.c485
-rw-r--r--driver/xf86-video-nv/compat/parser/xf86Parser.h1
12 files changed, 1139 insertions, 487 deletions
diff --git a/driver/xf86-video-nv/compat/Makefile.in b/driver/xf86-video-nv/compat/Makefile.in
index 6b95d3103..dba8b5923 100644
--- a/driver/xf86-video-nv/compat/Makefile.in
+++ b/driver/xf86-video-nv/compat/Makefile.in
@@ -88,6 +88,7 @@ F77 = @F77@
FFLAGS = @FFLAGS@
FILE_MAN_DIR = @FILE_MAN_DIR@
FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@
+GREP = @GREP@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -127,15 +128,9 @@ VERSION = @VERSION@
XMODES_CFLAGS = @XMODES_CFLAGS@
XORG_CFLAGS = @XORG_CFLAGS@
XORG_LIBS = @XORG_LIBS@
-ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
-ac_ct_DSYMUTIL = @ac_ct_DSYMUTIL@
ac_ct_F77 = @ac_ct_F77@
-ac_ct_NMEDIT = @ac_ct_NMEDIT@
-ac_ct_RANLIB = @ac_ct_RANLIB@
-ac_ct_STRIP = @ac_ct_STRIP@
-ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
@@ -152,17 +147,22 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
+htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
+localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
@@ -170,8 +170,10 @@ modes_dir = @modes_dir@
moduledir = @moduledir@
oldincludedir = @oldincludedir@
parser_dir = @parser_dir@
+pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
+psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
diff --git a/driver/xf86-video-nv/compat/modes/xf86Crtc.c b/driver/xf86-video-nv/compat/modes/xf86Crtc.c
index a5a0a6392..ad6ca9876 100644
--- a/driver/xf86-video-nv/compat/modes/xf86Crtc.c
+++ b/driver/xf86-video-nv/compat/modes/xf86Crtc.c
@@ -96,6 +96,7 @@ xf86CrtcCreate (ScrnInfoPtr scrn,
crtc = xcalloc (sizeof (xf86CrtcRec), 1);
if (!crtc)
return NULL;
+ crtc->version = XF86_CRTC_VERSION;
crtc->scrn = scrn;
crtc->funcs = funcs;
#ifdef RANDR_12_INTERFACE
@@ -103,6 +104,19 @@ xf86CrtcCreate (ScrnInfoPtr scrn,
#endif
crtc->rotation = RR_Rotate_0;
crtc->desiredRotation = RR_Rotate_0;
+ pixman_transform_init_identity (&crtc->crtc_to_framebuffer);
+ pixman_f_transform_init_identity (&crtc->f_crtc_to_framebuffer);
+ pixman_f_transform_init_identity (&crtc->f_framebuffer_to_crtc);
+ crtc->filter = NULL;
+ crtc->params = NULL;
+ crtc->nparams = 0;
+ crtc->filter_width = 0;
+ crtc->filter_height = 0;
+ crtc->transform_in_use = FALSE;
+ crtc->transformPresent = FALSE;
+ crtc->desiredTransformPresent = FALSE;
+ memset (&crtc->bounds, '\0', sizeof (crtc->bounds));
+
if (xf86_config->crtc)
crtcs = xrealloc (xf86_config->crtc,
(xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr));
@@ -134,6 +148,8 @@ xf86CrtcDestroy (xf86CrtcPtr crtc)
xf86_config->num_crtc--;
break;
}
+ if (crtc->params)
+ xfree (crtc->params);
xfree (crtc);
}
@@ -224,8 +240,8 @@ xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen)
* Sets the given video mode on the given crtc
*/
_X_EXPORT Bool
-xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
- int x, int y)
+xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
+ RRTransformPtr transform, int x, int y)
{
ScrnInfoPtr scrn = crtc->scrn;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -236,12 +252,14 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
DisplayModeRec saved_mode;
int saved_x, saved_y;
Rotation saved_rotation;
+ RRTransformRec saved_transform;
+ Bool saved_transform_present;
if (crtc->funcs->set_mode_major)
return crtc->funcs->set_mode_major(crtc, mode, rotation, x, y);
-
+
crtc->enabled = xf86CrtcInUse (crtc);
-
+
if (!crtc->enabled)
{
/* XXX disable crtc? */
@@ -256,6 +274,12 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
saved_x = crtc->x;
saved_y = crtc->y;
saved_rotation = crtc->rotation;
+ if (crtc->transformPresent) {
+ RRTransformInit (&saved_transform);
+ RRTransformCopy (&saved_transform, &crtc->transform);
+ }
+ saved_transform_present = crtc->transformPresent;
+
/* Update crtc values up front so the driver can rely on them for mode
* setting.
*/
@@ -263,33 +287,25 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
crtc->x = x;
crtc->y = y;
crtc->rotation = rotation;
+ if (transform) {
+ RRTransformCopy (&crtc->transform, transform);
+ crtc->transformPresent = TRUE;
+ } else
+ crtc->transformPresent = FALSE;
- /* Shift offsets that move us out of virtual size */
- if (x + mode->HDisplay > xf86_config->maxWidth ||
- y + mode->VDisplay > xf86_config->maxHeight)
+ if (crtc->funcs->set_origin &&
+ memcmp (mode, &saved_mode, sizeof(saved_mode)) == 0 &&
+ saved_rotation == rotation &&
+ saved_transform_present == crtc->transformPresent &&
+ (!crtc->transformPresent || RRTransformEqual(&saved_transform, &crtc->transform)))
{
- if (x + mode->HDisplay > xf86_config->maxWidth)
- crtc->x = xf86_config->maxWidth - mode->HDisplay;
- if (y + mode->VDisplay > xf86_config->maxHeight)
- crtc->y = xf86_config->maxHeight - mode->VDisplay;
- if (crtc->x < 0 || crtc->y < 0)
- {
- xf86DrvMsg (scrn->scrnIndex, X_ERROR,
- "Mode %dx%d does not fit virtual size %dx%d - "
- "internal error\n", mode->HDisplay, mode->VDisplay,
- xf86_config->maxWidth, xf86_config->maxHeight);
- goto done;
- }
- xf86DrvMsg (scrn->scrnIndex, X_ERROR,
- "Mode %dx%d+%d+%d does not fit virtual size %dx%d - "
- "offset updated to +%d+%d\n",
- mode->HDisplay, mode->VDisplay, x, y,
- xf86_config->maxWidth, xf86_config->maxHeight,
- crtc->x, crtc->y);
+ if (!xf86CrtcRotate (crtc))
+ goto done;
+ crtc->funcs->set_origin (crtc, crtc->x, crtc->y);
+ ret = TRUE;
+ goto done;
}
- /* XXX short-circuit changes to base location only */
-
/* Pass our mode to the outputs and the CRTC to give them a chance to
* adjust it according to limitations or output properties, and also
* a chance to reject the mode entirely.
@@ -309,9 +325,8 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
goto done;
}
- if (!xf86CrtcRotate (crtc, mode, rotation)) {
+ if (!xf86CrtcRotate (crtc))
goto done;
- }
/* Prepare the outputs and CRTCs before setting the mode. */
for (i = 0; i < xf86_config->num_output; i++) {
@@ -343,13 +358,7 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
{
xf86OutputPtr output = xf86_config->output[i];
if (output->crtc == crtc)
- {
output->funcs->commit(output);
-#ifdef RANDR_12_INTERFACE
- if (output->randr_output)
- RRPostPendingProperties (output->randr_output);
-#endif
- }
}
/* XXX free adjustedmode */
@@ -363,6 +372,9 @@ done:
crtc->y = saved_y;
crtc->rotation = saved_rotation;
crtc->mode = saved_mode;
+ if (saved_transform_present)
+ RRTransformCopy (&crtc->transform, &saved_transform);
+ crtc->transformPresent = saved_transform_present;
}
if (didLock)
@@ -371,6 +383,34 @@ done:
return ret;
}
+/**
+ * Sets the given video mode on the given crtc, but without providing
+ * a transform
+ */
+_X_EXPORT Bool
+xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
+ int x, int y)
+{
+ return xf86CrtcSetModeTransform (crtc, mode, rotation, NULL, x, y);
+}
+
+/**
+ * Pans the screen, does not change the mode
+ */
+_X_EXPORT void
+xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y)
+{
+ crtc->x = x;
+ crtc->y = y;
+ if (crtc->funcs->set_origin) {
+ if (!xf86CrtcRotate (crtc))
+ return;
+ crtc->funcs->set_origin (crtc, x, y);
+ }
+ else
+ xf86CrtcSetMode (crtc, &crtc->mode, crtc->rotation, x, y);
+}
+
/*
* Output functions
*/
@@ -390,6 +430,7 @@ typedef enum {
OPTION_MAX_CLOCK,
OPTION_IGNORE,
OPTION_ROTATE,
+ OPTION_PANNING,
} OutputOpts;
static OptionInfoRec xf86OutputOptions[] = {
@@ -405,6 +446,7 @@ static OptionInfoRec xf86OutputOptions[] = {
{OPTION_MAX_CLOCK, "MaxClock", OPTV_FREQ, {0}, FALSE },
{OPTION_IGNORE, "Ignore", OPTV_BOOLEAN, {0}, FALSE },
{OPTION_ROTATE, "Rotate", OPTV_STRING, {0}, FALSE },
+ {OPTION_PANNING, "Panning", OPTV_STRING, {0}, FALSE },
{-1, NULL, OPTV_NONE, {0}, FALSE },
};
@@ -719,11 +761,17 @@ xf86CrtcScreenInit (ScreenPtr screen)
break;
}
if (c == config->num_crtc)
+ {
xf86RandR12SetRotations (screen, RR_Rotate_0 | RR_Rotate_90 |
RR_Rotate_180 | RR_Rotate_270 |
RR_Reflect_X | RR_Reflect_Y);
+ xf86RandR12SetTransformSupport (screen, TRUE);
+ }
else
+ {
xf86RandR12SetRotations (screen, RR_Rotate_0);
+ xf86RandR12SetTransformSupport (screen, FALSE);
+ }
/* Wrap CreateScreenResources so we can initialize the RandR code */
config->CreateScreenResources = screen->CreateScreenResources;
@@ -914,7 +962,7 @@ xf86PickCrtcs (ScrnInfoPtr scrn,
* see if they can be cloned
*/
if (xf86ModesEqual (modes[o], modes[n]) &&
- config->output[0]->initial_rotation == config->output[n]->initial_rotation &&
+ config->output[o]->initial_rotation == config->output[n]->initial_rotation &&
config->output[o]->initial_x == config->output[n]->initial_x &&
config->output[o]->initial_y == config->output[n]->initial_y)
{
@@ -996,6 +1044,15 @@ xf86DefaultScreenLimits (ScrnInfoPtr scrn, int *widthp, int *heightp,
if (crtc_height > height)
height = crtc_height;
}
+
+ /* Make room for an external monitor if we have enough video ram */
+ if (scrn->videoRam >= 65536)
+ width += 1920;
+ else if (scrn->videoRam >= 32768)
+ width += 1280;
+ else if (scrn->videoRam >= 16384)
+ width += 1024;
+
if (config->maxWidth && width > config->maxWidth) width = config->maxWidth;
if (config->maxHeight && height > config->maxHeight) height = config->maxHeight;
if (config->minWidth && width < config->minWidth) width = config->minWidth;
@@ -1185,10 +1242,12 @@ xf86InitialOutputPositions (ScrnInfoPtr scrn, DisplayModePtr *modes)
output->initial_x += xf86ModeWidth (modes[or], relative->initial_rotation);
break;
case OPTION_ABOVE:
- output->initial_y -= xf86ModeHeight (modes[o], output->initial_rotation);
+ if (modes[o])
+ output->initial_y -= xf86ModeHeight (modes[o], output->initial_rotation);
break;
case OPTION_LEFT_OF:
- output->initial_x -= xf86ModeWidth (modes[o], output->initial_rotation);
+ if (modes[o])
+ output->initial_x -= xf86ModeWidth (modes[o], output->initial_rotation);
break;
default:
break;
@@ -1246,6 +1305,59 @@ xf86InitialOutputPositions (ScrnInfoPtr scrn, DisplayModePtr *modes)
return TRUE;
}
+static void
+xf86InitialPanning (ScrnInfoPtr scrn)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ int o;
+
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+ char *panning = xf86GetOptValString (output->options, OPTION_PANNING);
+ int width, height, left, top;
+ int track_width, track_height, track_left, track_top;
+ int brdr[4];
+
+ memset (&output->initialTotalArea, 0, sizeof(BoxRec));
+ memset (&output->initialTrackingArea, 0, sizeof(BoxRec));
+ memset (output->initialBorder, 0, 4*sizeof(INT16));
+
+ if (! panning)
+ continue;
+
+ switch (sscanf (panning, "%dx%d+%d+%d/%dx%d+%d+%d/%d/%d/%d/%d",
+ &width, &height, &left, &top,
+ &track_width, &track_height, &track_left, &track_top,
+ &brdr[0], &brdr[1], &brdr[2], &brdr[3])) {
+ case 12:
+ output->initialBorder[0] = brdr[0];
+ output->initialBorder[1] = brdr[1];
+ output->initialBorder[2] = brdr[2];
+ output->initialBorder[3] = brdr[3];
+ /* fall through */
+ case 8:
+ output->initialTrackingArea.x1 = track_left;
+ output->initialTrackingArea.y1 = track_top;
+ output->initialTrackingArea.x2 = track_left + track_width;
+ output->initialTrackingArea.y2 = track_top + track_height;
+ /* fall through */
+ case 4:
+ output->initialTotalArea.x1 = left;
+ output->initialTotalArea.y1 = top;
+ /* fall through */
+ case 2:
+ output->initialTotalArea.x2 = output->initialTotalArea.x1 + width;
+ output->initialTotalArea.y2 = output->initialTotalArea.y1 + height;
+ break;
+ default:
+ xf86DrvMsg (scrn->scrnIndex, X_ERROR,
+ "Broken panning specification '%s' for output %s in config file\n",
+ panning, output->name);
+ }
+ }
+}
+
/*
* XXX walk the monitor mode list and prune out duplicates that
* are inserted by xf86DDCMonitorSet. In an ideal world, that
@@ -1416,7 +1528,7 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
{
xf86OutputPtr output = config->output[o];
DisplayModePtr mode;
- DisplayModePtr config_modes = NULL, output_modes, default_modes;
+ DisplayModePtr config_modes = NULL, output_modes, default_modes = NULL;
char *preferred_mode;
xf86MonPtr edid_monitor;
XF86ConfMonitorPtr conf_monitor;
@@ -1424,6 +1536,7 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
int min_clock = 0;
int max_clock = 0;
double clock;
+ Bool add_default_modes = TRUE;
enum { sync_config, sync_edid, sync_default } sync_source = sync_default;
while (output->probed_modes != NULL)
@@ -1474,6 +1587,11 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
int i;
Bool set_hsync = mon_rec.nHsync == 0;
Bool set_vrefresh = mon_rec.nVrefresh == 0;
+ struct disp_features *features = &edid_monitor->features;
+
+ /* if display is not continuous-frequency, don't add default modes */
+ if (!GTF_SUPPORTED(features->msc))
+ add_default_modes = FALSE;
for (i = 0; i < sizeof (edid_monitor->det_mon) / sizeof (edid_monitor->det_mon[0]); i++)
{
@@ -1530,8 +1648,10 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
mon_rec.vrefresh[0].hi = 62.0;
mon_rec.nVrefresh = 1;
}
- default_modes = xf86GetDefaultModes (output->interlaceAllowed,
- output->doubleScanAllowed);
+
+ if (add_default_modes)
+ default_modes = xf86GetDefaultModes (output->interlaceAllowed,
+ output->doubleScanAllowed);
/*
* If this is not an RB monitor, remove RB modes from the default
@@ -1746,7 +1866,7 @@ xf86SetScrnInfoModes (ScrnInfoPtr scrn)
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
xf86OutputPtr output;
xf86CrtcPtr crtc;
- DisplayModePtr last, mode;
+ DisplayModePtr last, mode = NULL;
output = SetCompatOutput(config);
@@ -1818,6 +1938,66 @@ nextEnabledOutput(xf86CrtcConfigPtr config, Bool *enabled, int *index)
}
static Bool
+aspectMatch(float a, float b)
+{
+ return fabs(1 - (a / b)) < 0.05;
+}
+
+static DisplayModePtr
+nextAspectMode(xf86OutputPtr o, DisplayModePtr last, float aspect)
+{
+ DisplayModePtr m = NULL;
+
+ if (!o)
+ return NULL;
+
+ if (!last)
+ m = o->probed_modes;
+ else
+ m = last->next;
+
+ for (; m; m = m->next)
+ if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay))
+ return m;
+
+ return NULL;
+}
+
+static DisplayModePtr
+bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
+{
+ int o = -1, p;
+ DisplayModePtr mode = NULL, test = NULL, match = NULL;
+
+ if (!nextEnabledOutput(config, enabled, &o))
+ return NULL;
+ while ((mode = nextAspectMode(config->output[o], mode, aspect))) {
+ test = mode;
+ for (p = o; nextEnabledOutput(config, enabled, &p); ) {
+ test = xf86OutputFindClosestMode(config->output[p], mode);
+ if (!test)
+ break;
+ if (test->HDisplay != mode->HDisplay ||
+ test->VDisplay != mode->VDisplay) {
+ test = NULL;
+ break;
+ }
+ }
+
+ /* if we didn't match it on all outputs, try the next one */
+ if (!test)
+ continue;
+
+ /* if it's bigger than the last one, save it */
+ if (!match || (test->HDisplay > match->HDisplay))
+ match = test;
+ }
+
+ /* return the biggest one found */
+ return match;
+}
+
+static Bool
xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
DisplayModePtr *modes, Bool *enabled,
int width, int height)
@@ -1869,74 +2049,43 @@ xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
}
}
- if (ret) {
- /* oh good, there is a match. stash the selected modes and return. */
- memcpy(modes, preferred_match,
- config->num_output * sizeof(DisplayModePtr));
- }
-
- xfree(preferred);
- xfree(preferred_match);
- return ret;
-}
+ /*
+ * If there's no preferred mode, but only one monitor, pick the
+ * biggest mode for its aspect ratio, assuming one exists.
+ */
+ if (!ret) do {
+ int i = 0;
+ float aspect = 0.0;
-static Bool
-aspectMatch(float a, float b)
-{
- return fabs(1 - (a / b)) < 0.05;
-}
+ /* count the number of enabled outputs */
+ for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ;
-static DisplayModePtr
-nextAspectMode(xf86OutputPtr o, DisplayModePtr last, float aspect)
-{
- DisplayModePtr m = NULL;
+ if (i != 1)
+ break;
- if (!o)
- return NULL;
+ p = -1;
+ nextEnabledOutput(config, enabled, &p);
+ if (config->output[p]->mm_height)
+ aspect = (float)config->output[p]->mm_width /
+ (float)config->output[p]->mm_height;
- if (!last)
- m = o->probed_modes;
- else
- m = last->next;
+ if (aspect)
+ preferred_match[p] = bestModeForAspect(config, enabled, aspect);
- for (; m; m = m->next)
- if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay))
- return m;
+ if (preferred_match[p])
+ ret = TRUE;
- return NULL;
-}
+ } while (0);
-static DisplayModePtr
-bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
-{
- int o = -1, p;
- DisplayModePtr mode = NULL, test = NULL, match = NULL;
-
- nextEnabledOutput(config, enabled, &o);
- while ((mode = nextAspectMode(config->output[o], mode, aspect))) {
- test = mode;
- for (p = o; nextEnabledOutput(config, enabled, &p); ) {
- test = xf86OutputFindClosestMode(config->output[p], mode);
- if (!test)
- break;
- if (test->HDisplay != mode->HDisplay ||
- test->VDisplay != mode->VDisplay) {
- test = NULL;
- break;
- }
- }
-
- /* if we didn't match it on all outputs, try the next one */
- if (!test)
- continue;
-
- /* if it's bigger than the last one, save it */
- if (!match || (test->HDisplay > match->HDisplay))
- match = test;
+ if (ret) {
+ /* oh good, there is a match. stash the selected modes and return. */
+ memcpy(modes, preferred_match,
+ config->num_output * sizeof(DisplayModePtr));
}
- /* return the biggest one found */
- return match;
+ xfree(preferred);
+ xfree(preferred_match);
+ return ret;
}
static Bool
@@ -2084,8 +2233,7 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
xf86ProcessOptions (scrn->scrnIndex,
scrn->options,
config->options);
- config->debug_modes = xf86ReturnOptValBool (config->options,
- OPTION_MODEDEBUG, FALSE);
+ config->debug_modes = TRUE;
if (scrn->display->virtualX)
width = scrn->display->virtualX;
@@ -2135,6 +2283,11 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
xfree (modes);
return FALSE;
}
+
+ /*
+ * Set initial panning of each output
+ */
+ xf86InitialPanning (scrn);
/*
* Assign CRTCs to fit output configuration
@@ -2174,9 +2327,13 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
crtc->desiredRotation = output->initial_rotation;
crtc->desiredX = output->initial_x;
crtc->desiredY = output->initial_y;
+ crtc->desiredTransformPresent = FALSE;
crtc->enabled = TRUE;
crtc->x = output->initial_x;
crtc->y = output->initial_y;
+ memcpy (&crtc->panningTotalArea, &output->initialTotalArea, sizeof(BoxRec));
+ memcpy (&crtc->panningTrackingArea, &output->initialTrackingArea, sizeof(BoxRec));
+ memcpy (crtc->panningBorder, output->initialBorder, 4*sizeof(INT16));
output->crtc = crtc;
} else {
output->crtc = NULL;
@@ -2305,6 +2462,7 @@ xf86SetDesiredModes (ScrnInfoPtr scrn)
xf86CrtcPtr crtc = config->crtc[c];
xf86OutputPtr output = NULL;
int o;
+ RRTransformPtr transform;
/* Skip disabled CRTCs */
if (!crtc->enabled)
@@ -2335,12 +2493,17 @@ xf86SetDesiredModes (ScrnInfoPtr scrn)
return FALSE;
crtc->desiredMode = *mode;
crtc->desiredRotation = RR_Rotate_0;
+ crtc->desiredTransformPresent = FALSE;
crtc->desiredX = 0;
crtc->desiredY = 0;
}
- if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation,
- crtc->desiredX, crtc->desiredY))
+ if (crtc->desiredTransformPresent)
+ transform = &crtc->desiredTransform;
+ else
+ transform = NULL;
+ if (!xf86CrtcSetModeTransform (crtc, &crtc->desiredMode, crtc->desiredRotation,
+ transform, crtc->desiredX, crtc->desiredY))
return FALSE;
}
@@ -2469,12 +2632,13 @@ xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation)
crtc->enabled = FALSE;
continue;
}
- if (!xf86CrtcSetMode (crtc, crtc_mode, rotation, 0, 0))
+ if (!xf86CrtcSetModeTransform (crtc, crtc_mode, rotation, NULL, 0, 0))
ok = FALSE;
else
{
crtc->desiredMode = *crtc_mode;
crtc->desiredRotation = rotation;
+ crtc->desiredTransformPresent = FALSE;
crtc->desiredX = 0;
crtc->desiredY = 0;
}
@@ -2568,8 +2732,11 @@ xf86DisableUnusedFunctions(ScrnInfoPtr pScrn)
{
crtc->funcs->dpms(crtc, DPMSModeOff);
memset(&crtc->mode, 0, sizeof(crtc->mode));
+ xf86RotateDestroy(crtc);
}
}
+ if (pScrn->pScreen)
+ xf86_crtc_notify(pScrn->pScreen);
}
#ifdef RANDR_12_INTERFACE
@@ -2631,9 +2798,11 @@ xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon)
size = 0;
if (edid_mon)
{
- if (edid_mon->ver.version == 1)
+ if (edid_mon->ver.version == 1) {
size = 128;
- else if (edid_mon->ver.version == 2)
+ if (edid_mon->flags & EDID_COMPLETE_RAWDATA)
+ size += edid_mon->no_sections * 128;
+ } else if (edid_mon->ver.version == 2)
size = 256;
}
xf86OutputSetEDIDProperty (output, edid_mon ? edid_mon->rawData : NULL, size);
@@ -2822,3 +2991,41 @@ xf86_crtc_clip_video_helper(ScrnInfoPtr pScrn,
return ret;
}
+
+xf86_crtc_notify_proc_ptr
+xf86_wrap_crtc_notify (ScreenPtr screen, xf86_crtc_notify_proc_ptr new)
+{
+ if (xf86CrtcConfigPrivateIndex != -1)
+ {
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86_crtc_notify_proc_ptr old;
+
+ old = config->xf86_crtc_notify;
+ config->xf86_crtc_notify = new;
+ return old;
+ }
+ return NULL;
+}
+
+void
+xf86_unwrap_crtc_notify(ScreenPtr screen, xf86_crtc_notify_proc_ptr old)
+{
+ if (xf86CrtcConfigPrivateIndex != -1)
+ {
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+
+ config->xf86_crtc_notify = old;
+ }
+}
+
+void
+xf86_crtc_notify(ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+
+ if (config->xf86_crtc_notify)
+ config->xf86_crtc_notify(screen);
+}
diff --git a/driver/xf86-video-nv/compat/modes/xf86Crtc.h b/driver/xf86-video-nv/compat/modes/xf86Crtc.h
index 83b1f13e8..0a596bc49 100644
--- a/driver/xf86-video-nv/compat/modes/xf86Crtc.h
+++ b/driver/xf86-video-nv/compat/modes/xf86Crtc.h
@@ -213,9 +213,16 @@ typedef struct _xf86CrtcFuncs {
Bool
(*set_mode_major)(xf86CrtcPtr crtc, DisplayModePtr mode,
Rotation rotation, int x, int y);
+
+ /**
+ * Callback for panning. Doesn't change the mode.
+ */
+ void
+ (*set_origin)(xf86CrtcPtr crtc, int x, int y);
+
} xf86CrtcFuncsRec, *xf86CrtcFuncsPtr;
-#define XF86_CRTC_VERSION 1
+#define XF86_CRTC_VERSION 2
struct _xf86Crtc {
/**
@@ -305,12 +312,35 @@ struct _xf86Crtc {
* Current transformation matrix
*/
PictTransform crtc_to_framebuffer;
- PictTransform framebuffer_to_crtc;
+ struct pict_f_transform f_crtc_to_framebuffer;
+ struct pict_f_transform f_framebuffer_to_crtc;
+ PictFilterPtr filter;
+ xFixed *params;
+ int nparams;
+ int filter_width;
+ int filter_height;
Bool transform_in_use;
+ RRTransformRec transform;
+ Bool transformPresent;
+ RRTransformRec desiredTransform;
+ Bool desiredTransformPresent;
/**
* Bounding box in screen space
*/
BoxRec bounds;
+ /**
+ * Panning:
+ * TotalArea: total panning area, larger than CRTC's size
+ * TrackingArea: Area of the pointer for which the CRTC is panned
+ * border: Borders of the displayed CRTC area which induces panning if the pointer reaches them
+ */
+ BoxRec panningTotalArea;
+ BoxRec panningTrackingArea;
+ INT16 panningBorder[4];
+ /**
+ * Clear the shadow
+ */
+ Bool shadowClear;
};
typedef struct _xf86OutputFuncs {
@@ -440,7 +470,7 @@ typedef struct _xf86OutputFuncs {
} xf86OutputFuncsRec, *xf86OutputFuncsPtr;
-#define XF86_OUTPUT_VERSION 1
+#define XF86_OUTPUT_VERSION 2
struct _xf86Output {
/**
@@ -548,6 +578,10 @@ struct _xf86Output {
#else
void *randr_output;
#endif
+ /** Desired initial panning */
+ BoxRec initialTotalArea;
+ BoxRec initialTrackingArea;
+ INT16 initialBorder[4];
};
typedef struct _xf86CrtcConfigFuncs {
@@ -569,6 +603,8 @@ typedef struct _xf86CrtcConfigFuncs {
int height);
} xf86CrtcConfigFuncsRec, *xf86CrtcConfigFuncsPtr;
+typedef void (*xf86_crtc_notify_proc_ptr) (ScreenPtr pScreen);
+
typedef struct _xf86CrtcConfig {
int num_output;
xf86OutputPtr *output;
@@ -621,6 +657,9 @@ typedef struct _xf86CrtcConfig {
/* wrap screen BlockHandler for rotation */
ScreenBlockHandlerProcPtr BlockHandler;
+ /* callback when crtc configuration changes */
+ xf86_crtc_notify_proc_ptr xf86_crtc_notify;
+
} xf86CrtcConfigRec, *xf86CrtcConfigPtr;
extern int xf86CrtcConfigPrivateIndex;
@@ -654,15 +693,30 @@ xf86CrtcDestroy (xf86CrtcPtr crtc);
/**
* Sets the given video mode on the given crtc
*/
+
+Bool
+xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
+ RRTransformPtr transform, int x, int y);
+
Bool
xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
int x, int y);
+void
+xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y);
+
/*
* Assign crtc rotation during mode set
*/
Bool
-xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation);
+xf86CrtcRotate (xf86CrtcPtr crtc);
+
+/*
+ * Clean up any rotation data, used when a crtc is turned off
+ * as well as when rotation is disabled.
+ */
+void
+xf86RotateDestroy (xf86CrtcPtr crtc);
/*
* free shadow memory allocated for all crtcs
@@ -838,4 +892,28 @@ xf86_crtc_clip_video_helper(ScrnInfoPtr pScrn,
INT32 width,
INT32 height);
+xf86_crtc_notify_proc_ptr
+xf86_wrap_crtc_notify (ScreenPtr pScreen, xf86_crtc_notify_proc_ptr new);
+
+void
+xf86_unwrap_crtc_notify(ScreenPtr pScreen, xf86_crtc_notify_proc_ptr old);
+
+void
+xf86_crtc_notify(ScreenPtr pScreen);
+
+/**
+ * Panning
+ */
+Bool
+xf86_crtc_get_panning(ScrnInfoPtr pScrn,
+ BoxPtr totalArea,
+ BoxPtr TrackingArea,
+ INT16 *border);
+
+Bool
+xf86_crtc_set_panning(ScrnInfoPtr pScrn,
+ BoxPtr totalArea,
+ BoxPtr TrackingArea,
+ INT16 *border);
+
#endif /* _XF86CRTC_H_ */
diff --git a/driver/xf86-video-nv/compat/modes/xf86Cursors.c b/driver/xf86-video-nv/compat/modes/xf86Cursors.c
index 5dddaddb0..3106f051b 100644
--- a/driver/xf86-video-nv/compat/modes/xf86Cursors.c
+++ b/driver/xf86-video-nv/compat/modes/xf86Cursors.c
@@ -37,6 +37,7 @@
#include "xf86Crtc.h"
#include "xf86Modes.h"
#include "xf86RandR12.h"
+#include "xf86CursorPriv.h"
#include "X11/extensions/render.h"
#define DPMS_SERVER
#include "X11/extensions/dpms.h"
@@ -230,7 +231,7 @@ xf86_set_cursor_colors (ScrnInfoPtr scrn, int bg, int fg)
int c;
CARD8 *bits = cursor ?
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
- dixLookupPrivate(&cursor->devPrivates, screen)
+ dixLookupPrivate(&cursor->devPrivates, CursorScreenKey(screen))
#else
cursor->devPriv[screen->myNum]
#endif
@@ -321,25 +322,31 @@ xf86_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
*/
if (crtc->transform_in_use)
{
- PictVector v;
- v.vector[0] = IntToxFixed (x); v.vector[1] = IntToxFixed (y); v.vector[2] = IntToxFixed(1);
- PictureTransformPoint (&crtc->framebuffer_to_crtc, &v);
- x = xFixedToInt (v.vector[0]); y = xFixedToInt (v.vector[1]);
- }
+ ScreenPtr screen = scrn->pScreen;
+ xf86CursorScreenPtr ScreenPriv =
+ (xf86CursorScreenPtr)dixLookupPrivate(&screen->devPrivates,
+ xf86CursorScreenKey);
+ struct pict_f_vector v;
+
+ v.v[0] = x + ScreenPriv->HotX; v.v[1] = y + ScreenPriv->HotY; v.v[2] = 1;
+ pixman_f_transform_point (&crtc->f_framebuffer_to_crtc, &v);
+ x = floor (v.v[0] + 0.5);
+ y = floor (v.v[1] + 0.5);
+ /*
+ * Transform position of cursor upper left corner
+ */
+ xf86_crtc_rotate_coord_back (crtc->rotation,
+ cursor_info->MaxWidth,
+ cursor_info->MaxHeight,
+ ScreenPriv->HotX, ScreenPriv->HotY, &dx, &dy);
+ x -= dx;
+ y -= dy;
+ }
else
{
x -= crtc->x;
y -= crtc->y;
}
- /*
- * Transform position of cursor upper left corner
- */
- xf86_crtc_rotate_coord_back (crtc->rotation,
- cursor_info->MaxWidth,
- cursor_info->MaxHeight,
- 0, 0, &dx, &dy);
- x -= dx;
- y -= dy;
/*
* Disable the cursor when it is outside the viewport
@@ -595,12 +602,19 @@ xf86_reload_cursors (ScreenPtr screen)
xf86CursorInfoPtr cursor_info;
CursorPtr cursor;
int x, y;
+ xf86CursorScreenPtr cursor_screen_priv;
/* initial mode setting will not have set a screen yet.
May be called before the devices are initialised.
*/
if (!screen || !inputInfo.pointer)
return;
+ cursor_screen_priv = dixLookupPrivate(&screen->devPrivates,
+ xf86CursorScreenKey);
+ /* return if HW cursor is inactive, to avoid displaying two cursors */
+ if (!cursor_screen_priv->isUp)
+ return;
+
scrn = xf86Screens[screen->myNum];
xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -608,7 +622,7 @@ xf86_reload_cursors (ScreenPtr screen)
cursor_info = xf86_config->cursor_info;
if (!cursor_info)
return;
-
+
cursor = xf86_config->cursor;
GetSpritePosition (inputInfo.pointer, &x, &y);
if (!(cursor_info->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
@@ -617,7 +631,7 @@ xf86_reload_cursors (ScreenPtr screen)
if (cursor)
{
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
- void *src = dixLookupPrivate(&cursor->devPrivates, screen);
+ void *src = dixLookupPrivate(&cursor->devPrivates, CursorScreenKey(screen));
#else
void *src = cursor->devPriv[screen->myNum];
#endif
@@ -629,7 +643,6 @@ xf86_reload_cursors (ScreenPtr screen)
(*cursor_info->LoadCursorImage)(cursor_info->pScrn, src);
(*cursor_info->SetCursorPosition)(cursor_info->pScrn, x, y);
- (*cursor_info->ShowCursor)(cursor_info->pScrn);
}
}
diff --git a/driver/xf86-video-nv/compat/modes/xf86EdidModes.c b/driver/xf86-video-nv/compat/modes/xf86EdidModes.c
index bea2f7e64..5ed61c1d0 100644
--- a/driver/xf86-video-nv/compat/modes/xf86EdidModes.c
+++ b/driver/xf86-video-nv/compat/modes/xf86EdidModes.c
@@ -418,7 +418,7 @@ MonitorStandardTimingLevel(xf86MonPtr DDC)
}
static int
-ModeRefresh(DisplayModePtr mode)
+ModeRefresh(const DisplayModeRec *mode)
{
return (int)(xf86ModeVRefresh(mode) + 0.5);
}
@@ -432,7 +432,7 @@ static DisplayModePtr
FindDMTMode(int hsize, int vsize, int refresh, Bool rb)
{
int i;
- DisplayModePtr ret;
+ const DisplayModeRec *ret;
for (i = 0; i < sizeof(DMTModes) / sizeof(DisplayModeRec); i++) {
ret = &DMTModes[i];
diff --git a/driver/xf86-video-nv/compat/modes/xf86Modes.c b/driver/xf86-video-nv/compat/modes/xf86Modes.c
index 0fdfbdb85..1522fa731 100644
--- a/driver/xf86-video-nv/compat/modes/xf86Modes.c
+++ b/driver/xf86-video-nv/compat/modes/xf86Modes.c
@@ -52,7 +52,7 @@ extern XF86ConfigPtr xf86configptr;
* Exact copy of xf86Mode.c's.
*/
_X_EXPORT double
-xf86ModeHSync(DisplayModePtr mode)
+xf86ModeHSync(const DisplayModeRec *mode)
{
double hsync = 0.0;
@@ -70,7 +70,7 @@ xf86ModeHSync(DisplayModePtr mode)
* Exact copy of xf86Mode.c's.
*/
_X_EXPORT double
-xf86ModeVRefresh(DisplayModePtr mode)
+xf86ModeVRefresh(const DisplayModeRec *mode)
{
double refresh = 0.0;
@@ -89,7 +89,7 @@ xf86ModeVRefresh(DisplayModePtr mode)
}
_X_EXPORT int
-xf86ModeWidth (DisplayModePtr mode, Rotation rotation)
+xf86ModeWidth (const DisplayModeRec *mode, Rotation rotation)
{
switch (rotation & 0xf) {
case RR_Rotate_0:
@@ -104,7 +104,7 @@ xf86ModeWidth (DisplayModePtr mode, Rotation rotation)
}
_X_EXPORT int
-xf86ModeHeight (DisplayModePtr mode, Rotation rotation)
+xf86ModeHeight (const DisplayModeRec *mode, Rotation rotation)
{
switch (rotation & 0xf) {
case RR_Rotate_0:
@@ -206,7 +206,7 @@ xf86SetModeCrtc(DisplayModePtr p, int adjustFlags)
* Allocates and returns a copy of pMode, including pointers within pMode.
*/
_X_EXPORT DisplayModePtr
-xf86DuplicateMode(DisplayModePtr pMode)
+xf86DuplicateMode(const DisplayModeRec *pMode)
{
DisplayModePtr pNew;
@@ -264,7 +264,7 @@ xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList)
* This isn't in xf86Modes.c, but it might deserve to be there.
*/
_X_EXPORT Bool
-xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2)
+xf86ModesEqual(const DisplayModeRec *pMode1, const DisplayModeRec *pMode2)
{
if (pMode1->Clock == pMode2->Clock &&
pMode1->HDisplay == pMode2->HDisplay &&
@@ -519,7 +519,7 @@ xf86ValidateModesBandwidth(ScrnInfoPtr pScrn, DisplayModePtr modeList,
}
Bool
-xf86ModeIsReduced(DisplayModePtr mode)
+xf86ModeIsReduced(const DisplayModeRec *mode)
{
if ((((mode->HDisplay * 5 / 4) & ~0x07) > mode->HTotal) &&
((mode->HTotal - mode->HDisplay) == 160) &&
@@ -698,7 +698,7 @@ xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed)
for (i = 0; i < xf86NumDefaultModes; i++)
{
- DisplayModePtr defMode = &xf86DefaultModes[i];
+ const DisplayModeRec *defMode = &xf86DefaultModes[i];
if (!interlaceAllowed && (defMode->Flags & V_INTERLACE))
continue;
diff --git a/driver/xf86-video-nv/compat/modes/xf86Modes.h b/driver/xf86-video-nv/compat/modes/xf86Modes.h
index af5987b24..2fb6a374d 100644
--- a/driver/xf86-video-nv/compat/modes/xf86Modes.h
+++ b/driver/xf86-video-nv/compat/modes/xf86Modes.h
@@ -40,22 +40,23 @@
#include "xf86Rename.h"
#endif
-double xf86ModeHSync(DisplayModePtr mode);
-double xf86ModeVRefresh(DisplayModePtr mode);
+double xf86ModeHSync(const DisplayModeRec *mode);
+double xf86ModeVRefresh(const DisplayModeRec *mode);
unsigned int xf86ModeBandwidth(DisplayModePtr mode, int depth);
int
-xf86ModeWidth (DisplayModePtr mode, Rotation rotation);
+xf86ModeWidth (const DisplayModeRec *mode, Rotation rotation);
int
-xf86ModeHeight (DisplayModePtr mode, Rotation rotation);
+xf86ModeHeight (const DisplayModeRec *mode, Rotation rotation);
-DisplayModePtr xf86DuplicateMode(DisplayModePtr pMode);
+DisplayModePtr xf86DuplicateMode(const DisplayModeRec *pMode);
DisplayModePtr xf86DuplicateModes(ScrnInfoPtr pScrn,
DisplayModePtr modeList);
void xf86SetModeDefaultName(DisplayModePtr mode);
void xf86SetModeCrtc(DisplayModePtr p, int adjustFlags);
-Bool xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2);
+Bool xf86ModesEqual(const DisplayModeRec *pMode1,
+ const DisplayModeRec *pMode2);
void xf86PrintModeline(int scrnIndex,DisplayModePtr mode);
DisplayModePtr xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new);
@@ -65,7 +66,7 @@ DisplayModePtr xf86CVTMode(int HDisplay, int VDisplay, float VRefresh,
DisplayModePtr xf86GTFMode(int h_pixels, int v_lines, float freq, int interlaced, int margins);
Bool
-xf86ModeIsReduced(DisplayModePtr mode);
+xf86ModeIsReduced(const DisplayModeRec *mode);
void
xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
diff --git a/driver/xf86-video-nv/compat/modes/xf86RandR12.c b/driver/xf86-video-nv/compat/modes/xf86RandR12.c
index ac0b438d3..6f93a0dc3 100644
--- a/driver/xf86-video-nv/compat/modes/xf86RandR12.c
+++ b/driver/xf86-video-nv/compat/modes/xf86RandR12.c
@@ -51,6 +51,8 @@ typedef struct _xf86RandR12Info {
int mmHeight;
int maxX;
int maxY;
+ int pointerX;
+ int pointerY;
Rotation rotation; /* current mode */
Rotation supported_rotations; /* driver supported */
} XF86RandRInfoRec, *XF86RandRInfoPtr;
@@ -63,6 +65,7 @@ static Bool xf86RandR12CreateScreenResources12 (ScreenPtr pScreen);
static int xf86RandR12Generation;
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
+static int xf86RandR12KeyIndex;
static DevPrivateKey xf86RandR12Key;
#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) \
dixLookupPrivate(&(p)->devPrivates, xf86RandR12Key))
@@ -85,6 +88,355 @@ xf86RandR12ModeRefresh (DisplayModePtr mode)
return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
}
+/* Adapt panning area; return TRUE if panning area was valid without adaption */
+static int
+xf86RandR13VerifyPanningArea (xf86CrtcPtr crtc, int screenWidth, int screenHeight)
+{
+ int ret = TRUE;
+
+ if (crtc->version < 2)
+ return FALSE;
+
+ if (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1) {
+ /* Panning in X is disabled */
+ if (crtc->panningTotalArea.x1 || crtc->panningTotalArea.x2)
+ /* Illegal configuration -> fail/disable */
+ ret = FALSE;
+ crtc->panningTotalArea.x1 = crtc->panningTotalArea.x2 = 0;
+ crtc->panningTrackingArea.x1 = crtc->panningTrackingArea.x2 = 0;
+ crtc->panningBorder[0] = crtc->panningBorder[2] = 0;
+ } else {
+ /* Panning in X is enabled */
+ if (crtc->panningTotalArea.x1 < 0) {
+ /* Panning region outside screen -> move inside */
+ crtc->panningTotalArea.x2 -= crtc->panningTotalArea.x1;
+ crtc->panningTotalArea.x1 = 0;
+ ret = FALSE;
+ }
+ if (crtc->panningTotalArea.x2 < crtc->panningTotalArea.x1 + crtc->mode.HDisplay) {
+ /* Panning region smaller than displayed area -> crop to displayed area */
+ crtc->panningTotalArea.x2 = crtc->panningTotalArea.x1 + crtc->mode.HDisplay;
+ ret = FALSE;
+ }
+ if (crtc->panningTotalArea.x2 > screenWidth) {
+ /* Panning region larger than screen -> move inside, then crop to screen */
+ crtc->panningTotalArea.x1 -= crtc->panningTotalArea.x2 - screenWidth;
+ crtc->panningTotalArea.x2 = screenWidth;
+ ret = FALSE;
+ if (crtc->panningTotalArea.x1 < 0)
+ crtc->panningTotalArea.x1 = 0;
+ }
+ if (crtc->panningBorder[0] + crtc->panningBorder[2] > crtc->mode.HDisplay) {
+ /* Borders too large -> set to 0 */
+ crtc->panningBorder[0] = crtc->panningBorder[2] = 0;
+ ret = FALSE;
+ }
+ }
+
+ if (crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1) {
+ /* Panning in Y is disabled */
+ if (crtc->panningTotalArea.y1 || crtc->panningTotalArea.y2)
+ /* Illegal configuration -> fail/disable */
+ ret = FALSE;
+ crtc->panningTotalArea.y1 = crtc->panningTotalArea.y2 = 0;
+ crtc->panningTrackingArea.y1 = crtc->panningTrackingArea.y2 = 0;
+ crtc->panningBorder[1] = crtc->panningBorder[3] = 0;
+ } else {
+ /* Panning in Y is enabled */
+ if (crtc->panningTotalArea.y1 < 0) {
+ /* Panning region outside screen -> move inside */
+ crtc->panningTotalArea.y2 -= crtc->panningTotalArea.y1;
+ crtc->panningTotalArea.y1 = 0;
+ ret = FALSE;
+ }
+ if (crtc->panningTotalArea.y2 < crtc->panningTotalArea.y1 + crtc->mode.VDisplay) {
+ /* Panning region smaller than displayed area -> crop to displayed area */
+ crtc->panningTotalArea.y2 = crtc->panningTotalArea.y1 + crtc->mode.VDisplay;
+ ret = FALSE;
+ }
+ if (crtc->panningTotalArea.y2 > screenHeight) {
+ /* Panning region larger than screen -> move inside, then crop to screen */
+ crtc->panningTotalArea.y1 -= crtc->panningTotalArea.y2 - screenHeight;
+ crtc->panningTotalArea.y2 = screenHeight;
+ ret = FALSE;
+ if (crtc->panningTotalArea.y1 < 0)
+ crtc->panningTotalArea.y1 = 0;
+ }
+ if (crtc->panningBorder[1] + crtc->panningBorder[3] > crtc->mode.VDisplay) {
+ /* Borders too large -> set to 0 */
+ crtc->panningBorder[1] = crtc->panningBorder[3] = 0;
+ ret = FALSE;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * The heart of the panning operation:
+ *
+ * Given a frame buffer position (fb_x, fb_y),
+ * and a crtc position (crtc_x, crtc_y),
+ * and a transform matrix which maps frame buffer to crtc,
+ * compute a panning position (pan_x, pan_y) that
+ * makes the resulting transform line those two up
+ */
+
+static void
+xf86ComputeCrtcPan (Bool transform_in_use,
+ struct pixman_f_transform *m,
+ double screen_x, double screen_y,
+ double crtc_x, double crtc_y,
+ int old_pan_x, int old_pan_y,
+ int *new_pan_x, int *new_pan_y)
+{
+ if (transform_in_use) {
+ /*
+ * Given the current transform, M, the current position
+ * on the Screen, S, and the desired position on the CRTC,
+ * C, compute a translation, T, such that:
+ *
+ * M T S = C
+ *
+ * where T is of the form
+ *
+ * | 1 0 dx |
+ * | 0 1 dy |
+ * | 0 0 1 |
+ *
+ * M T S =
+ * | M00 Sx + M01 Sy + M00 dx + M01 dy + M02 | | Cx F |
+ * | M10 Sx + M11 Sy + M10 dx + M11 dy + M12 | = | Cy F |
+ * | M20 Sx + M21 Sy + M20 dx + M21 dy + M22 | | F |
+ *
+ * R = M S
+ *
+ * Cx F = M00 dx + M01 dy + R0
+ * Cy F = M10 dx + M11 dy + R1
+ * F = M20 dx + M21 dy + R2
+ *
+ * Zero out dx, then dy
+ *
+ * F (Cx M10 - Cy M00) =
+ * (M10 M01 - M00 M11) dy + M10 R0 - M00 R1
+ * F (M10 - Cy M20) =
+ * (M10 M21 - M20 M11) dy + M10 R2 - M20 R1
+ *
+ * F (Cx M11 - Cy M01) =
+ * (M11 M00 - M01 M10) dx + M11 R0 - M01 R1
+ * F (M11 - Cy M21) =
+ * (M11 M20 - M21 M10) dx + M11 R2 - M21 R1
+ *
+ * Make some temporaries
+ *
+ * T = | Cx M10 - Cy M00 |
+ * | Cx M11 - Cy M01 |
+ *
+ * U = | M10 M01 - M00 M11 |
+ * | M11 M00 - M01 M10 |
+ *
+ * Q = | M10 R0 - M00 R1 |
+ * | M11 R0 - M01 R1 |
+ *
+ * P = | M10 - Cy M20 |
+ * | M11 - Cy M21 |
+ *
+ * W = | M10 M21 - M20 M11 |
+ * | M11 M20 - M21 M10 |
+ *
+ * V = | M10 R2 - M20 R1 |
+ * | M11 R2 - M21 R1 |
+ *
+ * Rewrite:
+ *
+ * F T0 = U0 dy + Q0
+ * F P0 = W0 dy + V0
+ * F T1 = U1 dx + Q1
+ * F P1 = W1 dx + V1
+ *
+ * Solve for F (two ways)
+ *
+ * F (W0 T0 - U0 P0) = W0 Q0 - U0 V0
+ *
+ * W0 Q0 - U0 V0
+ * F = -------------
+ * W0 T0 - U0 P0
+ *
+ * F (W1 T1 - U1 P1) = W1 Q1 - U1 V1
+ *
+ * W1 Q1 - U1 V1
+ * F = -------------
+ * W1 T1 - U1 P1
+ *
+ * We'll use which ever solution works (denominator != 0)
+ *
+ * Finally, solve for dx and dy:
+ *
+ * dx = (F T1 - Q1) / U1
+ * dx = (F P1 - V1) / W1
+ *
+ * dy = (F T0 - Q0) / U0
+ * dy = (F P0 - V0) / W0
+ */
+ double r[3];
+ double q[2], u[2], t[2], v[2], w[2], p[2];
+ double f;
+ struct pict_f_vector d;
+ int i;
+
+ /* Get the un-normalized crtc coordinates again */
+ for (i = 0; i < 3; i++)
+ r[i] = m->m[i][0] * screen_x + m->m[i][1] * screen_y + m->m[i][2];
+
+ /* Combine values into temporaries */
+ for (i = 0; i < 2; i++) {
+ q[i] = m->m[1][i] * r[0] - m->m[0][i] * r[1];
+ u[i] = m->m[1][i] * m->m[0][1-i] - m->m[0][i] * m->m[1][1-i];
+ t[i] = m->m[1][i] * crtc_x - m->m[0][i] * crtc_y;
+
+ v[i] = m->m[1][i] * r[2] - m->m[2][i] * r[1];
+ w[i] = m->m[1][i] * m->m[2][1-i] - m->m[2][i] * m->m[1][1-i];
+ p[i] = m->m[1][i] - m->m[2][i] * crtc_y;
+ }
+
+ /* Find a way to compute f */
+ f = 0;
+ for (i = 0; i < 2; i++) {
+ double a = w[i] * q[i] - u[i] * v[i];
+ double b = w[i] * t[i] - u[i] * p[i];
+ if (b != 0) {
+ f = a/b;
+ break;
+ }
+ }
+
+ /* Solve for the resulting transform vector */
+ for (i = 0; i < 2; i++) {
+ if (u[i])
+ d.v[1-i] = (t[i] * f - q[i]) / u[i];
+ else if (w[1])
+ d.v[1-i] = (p[i] * f - v[i]) / w[i];
+ else
+ d.v[1-i] = 0;
+ }
+ *new_pan_x = old_pan_x - floor (d.v[0] + 0.5);
+ *new_pan_y = old_pan_y - floor (d.v[1] + 0.5);
+ } else {
+ *new_pan_x = screen_x - crtc_x;
+ *new_pan_y = screen_y - crtc_y;
+ }
+}
+
+static void
+xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y)
+{
+ int newX, newY;
+ int width, height;
+ Bool panned = FALSE;
+
+ if (crtc->version < 2)
+ return;
+
+ if (! crtc->enabled ||
+ (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1 &&
+ crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1))
+ return;
+
+ newX = crtc->x;
+ newY = crtc->y;
+ width = crtc->mode.HDisplay;
+ height = crtc->mode.VDisplay;
+
+ if ((crtc->panningTrackingArea.x2 <= crtc->panningTrackingArea.x1 ||
+ (x >= crtc->panningTrackingArea.x1 && x < crtc->panningTrackingArea.x2)) &&
+ (crtc->panningTrackingArea.y2 <= crtc->panningTrackingArea.y1 ||
+ (y >= crtc->panningTrackingArea.y1 && y < crtc->panningTrackingArea.y2)))
+ {
+ struct pict_f_vector c;
+
+ /*
+ * Pre-clip the mouse position to the panning area so that we don't
+ * push the crtc outside. This doesn't deal with changes to the
+ * panning values, only mouse position changes.
+ */
+ if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1)
+ {
+ if (x < crtc->panningTotalArea.x1)
+ x = crtc->panningTotalArea.x1;
+ if (x >= crtc->panningTotalArea.x2)
+ x = crtc->panningTotalArea.x2 - 1;
+ }
+ if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1)
+ {
+ if (y < crtc->panningTotalArea.y1)
+ y = crtc->panningTotalArea.y1;
+ if (y >= crtc->panningTotalArea.y2)
+ y = crtc->panningTotalArea.y2 - 1;
+ }
+
+ c.v[0] = x;
+ c.v[1] = y;
+ c.v[2] = 1.0;
+ if (crtc->transform_in_use) {
+ pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, &c);
+ } else {
+ c.v[0] -= crtc->x;
+ c.v[1] -= crtc->y;
+ }
+
+ if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
+ if (c.v[0] < crtc->panningBorder[0]) {
+ c.v[0] = crtc->panningBorder[0];
+ panned = TRUE;
+ }
+ if (c.v[0] >= width - crtc->panningBorder[2]) {
+ c.v[0] = width - crtc->panningBorder[2] - 1;
+ panned = TRUE;
+ }
+ }
+ if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
+ if (c.v[1] < crtc->panningBorder[1]) {
+ c.v[1] = crtc->panningBorder[1];
+ panned = TRUE;
+ }
+ if (c.v[1] >= height - crtc->panningBorder[3]) {
+ c.v[1] = height - crtc->panningBorder[3] - 1;
+ panned = TRUE;
+ }
+ }
+ if (panned)
+ xf86ComputeCrtcPan (crtc->transform_in_use,
+ &crtc->f_framebuffer_to_crtc,
+ x, y, c.v[0], c.v[1],
+ newX, newY, &newX, &newY);
+ }
+
+ /*
+ * Ensure that the crtc is within the panning region.
+ *
+ * XXX This computation only works when we do not have a transform
+ * in use.
+ */
+ if (!crtc->transform_in_use)
+ {
+ /* Validate against [xy]1 after [xy]2, to be sure that results are > 0 for [xy]1 > 0 */
+ if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
+ if (newX > crtc->panningTotalArea.x2 - width)
+ newX = crtc->panningTotalArea.x2 - width;
+ if (newX < crtc->panningTotalArea.x1)
+ newX = crtc->panningTotalArea.x1;
+ }
+ if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
+ if (newY > crtc->panningTotalArea.y2 - height)
+ newY = crtc->panningTotalArea.y2 - height;
+ if (newY < crtc->panningTotalArea.y1)
+ newY = crtc->panningTotalArea.y1;
+ }
+ }
+ if (newX != crtc->x || newY != crtc->y)
+ xf86CrtcSetOrigin (crtc, newX, newY);
+}
+
static Bool
xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations)
{
@@ -331,6 +683,7 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen,
WindowPtr pRoot = WindowTable[pScreen->myNum];
PixmapPtr pScrnPix = (*pScreen->GetScreenPixmap)(pScreen);
Bool ret = FALSE;
+ int c;
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
if (xf86RandR12Key) {
@@ -351,6 +704,23 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen,
goto finish;
ret = TRUE;
+ /* Update panning information */
+ for (c = 0; c < config->num_crtc; c++) {
+ xf86CrtcPtr crtc = config->crtc[c];
+ if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1 ||
+ crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
+ if (crtc->panningTotalArea.x2 > crtc->panningTrackingArea.x1)
+ crtc->panningTotalArea.x2 += width - pScreen->width;
+ if (crtc->panningTotalArea.y2 > crtc->panningTrackingArea.y1)
+ crtc->panningTotalArea.y2 += height - pScreen->height;
+ if (crtc->panningTrackingArea.x2 > crtc->panningTrackingArea.x1)
+ crtc->panningTrackingArea.x2 += width - pScreen->width;
+ if (crtc->panningTrackingArea.y2 > crtc->panningTrackingArea.y1)
+ crtc->panningTrackingArea.y2 += height - pScreen->height;
+ xf86RandR13VerifyPanningArea (crtc, width, height);
+ xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
+ }
+ }
pScreen->width = pScrnPix->drawable.width = width;
pScreen->height = pScrnPix->drawable.height = height;
@@ -403,10 +773,16 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen)
int crtc_width = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
int crtc_height = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
- if (crtc->enabled && crtc_width > width)
- width = crtc_width;
- if (crtc->enabled && crtc_height > height)
- height = crtc_height;
+ if (crtc->enabled) {
+ if (crtc_width > width)
+ width = crtc_width;
+ if (crtc_height > height)
+ height = crtc_height;
+ if (crtc->panningTotalArea.x2 > width)
+ width = crtc->panningTotalArea.x2;
+ if (crtc->panningTotalArea.y2 > height)
+ height = crtc->panningTotalArea.y2;
+ }
}
if (width && height)
@@ -457,6 +833,13 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Setting screen physical size to %d x %d\n",
mmWidth, mmHeight);
+ /*
+ * This is the initial setting of the screen size.
+ * We have to pre-set it here, otherwise panning would be adapted
+ * to the new screen size.
+ */
+ pScreen->width = width;
+ pScreen->height = height;
xf86RandR12ScreenSetSize (pScreen,
width,
height,
@@ -499,7 +882,7 @@ xf86RandR12Init (ScreenPtr pScreen)
xf86RandR12Generation = serverGeneration;
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
- xf86RandR12Key = &xf86RandR12Key;
+ xf86RandR12Key = &xf86RandR12KeyIndex;
#else
xf86RandR12Index = AllocateScreenPrivateIndex();
#endif
@@ -568,6 +951,31 @@ xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations)
}
_X_EXPORT void
+xf86RandR12SetTransformSupport (ScreenPtr pScreen, Bool transforms)
+{
+ XF86RandRInfoPtr randrp;
+#if RANDR_13_INTERFACE
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ int c;
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+#endif
+
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
+ if (xf86RandR12Key == NULL)
+ return;
+#endif
+
+ randrp = XF86RANDRINFO(pScreen);
+#if RANDR_13_INTERFACE
+ for (c = 0; c < config->num_crtc; c++) {
+ xf86CrtcPtr crtc = config->crtc[c];
+
+ RRCrtcSetTransformSupport (crtc->randr_crtc, transforms);
+ }
+#endif
+}
+
+_X_EXPORT void
xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
{
ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
@@ -689,7 +1097,9 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
}
}
ret = RRCrtcNotify (randr_crtc, randr_mode, x, y,
- rotation, numOutputs, randr_outputs);
+ rotation,
+ crtc->transformPresent ? &crtc->transform : NULL,
+ numOutputs, randr_outputs);
xfree(randr_outputs);
return ret;
}
@@ -725,18 +1135,20 @@ xf86RandRModeConvert (ScrnInfoPtr scrn,
}
static Bool
-xf86RandR12CrtcSet (ScreenPtr pScreen,
- RRCrtcPtr randr_crtc,
- RRModePtr randr_mode,
- int x,
- int y,
- Rotation rotation,
- int num_randr_outputs,
- RROutputPtr *randr_outputs)
+xf86RandR12CrtcSet (ScreenPtr pScreen,
+ RRCrtcPtr randr_crtc,
+ RRModePtr randr_mode,
+ int x,
+ int y,
+ Rotation rotation,
+ int num_randr_outputs,
+ RROutputPtr *randr_outputs)
{
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
xf86CrtcPtr crtc = randr_crtc->devPrivate;
+ RRTransformPtr transform;
Bool changed = FALSE;
int o, ro;
xf86CrtcPtr *save_crtcs;
@@ -754,6 +1166,13 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
if (rotation != crtc->rotation)
changed = TRUE;
+ transform = RRCrtcGetTransform (randr_crtc);
+ if ((transform != NULL) != crtc->transformPresent)
+ changed = TRUE;
+ else if (transform && memcmp (&transform->transform, &crtc->transform.transform,
+ sizeof (transform->transform)) != 0)
+ changed = TRUE;
+
if (x != crtc->x || y != crtc->y)
changed = TRUE;
for (o = 0; o < config->num_output; o++)
@@ -791,9 +1210,10 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
if (randr_mode)
{
DisplayModeRec mode;
+ RRTransformPtr transform = RRCrtcGetTransform (randr_crtc);
xf86RandRModeConvert (pScrn, randr_mode, &mode);
- if (!xf86CrtcSetMode (crtc, &mode, rotation, x, y))
+ if (!xf86CrtcSetModeTransform (crtc, &mode, rotation, transform, x, y))
{
crtc->enabled = save_enabled;
for (o = 0; o < config->num_output; o++)
@@ -804,11 +1224,19 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
xfree(save_crtcs);
return FALSE;
}
+ xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height);
+ xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
/*
* Save the last successful setting for EnterVT
*/
crtc->desiredMode = mode;
crtc->desiredRotation = rotation;
+ if (transform) {
+ crtc->desiredTransform = *transform;
+ crtc->desiredTransformPresent = TRUE;
+ } else
+ crtc->desiredTransformPresent = FALSE;
+
crtc->desiredX = x;
crtc->desiredY = y;
}
@@ -1144,6 +1572,77 @@ xf86RandR12TellChanged (ScreenPtr pScreen)
static void
xf86RandR12PointerMoved (int scrnIndex, int x, int y)
{
+ ScreenPtr pScreen = screenInfo.screens[scrnIndex];
+ ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ int c;
+
+ randrp->pointerX = x;
+ randrp->pointerY = y;
+ for (c = 0; c < config->num_crtc; c++)
+ xf86RandR13Pan (config->crtc[c], x, y);
+}
+
+static Bool
+xf86RandR13GetPanning (ScreenPtr pScreen,
+ RRCrtcPtr randr_crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border)
+{
+ xf86CrtcPtr crtc = randr_crtc->devPrivate;
+
+ if (crtc->version < 2)
+ return FALSE;
+ if (totalArea)
+ memcpy (totalArea, &crtc->panningTotalArea, sizeof(BoxRec));
+ if (trackingArea)
+ memcpy (trackingArea, &crtc->panningTrackingArea, sizeof(BoxRec));
+ if (border)
+ memcpy (border, crtc->panningBorder, 4*sizeof(INT16));
+
+ return TRUE;
+}
+
+static Bool
+xf86RandR13SetPanning (ScreenPtr pScreen,
+ RRCrtcPtr randr_crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border)
+{
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ xf86CrtcPtr crtc = randr_crtc->devPrivate;
+ BoxRec oldTotalArea;
+ BoxRec oldTrackingArea;
+ INT16 oldBorder[4];
+
+
+ if (crtc->version < 2)
+ return FALSE;
+
+ memcpy (&oldTotalArea, &crtc->panningTotalArea, sizeof(BoxRec));
+ memcpy (&oldTrackingArea, &crtc->panningTrackingArea, sizeof(BoxRec));
+ memcpy (oldBorder, crtc->panningBorder, 4*sizeof(INT16));
+
+ if (totalArea)
+ memcpy (&crtc->panningTotalArea, totalArea, sizeof(BoxRec));
+ if (trackingArea)
+ memcpy (&crtc->panningTrackingArea, trackingArea, sizeof(BoxRec));
+ if (border)
+ memcpy (crtc->panningBorder, border, 4*sizeof(INT16));
+
+ if (xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height)) {
+ xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
+ return TRUE;
+ } else {
+ /* Restore old settings */
+ memcpy (&crtc->panningTotalArea, &oldTotalArea, sizeof(BoxRec));
+ memcpy (&crtc->panningTrackingArea, &oldTrackingArea, sizeof(BoxRec));
+ memcpy (crtc->panningBorder, oldBorder, 4*sizeof(INT16));
+ return FALSE;
+ }
}
static Bool
@@ -1160,6 +1659,8 @@ xf86RandR12Init12 (ScreenPtr pScreen)
rp->rrOutputValidateMode = xf86RandR12OutputValidateMode;
#if RANDR_13_INTERFACE
rp->rrOutputGetProperty = xf86RandR13OutputGetProperty;
+ rp->rrGetPanning = xf86RandR13GetPanning;
+ rp->rrSetPanning = xf86RandR13SetPanning;
#endif
rp->rrModeDestroy = xf86RandR12ModeDestroy;
rp->rrSetConfig = NULL;
diff --git a/driver/xf86-video-nv/compat/modes/xf86RandR12.h b/driver/xf86-video-nv/compat/modes/xf86RandR12.h
index 4fd855cf5..17a2dcc7f 100644
--- a/driver/xf86-video-nv/compat/modes/xf86RandR12.h
+++ b/driver/xf86-video-nv/compat/modes/xf86RandR12.h
@@ -31,6 +31,7 @@
Bool xf86RandR12CreateScreenResources (ScreenPtr pScreen);
Bool xf86RandR12Init(ScreenPtr pScreen);
void xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotation);
+void xf86RandR12SetTransformSupport (ScreenPtr pScreen, Bool transforms);
Bool xf86RandR12SetConfig(ScreenPtr pScreen, Rotation rotation, int rate,
RRScreenSizePtr pSize);
Rotation xf86RandR12GetRotation(ScreenPtr pScreen);
diff --git a/driver/xf86-video-nv/compat/modes/xf86Rename.h b/driver/xf86-video-nv/compat/modes/xf86Rename.h
index b8c1d70ef..e3418caad 100644
--- a/driver/xf86-video-nv/compat/modes/xf86Rename.h
+++ b/driver/xf86-video-nv/compat/modes/xf86Rename.h
@@ -38,6 +38,7 @@
#define xf86CrtcInUse XF86NAME(xf86CrtcInUse)
#define xf86CrtcRotate XF86NAME(xf86CrtcRotate)
#define xf86CrtcScreenInit XF86NAME(xf86CrtcScreenInit)
+#define xf86CrtcSetModeTransform XF86NAME(xf86CrtcSetModeTransform)
#define xf86CrtcSetMode XF86NAME(xf86CrtcSetMode)
#define xf86CrtcSetSizeRange XF86NAME(xf86CrtcSetSizeRange)
#define xf86CVTMode XF86NAME(xf86CVTMode)
diff --git a/driver/xf86-video-nv/compat/modes/xf86Rotate.c b/driver/xf86-video-nv/compat/modes/xf86Rotate.c
index 6c93066c7..6be77d556 100644
--- a/driver/xf86-video-nv/compat/modes/xf86Rotate.c
+++ b/driver/xf86-video-nv/compat/modes/xf86Rotate.c
@@ -70,205 +70,9 @@ compWindowFormat (WindowPtr pWin)
#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)
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 (a);
- ErrorF ("\n");
- return FALSE;
- }
- return TRUE;
-}
-
-static void
xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
{
ScrnInfoPtr scrn = crtc->scrn;
@@ -305,19 +109,37 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
error = SetPictureTransform (src, &crtc->crtc_to_framebuffer);
if (error)
return;
+ if (crtc->transform_in_use && crtc->filter)
+ SetPicturePictFilter (src, crtc->filter,
+ crtc->params, crtc->nparams);
- while (n--)
+ if (crtc->shadowClear)
{
- BoxRec dst_box;
-
- dst_box = *b;
- PictureTransformBounds (&dst_box, &crtc->framebuffer_to_crtc);
CompositePicture (PictOpSrc,
src, NULL, dst,
- dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1,
- dst_box.x2 - dst_box.x1,
- dst_box.y2 - dst_box.y1);
- b++;
+ 0, 0, 0, 0, 0, 0,
+ crtc->mode.HDisplay, crtc->mode.VDisplay);
+ crtc->shadowClear = FALSE;
+ }
+ else
+ {
+ while (n--)
+ {
+ BoxRec dst_box;
+
+ dst_box = *b;
+ dst_box.x1 -= crtc->filter_width >> 1;
+ dst_box.x2 += crtc->filter_width >> 1;
+ dst_box.y1 -= crtc->filter_height >> 1;
+ dst_box.y2 += crtc->filter_height >> 1;
+ pixman_f_transform_bounds (&crtc->f_framebuffer_to_crtc, &dst_box);
+ CompositePicture (PictOpSrc,
+ src, NULL, dst,
+ dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1,
+ dst_box.x2 - dst_box.x1,
+ dst_box.y2 - dst_box.y1);
+ b++;
+ }
}
FreePicture (src, None);
FreePicture (dst, None);
@@ -331,14 +153,26 @@ xf86CrtcDamageShadow (xf86CrtcPtr crtc)
RegionRec damage_region;
ScreenPtr pScreen = pScrn->pScreen;
- damage_box.x1 = crtc->x;
- damage_box.x2 = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
- damage_box.y1 = crtc->y;
- damage_box.y2 = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
+ damage_box.x1 = 0;
+ damage_box.x2 = crtc->mode.HDisplay;
+ damage_box.y1 = 0;
+ damage_box.y2 = crtc->mode.VDisplay;
+ if (!pixman_transform_bounds (&crtc->crtc_to_framebuffer, &damage_box))
+ {
+ damage_box.x1 = 0;
+ damage_box.y1 = 0;
+ damage_box.x2 = pScreen->width;
+ damage_box.y2 = pScreen->height;
+ }
+ if (damage_box.x1 < 0) damage_box.x1 = 0;
+ if (damage_box.y1 < 0) damage_box.y1 = 0;
+ if (damage_box.x2 > pScreen->width) damage_box.x2 = pScreen->width;
+ if (damage_box.y2 > pScreen->height) damage_box.y2 = pScreen->height;
REGION_INIT (pScreen, &damage_region, &damage_box, 1);
- DamageDamageRegion (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
+ DamageRegionAppend (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
&damage_region);
REGION_UNINIT (pScreen, &damage_region);
+ crtc->shadowClear = TRUE;
}
static void
@@ -401,7 +235,7 @@ xf86RotateRedisplay(ScreenPtr pScreen)
{
xf86CrtcPtr crtc = xf86_config->crtc[c];
- if (crtc->rotation != RR_Rotate_0 && crtc->enabled)
+ if (crtc->transform_in_use && crtc->enabled)
{
RegionRec crtc_damage;
@@ -437,10 +271,12 @@ xf86RotateBlockHandler(int screenNum, pointer blockData,
/* Re-wrap if rotation is still happening */
xf86_config->BlockHandler = pScreen->BlockHandler;
pScreen->BlockHandler = xf86RotateBlockHandler;
+ } else {
+ xf86_config->BlockHandler = NULL;
}
}
-static void
+void
xf86RotateDestroy (xf86CrtcPtr crtc)
{
ScrnInfoPtr pScrn = crtc->scrn;
@@ -506,116 +342,93 @@ xf86RotateCloseScreen (ScreenPtr screen)
xf86RotateDestroy (xf86_config->crtc[c]);
}
+static Bool
+xf86CrtcFitsScreen (xf86CrtcPtr crtc, struct pict_f_transform *crtc_to_fb)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ BoxRec b;
+
+ /* When called before PreInit, the driver is
+ * presumably doing load detect
+ */
+ if (pScrn->virtualX == 0 || pScrn->virtualY == 0)
+ return TRUE;
+
+ b.x1 = 0;
+ b.y1 = 0;
+ b.x2 = crtc->mode.HDisplay;
+ b.y2 = crtc->mode.VDisplay;
+ if (crtc_to_fb)
+ pixman_f_transform_bounds (crtc_to_fb, &b);
+ else {
+ b.x1 += crtc->x;
+ b.y1 += crtc->y;
+ b.x2 += crtc->x;
+ b.y2 += crtc->y;
+ }
+
+ return (0 <= b.x1 && b.x2 <= pScrn->virtualX &&
+ 0 <= b.y1 && b.y2 <= pScrn->virtualY);
+}
+
_X_EXPORT Bool
-xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
+xf86CrtcRotate (xf86CrtcPtr crtc)
{
ScrnInfoPtr pScrn = crtc->scrn;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
/* if this is called during ScreenInit() we don't have pScrn->pScreen yet */
ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
- PictTransform crtc_to_fb, fb_to_crtc;
-
- PictureTransformIdentity (&crtc_to_fb);
- PictureTransformIdentity (&fb_to_crtc);
- PictureTransformIsInverse ("identity", &crtc_to_fb, &fb_to_crtc);
- 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 = crtc->mode.HDisplay;
- int mode_h = crtc->mode.VDisplay;
-
- /* 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 (&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);
- PictureTransformIsInverse ("rotate translate", &crtc_to_fb, &fb_to_crtc);
-
- /* 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 (&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);
- PictureTransformIsInverse ("scale translate", &crtc_to_fb, &fb_to_crtc);
-
- }
-
- /*
- * If the untranslated transformation is the identity,
- * disable the shadow buffer
- */
- if (PictureTransformIsIdentity (&crtc_to_fb))
+ PictTransform crtc_to_fb;
+ struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc;
+ xFixed *new_params = NULL;
+ int new_nparams = 0;
+ PictFilterPtr new_filter = NULL;
+ int new_width = 0;
+ int new_height = 0;
+ RRTransformPtr transform = NULL;
+ Bool damage = FALSE;
+
+ if (crtc->transformPresent)
+ transform = &crtc->transform;
+
+ if (!RRTransformCompute (crtc->x, crtc->y,
+ crtc->mode.HDisplay, crtc->mode.VDisplay,
+ crtc->rotation,
+ transform,
+
+ &crtc_to_fb,
+ &f_crtc_to_fb,
+ &f_fb_to_crtc) &&
+ xf86CrtcFitsScreen (crtc, &f_crtc_to_fb))
{
- crtc->transform_in_use = FALSE;
- PictureTransformInitTranslate (&crtc->crtc_to_framebuffer,
- F (-crtc->x), F (-crtc->y));
- PictureTransformInitTranslate (&crtc->framebuffer_to_crtc,
- F ( crtc->x), F ( crtc->y));
+ /*
+ * If the untranslated transformation is the identity,
+ * disable the shadow buffer
+ */
xf86RotateDestroy (crtc);
+ crtc->transform_in_use = FALSE;
+ if (new_params)
+ xfree (new_params);
+ new_params = NULL;
+ new_nparams = 0;
+ new_filter = NULL;
+ new_width = 0;
+ new_height = 0;
}
else
{
- int width, height, old_width, old_height;
- void *shadowData;
- PixmapPtr shadow;
-
- 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
* matches the mode, not the pre-rotated copy in the
* frame buffer
*/
- width = mode->HDisplay;
- height = mode->VDisplay;
- shadowData = crtc->rotatedData;
- shadow = crtc->rotatedPixmap;
- old_width = shadow ? shadow->drawable.width : 0;
- old_height = shadow ? shadow->drawable.height : 0;
-
+ int width = crtc->mode.HDisplay;
+ int height = crtc->mode.VDisplay;
+ void *shadowData = crtc->rotatedData;
+ PixmapPtr shadow = crtc->rotatedPixmap;
+ int old_width = shadow ? shadow->drawable.width : 0;
+ int old_height = shadow ? shadow->drawable.height : 0;
+
/* Allocate memory for rotation */
if (old_width != width || old_height != height)
{
@@ -634,9 +447,9 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
else
{
/* mark shadowed area as damaged so it will be repainted */
- xf86CrtcDamageShadow (crtc);
+ damage = TRUE;
}
-
+
if (!xf86_config->rotation_damage)
{
/* Create damage structure */
@@ -647,9 +460,32 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
goto bail2;
/* Wrap block handler */
- xf86_config->BlockHandler = pScreen->BlockHandler;
- pScreen->BlockHandler = xf86RotateBlockHandler;
+ if (!xf86_config->BlockHandler) {
+ xf86_config->BlockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = xf86RotateBlockHandler;
+ }
}
+#ifdef RANDR_12_INTERFACE
+ if (transform)
+ {
+ if (transform->nparams) {
+ new_params = xalloc (transform->nparams * sizeof (xFixed));
+ if (new_params) {
+ memcpy (new_params, transform->params,
+ transform->nparams * sizeof (xFixed));
+ new_nparams = transform->nparams;
+ new_filter = transform->filter;
+ }
+ } else
+ new_filter = transform->filter;
+ if (new_filter)
+ {
+ new_width = new_filter->width;
+ new_height = new_filter->height;
+ }
+ }
+#endif
+
if (0)
{
bail2:
@@ -668,15 +504,26 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
return FALSE;
}
crtc->transform_in_use = TRUE;
- crtc->crtc_to_framebuffer = crtc_to_fb;
- crtc->framebuffer_to_crtc = fb_to_crtc;
- crtc->bounds.x1 = 0;
- crtc->bounds.x2 = crtc->mode.HDisplay;
- crtc->bounds.y1 = 0;
- crtc->bounds.y2 = crtc->mode.VDisplay;
- PictureTransformBounds (&crtc->bounds, &crtc_to_fb);
}
-
+ crtc->crtc_to_framebuffer = crtc_to_fb;
+ crtc->f_crtc_to_framebuffer = f_crtc_to_fb;
+ crtc->f_framebuffer_to_crtc = f_fb_to_crtc;
+ if (crtc->params)
+ xfree (crtc->params);
+ crtc->params = new_params;
+ crtc->nparams = new_nparams;
+ crtc->filter = new_filter;
+ crtc->filter_width = new_width;
+ crtc->filter_height = new_height;
+ crtc->bounds.x1 = 0;
+ crtc->bounds.x2 = crtc->mode.HDisplay;
+ crtc->bounds.y1 = 0;
+ crtc->bounds.y2 = crtc->mode.VDisplay;
+ pixman_f_transform_bounds (&f_crtc_to_fb, &crtc->bounds);
+
+ if (damage)
+ xf86CrtcDamageShadow (crtc);
+
/* All done */
return TRUE;
}
diff --git a/driver/xf86-video-nv/compat/parser/xf86Parser.h b/driver/xf86-video-nv/compat/parser/xf86Parser.h
index fd6cc530b..1c7b285c8 100644
--- a/driver/xf86-video-nv/compat/parser/xf86Parser.h
+++ b/driver/xf86-video-nv/compat/parser/xf86Parser.h
@@ -75,6 +75,7 @@ typedef struct
char *file_inputdevs;
char *file_fontpath;
char *file_comment;
+ char *file_xkbdir;
}
XF86ConfFilesRec, *XF86ConfFilesPtr;