aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xfree86/modes
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2009-07-25 20:12:58 +0000
committermarha <marha@users.sourceforge.net>2009-07-25 20:12:58 +0000
commit2553bdd7c359cd87525d367761c86932cec5adff (patch)
treeae71245933c98474a699d3e392de5820879b2018 /xorg-server/hw/xfree86/modes
parente2c51f2ee7b0a3ea1a052fc49324057b4a4bbc78 (diff)
parent4a3dbb926ae3f5410198d7cc4f4ebe4f62eebf05 (diff)
downloadvcxsrv-2553bdd7c359cd87525d367761c86932cec5adff.tar.gz
vcxsrv-2553bdd7c359cd87525d367761c86932cec5adff.tar.bz2
vcxsrv-2553bdd7c359cd87525d367761c86932cec5adff.zip
svn merge file:///D:/svnrepos/vcxsrv/branches/released .
Diffstat (limited to 'xorg-server/hw/xfree86/modes')
-rw-r--r--xorg-server/hw/xfree86/modes/Makefile.in76
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Crtc.c516
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Crtc.h122
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Cursors.c65
-rw-r--r--xorg-server/hw/xfree86/modes/xf86EdidModes.c331
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Modes.c34
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Modes.h16
-rw-r--r--xorg-server/hw/xfree86/modes/xf86RandR12.c596
-rw-r--r--xorg-server/hw/xfree86/modes/xf86RandR12.h1
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Rename.h1
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Rotate.c494
-rw-r--r--xorg-server/hw/xfree86/modes/xf86gtf.c4
12 files changed, 1666 insertions, 590 deletions
diff --git a/xorg-server/hw/xfree86/modes/Makefile.in b/xorg-server/hw/xfree86/modes/Makefile.in
index ff0a94f9f..0af44e357 100644
--- a/xorg-server/hw/xfree86/modes/Makefile.in
+++ b/xorg-server/hw/xfree86/modes/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -45,7 +45,6 @@ mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/include/do-not-use-config.h \
$(top_builddir)/include/xorg-server.h \
$(top_builddir)/include/dix-config.h \
- $(top_builddir)/include/xgl-config.h \
$(top_builddir)/include/xorg-config.h \
$(top_builddir)/include/xkb-config.h \
$(top_builddir)/include/xwin-config.h \
@@ -65,9 +64,6 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
@@ -91,8 +87,9 @@ ADMIN_MAN_DIR = @ADMIN_MAN_DIR@
ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
-APPDEFAULTDIR = @APPDEFAULTDIR@
APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@
+APPLE_APPLICATION_ID = @APPLE_APPLICATION_ID@
+APPLE_APPLICATION_NAME = @APPLE_APPLICATION_NAME@
APP_MAN_DIR = @APP_MAN_DIR@
APP_MAN_SUFFIX = @APP_MAN_SUFFIX@
AR = @AR@
@@ -113,10 +110,6 @@ CFLAGS = @CFLAGS@
COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DARWIN_LIBS = @DARWIN_LIBS@
DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -138,6 +131,7 @@ DMXXIEXAMPLES_DEP_CFLAGS = @DMXXIEXAMPLES_DEP_CFLAGS@
DMXXIEXAMPLES_DEP_LIBS = @DMXXIEXAMPLES_DEP_LIBS@
DMXXMUEXAMPLES_DEP_CFLAGS = @DMXXMUEXAMPLES_DEP_CFLAGS@
DMXXMUEXAMPLES_DEP_LIBS = @DMXXMUEXAMPLES_DEP_LIBS@
+DOLT_BASH = @DOLT_BASH@
DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@
DRI2PROTO_LIBS = @DRI2PROTO_LIBS@
DRIPROTO_CFLAGS = @DRIPROTO_CFLAGS@
@@ -147,18 +141,15 @@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@
DRI_DRIVER_PATH = @DRI_DRIVER_PATH@
DSYMUTIL = @DSYMUTIL@
DTRACE = @DTRACE@
-ECHO = @ECHO@
+DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
-F77 = @F77@
-FFLAGS = @FFLAGS@
+FGREP = @FGREP@
FILE_MAN_DIR = @FILE_MAN_DIR@
FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@
-FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
-FREETYPE_LIBS = @FREETYPE_LIBS@
GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@
GLX_DEFINES = @GLX_DEFINES@
GL_CFLAGS = @GL_CFLAGS@
@@ -177,7 +168,7 @@ KDRIVE_LIBS = @KDRIVE_LIBS@
KDRIVE_LOCAL_LIBS = @KDRIVE_LOCAL_LIBS@
KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@
KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@
-LAUNCHD = @LAUNCHD@
+LD = @LD@
LDFLAGS = @LDFLAGS@
LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@
LEX = @LEX@
@@ -191,7 +182,10 @@ LIBTOOL = @LIBTOOL@
LIB_MAN_DIR = @LIB_MAN_DIR@
LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@
LINUXDOC = @LINUXDOC@
+LIPO = @LIPO@
LN_S = @LN_S@
+LTCOMPILE = @LTCOMPILE@
+LTCXXCOMPILE = @LTCXXCOMPILE@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
@@ -203,8 +197,7 @@ MESA_SOURCE = @MESA_SOURCE@
MISC_MAN_DIR = @MISC_MAN_DIR@
MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@
MKDIR_P = @MKDIR_P@
-MKFONTDIR = @MKFONTDIR@
-MKFONTSCALE = @MKFONTSCALE@
+NM = @NM@
NMEDIT = @NMEDIT@
OBJC = @OBJC@
OBJCCLD = @OBJCCLD@
@@ -213,8 +206,8 @@ OBJCFLAGS = @OBJCFLAGS@
OBJCLINK = @OBJCLINK@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
-OPENSSL_LIBS = @OPENSSL_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
@@ -247,7 +240,6 @@ VENDOR_NAME = @VENDOR_NAME@
VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@
VENDOR_RELEASE = @VENDOR_RELEASE@
VERSION = @VERSION@
-X11APP_ARCHS = @X11APP_ARCHS@
X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@
X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@
XDMCP_CFLAGS = @XDMCP_CFLAGS@
@@ -257,27 +249,12 @@ XDMXCONFIG_DEP_LIBS = @XDMXCONFIG_DEP_LIBS@
XDMX_CFLAGS = @XDMX_CFLAGS@
XDMX_LIBS = @XDMX_LIBS@
XDMX_SYS_LIBS = @XDMX_SYS_LIBS@
-XEGLMODULES_CFLAGS = @XEGLMODULES_CFLAGS@
-XEGL_LIBS = @XEGL_LIBS@
-XEGL_SYS_LIBS = @XEGL_SYS_LIBS@
XEPHYR_CFLAGS = @XEPHYR_CFLAGS@
-XEPHYR_DRI_LIBS = @XEPHYR_DRI_LIBS@
XEPHYR_INCS = @XEPHYR_INCS@
XEPHYR_LIBS = @XEPHYR_LIBS@
XF86CONFIGFILE = @XF86CONFIGFILE@
-XF86MISC_CFLAGS = @XF86MISC_CFLAGS@
-XF86MISC_LIBS = @XF86MISC_LIBS@
XF86VIDMODE_CFLAGS = @XF86VIDMODE_CFLAGS@
XF86VIDMODE_LIBS = @XF86VIDMODE_LIBS@
-XGLMODULES_CFLAGS = @XGLMODULES_CFLAGS@
-XGLMODULES_LIBS = @XGLMODULES_LIBS@
-XGLXMODULES_CFLAGS = @XGLXMODULES_CFLAGS@
-XGLXMODULES_LIBS = @XGLXMODULES_LIBS@
-XGLX_LIBS = @XGLX_LIBS@
-XGLX_SYS_LIBS = @XGLX_SYS_LIBS@
-XGL_LIBS = @XGL_LIBS@
-XGL_MODULE_PATH = @XGL_MODULE_PATH@
-XGL_SYS_LIBS = @XGL_SYS_LIBS@
XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@
XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@
XKB_COMPILED_DIR = @XKB_COMPILED_DIR@
@@ -288,10 +265,6 @@ XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@
XNESTMODULES_LIBS = @XNESTMODULES_LIBS@
XNEST_LIBS = @XNEST_LIBS@
XNEST_SYS_LIBS = @XNEST_SYS_LIBS@
-XORGCFG_DEP_CFLAGS = @XORGCFG_DEP_CFLAGS@
-XORGCFG_DEP_LIBS = @XORGCFG_DEP_LIBS@
-XORGCONFIG_DEP_CFLAGS = @XORGCONFIG_DEP_CFLAGS@
-XORGCONFIG_DEP_LIBS = @XORGCONFIG_DEP_LIBS@
XORG_CFLAGS = @XORG_CFLAGS@
XORG_INCS = @XORG_INCS@
XORG_LIBS = @XORG_LIBS@
@@ -300,13 +273,8 @@ XORG_MODULES_LIBS = @XORG_MODULES_LIBS@
XORG_OS = @XORG_OS@
XORG_OS_SUBDIR = @XORG_OS_SUBDIR@
XORG_SYS_LIBS = @XORG_SYS_LIBS@
-XPRINTMODULES_CFLAGS = @XPRINTMODULES_CFLAGS@
-XPRINTMODULES_LIBS = @XPRINTMODULES_LIBS@
-XPRINTPROTO_CFLAGS = @XPRINTPROTO_CFLAGS@
-XPRINTPROTO_LIBS = @XPRINTPROTO_LIBS@
-XPRINT_CFLAGS = @XPRINT_CFLAGS@
-XPRINT_LIBS = @XPRINT_LIBS@
-XPRINT_SYS_LIBS = @XPRINT_SYS_LIBS@
+XPBPROXY_CFLAGS = @XPBPROXY_CFLAGS@
+XPBPROXY_LIBS = @XPBPROXY_LIBS@
XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@
XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_LIBS@
XSDL_INCS = @XSDL_INCS@
@@ -339,8 +307,7 @@ abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_F77 = @ac_ct_F77@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -360,7 +327,6 @@ driverdir = @driverdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
extdir = @extdir@
-ft_config = @ft_config@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -370,12 +336,12 @@ htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
-launchagentsdir = @launchagentsdir@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
logdir = @logdir@
+lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
moduledir = @moduledir@
@@ -393,8 +359,6 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-xglmoduledir = @xglmoduledir@
-xpconfigdir = @xpconfigdir@
noinst_LIBRARIES = libxf86modes.a
libxf86modes_a_SOURCES = \
xf86Crtc.c \
@@ -432,8 +396,8 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -530,7 +494,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.c b/xorg-server/hw/xfree86/modes/xf86Crtc.c
index 1facf86e9..84d3cac3e 100644
--- a/xorg-server/hw/xfree86/modes/xf86Crtc.c
+++ b/xorg-server/hw/xfree86/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 },
};
@@ -694,7 +736,12 @@ xf86CrtcCloseScreen (int index, ScreenPtr screen)
/*
* Called at ScreenInit time to set up
*/
-_X_EXPORT Bool
+_X_EXPORT
+#ifdef RANDR_13_INTERFACE
+int
+#else
+Bool
+#endif
xf86CrtcScreenInit (ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
@@ -714,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;
@@ -727,7 +780,11 @@ xf86CrtcScreenInit (ScreenPtr screen)
config->CloseScreen = screen->CloseScreen;
screen->CloseScreen = xf86CrtcCloseScreen;
+#ifdef RANDR_13_INTERFACE
+ return RANDR_INTERFACE_VERSION;
+#else
return TRUE;
+#endif
}
static DisplayModePtr
@@ -905,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)
{
@@ -1176,10 +1233,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], relative->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], relative->initial_rotation);
+ if (modes[o])
+ output->initial_x -= xf86ModeWidth (modes[o], output->initial_rotation);
break;
default:
break;
@@ -1237,6 +1296,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
@@ -1407,7 +1519,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;
@@ -1415,6 +1527,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)
@@ -1465,6 +1578,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++)
{
@@ -1521,8 +1639,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
@@ -1809,6 +1929,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)
@@ -1860,75 +2040,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;
-}
-
-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 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;
- if (!last)
- m = o->probed_modes;
- else
- m = last->next;
+ /* count the number of enabled outputs */
+ for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ;
- for (; m; m = m->next)
- if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay))
- return m;
+ if (i != 1)
+ break;
- 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;
-static DisplayModePtr
-bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
-{
- int o = -1, p;
- DisplayModePtr mode = NULL, test = NULL, match = NULL;
+ if (aspect)
+ preferred_match[p] = bestModeForAspect(config, enabled, aspect);
- 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 (preferred_match[p])
+ ret = TRUE;
- /* if we didn't match it on all outputs, try the next one */
- if (!test)
- continue;
+ } while (0);
- /* 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
@@ -2127,6 +2275,11 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
xfree (modes);
return FALSE;
}
+
+ /*
+ * Set initial panning of each output
+ */
+ xf86InitialPanning (scrn);
/*
* Assign CRTCs to fit output configuration
@@ -2166,9 +2319,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;
@@ -2217,6 +2374,68 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
}
/*
+ * Check the CRTC we're going to map each output to vs. it's current
+ * CRTC. If they don't match, we have to disable the output and the CRTC
+ * since the driver will have to re-route things.
+ */
+static void
+xf86PrepareOutputs (ScrnInfoPtr scrn)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ int o;
+
+ for (o = 0; o < config->num_output; o++) {
+ xf86OutputPtr output = config->output[o];
+#if RANDR_GET_CRTC_INTERFACE
+ /* Disable outputs that are unused or will be re-routed */
+ if (!output->funcs->get_crtc ||
+ output->crtc != (*output->funcs->get_crtc)(output) ||
+ output->crtc == NULL)
+#endif
+ (*output->funcs->dpms)(output, DPMSModeOff);
+ }
+}
+
+static void
+xf86PrepareCrtcs (ScrnInfoPtr scrn)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c;
+
+ for (c = 0; c < config->num_crtc; c++) {
+#if RANDR_GET_CRTC_INTERFACE
+ xf86CrtcPtr crtc = config->crtc[c];
+ xf86OutputPtr output = NULL;
+ uint32_t desired_outputs = 0, current_outputs = 0;
+ int o;
+
+ for (o = 0; o < config->num_output; o++) {
+ output = config->output[o];
+ if (output->crtc == crtc)
+ desired_outputs |= (1<<o);
+ /* If we can't tell where it's mapped, force it off */
+ if (!output->funcs->get_crtc) {
+ desired_outputs = 0;
+ break;
+ }
+ if ((*output->funcs->get_crtc)(output) == crtc)
+ current_outputs |= (1<<o);
+ }
+
+ /*
+ * If mappings are different or the CRTC is unused,
+ * we need to disable it
+ */
+ if (desired_outputs != current_outputs ||
+ !desired_outputs)
+ (*crtc->funcs->dpms)(crtc, DPMSModeOff);
+#else
+ (*crtc->funcs->dpms)(crtc, DPMSModeOff);
+#endif
+ }
+}
+
+/*
* Using the desired mode information in each crtc, set
* modes (used in EnterVT functions, or at server startup)
*/
@@ -2225,31 +2444,22 @@ _X_EXPORT Bool
xf86SetDesiredModes (ScrnInfoPtr scrn)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
- int c, o;
+ xf86CrtcPtr crtc = config->crtc[0];
+ int c;
- /*
- * Turn off everything so mode setting is done
- * with hardware in a consistent state
- */
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
- (*output->funcs->dpms)(output, DPMSModeOff);
+ /* A driver with this hook will take care of this */
+ if (!crtc->funcs->set_mode_major) {
+ xf86PrepareOutputs(scrn);
+ xf86PrepareCrtcs(scrn);
}
- for (c = 0; c < config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = config->crtc[c];
-
- crtc->funcs->dpms(crtc, DPMSModeOff);
- memset(&crtc->mode, 0, sizeof(crtc->mode));
- }
-
for (c = 0; c < config->num_crtc; c++)
{
- xf86CrtcPtr crtc = config->crtc[c];
xf86OutputPtr output = NULL;
int o;
+ RRTransformPtr transform;
+
+ crtc = config->crtc[c];
/* Skip disabled CRTCs */
if (!crtc->enabled)
@@ -2280,12 +2490,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;
}
@@ -2414,18 +2629,19 @@ 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;
}
}
xf86DisableUnusedFunctions(pScrn);
-#if RANDR_12_INTERFACE
+#ifdef RANDR_12_INTERFACE
xf86RandR12TellChanged (pScrn->pScreen);
#endif
return ok;
@@ -2513,8 +2729,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
@@ -2576,9 +2795,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);
@@ -2623,15 +2844,16 @@ xf86OutputGetEDIDModes (xf86OutputPtr output)
return xf86DDCGetModes(scrn->scrnIndex, edid_mon);
}
+/* maybe we should care about DDC1? meh. */
_X_EXPORT xf86MonPtr
xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
{
ScrnInfoPtr scrn = output->scrn;
xf86MonPtr mon;
- mon = xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus);
+ mon = xf86DoEEDID(scrn->scrnIndex, pDDCBus, TRUE);
if (mon)
- xf86DDCApplyQuirks (scrn->scrnIndex, mon);
+ xf86DDCApplyQuirks(scrn->scrnIndex, mon);
return mon;
}
@@ -2766,3 +2988,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/xorg-server/hw/xfree86/modes/xf86Crtc.h b/xorg-server/hw/xfree86/modes/xf86Crtc.h
index cc045b229..0a596bc49 100644
--- a/xorg-server/hw/xfree86/modes/xf86Crtc.h
+++ b/xorg-server/hw/xfree86/modes/xf86Crtc.h
@@ -213,10 +213,24 @@ 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 2
+
struct _xf86Crtc {
/**
+ * ABI versioning
+ */
+ int version;
+
+ /**
* Associated ScrnInfo
*/
ScrnInfoPtr scrn;
@@ -298,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 {
@@ -410,6 +447,21 @@ typedef struct _xf86OutputFuncs {
Atom property,
RRPropertyValuePtr value);
#endif
+#ifdef RANDR_13_INTERFACE
+ /**
+ * Callback to get an updated property value
+ */
+ Bool
+ (*get_property)(xf86OutputPtr output,
+ Atom property);
+#endif
+#ifdef RANDR_GET_CRTC_INTERFACE
+ /**
+ * Callback to get current CRTC for a given output
+ */
+ xf86CrtcPtr
+ (*get_crtc)(xf86OutputPtr output);
+#endif
/**
* Clean up driver-specific bits of the output
*/
@@ -417,8 +469,16 @@ typedef struct _xf86OutputFuncs {
(*destroy) (xf86OutputPtr output);
} xf86OutputFuncsRec, *xf86OutputFuncsPtr;
+
+#define XF86_OUTPUT_VERSION 2
+
struct _xf86Output {
/**
+ * ABI versioning
+ */
+ int version;
+
+ /**
* Associated ScrnInfo
*/
ScrnInfoPtr scrn;
@@ -518,6 +578,10 @@ struct _xf86Output {
#else
void *randr_output;
#endif
+ /** Desired initial panning */
+ BoxRec initialTotalArea;
+ BoxRec initialTrackingArea;
+ INT16 initialBorder[4];
};
typedef struct _xf86CrtcConfigFuncs {
@@ -539,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;
@@ -591,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;
@@ -624,15 +693,36 @@ 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
+ */
+void
+xf86RotateFreeShadow(ScrnInfoPtr pScrn);
/*
* Clean up rotation during CloseScreen
@@ -669,7 +759,11 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY);
void
xf86SetScrnInfoModes (ScrnInfoPtr pScrn);
+#ifdef RANDR_13_INTERFACE
+int
+#else
Bool
+#endif
xf86CrtcScreenInit (ScreenPtr pScreen);
Bool
@@ -798,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/xorg-server/hw/xfree86/modes/xf86Cursors.c b/xorg-server/hw/xfree86/modes/xf86Cursors.c
index fee02df38..3106f051b 100644
--- a/xorg-server/hw/xfree86/modes/xf86Cursors.c
+++ b/xorg-server/hw/xfree86/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"
@@ -45,6 +46,7 @@
#include "picturestr.h"
#endif
#include "cursorstr.h"
+#include "inputstr.h"
/*
* Given a screen coordinate, rotate back to a cursor source coordinate
@@ -227,8 +229,13 @@ xf86_set_cursor_colors (ScrnInfoPtr scrn, int bg, int fg)
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
CursorPtr cursor = xf86_config->cursor;
int c;
- CARD8 *bits = cursor ? dixLookupPrivate(&cursor->devPrivates,
- screen) : NULL;
+ CARD8 *bits = cursor ?
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
+ dixLookupPrivate(&cursor->devPrivates, CursorScreenKey(screen))
+#else
+ cursor->devPriv[screen->myNum]
+#endif
+ : NULL;
/* Save ARGB versions of these colors */
xf86_config->cursor_fg = (CARD32) fg | 0xff000000;
@@ -315,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
@@ -589,10 +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 */
- if (!screen)
+ /* 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);
@@ -600,16 +622,16 @@ xf86_reload_cursors (ScreenPtr screen)
cursor_info = xf86_config->cursor_info;
if (!cursor_info)
return;
-
+
cursor = xf86_config->cursor;
- GetSpritePosition (&x, &y);
+ GetSpritePosition (inputInfo.pointer, &x, &y);
if (!(cursor_info->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
(*cursor_info->HideCursor)(scrn);
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
@@ -621,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/xorg-server/hw/xfree86/modes/xf86EdidModes.c b/xorg-server/hw/xfree86/modes/xf86EdidModes.c
index bf0ea3f64..087f66376 100644
--- a/xorg-server/hw/xfree86/modes/xf86EdidModes.c
+++ b/xorg-server/hw/xfree86/modes/xf86EdidModes.c
@@ -1,5 +1,6 @@
/*
* Copyright 2006 Luc Verhaegen.
+ * Copyright 2008 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -34,16 +35,39 @@
#endif
#endif
+#define _PARSE_EDID_
#include "xf86.h"
#include "xf86DDC.h"
#include <X11/Xatom.h>
#include "property.h"
#include "propertyst.h"
-#include "xf86DDC.h"
#include "xf86Crtc.h"
#include <string.h>
#include <math.h>
+static Bool
+xf86MonitorSupportsReducedBlanking(xf86MonPtr DDC)
+{
+ /* EDID 1.4 explicitly defines RB support */
+ if (DDC->ver.revision >= 4) {
+ int i;
+ for (i = 0; i < DET_TIMINGS; i++) {
+ struct detailed_monitor_section *det_mon = &DDC->det_mon[i];
+ if (det_mon->type == DS_RANGES)
+ if (det_mon->section.ranges.supported_blanking & CVT_REDUCED)
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+ /* For anything older, assume digital means RB support. Boo. */
+ if (DDC->features.input_type)
+ return TRUE;
+
+ return FALSE;
+}
+
/*
* Quirks to work around broken EDID data from various monitors.
*/
@@ -68,6 +92,8 @@ typedef enum {
DDC_QUIRK_FIRST_DETAILED_PREFERRED = 1 << 6,
/* use +hsync +vsync for detailed mode */
DDC_QUIRK_DETAILED_SYNC_PP = 1 << 7,
+ /* Force single-link DVI bandwidth limit */
+ DDC_QUIRK_DVI_SINGLE_LINK = 1 << 8,
} ddc_quirk_t;
static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
@@ -129,6 +155,11 @@ static Bool quirk_detailed_v_in_cm (int scrnIndex, xf86MonPtr DDC)
DDC->vendor.prod_id == 13600)
return TRUE;
+ /* Bug #21000: LGPhilipsLCD LP154W01-TLAJ */
+ if (memcmp (DDC->vendor.name, "LPL", 4) == 0 &&
+ DDC->vendor.prod_id == 47360)
+ return TRUE;
+
return FALSE;
}
@@ -139,6 +170,11 @@ static Bool quirk_detailed_use_maximum_size (int scrnIndex, xf86MonPtr DDC)
(DDC->vendor.prod_id == 0 || DDC->vendor.prod_id == 0x2a00))
return TRUE;
+ /* Bug #21324: Iiyama Vision Master 450 */
+ if (memcmp (DDC->vendor.name, "IVM", 4) == 0 &&
+ DDC->vendor.prod_id == 6400)
+ return TRUE;
+
return FALSE;
}
@@ -181,6 +217,16 @@ static Bool quirk_detailed_sync_pp(int scrnIndex, xf86MonPtr DDC)
return FALSE;
}
+/* This should probably be made more generic */
+static Bool quirk_dvi_single_link(int scrnIndex, xf86MonPtr DDC)
+{
+ /* Red Hat bug #453106: Apple 23" Cinema Display */
+ if (memcmp (DDC->vendor.name, "APL", 4) == 0 &&
+ DDC->vendor.prod_id == 0x921c)
+ return TRUE;
+ return FALSE;
+}
+
typedef struct {
Bool (*detect) (int scrnIndex, xf86MonPtr DDC);
ddc_quirk_t quirk;
@@ -220,6 +266,10 @@ static const ddc_quirk_map_t ddc_quirks[] = {
quirk_detailed_sync_pp, DDC_QUIRK_DETAILED_SYNC_PP,
"Use +hsync +vsync for detailed timing."
},
+ {
+ quirk_dvi_single_link, DDC_QUIRK_DVI_SINGLE_LINK,
+ "Forcing maximum pixel clock to single DVI link."
+ },
{
NULL, DDC_QUIRK_NONE,
"No known quirks"
@@ -227,8 +277,13 @@ static const ddc_quirk_map_t ddc_quirks[] = {
};
/*
- * TODO:
- * - for those with access to the VESA DMT standard; review please.
+ * These more or less come from the DMT spec. The 720x400 modes are
+ * inferred from historical 80x25 practice. The 640x480@67 and 832x624@75
+ * modes are old-school Mac modes. The EDID spec says the 1152x864@75 mode
+ * should be 1152x870, again for the Mac, but instead we use the x864 DMT
+ * mode.
+ *
+ * The DMT modes have been fact-checked; the rest are mild guesses.
*/
#define MODEPREFIX NULL, NULL, NULL, 0, M_T_DRIVER
#define MODESUFFIX 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0
@@ -237,16 +292,16 @@ static const DisplayModeRec DDCEstablishedModes[17] = {
{ MODEPREFIX, 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@60Hz */
{ MODEPREFIX, 36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@56Hz */
{ MODEPREFIX, 31500, 640, 656, 720, 840, 0, 480, 481, 484, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@75Hz */
- { MODEPREFIX, 31500, 640, 664, 704, 832, 0, 480, 489, 491, 520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@72Hz */
+ { MODEPREFIX, 31500, 640, 664, 704, 832, 0, 480, 489, 492, 520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@72Hz */
{ MODEPREFIX, 30240, 640, 704, 768, 864, 0, 480, 483, 486, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@67Hz */
- { MODEPREFIX, 25200, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@60Hz */
+ { MODEPREFIX, 25175, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@60Hz */
{ MODEPREFIX, 35500, 720, 738, 846, 900, 0, 400, 421, 423, 449, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 720x400@88Hz */
{ MODEPREFIX, 28320, 720, 738, 846, 900, 0, 400, 412, 414, 449, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400@70Hz */
{ MODEPREFIX, 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@75Hz */
- { MODEPREFIX, 78800, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@75Hz */
+ { MODEPREFIX, 78750, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@75Hz */
{ MODEPREFIX, 75000, 1024, 1048, 1184, 1328, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@70Hz */
{ MODEPREFIX, 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@60Hz */
- { MODEPREFIX, 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 776, 817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768@43Hz */
+ { MODEPREFIX, 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 772, 817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768@43Hz */
{ MODEPREFIX, 57284, 832, 864, 928, 1152, 0, 624, 625, 628, 667, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 832x624@75Hz */
{ MODEPREFIX, 49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@75Hz */
{ MODEPREFIX, 50000, 800, 856, 976, 1040, 0, 600, 637, 643, 666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@72Hz */
@@ -272,6 +327,90 @@ DDCModesFromEstablished(int scrnIndex, struct established_timings *timing,
return Modes;
}
+/* Autogenerated from the DMT spec */
+static const DisplayModeRec DMTModes[] = {
+ { MODEPREFIX, 31500, 640, 672, 736, 832, 0, 350, 382, 385, 445, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x350@85Hz */
+ { MODEPREFIX, 31500, 640, 672, 736, 832, 0, 400, 401, 404, 445, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 640x400@85Hz */
+ { MODEPREFIX, 35500, 720, 756, 828, 936, 0, 400, 401, 404, 446, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400@85Hz */
+ { MODEPREFIX, 25175, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@60Hz */
+ { MODEPREFIX, 31500, 640, 664, 704, 832, 0, 480, 489, 492, 520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@72Hz */
+ { MODEPREFIX, 31500, 640, 656, 720, 840, 0, 480, 481, 484, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@75Hz */
+ { MODEPREFIX, 36000, 640, 696, 752, 832, 0, 480, 481, 484, 509, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@85Hz */
+ { MODEPREFIX, 36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@56Hz */
+ { MODEPREFIX, 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@60Hz */
+ { MODEPREFIX, 50000, 800, 856, 976, 1040, 0, 600, 637, 643, 666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@72Hz */
+ { MODEPREFIX, 49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@75Hz */
+ { MODEPREFIX, 56250, 800, 832, 896, 1048, 0, 600, 601, 604, 631, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@85Hz */
+ { MODEPREFIX, 73250, 800, 848, 880, 960, 0, 600, 603, 607, 636, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 800x600@120Hz RB */
+ { MODEPREFIX, 33750, 848, 864, 976, 1088, 0, 480, 486, 494, 517, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 848x480@60Hz */
+ { MODEPREFIX, 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 772, 817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768@43Hz (interlaced) */
+ { MODEPREFIX, 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@60Hz */
+ { MODEPREFIX, 75000, 1024, 1048, 1184, 1328, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@70Hz */
+ { MODEPREFIX, 78750, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@75Hz */
+ { MODEPREFIX, 94500, 1024, 1072, 1168, 1376, 0, 768, 769, 772, 808, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@85Hz */
+ { MODEPREFIX, 115500, 1024, 1072, 1104, 1184, 0, 768, 771, 775, 813, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@120Hz RB */
+ { MODEPREFIX, 108000, 1152, 1216, 1344, 1600, 0, 864, 865, 868, 900, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1152x864@75Hz */
+ { MODEPREFIX, 68250, 1280, 1328, 1360, 1440, 0, 768, 771, 778, 790, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x768@60Hz RB */
+ { MODEPREFIX, 79500, 1280, 1344, 1472, 1664, 0, 768, 771, 778, 798, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x768@60Hz */
+ { MODEPREFIX, 102250, 1280, 1360, 1488, 1696, 0, 768, 771, 778, 805, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x768@75Hz */
+ { MODEPREFIX, 117500, 1280, 1360, 1496, 1712, 0, 768, 771, 778, 809, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x768@85Hz */
+ { MODEPREFIX, 140250, 1280, 1328, 1360, 1440, 0, 768, 771, 778, 813, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x768@120Hz RB */
+ { MODEPREFIX, 71000, 1280, 1328, 1360, 1440, 0, 800, 803, 809, 823, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x800@60Hz RB */
+ { MODEPREFIX, 83500, 1280, 1352, 1480, 1680, 0, 800, 803, 809, 831, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x800@60Hz */
+ { MODEPREFIX, 106500, 1280, 1360, 1488, 1696, 0, 800, 803, 809, 838, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x800@75Hz */
+ { MODEPREFIX, 122500, 1280, 1360, 1496, 1712, 0, 800, 803, 809, 843, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x800@85Hz */
+ { MODEPREFIX, 146250, 1280, 1328, 1360, 1440, 0, 800, 803, 809, 847, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x800@120Hz RB */
+ { MODEPREFIX, 108000, 1280, 1376, 1488, 1800, 0, 960, 961, 964, 1000, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x960@60Hz */
+ { MODEPREFIX, 148500, 1280, 1344, 1504, 1728, 0, 960, 961, 964, 1011, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x960@85Hz */
+ { MODEPREFIX, 175500, 1280, 1328, 1360, 1440, 0, 960, 963, 967, 1017, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x960@120Hz RB */
+ { MODEPREFIX, 108000, 1280, 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@60Hz */
+ { MODEPREFIX, 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@75Hz */
+ { MODEPREFIX, 157500, 1280, 1344, 1504, 1728, 0, 1024, 1025, 1028, 1072, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@85Hz */
+ { MODEPREFIX, 187250, 1280, 1328, 1360, 1440, 0, 1024, 1027, 1034, 1084, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x1024@120Hz RB */
+ { MODEPREFIX, 85500, 1360, 1424, 1536, 1792, 0, 768, 771, 777, 795, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1360x768@60Hz */
+ { MODEPREFIX, 148250, 1360, 1408, 1440, 1520, 0, 768, 771, 776, 813, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1360x768@120Hz RB */
+ { MODEPREFIX, 101000, 1400, 1448, 1480, 1560, 0, 1050, 1053, 1057, 1080, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1400x1050@60Hz RB */
+ { MODEPREFIX, 121750, 1400, 1488, 1632, 1864, 0, 1050, 1053, 1057, 1089, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1400x1050@60Hz */
+ { MODEPREFIX, 156000, 1400, 1504, 1648, 1896, 0, 1050, 1053, 1057, 1099, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1400x1050@75Hz */
+ { MODEPREFIX, 179500, 1400, 1504, 1656, 1912, 0, 1050, 1053, 1057, 1105, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1400x1050@85Hz */
+ { MODEPREFIX, 208000, 1400, 1448, 1480, 1560, 0, 1050, 1053, 1057, 1112, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1400x1050@120Hz RB */
+ { MODEPREFIX, 88750, 1440, 1488, 1520, 1600, 0, 900, 903, 909, 926, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1440x900@60Hz RB */
+ { MODEPREFIX, 106500, 1440, 1520, 1672, 1904, 0, 900, 903, 909, 934, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1440x900@60Hz */
+ { MODEPREFIX, 136750, 1440, 1536, 1688, 1936, 0, 900, 903, 909, 942, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1440x900@75Hz */
+ { MODEPREFIX, 157000, 1440, 1544, 1696, 1952, 0, 900, 903, 909, 948, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1440x900@85Hz */
+ { MODEPREFIX, 182750, 1440, 1488, 1520, 1600, 0, 900, 903, 909, 953, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1440x900@120Hz RB */
+ { MODEPREFIX, 162000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@60Hz */
+ { MODEPREFIX, 175500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@65Hz */
+ { MODEPREFIX, 189000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@70Hz */
+ { MODEPREFIX, 202500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@75Hz */
+ { MODEPREFIX, 229500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@85Hz */
+ { MODEPREFIX, 268250, 1600, 1648, 1680, 1760, 0, 1200, 1203, 1207, 1271, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1600x1200@120Hz RB */
+ { MODEPREFIX, 119000, 1680, 1728, 1760, 1840, 0, 1050, 1053, 1059, 1080, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1680x1050@60Hz RB */
+ { MODEPREFIX, 146250, 1680, 1784, 1960, 2240, 0, 1050, 1053, 1059, 1089, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1680x1050@60Hz */
+ { MODEPREFIX, 187000, 1680, 1800, 1976, 2272, 0, 1050, 1053, 1059, 1099, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1680x1050@75Hz */
+ { MODEPREFIX, 214750, 1680, 1808, 1984, 2288, 0, 1050, 1053, 1059, 1105, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1680x1050@85Hz */
+ { MODEPREFIX, 245500, 1680, 1728, 1760, 1840, 0, 1050, 1053, 1059, 1112, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1680x1050@120Hz RB */
+ { MODEPREFIX, 204750, 1792, 1920, 2120, 2448, 0, 1344, 1345, 1348, 1394, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1792x1344@60Hz */
+ { MODEPREFIX, 261000, 1792, 1888, 2104, 2456, 0, 1344, 1345, 1348, 1417, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1792x1344@75Hz */
+ { MODEPREFIX, 333250, 1792, 1840, 1872, 1952, 0, 1344, 1347, 1351, 1423, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1792x1344@120Hz RB */
+ { MODEPREFIX, 218250, 1856, 1952, 2176, 2528, 0, 1392, 1393, 1396, 1439, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1856x1392@60Hz */
+ { MODEPREFIX, 288000, 1856, 1984, 2208, 2560, 0, 1392, 1393, 1396, 1500, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1856x1392@75Hz */
+ { MODEPREFIX, 356500, 1856, 1904, 1936, 2016, 0, 1392, 1395, 1399, 1474, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1856x1392@120Hz RB */
+ { MODEPREFIX, 154000, 1920, 1968, 2000, 2080, 0, 1200, 1203, 1209, 1235, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1920x1200@60Hz RB */
+ { MODEPREFIX, 193250, 1920, 2056, 2256, 2592, 0, 1200, 1203, 1209, 1245, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1200@60Hz */
+ { MODEPREFIX, 245250, 1920, 2056, 2264, 2608, 0, 1200, 1203, 1209, 1255, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1200@75Hz */
+ { MODEPREFIX, 281250, 1920, 2064, 2272, 2624, 0, 1200, 1203, 1209, 1262, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1200@85Hz */
+ { MODEPREFIX, 317000, 1920, 1968, 2000, 2080, 0, 1200, 1203, 1209, 1271, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1920x1200@120Hz RB */
+ { MODEPREFIX, 234000, 1920, 2048, 2256, 2600, 0, 1440, 1441, 1444, 1500, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1440@60Hz */
+ { MODEPREFIX, 297000, 1920, 2064, 2288, 2640, 0, 1440, 1441, 1444, 1500, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1440@75Hz */
+ { MODEPREFIX, 380500, 1920, 1968, 2000, 2080, 0, 1440, 1443, 1447, 1525, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1920x1440@120Hz RB */
+ { MODEPREFIX, 268500, 2560, 2608, 2640, 2720, 0, 1600, 1603, 1609, 1646, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 2560x1600@60Hz RB */
+ { MODEPREFIX, 348500, 2560, 2752, 3032, 3504, 0, 1600, 1603, 1609, 1658, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 2560x1600@60Hz */
+ { MODEPREFIX, 443250, 2560, 2768, 3048, 3536, 0, 1600, 1603, 1609, 1672, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 2560x1600@75Hz */
+ { MODEPREFIX, 505250, 2560, 2768, 3048, 3536, 0, 1600, 1603, 1609, 1682, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 2560x1600@85Hz */
+ { MODEPREFIX, 552750, 2560, 2608, 2640, 2720, 0, 1600, 1603, 1609, 1694, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 2560x1600@120Hz RB */
+};
+
#define LEVEL_DMT 0
#define LEVEL_GTF 1
#define LEVEL_CVT 2
@@ -288,12 +427,43 @@ MonitorStandardTimingLevel(xf86MonPtr DDC)
return LEVEL_DMT;
}
+static int
+ModeRefresh(const DisplayModeRec *mode)
+{
+ return (int)(xf86ModeVRefresh(mode) + 0.5);
+}
+
/*
- * This is not really correct. Appendix B of the EDID 1.4 spec defines
- * the right thing to do here. If the timing given here matches a mode
- * defined in the VESA DMT standard, we _must_ use that. If the device
- * supports CVT modes, then we should generate a CVT timing. If both
- * of the above fail, use GTF.
+ * If rb is not set, then we'll not consider reduced-blanking modes as
+ * part of the DMT pool. For the 'standard' EDID mode descriptor there's
+ * no way to specify whether the mode should be RB or not.
+ */
+static DisplayModePtr
+FindDMTMode(int hsize, int vsize, int refresh, Bool rb)
+{
+ int i;
+ const DisplayModeRec *ret;
+
+ for (i = 0; i < sizeof(DMTModes) / sizeof(DisplayModeRec); i++) {
+ ret = &DMTModes[i];
+
+ if (!rb && xf86ModeIsReduced(ret))
+ continue;
+
+ if (ret->HDisplay == hsize &&
+ ret->VDisplay == vsize &&
+ refresh == ModeRefresh(ret))
+ return xf86DuplicateMode(ret);
+ }
+
+ return NULL;
+}
+
+/*
+ * Appendix B of the EDID 1.4 spec defines the right thing to do here.
+ * If the timing given here matches a mode defined in the VESA DMT standard,
+ * we _must_ use that. If the device supports CVT modes, then we should
+ * generate a CVT timing. If both of the above fail, use GTF.
*
* There are some wrinkles here. EDID 1.1 and 1.0 sinks can't really
* "support" GTF, since it wasn't a standard yet; so if they ask for a
@@ -308,20 +478,28 @@ MonitorStandardTimingLevel(xf86MonPtr DDC)
*/
static DisplayModePtr
DDCModesFromStandardTiming(struct std_timings *timing, ddc_quirk_t quirks,
- int timing_level)
+ int timing_level, Bool rb)
{
DisplayModePtr Modes = NULL, Mode = NULL;
int i;
for (i = 0; i < STD_TIMINGS; i++) {
if (timing[i].hsize && timing[i].vsize && timing[i].refresh) {
- /* XXX check for DMT first, else... */
- if (timing_level == LEVEL_CVT)
- Mode = xf86CVTMode(timing[i].hsize, timing[i].vsize,
- timing[i].refresh, FALSE, FALSE);
- else
- Mode = xf86GTFMode(timing[i].hsize, timing[i].vsize,
- timing[i].refresh, FALSE, FALSE);
+ Mode = FindDMTMode(timing[i].hsize, timing[i].vsize,
+ timing[i].refresh, rb);
+
+ if (!Mode) {
+ if (timing_level == LEVEL_CVT)
+ /* pass rb here too? */
+ Mode = xf86CVTMode(timing[i].hsize, timing[i].vsize,
+ timing[i].refresh, FALSE, FALSE);
+ else if (timing_level == LEVEL_GTF)
+ Mode = xf86GTFMode(timing[i].hsize, timing[i].vsize,
+ timing[i].refresh, FALSE, FALSE);
+ }
+
+ if (!Mode)
+ continue;
Mode->type = M_T_DRIVER;
Modes = xf86ModesAdd(Modes, Mode);
@@ -363,7 +541,7 @@ DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
/* We only do seperate sync currently */
if (timing->sync != 0x03) {
xf86DrvMsg(scrnIndex, X_INFO,
- "%s: %dx%d Warning: We only handle seperate"
+ "%s: %dx%d Warning: We only handle separate"
" sync.\n", __func__, timing->h_active, timing->v_active);
}
@@ -419,6 +597,7 @@ DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
return Mode;
}
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
static DisplayModePtr
DDCModesFromCVT(int scrnIndex, struct cvt_timings *t)
{
@@ -447,7 +626,87 @@ DDCModesFromCVT(int scrnIndex, struct cvt_timings *t)
return modes;
}
+#endif
+
+static const struct {
+ short w;
+ short h;
+ short r;
+ short rb;
+} EstIIIModes[] = {
+ /* byte 6 */
+ { 640, 350, 85, 0 },
+ { 640, 400, 85, 0 },
+ { 720, 400, 85, 0 },
+ { 640, 480, 85, 0 },
+ { 848, 480, 60, 0 },
+ { 800, 600, 85, 0 },
+ { 1024, 768, 85, 0 },
+ { 1152, 864, 75, 0 },
+ /* byte 7 */
+ { 1280, 768, 60, 1 },
+ { 1280, 768, 60, 0 },
+ { 1280, 768, 75, 0 },
+ { 1280, 768, 85, 0 },
+ { 1280, 960, 60, 0 },
+ { 1280, 960, 85, 0 },
+ { 1280, 1024, 60, 0 },
+ { 1280, 1024, 85, 0 },
+ /* byte 8 */
+ { 1360, 768, 60, 0 },
+ { 1440, 900, 60, 1 },
+ { 1440, 900, 60, 0 },
+ { 1440, 900, 75, 0 },
+ { 1440, 900, 85, 0 },
+ { 1400, 1050, 60, 1 },
+ { 1400, 1050, 60, 0 },
+ { 1400, 1050, 75, 0 },
+ /* byte 9 */
+ { 1400, 1050, 85, 0 },
+ { 1680, 1050, 60, 1 },
+ { 1680, 1050, 60, 0 },
+ { 1680, 1050, 75, 0 },
+ { 1680, 1050, 85, 0 },
+ { 1600, 1200, 60, 0 },
+ { 1600, 1200, 65, 0 },
+ { 1600, 1200, 70, 0 },
+ /* byte 10 */
+ { 1600, 1200, 75, 0 },
+ { 1600, 1200, 85, 0 },
+ { 1792, 1344, 60, 0 },
+ { 1792, 1344, 85, 0 },
+ { 1856, 1392, 60, 0 },
+ { 1856, 1392, 75, 0 },
+ { 1920, 1200, 60, 1 },
+ { 1920, 1200, 60, 0 },
+ /* byte 11 */
+ { 1920, 1200, 75, 0 },
+ { 1920, 1200, 85, 0 },
+ { 1920, 1440, 60, 0 },
+ { 1920, 1440, 75, 0 },
+};
+
+static DisplayModePtr
+DDCModesFromEstIII(unsigned char *est)
+{
+ DisplayModePtr modes = NULL;
+ int i, j, m;
+
+ for (i = 0; i < 6; i++) {
+ for (j = 7; j > 0; j--) {
+ if (est[i] & (1 << j)) {
+ m = (i * 8) + (7 - j);
+ modes = xf86ModesAdd(modes,
+ FindDMTMode(EstIIIModes[m].w,
+ EstIIIModes[m].h,
+ EstIIIModes[m].r,
+ EstIIIModes[m].rb));
+ }
+ }
+ }
+ return modes;
+}
/*
* This is only valid when the sink claims to be continuous-frequency
@@ -595,7 +854,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
int i;
DisplayModePtr Modes = NULL, Mode;
ddc_quirk_t quirks;
- Bool preferred;
+ Bool preferred, rb;
int timing_level;
xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n",
@@ -611,11 +870,14 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
if (quirks & (DDC_QUIRK_PREFER_LARGE_60 | DDC_QUIRK_PREFER_LARGE_75))
preferred = FALSE;
+ rb = xf86MonitorSupportsReducedBlanking(DDC);
+
timing_level = MonitorStandardTimingLevel(DDC);
for (i = 0; i < DET_TIMINGS; i++) {
struct detailed_monitor_section *det_mon = &DDC->det_mon[i];
+ Mode = NULL;
switch (det_mon->type) {
case DT:
Mode = DDCModeFromDetailedTiming(scrnIndex,
@@ -623,20 +885,23 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
preferred,
quirks);
preferred = FALSE;
- Modes = xf86ModesAdd(Modes, Mode);
break;
case DS_STD_TIMINGS:
Mode = DDCModesFromStandardTiming(det_mon->section.std_t,
- quirks, timing_level);
- Modes = xf86ModesAdd(Modes, Mode);
+ quirks, timing_level, rb);
break;
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
case DS_CVT:
Mode = DDCModesFromCVT(scrnIndex, det_mon->section.cvt);
- Modes = xf86ModesAdd(Modes, Mode);
+ break;
+#endif
+ case DS_EST_III:
+ Mode = DDCModesFromEstIII(det_mon->section.est_iii);
break;
default:
break;
}
+ Modes = xf86ModesAdd(Modes, Mode);
}
/* Add established timings */
@@ -644,7 +909,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
Modes = xf86ModesAdd(Modes, Mode);
/* Add standard timings */
- Mode = DDCModesFromStandardTiming(DDC->timings2, quirks, timing_level);
+ Mode = DDCModesFromStandardTiming(DDC->timings2, quirks, timing_level, rb);
Modes = xf86ModesAdd(Modes, Mode);
if (quirks & DDC_QUIRK_PREFER_LARGE_60)
@@ -665,23 +930,21 @@ xf86DDCMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC)
DisplayModePtr Modes = NULL, Mode;
int i, clock;
Bool have_hsync = FALSE, have_vrefresh = FALSE, have_maxpixclock = FALSE;
+ ddc_quirk_t quirks;
if (!Monitor || !DDC)
return;
Monitor->DDC = DDC;
+ quirks = xf86DDCDetectQuirks(scrnIndex, DDC, FALSE);
+
if (Monitor->widthmm <= 0 && Monitor->heightmm <= 0) {
Monitor->widthmm = 10 * DDC->features.hsize;
Monitor->heightmm = 10 * DDC->features.vsize;
}
- /*
- * If this is a digital display, then we can use reduced blanking.
- * XXX This is a 1.3 heuristic. 1.4 explicitly defines rb support.
- */
- if (DDC->features.input_type)
- Monitor->reducedblanking = TRUE;
+ Monitor->reducedblanking = xf86MonitorSupportsReducedBlanking(DDC);
Modes = xf86DDCGetModes(scrnIndex, DDC);
@@ -723,6 +986,8 @@ xf86DDCMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC)
}
clock = DDC->det_mon[i].section.ranges.max_clock * 1000;
+ if (quirks & DDC_QUIRK_DVI_SINGLE_LINK)
+ clock = min(clock, 165000);
if (!have_maxpixclock && clock > Monitor->maxPixClock)
Monitor->maxPixClock = clock;
diff --git a/xorg-server/hw/xfree86/modes/xf86Modes.c b/xorg-server/hw/xfree86/modes/xf86Modes.c
index ea398ad81..1522fa731 100644
--- a/xorg-server/hw/xfree86/modes/xf86Modes.c
+++ b/xorg-server/hw/xfree86/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 &&
@@ -509,10 +509,27 @@ xf86ValidateModesBandwidth(ScrnInfoPtr pScrn, DisplayModePtr modeList,
for (mode = modeList; mode != NULL; mode = mode->next) {
if (xf86ModeBandwidth(mode, depth) > bandwidth)
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
mode->status = MODE_BANDWIDTH;
+#else
+ /* MODE_BANDWIDTH didn't exist in xserver 1.2 */
+ mode->status = MODE_BAD;
+#endif
}
}
+Bool
+xf86ModeIsReduced(const DisplayModeRec *mode)
+{
+ if ((((mode->HDisplay * 5 / 4) & ~0x07) > mode->HTotal) &&
+ ((mode->HTotal - mode->HDisplay) == 160) &&
+ ((mode->HSyncEnd - mode->HDisplay) == 80) &&
+ ((mode->HSyncEnd - mode->HSyncStart) == 32) &&
+ ((mode->VSyncStart - mode->VDisplay) == 3))
+ return TRUE;
+ return FALSE;
+}
+
/**
* Marks as bad any reduced-blanking modes.
*
@@ -521,7 +538,6 @@ xf86ValidateModesBandwidth(ScrnInfoPtr pScrn, DisplayModePtr modeList,
_X_EXPORT void
xf86ValidateModesReducedBlanking(ScrnInfoPtr pScrn, DisplayModePtr modeList)
{
- Bool mode_is_reduced = FALSE;
DisplayModePtr mode;
for (mode = modeList; mode != NULL; mode = mode->next) {
@@ -677,12 +693,12 @@ xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor)
_X_EXPORT DisplayModePtr
xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed)
{
- DisplayModePtr head = NULL, prev = NULL, mode;
+ DisplayModePtr head = NULL, mode;
int i;
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/xorg-server/hw/xfree86/modes/xf86Modes.h b/xorg-server/hw/xfree86/modes/xf86Modes.h
index acdea65d8..2fb6a374d 100644
--- a/xorg-server/hw/xfree86/modes/xf86Modes.h
+++ b/xorg-server/hw/xfree86/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);
@@ -64,6 +65,9 @@ DisplayModePtr xf86CVTMode(int HDisplay, int VDisplay, float VRefresh,
Bool Reduced, Bool Interlaced);
DisplayModePtr xf86GTFMode(int h_pixels, int v_lines, float freq, int interlaced, int margins);
+Bool
+xf86ModeIsReduced(const DisplayModeRec *mode);
+
void
xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
int flags);
diff --git a/xorg-server/hw/xfree86/modes/xf86RandR12.c b/xorg-server/hw/xfree86/modes/xf86RandR12.c
index 6f8ccdf84..454649213 100644
--- a/xorg-server/hw/xfree86/modes/xf86RandR12.c
+++ b/xorg-server/hw/xfree86/modes/xf86RandR12.c
@@ -37,6 +37,7 @@
#include "xf86DDC.h"
#include "mipointer.h"
#include "windowstr.h"
+#include "inputstr.h"
#include <randrstr.h>
#include <X11/extensions/render.h>
@@ -50,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;
@@ -60,11 +63,22 @@ static Bool xf86RandR12CreateScreenResources12 (ScreenPtr pScreen);
#endif
static int xf86RandR12Generation;
-static DevPrivateKey xf86RandR12Key;
+#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))
+#else /* XORG_VERSION_CURRENT < 7.0 */
+
+static int xf86RandR12Index;
+#define XF86RANDRINFO(p) \
+ ((XF86RandRInfoPtr)(p)->devPrivates[xf86RandR12Index].ptr)
+
+#endif /* XORG_VERSION_CURRENT < 7.0 */
+
+
static int
xf86RandR12ModeRefresh (DisplayModePtr mode)
{
@@ -74,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)
{
@@ -247,7 +610,7 @@ xf86RandR12SetConfig (ScreenPtr pScreen,
randrp->virtualY = scrp->virtualY;
}
- miPointerPosition (&px, &py);
+ miPointerGetPosition (inputInfo.pointer, &px, &py);
for (mode = scrp->modes; ; mode = mode->next)
{
if (randrp->maxX == 0 || randrp->maxY == 0)
@@ -294,14 +657,14 @@ xf86RandR12SetConfig (ScreenPtr pScreen,
/*
* Move the cursor back where it belongs; SwitchMode repositions it
*/
- if (pScreen == miPointerCurrentScreen ())
+ if (pScreen == miPointerGetScreen(inputInfo.pointer))
{
px = (px >= pScreen->width ? (pScreen->width - 1) : px);
py = (py >= pScreen->height ? (pScreen->height - 1) : py);
xf86SetViewport(pScreen, px, py);
- (*pScreen->SetCursorPosition) (pScreen, px, py, FALSE);
+ (*pScreen->SetCursorPosition) (inputInfo.pointer, pScreen, px, py, FALSE);
}
return TRUE;
@@ -320,14 +683,19 @@ 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) {
+#endif
if (randrp->virtualX == -1 || randrp->virtualY == -1)
{
randrp->virtualX = pScrn->virtualX;
randrp->virtualY = pScrn->virtualY;
}
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
}
+#endif
if (pRoot && pScrn->vtSema)
(*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
@@ -336,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;
@@ -367,8 +752,8 @@ _X_EXPORT Bool
xf86RandR12CreateScreenResources (ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ xf86CrtcConfigPtr config;
+ XF86RandRInfoPtr randrp;
int c;
int width, height;
int mmWidth, mmHeight;
@@ -378,6 +763,8 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen)
return TRUE;
#endif
+ config = XF86_CRTC_CONFIG_PTR(pScrn);
+ randrp = XF86RANDRINFO(pScreen);
/*
* Compute size of screen
*/
@@ -388,10 +775,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)
@@ -442,6 +835,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,
@@ -449,8 +849,10 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen)
mmHeight);
}
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
if (xf86RandR12Key == NULL)
return TRUE;
+#endif
if (randrp->virtualX == -1 || randrp->virtualY == -1)
{
@@ -481,7 +883,11 @@ xf86RandR12Init (ScreenPtr pScreen)
if (xf86RandR12Generation != serverGeneration)
xf86RandR12Generation = serverGeneration;
- xf86RandR12Key = &xf86RandR12Key;
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
+ xf86RandR12Key = &xf86RandR12KeyIndex;
+#else
+ xf86RandR12Index = AllocateScreenPrivateIndex();
+#endif
randrp = xalloc (sizeof (XF86RandRInfoRec));
if (!randrp)
@@ -507,7 +913,11 @@ xf86RandR12Init (ScreenPtr pScreen)
randrp->maxX = randrp->maxY = 0;
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
dixSetPrivate(&pScreen->devPrivates, xf86RandR12Key, randrp);
+#else
+ pScreen->devPrivates[xf86RandR12Index].ptr = randrp;
+#endif
#if RANDR_12_INTERFACE
if (!xf86RandR12Init12 (pScreen))
@@ -526,8 +936,10 @@ xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations)
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_12_INTERFACE
@@ -541,6 +953,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];
@@ -662,7 +1099,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;
}
@@ -698,18 +1137,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;
@@ -727,6 +1168,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++)
@@ -764,9 +1212,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++)
@@ -777,11 +1226,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;
}
@@ -832,6 +1289,20 @@ xf86RandR12OutputSetProperty (ScreenPtr pScreen,
}
static Bool
+xf86RandR13OutputGetProperty (ScreenPtr pScreen,
+ RROutputPtr randr_output,
+ Atom property)
+{
+ xf86OutputPtr output = randr_output->devPrivate;
+
+ if (output->funcs->get_property == NULL)
+ return TRUE;
+
+ /* Should be safe even w/o vtSema */
+ return output->funcs->get_property(output, property);
+}
+
+static Bool
xf86RandR12OutputValidateMode (ScreenPtr pScreen,
RROutputPtr randr_output,
RRModePtr randr_mode)
@@ -1060,8 +1531,10 @@ xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
if (xf86RandR12Key == NULL)
return TRUE;
+#endif
for (c = 0; c < config->num_crtc; c++)
xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
@@ -1083,8 +1556,13 @@ xf86RandR12TellChanged (ScreenPtr pScreen)
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
int c;
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
if (xf86RandR12Key == NULL)
return;
+#else
+ if (!XF86RANDRINFO(pScreen))
+ return;
+#endif
xf86RandR12SetInfo12 (pScreen);
for (c = 0; c < config->num_crtc; c++)
@@ -1096,6 +1574,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
@@ -1110,6 +1659,11 @@ xf86RandR12Init12 (ScreenPtr pScreen)
rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
rp->rrOutputSetProperty = xf86RandR12OutputSetProperty;
rp->rrOutputValidateMode = xf86RandR12OutputValidateMode;
+#if RANDR_13_INTERFACE
+ rp->rrOutputGetProperty = xf86RandR13OutputGetProperty;
+ rp->rrGetPanning = xf86RandR13GetPanning;
+ rp->rrSetPanning = xf86RandR13SetPanning;
+#endif
rp->rrModeDestroy = xf86RandR12ModeDestroy;
rp->rrSetConfig = NULL;
pScrn->PointerMoved = xf86RandR12PointerMoved;
diff --git a/xorg-server/hw/xfree86/modes/xf86RandR12.h b/xorg-server/hw/xfree86/modes/xf86RandR12.h
index 4fd855cf5..17a2dcc7f 100644
--- a/xorg-server/hw/xfree86/modes/xf86RandR12.h
+++ b/xorg-server/hw/xfree86/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/xorg-server/hw/xfree86/modes/xf86Rename.h b/xorg-server/hw/xfree86/modes/xf86Rename.h
index b8c1d70ef..e3418caad 100644
--- a/xorg-server/hw/xfree86/modes/xf86Rename.h
+++ b/xorg-server/hw/xfree86/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/xorg-server/hw/xfree86/modes/xf86Rotate.c b/xorg-server/hw/xfree86/modes/xf86Rotate.c
index e2d6295b9..6be77d556 100644
--- a/xorg-server/hw/xfree86/modes/xf86Rotate.c
+++ b/xorg-server/hw/xfree86/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;
@@ -457,8 +293,7 @@ xf86RotateDestroy (xf86CrtcPtr crtc)
}
for (c = 0; c < xf86_config->num_crtc; c++)
- if (xf86_config->crtc[c]->rotatedPixmap ||
- xf86_config->crtc[c]->rotatedData)
+ if (xf86_config->crtc[c]->transform_in_use)
return;
/*
@@ -479,6 +314,24 @@ xf86RotateDestroy (xf86CrtcPtr crtc)
}
_X_EXPORT void
+xf86RotateFreeShadow(ScrnInfoPtr pScrn)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int c;
+
+ for (c = 0; c < config->num_crtc; c++) {
+ xf86CrtcPtr crtc = config->crtc[c];
+
+ if (crtc->rotatedPixmap || crtc->rotatedData) {
+ crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
+ crtc->rotatedData);
+ crtc->rotatedPixmap = NULL;
+ crtc->rotatedData = NULL;
+ }
+ }
+}
+
+_X_EXPORT void
xf86RotateCloseScreen (ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
@@ -489,112 +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)
+ 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))
{
- 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))
- {
- 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
{
- 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
*/
- int width = mode->HDisplay;
- int height = mode->VDisplay;
+ 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)
{
@@ -613,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 */
@@ -626,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:
@@ -647,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/xorg-server/hw/xfree86/modes/xf86gtf.c b/xorg-server/hw/xfree86/modes/xf86gtf.c
index acbac83b6..fed56bd12 100644
--- a/xorg-server/hw/xfree86/modes/xf86gtf.c
+++ b/xorg-server/hw/xfree86/modes/xf86gtf.c
@@ -62,6 +62,10 @@
#ifdef HAVE_XORG_CONFIG_H
# include <xorg-config.h>
+#else
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#endif
#include "xf86.h"