aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/randr
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/randr')
-rw-r--r--xorg-server/randr/Makefile.am6
-rw-r--r--xorg-server/randr/Makefile.in89
-rw-r--r--xorg-server/randr/mirandr.c13
-rw-r--r--xorg-server/randr/randr.c27
-rw-r--r--xorg-server/randr/randrstr.h116
-rw-r--r--xorg-server/randr/rrcrtc.c501
-rw-r--r--xorg-server/randr/rrdispatch.c15
-rw-r--r--xorg-server/randr/rrinfo.c12
-rw-r--r--xorg-server/randr/rrmode.c3
-rw-r--r--xorg-server/randr/rroutput.c107
-rw-r--r--xorg-server/randr/rrpointer.c33
-rw-r--r--xorg-server/randr/rrproperty.c26
-rw-r--r--xorg-server/randr/rrscreen.c56
-rw-r--r--xorg-server/randr/rrsdispatch.c107
-rw-r--r--xorg-server/randr/rrtransform.c285
-rw-r--r--xorg-server/randr/rrtransform.h75
-rw-r--r--xorg-server/randr/rrxinerama.c81
17 files changed, 1369 insertions, 183 deletions
diff --git a/xorg-server/randr/Makefile.am b/xorg-server/randr/Makefile.am
index 20b0f72e0..1f1bea082 100644
--- a/xorg-server/randr/Makefile.am
+++ b/xorg-server/randr/Makefile.am
@@ -5,7 +5,7 @@ AM_CFLAGS = $(DIX_CFLAGS)
XINERAMA_SRCS = rrxinerama.c
if XORG
-sdk_HEADERS = randrstr.h
+sdk_HEADERS = randrstr.h rrtransform.h
endif
librandr_la_SOURCES = \
@@ -20,7 +20,9 @@ librandr_la_SOURCES = \
rrpointer.c \
rrproperty.c \
rrscreen.c \
- rrsdispatch.c
+ rrsdispatch.c \
+ rrtransform.h \
+ rrtransform.c
if XINERAMA
librandr_la_SOURCES += ${XINERAMA_SRCS}
diff --git a/xorg-server/randr/Makefile.in b/xorg-server/randr/Makefile.in
index 447f6cb21..74f4fd2cc 100644
--- a/xorg-server/randr/Makefile.in
+++ b/xorg-server/randr/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,
@@ -46,7 +46,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 \
@@ -56,28 +55,26 @@ LTLIBRARIES = $(noinst_LTLIBRARIES)
librandr_la_LIBADD =
am__librandr_la_SOURCES_DIST = mirandr.c randr.c randrstr.h rrcrtc.c \
rrdispatch.c rrinfo.c rrmode.c rroutput.c rrpointer.c \
- rrproperty.c rrscreen.c rrsdispatch.c rrxinerama.c
+ rrproperty.c rrscreen.c rrsdispatch.c rrtransform.h \
+ rrtransform.c rrxinerama.c
am__objects_1 = rrxinerama.lo
@XINERAMA_TRUE@am__objects_2 = $(am__objects_1)
am_librandr_la_OBJECTS = mirandr.lo randr.lo rrcrtc.lo rrdispatch.lo \
rrinfo.lo rrmode.lo rroutput.lo rrpointer.lo rrproperty.lo \
- rrscreen.lo rrsdispatch.lo $(am__objects_2)
+ rrscreen.lo rrsdispatch.lo rrtransform.lo $(am__objects_2)
librandr_la_OBJECTS = $(am_librandr_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include
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) \
$(LDFLAGS) -o $@
SOURCES = $(librandr_la_SOURCES)
DIST_SOURCES = $(am__librandr_la_SOURCES_DIST)
-am__sdk_HEADERS_DIST = randrstr.h
+am__sdk_HEADERS_DIST = randrstr.h rrtransform.h
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -95,8 +92,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@
@@ -117,10 +115,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@
@@ -142,6 +136,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@
@@ -151,18 +146,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@
@@ -181,7 +173,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@
@@ -195,7 +187,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@
@@ -207,8 +202,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@
@@ -217,8 +211,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@
@@ -251,7 +245,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@
@@ -261,27 +254,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@
@@ -292,10 +270,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@
@@ -304,13 +278,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@
@@ -343,8 +312,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@
@@ -364,7 +332,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@
@@ -374,12 +341,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@
@@ -397,15 +364,14 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-xglmoduledir = @xglmoduledir@
-xpconfigdir = @xpconfigdir@
noinst_LTLIBRARIES = librandr.la
AM_CFLAGS = $(DIX_CFLAGS)
XINERAMA_SRCS = rrxinerama.c
-@XORG_TRUE@sdk_HEADERS = randrstr.h
+@XORG_TRUE@sdk_HEADERS = randrstr.h rrtransform.h
librandr_la_SOURCES = mirandr.c randr.c randrstr.h rrcrtc.c \
rrdispatch.c rrinfo.c rrmode.c rroutput.c rrpointer.c \
- rrproperty.c rrscreen.c rrsdispatch.c $(am__append_1)
+ rrproperty.c rrscreen.c rrsdispatch.c rrtransform.h \
+ rrtransform.c $(am__append_1)
all: all-am
.SUFFIXES:
@@ -414,8 +380,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; \
@@ -468,6 +434,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrproperty.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrscreen.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrsdispatch.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrtransform.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrxinerama.Plo@am__quote@
.c.o:
@@ -519,7 +486,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/randr/mirandr.c b/xorg-server/randr/mirandr.c
index 3c4991e5a..05375e46c 100644
--- a/xorg-server/randr/mirandr.c
+++ b/xorg-server/randr/mirandr.c
@@ -74,6 +74,14 @@ miRROutputSetProperty (ScreenPtr pScreen,
}
Bool
+miRROutputGetProperty (ScreenPtr pScreen,
+ RROutputPtr output,
+ Atom property)
+{
+ return TRUE;
+}
+
+Bool
miRROutputValidateMode (ScreenPtr pScreen,
RROutputPtr output,
RRModePtr mode)
@@ -116,6 +124,9 @@ miRandRInit (ScreenPtr pScreen)
pScrPriv->rrCrtcSet = miRRCrtcSet;
pScrPriv->rrCrtcSetGamma = miRRCrtcSetGamma;
pScrPriv->rrOutputSetProperty = miRROutputSetProperty;
+#if RANDR_13_INTERFACE
+ pScrPriv->rrOutputGetProperty = miRROutputGetProperty;
+#endif
pScrPriv->rrOutputValidateMode = miRROutputValidateMode;
pScrPriv->rrModeDestroy = miRRModeDestroy;
@@ -148,7 +159,7 @@ miRandRInit (ScreenPtr pScreen)
return FALSE;
if (!RROutputSetConnection (output, RR_Connected))
return FALSE;
- RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, 1, &output);
+ RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, NULL, 1, &output);
#endif
return TRUE;
}
diff --git a/xorg-server/randr/randr.c b/xorg-server/randr/randr.c
index bc2b995d2..5bcb3597a 100644
--- a/xorg-server/randr/randr.c
+++ b/xorg-server/randr/randr.c
@@ -56,9 +56,11 @@ static int SProcRRDispatch (ClientPtr pClient);
int RREventBase;
int RRErrorBase;
RESTYPE RRClientType, RREventType; /* resource types for event masks */
-DevPrivateKey RRClientPrivateKey = &RRClientPrivateKey;
+static int RRClientPrivateKeyIndex;
+DevPrivateKey RRClientPrivateKey = &RRClientPrivateKeyIndex;
-DevPrivateKey rrPrivKey = &rrPrivKey;
+static int rrPrivKeyIndex;
+DevPrivateKey rrPrivKey = &rrPrivKeyIndex;
static void
RRClientCallback (CallbackListPtr *list,
@@ -86,11 +88,6 @@ RRClientCallback (CallbackListPtr *list,
}
}
-static void
-RRResetProc (ExtensionEntry *extEntry)
-{
-}
-
static Bool
RRCloseScreen (int i, ScreenPtr pScreen)
{
@@ -120,11 +117,11 @@ SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from,
cpswapl(from->root, to->root);
cpswapl(from->window, to->window);
cpswaps(from->sizeID, to->sizeID);
+ cpswaps(from->subpixelOrder, to->subpixelOrder);
cpswaps(from->widthInPixels, to->widthInPixels);
cpswaps(from->heightInPixels, to->heightInPixels);
cpswaps(from->widthInMillimeters, to->widthInMillimeters);
cpswaps(from->heightInMillimeters, to->heightInMillimeters);
- cpswaps(from->subpixelOrder, to->subpixelOrder);
}
static void
@@ -138,8 +135,8 @@ SRRCrtcChangeNotifyEvent(xRRCrtcChangeNotifyEvent *from,
cpswapl(from->window, to->window);
cpswapl(from->crtc, to->crtc);
cpswapl(from->mode, to->mode);
- cpswapl(from->window, to->window);
cpswaps(from->rotation, to->rotation);
+ /* pad1 */
cpswaps(from->x, to->x);
cpswaps(from->y, to->y);
cpswaps(from->width, to->width);
@@ -160,6 +157,8 @@ SRROutputChangeNotifyEvent(xRROutputChangeNotifyEvent *from,
cpswapl(from->crtc, to->crtc);
cpswapl(from->mode, to->mode);
cpswaps(from->rotation, to->rotation);
+ to->connection = from->connection;
+ to->subpixelOrder = from->subpixelOrder;
}
static void
@@ -173,6 +172,11 @@ SRROutputPropertyNotifyEvent(xRROutputPropertyNotifyEvent *from,
cpswapl(from->output, to->output);
cpswapl(from->atom, to->atom);
cpswapl(from->timestamp, to->timestamp);
+ to->state = from->state;
+ /* pad1 */
+ /* pad2 */
+ /* pad3 */
+ /* pad4 */
}
static void
@@ -339,7 +343,7 @@ RRExtensionInit (void)
return;
extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors,
ProcRRDispatch, SProcRRDispatch,
- RRResetProc, StandardMinorOpcode);
+ NULL, StandardMinorOpcode);
if (!extEntry)
return;
RRErrorBase = extEntry->errorBase;
@@ -441,6 +445,9 @@ RRFirstOutput (ScreenPtr pScreen)
RROutputPtr output;
int i, j;
+ if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc)
+ return pScrPriv->primaryOutput;
+
for (i = 0; i < pScrPriv->numCrtcs; i++)
{
RRCrtcPtr crtc = pScrPriv->crtcs[i];
diff --git a/xorg-server/randr/randrstr.h b/xorg-server/randr/randrstr.h
index e8358bc0c..9c9b7c074 100644
--- a/xorg-server/randr/randrstr.h
+++ b/xorg-server/randr/randrstr.h
@@ -2,6 +2,7 @@
* Copyright © 2000 Compaq Computer Corporation
* Copyright © 2002 Hewlett-Packard Company
* Copyright © 2006 Intel Corporation
+ * Copyright © 2008 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
@@ -43,6 +44,7 @@
#include "pixmapstr.h"
#include "extnsionst.h"
#include "servermd.h"
+#include "rrtransform.h"
#include <X11/extensions/randr.h>
#include <X11/extensions/randrproto.h>
#ifdef RENDER
@@ -54,6 +56,10 @@
/* required for ABI compatibility for now */
#define RANDR_10_INTERFACE 1
#define RANDR_12_INTERFACE 1
+#define RANDR_13_INTERFACE 1 /* requires RANDR_12_INTERFACE */
+#define RANDR_GET_CRTC_INTERFACE 1
+
+#define RANDR_INTERFACE_VERSION 0x0103
typedef XID RRMode;
typedef XID RROutput;
@@ -115,6 +121,12 @@ struct _rrCrtc {
CARD16 *gammaBlue;
CARD16 *gammaGreen;
void *devPrivate;
+ Bool transforms;
+ RRTransformRec client_pending_transform;
+ RRTransformRec client_current_transform;
+ PictTransform transform;
+ struct pict_f_transform f_transform;
+ struct pict_f_transform f_inverse;
};
struct _rrOutput {
@@ -175,6 +187,23 @@ typedef void (*RRModeDestroyProcPtr) (ScreenPtr pScreen,
#endif
+#if RANDR_13_INTERFACE
+typedef Bool (*RROutputGetPropertyProcPtr) (ScreenPtr pScreen,
+ RROutputPtr output,
+ Atom property);
+typedef Bool (*RRGetPanningProcPtr) (ScreenPtr pScrn,
+ RRCrtcPtr crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border);
+typedef Bool (*RRSetPanningProcPtr) (ScreenPtr pScrn,
+ RRCrtcPtr crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border);
+
+#endif /* RANDR_13_INTERFACE */
+
typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations);
typedef Bool (*RRCloseScreenProcPtr) ( int i, ScreenPtr pscreen);
@@ -220,6 +249,11 @@ typedef struct _rrScrPriv {
RROutputValidateModeProcPtr rrOutputValidateMode;
RRModeDestroyProcPtr rrModeDestroy;
#endif
+#if RANDR_13_INTERFACE
+ RROutputGetPropertyProcPtr rrOutputGetProperty;
+ RRGetPanningProcPtr rrGetPanning;
+ RRSetPanningProcPtr rrSetPanning;
+#endif
/*
* Private part of the structure; not considered part of the ABI
@@ -239,6 +273,7 @@ typedef struct _rrScrPriv {
int numOutputs;
RROutputPtr *outputs;
+ RROutputPtr primaryOutput;
int numCrtcs;
RRCrtcPtr *crtcs;
@@ -368,6 +403,9 @@ int
ProcRRGetScreenResources (ClientPtr client);
int
+ProcRRGetScreenResourcesCurrent (ClientPtr client);
+
+int
ProcRRSetScreenConfig (ClientPtr client);
int
@@ -406,6 +444,11 @@ miRROutputSetProperty (ScreenPtr pScreen,
RRPropertyValuePtr value);
Bool
+miRROutputGetProperty (ScreenPtr pScreen,
+ RROutputPtr output,
+ Atom property);
+
+Bool
miRROutputValidateMode (ScreenPtr pScreen,
RROutputPtr output,
RRModePtr mode);
@@ -425,7 +468,7 @@ RRTellChanged (ScreenPtr pScreen);
* Poll the driver for changed information
*/
Bool
-RRGetInfo (ScreenPtr pScreen);
+RRGetInfo (ScreenPtr pScreen, Bool force_query);
Bool RRInit (void);
@@ -506,6 +549,12 @@ void
RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations);
/*
+ * Set whether transforms are allowed on a CRTC
+ */
+void
+RRCrtcSetTransformSupport (RRCrtcPtr crtc, Bool transforms);
+
+/*
* Notify the extension that the Crtc has been reconfigured,
* the driver calls this whenever it has updated the mode
*/
@@ -515,6 +564,7 @@ RRCrtcNotify (RRCrtcPtr crtc,
int x,
int y,
Rotation rotation,
+ RRTransformPtr transform,
int numOutputs,
RROutputPtr *outputs);
@@ -569,11 +619,57 @@ void
RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height);
/*
+ * Compute the complete transformation matrix including
+ * client-specified transform, rotation/reflection values and the crtc
+ * offset.
+ *
+ * Return TRUE if the resulting transform is not a simple translation.
+ */
+Bool
+RRTransformCompute (int x,
+ int y,
+ int width,
+ int height,
+ Rotation rotation,
+ RRTransformPtr rr_transform,
+
+ PictTransformPtr transform,
+ struct pict_f_transform *f_transform,
+ struct pict_f_transform *f_inverse);
+
+/*
+ * Return crtc transform
+ */
+RRTransformPtr
+RRCrtcGetTransform (RRCrtcPtr crtc);
+
+/*
+ * Check whether the pending and current transforms are the same
+ */
+Bool
+RRCrtcPendingTransform (RRCrtcPtr crtc);
+
+/*
* Destroy a Crtc at shutdown
*/
void
RRCrtcDestroy (RRCrtcPtr crtc);
+
+/*
+ * Set the pending CRTC transformation
+ */
+
+int
+RRCrtcTransformSet (RRCrtcPtr crtc,
+ PictTransformPtr transform,
+ struct pict_f_transform *f_transform,
+ struct pict_f_transform *f_inverse,
+ char *filter,
+ int filter_len,
+ xFixed *params,
+ int nparams);
+
/*
* Initialize crtc type
*/
@@ -599,6 +695,18 @@ ProcRRGetCrtcGamma (ClientPtr client);
int
ProcRRSetCrtcGamma (ClientPtr client);
+int
+ProcRRSetCrtcTransform (ClientPtr client);
+
+int
+ProcRRGetCrtcTransform (ClientPtr client);
+
+int
+ProcRRGetPanning (ClientPtr client);
+
+int
+ProcRRSetPanning (ClientPtr client);
+
/* rrdispatch.c */
Bool
RRClientKnowsRates (ClientPtr pClient);
@@ -716,6 +824,12 @@ RROutputDestroy (RROutputPtr output);
int
ProcRRGetOutputInfo (ClientPtr client);
+extern int
+ProcRRSetOutputPrimary (ClientPtr client);
+
+extern int
+ProcRRGetOutputPrimary (ClientPtr client);
+
/*
* Initialize output type
*/
diff --git a/xorg-server/randr/rrcrtc.c b/xorg-server/randr/rrcrtc.c
index ec65a040e..8a5738fc5 100644
--- a/xorg-server/randr/rrcrtc.c
+++ b/xorg-server/randr/rrcrtc.c
@@ -89,6 +89,11 @@ RRCrtcCreate (ScreenPtr pScreen, void *devPrivate)
crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL;
crtc->changed = FALSE;
crtc->devPrivate = devPrivate;
+ RRTransformInit (&crtc->client_pending_transform);
+ RRTransformInit (&crtc->client_current_transform);
+ pixman_transform_init_identity (&crtc->transform);
+ pixman_f_transform_init_identity (&crtc->f_transform);
+ pixman_f_transform_init_identity (&crtc->f_inverse);
if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc))
return NULL;
@@ -110,6 +115,15 @@ RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations)
}
/*
+ * Set whether transforms are allowed on a CRTC
+ */
+void
+RRCrtcSetTransformSupport (RRCrtcPtr crtc, Bool transforms)
+{
+ crtc->transforms = transforms;
+}
+
+/*
* Notify the extension that the Crtc has been reconfigured,
* the driver calls this whenever it has updated the mode
*/
@@ -119,6 +133,7 @@ RRCrtcNotify (RRCrtcPtr crtc,
int x,
int y,
Rotation rotation,
+ RRTransformPtr transform,
int numOutputs,
RROutputPtr *outputs)
{
@@ -214,6 +229,19 @@ RRCrtcNotify (RRCrtcPtr crtc,
crtc->rotation = rotation;
RRCrtcChanged (crtc, TRUE);
}
+ if (!RRTransformEqual (transform, &crtc->client_current_transform)) {
+ RRTransformCopy (&crtc->client_current_transform, transform);
+ RRCrtcChanged (crtc, TRUE);
+ }
+ if (crtc->changed && mode)
+ {
+ RRTransformCompute (x, y,
+ mode->mode.width, mode->mode.height,
+ rotation,
+ &crtc->client_current_transform,
+ &crtc->transform, &crtc->f_transform,
+ &crtc->f_inverse);
+ }
return TRUE;
}
@@ -290,7 +318,8 @@ RRCrtcSet (RRCrtcPtr crtc,
crtc->rotation == rotation &&
crtc->numOutputs == numOutputs &&
!memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) &&
- !RRCrtcPendingProperties (crtc))
+ !RRCrtcPendingProperties (crtc) &&
+ !RRCrtcPendingTransform (crtc))
{
ret = TRUE;
}
@@ -313,7 +342,7 @@ RRCrtcSet (RRCrtcPtr crtc,
if (!mode)
{
- RRCrtcNotify (crtc, NULL, x, y, rotation, 0, NULL);
+ RRCrtcNotify (crtc, NULL, x, y, rotation, NULL, 0, NULL);
ret = TRUE;
}
else
@@ -339,7 +368,7 @@ RRCrtcSet (RRCrtcPtr crtc,
*/
if (ret)
{
- RRCrtcNotify (crtc, mode, x, y, rotation, 1, outputs);
+ RRCrtcNotify (crtc, mode, x, y, rotation, NULL, 1, outputs);
RRScreenSizeNotify (pScreen);
}
}
@@ -359,6 +388,30 @@ RRCrtcSet (RRCrtcPtr crtc,
}
/*
+ * Return crtc transform
+ */
+RRTransformPtr
+RRCrtcGetTransform (RRCrtcPtr crtc)
+{
+ RRTransformPtr transform = &crtc->client_pending_transform;
+
+ if (pixman_transform_is_identity (&transform->transform))
+ return NULL;
+ return transform;
+}
+
+/*
+ * Check whether the pending and current transforms are the same
+ */
+Bool
+RRCrtcPendingTransform (RRCrtcPtr crtc)
+{
+ return memcmp (&crtc->client_current_transform.transform,
+ &crtc->client_pending_transform.transform,
+ sizeof (PictTransform)) != 0;
+}
+
+/*
* Destroy a Crtc at shutdown
*/
void
@@ -438,30 +491,35 @@ RRCrtcGammaNotify (RRCrtcPtr crtc)
return TRUE; /* not much going on here */
}
-/**
- * Returns the width/height that the crtc scans out from the framebuffer
- */
-void
-RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height)
+static void
+RRModeGetScanoutSize (RRModePtr mode, PictTransformPtr transform,
+ int *width, int *height)
{
- if (crtc->mode == NULL) {
+ BoxRec box;
+
+ if (mode == NULL) {
*width = 0;
*height = 0;
return;
}
- switch (crtc->rotation & 0xf) {
- case RR_Rotate_0:
- case RR_Rotate_180:
- *width = crtc->mode->mode.width;
- *height = crtc->mode->mode.height;
- break;
- case RR_Rotate_90:
- case RR_Rotate_270:
- *width = crtc->mode->mode.height;
- *height = crtc->mode->mode.width;
- break;
- }
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = mode->mode.width;
+ box.y2 = mode->mode.height;
+
+ pixman_transform_bounds (transform, &box);
+ *width = box.x2 - box.x1;
+ *height = box.y2 - box.y1;
+}
+
+/**
+ * Returns the width/height that the crtc scans out from the framebuffer
+ */
+void
+RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height)
+{
+ return RRModeGetScanoutSize (crtc->mode, &crtc->transform, width, height);
}
/*
@@ -494,6 +552,59 @@ RRCrtcGammaSetSize (RRCrtcPtr crtc,
}
/*
+ * Set the pending CRTC transformation
+ */
+
+int
+RRCrtcTransformSet (RRCrtcPtr crtc,
+ PictTransformPtr transform,
+ struct pixman_f_transform *f_transform,
+ struct pixman_f_transform *f_inverse,
+ char *filter_name,
+ int filter_len,
+ xFixed *params,
+ int nparams)
+{
+ PictFilterPtr filter = NULL;
+ int width = 0, height = 0;
+
+ if (!crtc->transforms)
+ return BadValue;
+
+ if (filter_len)
+ {
+ filter = PictureFindFilter (crtc->pScreen,
+ filter_name,
+ filter_len);
+ if (!filter)
+ return BadName;
+ if (filter->ValidateParams)
+ {
+ if (!filter->ValidateParams (crtc->pScreen, filter->id,
+ params, nparams, &width, &height))
+ return BadMatch;
+ }
+ else {
+ width = filter->width;
+ height = filter->height;
+ }
+ }
+ else
+ {
+ if (nparams)
+ return BadMatch;
+ }
+ if (!RRTransformSetFilter (&crtc->client_pending_transform,
+ filter, params, nparams, width, height))
+ return BadAlloc;
+
+ crtc->client_pending_transform.transform = *transform;
+ crtc->client_pending_transform.f_transform = *f_transform;
+ crtc->client_pending_transform.f_inverse = *f_inverse;
+ return Success;
+}
+
+/*
* Initialize crtc type
*/
Bool
@@ -521,6 +632,7 @@ ProcRRGetCrtcInfo (ClientPtr client)
RROutput *possible;
int i, j, k, n;
int width, height;
+ BoxRec panned_area;
REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq);
crtc = LookupCrtc(client, stuff->crtc, DixReadAccess);
@@ -541,11 +653,23 @@ ProcRRGetCrtcInfo (ClientPtr client)
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.timestamp = pScrPriv->lastSetTime.milliseconds;
- rep.x = crtc->x;
- rep.y = crtc->y;
- RRCrtcGetScanoutSize (crtc, &width, &height);
- rep.width = width;
- rep.height = height;
+ if (pScrPriv->rrGetPanning &&
+ pScrPriv->rrGetPanning (pScreen, crtc, &panned_area, NULL, NULL) &&
+ (panned_area.x2 > panned_area.x1) && (panned_area.y2 > panned_area.y1))
+ {
+ rep.x = panned_area.x1;
+ rep.y = panned_area.y1;
+ rep.width = panned_area.x2 - panned_area.x1;
+ rep.height = panned_area.y2 - panned_area.y1;
+ }
+ else
+ {
+ RRCrtcGetScanoutSize (crtc, &width, &height);
+ rep.x = crtc->x;
+ rep.y = crtc->y;
+ rep.width = width;
+ rep.height = height;
+ }
rep.mode = mode ? mode->mode.id : 0;
rep.rotation = crtc->rotation;
rep.rotations = crtc->rotations;
@@ -789,18 +913,24 @@ ProcRRSetCrtcConfig (ClientPtr client)
/*
* Check screen size bounds if the DDX provides a 1.2 interface
* for setting screen size. Else, assume the CrtcSet sets
- * the size along with the mode
+ * the size along with the mode. If the driver supports transforms,
+ * then it must allow crtcs to display a subset of the screen, so
+ * only do this check for drivers without transform support.
*/
- if (pScrPriv->rrScreenSetSize)
+ if (pScrPriv->rrScreenSetSize && !crtc->transforms)
{
- int source_width = mode->mode.width;
- int source_height = mode->mode.height;
+ int source_width;
+ int source_height;
+ PictTransform transform;
+ struct pixman_f_transform f_transform, f_inverse;
- if ((rotation & 0xf) == RR_Rotate_90 || (rotation & 0xf) == RR_Rotate_270)
- {
- source_width = mode->mode.height;
- source_height = mode->mode.width;
- }
+ RRTransformCompute (stuff->x, stuff->y,
+ mode->mode.width, mode->mode.height,
+ rotation,
+ &crtc->client_pending_transform,
+ &transform, &f_transform, &f_inverse);
+
+ RRModeGetScanoutSize (mode, &transform, &source_width, &source_height);
if (stuff->x + source_width > pScreen->width)
{
client->errorValue = stuff->x;
@@ -837,6 +967,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
goto sendReply;
}
rep.status = RRSetConfigSuccess;
+ pScrPriv->lastSetTime = time;
sendReply:
if (outputs)
@@ -846,7 +977,7 @@ sendReply:
/* rep.status has already been filled in */
rep.length = 0;
rep.sequenceNumber = client->sequence;
- rep.newTimestamp = pScrPriv->lastConfigTime.milliseconds;
+ rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
if (client->swapped)
{
@@ -861,6 +992,161 @@ sendReply:
}
int
+ProcRRGetPanning (ClientPtr client)
+{
+ REQUEST(xRRGetPanningReq);
+ xRRGetPanningReply rep;
+ RRCrtcPtr crtc;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ BoxRec total;
+ BoxRec tracking;
+ INT16 border[4];
+ int n;
+
+ REQUEST_SIZE_MATCH(xRRGetPanningReq);
+ crtc = LookupCrtc(client, stuff->crtc, DixReadAccess);
+
+ if (!crtc)
+ return RRErrorBase + BadRRCrtc;
+
+ /* All crtcs must be associated with screens before client
+ * requests are processed
+ */
+ pScreen = crtc->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (!pScrPriv)
+ return RRErrorBase + BadRRCrtc;
+
+ memset(&rep, 0, sizeof(rep));
+ rep.type = X_Reply;
+ rep.status = RRSetConfigSuccess;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 1;
+ rep.timestamp = pScrPriv->lastSetTime.milliseconds;
+
+ if (pScrPriv->rrGetPanning &&
+ pScrPriv->rrGetPanning (pScreen, crtc, &total, &tracking, border)) {
+ rep.left = total.x1;
+ rep.top = total.y1;
+ rep.width = total.x2 - total.x1;
+ rep.height = total.y2 - total.y1;
+ rep.track_left = tracking.x1;
+ rep.track_top = tracking.y1;
+ rep.track_width = tracking.x2 - tracking.x1;
+ rep.track_height = tracking.y2 - tracking.y1;
+ rep.border_left = border[0];
+ rep.border_top = border[1];
+ rep.border_right = border[2];
+ rep.border_bottom = border[3];
+ }
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.timestamp, n);
+ swaps(&rep.left, n);
+ swaps(&rep.top, n);
+ swaps(&rep.width, n);
+ swaps(&rep.height, n);
+ swaps(&rep.track_left, n);
+ swaps(&rep.track_top, n);
+ swaps(&rep.track_width, n);
+ swaps(&rep.track_height, n);
+ swaps(&rep.border_left, n);
+ swaps(&rep.border_top, n);
+ swaps(&rep.border_right, n);
+ swaps(&rep.border_bottom, n);
+ }
+ WriteToClient(client, sizeof(xRRGetPanningReply), (char *)&rep);
+ return client->noClientException;
+}
+
+int
+ProcRRSetPanning (ClientPtr client)
+{
+ REQUEST(xRRSetPanningReq);
+ xRRSetPanningReply rep;
+ RRCrtcPtr crtc;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ TimeStamp time;
+ BoxRec total;
+ BoxRec tracking;
+ INT16 border[4];
+ int n;
+
+ REQUEST_SIZE_MATCH(xRRSetPanningReq);
+ crtc = LookupCrtc(client, stuff->crtc, DixReadAccess);
+
+ if (!crtc)
+ return RRErrorBase + BadRRCrtc;
+
+
+ /* All crtcs must be associated with screens before client
+ * requests are processed
+ */
+ pScreen = crtc->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (!pScrPriv) {
+ time = currentTime;
+ rep.status = RRSetConfigFailed;
+ goto sendReply;
+ }
+
+ time = ClientTimeToServerTime(stuff->timestamp);
+
+ /*
+ * Make sure the requested set-time is not older than
+ * the last set-time
+ */
+ if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0)
+ {
+ rep.status = RRSetConfigInvalidTime;
+ goto sendReply;
+ }
+
+ if (!pScrPriv->rrGetPanning)
+ return RRErrorBase + BadRRCrtc;
+
+ total.x1 = stuff->left;
+ total.y1 = stuff->top;
+ total.x2 = total.x1 + stuff->width;
+ total.y2 = total.y1 + stuff->height;
+ tracking.x1 = stuff->track_left;
+ tracking.y1 = stuff->track_top;
+ tracking.x2 = tracking.x1 + stuff->track_width;
+ tracking.y2 = tracking.y1 + stuff->track_height;
+ border[0] = stuff->border_left;
+ border[1] = stuff->border_top;
+ border[2] = stuff->border_right;
+ border[3] = stuff->border_bottom;
+
+ if (! pScrPriv->rrSetPanning (pScreen, crtc, &total, &tracking, border))
+ return BadMatch;
+
+ pScrPriv->lastSetTime = time;
+
+ rep.status = RRSetConfigSuccess;
+
+sendReply:
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.newTimestamp, n);
+ }
+ WriteToClient(client, sizeof(xRRSetPanningReply), (char *)&rep);
+ return client->noClientException;
+}
+
+int
ProcRRGetCrtcGammaSize (ClientPtr client)
{
REQUEST(xRRGetCrtcGammaSizeReq);
@@ -894,7 +1180,7 @@ ProcRRGetCrtcGamma (ClientPtr client)
RRCrtcPtr crtc;
int n;
unsigned long len;
- char *extra;
+ char *extra = NULL;
REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq);
crtc = LookupCrtc (client, stuff->crtc, DixReadAccess);
@@ -958,3 +1244,144 @@ ProcRRSetCrtcGamma (ClientPtr client)
return Success;
}
+/* Version 1.3 additions */
+
+int
+ProcRRSetCrtcTransform (ClientPtr client)
+{
+ REQUEST(xRRSetCrtcTransformReq);
+ RRCrtcPtr crtc;
+ PictTransform transform;
+ struct pixman_f_transform f_transform, f_inverse;
+ char *filter;
+ int nbytes;
+ xFixed *params;
+ int nparams;
+
+ REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq);
+ crtc = LookupCrtc (client, stuff->crtc, DixWriteAccess);
+ if (!crtc)
+ return RRErrorBase + BadRRCrtc;
+
+ PictTransform_from_xRenderTransform (&transform, &stuff->transform);
+ pixman_f_transform_from_pixman_transform (&f_transform, &transform);
+ if (!pixman_f_transform_invert (&f_inverse, &f_transform))
+ return BadMatch;
+
+ filter = (char *) (stuff + 1);
+ nbytes = stuff->nbytesFilter;
+ params = (xFixed *) (filter + ((nbytes + 3) & ~3));
+ nparams = ((xFixed *) stuff + client->req_len) - params;
+ if (nparams < 0)
+ return BadLength;
+
+ return RRCrtcTransformSet (crtc, &transform, &f_transform, &f_inverse,
+ filter, nbytes, params, nparams);
+}
+
+
+#define CrtcTransformExtra (SIZEOF(xRRGetCrtcTransformReply) - 32)
+
+static int
+transform_filter_length (RRTransformPtr transform)
+{
+ int nbytes, nparams;
+
+ if (transform->filter == NULL)
+ return 0;
+ nbytes = strlen (transform->filter->name);
+ nparams = transform->nparams;
+ return ((nbytes + 3) & ~3) + (nparams * sizeof (xFixed));
+}
+
+static int
+transform_filter_encode (ClientPtr client, char *output,
+ CARD16 *nbytesFilter,
+ CARD16 *nparamsFilter,
+ RRTransformPtr transform)
+{
+ int nbytes, nparams;
+ int n;
+
+ if (transform->filter == NULL) {
+ *nbytesFilter = 0;
+ *nparamsFilter = 0;
+ return 0;
+ }
+ nbytes = strlen (transform->filter->name);
+ nparams = transform->nparams;
+ *nbytesFilter = nbytes;
+ *nparamsFilter = nparams;
+ memcpy (output, transform->filter->name, nbytes);
+ while ((nbytes & 3) != 0)
+ output[nbytes++] = 0;
+ memcpy (output + nbytes, transform->params, nparams * sizeof (xFixed));
+ if (client->swapped) {
+ swaps (nbytesFilter, n);
+ swaps (nparamsFilter, n);
+ SwapLongs ((CARD32 *) (output + nbytes), nparams);
+ }
+ nbytes += nparams * sizeof (xFixed);
+ return nbytes;
+}
+
+static void
+transform_encode (ClientPtr client, xRenderTransform *wire, PictTransform *pict)
+{
+ xRenderTransform_from_PictTransform (wire, pict);
+ if (client->swapped)
+ SwapLongs ((CARD32 *) wire, sizeof (xRenderTransform) >> 2);
+}
+
+int
+ProcRRGetCrtcTransform (ClientPtr client)
+{
+ REQUEST(xRRGetCrtcTransformReq);
+ xRRGetCrtcTransformReply *reply;
+ RRCrtcPtr crtc;
+ int n, nextra;
+ RRTransformPtr current, pending;
+ char *extra;
+
+ REQUEST_SIZE_MATCH (xRRGetCrtcTransformReq);
+ crtc = LookupCrtc (client, stuff->crtc, DixWriteAccess);
+ if (!crtc)
+ return RRErrorBase + BadRRCrtc;
+
+ pending = &crtc->client_pending_transform;
+ current = &crtc->client_current_transform;
+
+ nextra = (transform_filter_length (pending) +
+ transform_filter_length (current));
+
+ reply = xalloc (sizeof (xRRGetCrtcTransformReply) + nextra);
+ if (!reply)
+ return BadAlloc;
+
+ extra = (char *) (reply + 1);
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+ reply->length = (CrtcTransformExtra + nextra) >> 2;
+
+ reply->hasTransforms = crtc->transforms;
+
+ transform_encode (client, &reply->pendingTransform, &pending->transform);
+ extra += transform_filter_encode (client, extra,
+ &reply->pendingNbytesFilter,
+ &reply->pendingNparamsFilter,
+ pending);
+
+ transform_encode (client, &reply->currentTransform, &current->transform);
+ extra += transform_filter_encode (client, extra,
+ &reply->currentNbytesFilter,
+ &reply->currentNparamsFilter,
+ current);
+
+ if (client->swapped) {
+ swaps (&reply->sequenceNumber, n);
+ swapl (&reply->length, n);
+ }
+ WriteToClient (client, sizeof (xRRGetCrtcTransformReply) + nextra, (char *) reply);
+ xfree(reply);
+ return client->noClientException;
+}
diff --git a/xorg-server/randr/rrdispatch.c b/xorg-server/randr/rrdispatch.c
index 5525427f6..0925875bf 100644
--- a/xorg-server/randr/rrdispatch.c
+++ b/xorg-server/randr/rrdispatch.c
@@ -23,7 +23,7 @@
#include "randrstr.h"
#define SERVER_RANDR_MAJOR 1
-#define SERVER_RANDR_MINOR 2
+#define SERVER_RANDR_MINOR 3
Bool
RRClientKnowsRates (ClientPtr pClient)
@@ -76,7 +76,7 @@ ProcRRSelectInput (ClientPtr client)
int rc;
REQUEST_SIZE_MATCH(xRRSelectInputReq);
- rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess);
if (rc != Success)
return rc;
pHead = (RREventPtr *)SecurityLookupIDByType(client,
@@ -85,7 +85,8 @@ ProcRRSelectInput (ClientPtr client)
if (stuff->enable & (RRScreenChangeNotifyMask|
RRCrtcChangeNotifyMask|
- RROutputChangeNotifyMask))
+ RROutputChangeNotifyMask|
+ RROutputPropertyNotifyMask))
{
ScreenPtr pScreen = pWin->drawable.pScreen;
rrScrPriv (pScreen);
@@ -210,5 +211,13 @@ int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = {
ProcRRGetCrtcGammaSize, /* 22 */
ProcRRGetCrtcGamma, /* 23 */
ProcRRSetCrtcGamma, /* 24 */
+/* V1.3 additions */
+ ProcRRGetScreenResourcesCurrent, /* 25 */
+ ProcRRSetCrtcTransform, /* 26 */
+ ProcRRGetCrtcTransform, /* 27 */
+ ProcRRGetPanning, /* 28 */
+ ProcRRSetPanning, /* 29 */
+ ProcRRSetOutputPrimary, /* 30 */
+ ProcRRGetOutputPrimary, /* 31 */
};
diff --git a/xorg-server/randr/rrinfo.c b/xorg-server/randr/rrinfo.c
index 7e77d393d..12b9a4aab 100644
--- a/xorg-server/randr/rrinfo.c
+++ b/xorg-server/randr/rrinfo.c
@@ -170,7 +170,7 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations)
/* notice current mode */
if (newMode)
RRCrtcNotify (crtc, newMode, 0, 0, pScrPriv->rotation,
- 1, &output);
+ NULL, 1, &output);
}
#endif
@@ -178,12 +178,20 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations)
* Poll the driver for changed information
*/
Bool
-RRGetInfo (ScreenPtr pScreen)
+RRGetInfo (ScreenPtr pScreen, Bool force_query)
{
rrScrPriv (pScreen);
Rotation rotations;
int i;
+ /* Return immediately if we don't need to re-query and we already have the
+ * information.
+ */
+ if (!force_query) {
+ if (pScrPriv->numCrtcs != 0 || pScrPriv->numOutputs != 0)
+ return TRUE;
+ }
+
for (i = 0; i < pScrPriv->numOutputs; i++)
pScrPriv->outputs[i]->changed = FALSE;
for (i = 0; i < pScrPriv->numCrtcs; i++)
diff --git a/xorg-server/randr/rrmode.c b/xorg-server/randr/rrmode.c
index d5072084a..2fa440385 100644
--- a/xorg-server/randr/rrmode.c
+++ b/xorg-server/randr/rrmode.c
@@ -320,7 +320,8 @@ ProcRRCreateMode (ClientPtr client)
swapl(&rep.mode, n);
}
WriteToClient(client, sizeof(xRRCreateModeReply), (char *)&rep);
-
+ /* Drop out reference to this mode */
+ RRModeDestroy (mode);
return client->noClientException;
}
diff --git a/xorg-server/randr/rroutput.c b/xorg-server/randr/rroutput.c
index 1ecde31a2..939c14dd9 100644
--- a/xorg-server/randr/rroutput.c
+++ b/xorg-server/randr/rroutput.c
@@ -1,5 +1,6 @@
/*
* Copyright © 2006 Keith Packard
+ * Copyright © 2008 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
@@ -379,6 +380,9 @@ RROutputDestroyResource (pointer value, XID pid)
{
rrScrPriv(pScreen);
int i;
+
+ if (pScrPriv->primaryOutput == output)
+ pScrPriv->primaryOutput = NULL;
for (i = 0; i < pScrPriv->numOutputs; i++)
{
@@ -426,7 +430,7 @@ RROutputInit (void)
}
#define OutputInfoExtra (SIZEOF(xRRGetOutputInfoReply) - 32)
-
+
int
ProcRRGetOutputInfo (ClientPtr client)
{
@@ -533,3 +537,104 @@ ProcRRGetOutputInfo (ClientPtr client)
return client->noClientException;
}
+
+void
+RRSetPrimaryOutput(ScreenPtr pScreen, rrScrPrivPtr pScrPriv,
+ RROutputPtr output)
+{
+ if (pScrPriv->primaryOutput == output)
+ return;
+
+ /* clear the old primary */
+ if (pScrPriv->primaryOutput) {
+ RROutputChanged(pScrPriv->primaryOutput, 0);
+ pScrPriv->primaryOutput = NULL;
+ }
+
+ /* set the new primary */
+ if (output) {
+ pScrPriv->primaryOutput = output;
+ RROutputChanged(output, 0);
+ }
+
+ pScrPriv->layoutChanged = TRUE;
+
+ RRTellChanged(pScreen);
+}
+
+int
+ProcRRSetOutputPrimary(ClientPtr client)
+{
+ REQUEST(xRRSetOutputPrimaryReq);
+ RROutputPtr output = NULL;
+ WindowPtr pWin;
+ rrScrPrivPtr pScrPriv;
+
+ REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq);
+
+ pWin = SecurityLookupIDByType(client, stuff->window, RT_WINDOW,
+ DixReadAccess);
+
+ if (!pWin) {
+ client->errorValue = stuff->window;
+ return BadWindow;
+ }
+
+ if (stuff->output) {
+ output = LookupOutput(client, stuff->output, DixReadAccess);
+
+ if (!output) {
+ client->errorValue = stuff->output;
+ return RRErrorBase + BadRROutput;
+ }
+
+ if (output->pScreen != pWin->drawable.pScreen) {
+ client->errorValue = stuff->window;
+ return BadMatch;
+ }
+ }
+
+ pScrPriv = rrGetScrPriv(pWin->drawable.pScreen);
+ RRSetPrimaryOutput(pWin->drawable.pScreen, pScrPriv, output);
+
+ return client->noClientException;
+}
+
+int
+ProcRRGetOutputPrimary(ClientPtr client)
+{
+ REQUEST(xRRGetOutputPrimaryReq);
+ WindowPtr pWin;
+ rrScrPrivPtr pScrPriv;
+ xRRGetOutputPrimaryReply rep;
+ RROutputPtr primary = NULL;
+
+ REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq);
+
+ pWin = SecurityLookupIDByType(client, stuff->window, RT_WINDOW,
+ DixReadAccess);
+
+ if (!pWin) {
+ client->errorValue = stuff->window;
+ return BadWindow;
+ }
+
+ pScrPriv = rrGetScrPriv(pWin->drawable.pScreen);
+ if (pScrPriv)
+ primary = pScrPriv->primaryOutput;
+
+ memset(&rep, 0, sizeof(rep));
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.output = primary ? primary->id : None;
+
+ if (client->swapped) {
+ int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.output, n);
+ }
+
+ WriteToClient(client, sizeof(xRRGetOutputPrimaryReply), &rep);
+
+ return client->noClientException;
+}
diff --git a/xorg-server/randr/rrpointer.c b/xorg-server/randr/rrpointer.c
index c88a0f83e..6b934c0c6 100644
--- a/xorg-server/randr/rrpointer.c
+++ b/xorg-server/randr/rrpointer.c
@@ -21,6 +21,7 @@
*/
#include "randrstr.h"
+#include "inputstr.h"
/*
* When the pointer moves, check to see if the specified position is outside
@@ -51,7 +52,7 @@ RRCrtcContainsPosition (RRCrtcPtr crtc, int x, int y)
* Find the CRTC nearest the specified position, ignoring 'skip'
*/
static void
-RRPointerToNearestCrtc (ScreenPtr pScreen, int x, int y, RRCrtcPtr skip)
+RRPointerToNearestCrtc (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y, RRCrtcPtr skip)
{
rrScrPriv (pScreen);
int c;
@@ -95,7 +96,7 @@ RRPointerToNearestCrtc (ScreenPtr pScreen, int x, int y, RRCrtcPtr skip)
}
}
if (best_dx || best_dy)
- (*pScreen->SetCursorPosition) (pScreen, x + best_dx, y + best_dy, TRUE);
+ (*pScreen->SetCursorPosition) (pDev, pScreen, x + best_dx, y + best_dy, TRUE);
pScrPriv->pointerCrtc = nearest;
}
@@ -124,22 +125,34 @@ RRPointerMoved (ScreenPtr pScreen, int x, int y)
}
/* None contain pointer, find nearest */
- RRPointerToNearestCrtc (pScreen, x, y, pointerCrtc);
+ ErrorF("RRPointerMoved: Untested, may cause \"bogus pointer event\"\n");
+ RRPointerToNearestCrtc (inputInfo.pointer, pScreen, x, y, pointerCrtc);
}
/*
- * When the screen is reconfigured, move the pointer to the nearest
+ * When the screen is reconfigured, move all pointers to the nearest
* CRTC
*/
void
RRPointerScreenConfigured (ScreenPtr pScreen)
{
- WindowPtr pRoot = GetCurrentRootWindow ();
- ScreenPtr pCurrentScreen = pRoot ? pRoot->drawable.pScreen : NULL;
+ WindowPtr pRoot;
+ ScreenPtr pCurrentScreen;
int x, y;
+ DeviceIntPtr pDev;
- if (pScreen != pCurrentScreen)
- return;
- GetSpritePosition (&x, &y);
- RRPointerToNearestCrtc (pScreen, x, y, NULL);
+ for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
+ {
+ if (IsPointerDevice(pDev))
+ {
+ pRoot = GetCurrentRootWindow(pDev);
+ pCurrentScreen = pRoot ? pRoot->drawable.pScreen : NULL;
+
+ if (pScreen == pCurrentScreen)
+ {
+ GetSpritePosition(pDev, &x, &y);
+ RRPointerToNearestCrtc (pDev, pScreen, x, y, NULL);
+ }
+ }
+ }
}
diff --git a/xorg-server/randr/rrproperty.c b/xorg-server/randr/rrproperty.c
index 8e4103b5e..12923a2c7 100644
--- a/xorg-server/randr/rrproperty.c
+++ b/xorg-server/randr/rrproperty.c
@@ -59,7 +59,8 @@ DeliverPropertyEvent(WindowPtr pWin, void *value)
static void RRDeliverPropertyEvent(ScreenPtr pScreen, xEvent *event)
{
- WalkTree(pScreen, DeliverPropertyEvent, event);
+ if (!(dispatchException & (DE_RESET | DE_TERMINATE)))
+ WalkTree(pScreen, DeliverPropertyEvent, event);
}
void
@@ -332,13 +333,21 @@ RRPropertyValuePtr
RRGetOutputProperty (RROutputPtr output, Atom property, Bool pending)
{
RRPropertyPtr prop = RRQueryOutputProperty (output, property);
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(output->pScreen);
if (!prop)
return NULL;
if (pending && prop->is_pending)
return &prop->pending;
- else
+ else {
+#if RANDR_13_INTERFACE
+ /* If we can, try to update the property value first */
+ if (pScrPriv->rrOutputGetProperty)
+ pScrPriv->rrOutputGetProperty(output->pScreen, output,
+ prop->propertyName);
+#endif
return &prop->current;
+ }
}
int
@@ -453,7 +462,7 @@ ProcRRQueryOutputProperty (ClientPtr client)
xRRQueryOutputPropertyReply rep;
RROutputPtr output;
RRPropertyPtr prop;
- char *extra;
+ char *extra = NULL;
REQUEST_SIZE_MATCH(xRRQueryOutputPropertyReq);
@@ -605,7 +614,7 @@ ProcRRGetOutputProperty (ClientPtr client)
unsigned long n, len, ind;
RROutputPtr output;
xRRGetOutputPropertyReply reply;
- char *extra;
+ char *extra = NULL;
REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq);
if (stuff->delete)
@@ -661,11 +670,10 @@ ProcRRGetOutputProperty (ClientPtr client)
if (prop->immutable && stuff->delete)
return BadAccess;
- if (stuff->pending && prop->is_pending)
- prop_value = &prop->pending;
- else
- prop_value = &prop->current;
-
+ prop_value = RRGetOutputProperty(output, stuff->property, stuff->pending);
+ if (!prop_value)
+ return BadAtom;
+
/* If the request type and actual type don't match. Return the
property information, but not the data. */
diff --git a/xorg-server/randr/rrscreen.c b/xorg-server/randr/rrscreen.c
index f39197337..dd645a936 100644
--- a/xorg-server/randr/rrscreen.c
+++ b/xorg-server/randr/rrscreen.c
@@ -22,9 +22,7 @@
#include "randrstr.h"
-extern char *ConnectionInfo;
-
-static int padlength[4] = {0, 3, 2, 1};
+static const int padlength[4] = {0, 3, 2, 1};
static CARD16
RR10CurrentSizeID (ScreenPtr pScreen);
@@ -226,7 +224,7 @@ ProcRRGetScreenSizeRange (ClientPtr client)
if (pScrPriv)
{
- if (!RRGetInfo (pScreen))
+ if (!RRGetInfo (pScreen, FALSE))
return BadAlloc;
rep.minWidth = pScrPriv->minWidth;
rep.minHeight = pScrPriv->minHeight;
@@ -316,8 +314,8 @@ ProcRRSetScreenSize (ClientPtr client)
return Success;
}
-int
-ProcRRGetScreenResources (ClientPtr client)
+static int
+rrGetScreenResources(ClientPtr client, Bool query)
{
REQUEST(xRRGetScreenResourcesReq);
xRRGetScreenResourcesReply rep;
@@ -326,7 +324,7 @@ ProcRRGetScreenResources (ClientPtr client)
rrScrPrivPtr pScrPriv;
CARD8 *extra;
unsigned long extraLen;
- int i, n, rc;
+ int i, n, rc, has_primary = 0;
RRCrtc *crtcs;
RROutput *outputs;
xRRModeInfo *modeinfos;
@@ -341,8 +339,8 @@ ProcRRGetScreenResources (ClientPtr client)
pScrPriv = rrGetScrPriv(pScreen);
rep.pad = 0;
- if (pScrPriv)
- if (!RRGetInfo (pScreen))
+ if (query && pScrPriv)
+ if (!RRGetInfo (pScreen, query))
return BadAlloc;
if (!pScrPriv)
@@ -403,12 +401,26 @@ ProcRRGetScreenResources (ClientPtr client)
outputs = (RROutput *) (crtcs + pScrPriv->numCrtcs);
modeinfos = (xRRModeInfo *) (outputs + pScrPriv->numOutputs);
names = (CARD8 *) (modeinfos + num_modes);
+
+ if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc)
+ {
+ has_primary = 1;
+ crtcs[0] = pScrPriv->primaryOutput->crtc->id;
+ if (client->swapped)
+ swapl (&crtcs[0], n);
+ }
for (i = 0; i < pScrPriv->numCrtcs; i++)
{
- crtcs[i] = pScrPriv->crtcs[i]->id;
+ if (has_primary &&
+ pScrPriv->primaryOutput->crtc == pScrPriv->crtcs[i])
+ {
+ has_primary = 0;
+ continue;
+ }
+ crtcs[i + has_primary] = pScrPriv->crtcs[i]->id;
if (client->swapped)
- swapl (&crtcs[i], n);
+ swapl (&crtcs[i + has_primary], n);
}
for (i = 0; i < pScrPriv->numOutputs; i++)
@@ -465,6 +477,18 @@ ProcRRGetScreenResources (ClientPtr client)
return client->noClientException;
}
+int
+ProcRRGetScreenResources (ClientPtr client)
+{
+ return rrGetScreenResources(client, TRUE);
+}
+
+int
+ProcRRGetScreenResourcesCurrent (ClientPtr client)
+{
+ return rrGetScreenResources(client, FALSE);
+}
+
typedef struct _RR10Data {
RRScreenSizePtr sizes;
int nsize;
@@ -591,7 +615,7 @@ ProcRRGetScreenInfo (ClientPtr client)
rep.pad = 0;
if (pScrPriv)
- if (!RRGetInfo (pScreen))
+ if (!RRGetInfo (pScreen, TRUE))
return BadAlloc;
output = RRFirstOutput (pScreen);
@@ -599,7 +623,7 @@ ProcRRGetScreenInfo (ClientPtr client)
if (!pScrPriv || !output)
{
rep.type = X_Reply;
- rep.setOfRotations = RR_Rotate_0;;
+ rep.setOfRotations = RR_Rotate_0;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
@@ -772,7 +796,7 @@ ProcRRSetScreenConfig (ClientPtr client)
rep.status = RRSetConfigFailed;
goto sendReply;
}
- if (!RRGetInfo (pScreen))
+ if (!RRGetInfo (pScreen, FALSE))
return BadAlloc;
output = RRFirstOutput (pScreen);
@@ -921,8 +945,10 @@ ProcRRSetScreenConfig (ClientPtr client)
if (!RRCrtcSet (crtc, mode, 0, 0, stuff->rotation, 1, &output))
rep.status = RRSetConfigFailed;
- else
+ else {
+ pScrPriv->lastSetTime = time;
rep.status = RRSetConfigSuccess;
+ }
/*
* XXX Configure other crtcs to mirror as much as possible
diff --git a/xorg-server/randr/rrsdispatch.c b/xorg-server/randr/rrsdispatch.c
index 80d16b75a..9fbf8f0f5 100644
--- a/xorg-server/randr/rrsdispatch.c
+++ b/xorg-server/randr/rrsdispatch.c
@@ -125,7 +125,7 @@ static int
SProcRRGetOutputInfo (ClientPtr client)
{
int n;
- REQUEST(xRRGetOutputInfoReq);;
+ REQUEST(xRRGetOutputInfoReq);
REQUEST_SIZE_MATCH(xRRGetOutputInfoReq);
swaps(&stuff->length, n);
@@ -364,6 +364,103 @@ SProcRRSetCrtcGamma (ClientPtr client)
return (*ProcRandrVector[stuff->randrReqType]) (client);
}
+static int
+SProcRRSetCrtcTransform (ClientPtr client)
+{
+ int n, nparams;
+ char *filter;
+ CARD32 *params;
+ REQUEST(xRRSetCrtcTransformReq);
+
+ REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->crtc, n);
+ SwapLongs((CARD32 *)&stuff->transform, (sizeof(xRenderTransform)) >> 2);
+ swaps(&stuff->nbytesFilter, n);
+ filter = (char *)(stuff + 1);
+ params = (CARD32 *) (filter + ((stuff->nbytesFilter + 3) & ~3));
+ nparams = ((CARD32 *) stuff + client->req_len) - params;
+ if (nparams < 0)
+ return BadLength;
+
+ SwapLongs(params, nparams);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetCrtcTransform (ClientPtr client)
+{
+ int n;
+ REQUEST(xRRGetCrtcTransformReq);
+
+ REQUEST_SIZE_MATCH(xRRGetCrtcTransformReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->crtc, n);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetPanning (ClientPtr client)
+{
+ int n;
+ REQUEST(xRRGetPanningReq);
+
+ REQUEST_SIZE_MATCH(xRRGetPanningReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->crtc, n);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSetPanning (ClientPtr client)
+{
+ int n;
+ REQUEST(xRRSetPanningReq);
+
+ REQUEST_SIZE_MATCH(xRRSetPanningReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->crtc, n);
+ swapl(&stuff->timestamp, n);
+ swaps(&stuff->left, n);
+ swaps(&stuff->top, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ swaps(&stuff->track_left, n);
+ swaps(&stuff->track_top, n);
+ swaps(&stuff->track_width, n);
+ swaps(&stuff->track_height, n);
+ swaps(&stuff->border_left, n);
+ swaps(&stuff->border_top, n);
+ swaps(&stuff->border_right, n);
+ swaps(&stuff->border_bottom, n);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSetOutputPrimary (ClientPtr client)
+{
+ int n;
+ REQUEST(xRRSetOutputPrimaryReq);
+
+ REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ swapl(&stuff->output, n);
+ return ProcRandrVector[stuff->randrReqType](client);
+}
+
+static int
+SProcRRGetOutputPrimary (ClientPtr client)
+{
+ int n;
+ REQUEST(xRRSetOutputPrimaryReq);
+
+ REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ return ProcRandrVector[stuff->randrReqType](client);
+}
+
int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = {
SProcRRQueryVersion, /* 0 */
/* we skip 1 to make old clients fail pretty immediately */
@@ -394,5 +491,13 @@ int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = {
SProcRRGetCrtcGammaSize, /* 22 */
SProcRRGetCrtcGamma, /* 23 */
SProcRRSetCrtcGamma, /* 24 */
+/* V1.3 additions */
+ SProcRRGetScreenResources, /* 25 GetScreenResourcesCurrent */
+ SProcRRSetCrtcTransform, /* 26 */
+ SProcRRGetCrtcTransform, /* 27 */
+ SProcRRGetPanning, /* 28 */
+ SProcRRSetPanning, /* 29 */
+ SProcRRSetOutputPrimary, /* 30 */
+ SProcRRGetOutputPrimary, /* 31 */
};
diff --git a/xorg-server/randr/rrtransform.c b/xorg-server/randr/rrtransform.c
new file mode 100644
index 000000000..8bdff5ab6
--- /dev/null
+++ b/xorg-server/randr/rrtransform.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright © 2007 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include "randrstr.h"
+#include "rrtransform.h"
+
+void
+RRTransformInit (RRTransformPtr transform)
+{
+ pixman_transform_init_identity (&transform->transform);
+ pixman_f_transform_init_identity (&transform->f_transform);
+ pixman_f_transform_init_identity (&transform->f_inverse);
+ transform->filter = NULL;
+ transform->params = NULL;
+ transform->nparams = 0;
+}
+
+void
+RRTransformFini (RRTransformPtr transform)
+{
+ if (transform->params)
+ xfree (transform->params);
+}
+
+Bool
+RRTransformEqual (RRTransformPtr a, RRTransformPtr b)
+{
+ if (a && pixman_transform_is_identity (&a->transform))
+ a = NULL;
+ if (b && pixman_transform_is_identity (&b->transform))
+ b = NULL;
+ if (a == NULL && b == NULL)
+ return TRUE;
+ if (a == NULL || b == NULL)
+ return FALSE;
+ if (memcmp (&a->transform, &b->transform, sizeof (a->transform)) != 0)
+ return FALSE;
+ if (a->filter != b->filter)
+ return FALSE;
+ if (a->nparams != b->nparams)
+ return FALSE;
+ if (memcmp (a->params, b->params, a->nparams * sizeof (xFixed)) != 0)
+ return FALSE;
+ return TRUE;
+}
+
+Bool
+RRTransformSetFilter (RRTransformPtr dst,
+ PictFilterPtr filter,
+ xFixed *params,
+ int nparams,
+ int width,
+ int height)
+{
+ xFixed *new_params;
+
+ if (nparams)
+ {
+ new_params = xalloc (nparams * sizeof (xFixed));
+ if (!new_params)
+ return FALSE;
+ memcpy (new_params, params, nparams * sizeof (xFixed));
+ }
+ else
+ new_params = NULL;
+ if (dst->params)
+ xfree (dst->params);
+ dst->filter = filter;
+ dst->params = new_params;
+ dst->nparams = nparams;
+ dst->width = width;
+ dst->height = height;
+ return TRUE;
+}
+
+Bool
+RRTransformCopy (RRTransformPtr dst, RRTransformPtr src)
+{
+ if (src && pixman_transform_is_identity (&src->transform))
+ src = NULL;
+
+ if (src)
+ {
+ if (!RRTransformSetFilter (dst, src->filter,
+ src->params, src->nparams, src->width, src->height))
+ return FALSE;
+ dst->transform = src->transform;
+ dst->f_transform = src->f_transform;
+ dst->f_inverse = src->f_inverse;
+ }
+ else
+ {
+ if (!RRTransformSetFilter (dst, NULL, NULL, 0, 0, 0))
+ return FALSE;
+ pixman_transform_init_identity (&dst->transform);
+ pixman_f_transform_init_identity (&dst->f_transform);
+ pixman_f_transform_init_identity (&dst->f_inverse);
+ }
+ return TRUE;
+}
+
+#define F(x) IntToxFixed(x)
+
+static void
+RRTransformRescale(struct pixman_f_transform *f_transform, double limit)
+{
+ double max = 0, v, scale;
+ int i, j;
+
+ for (j = 0; j < 3; j++)
+ for (i = 0; i < 3; i++)
+ if ((v = abs (f_transform->m[j][i])) > max)
+ max = v;
+ scale = limit / max;
+ for (j = 0; j < 3; j++)
+ for (i = 0; i < 3; i++)
+ f_transform->m[j][i] *= scale;
+}
+
+/*
+ * Compute the complete transformation matrix including
+ * client-specified transform, rotation/reflection values and the crtc
+ * offset.
+ *
+ * Return TRUE if the resulting transform is not a simple translation.
+ */
+Bool
+RRTransformCompute (int x,
+ int y,
+ int width,
+ int height,
+ Rotation rotation,
+ RRTransformPtr rr_transform,
+
+ PictTransformPtr transform,
+ struct pixman_f_transform *f_transform,
+ struct pixman_f_transform *f_inverse)
+{
+ PictTransform t_transform, inverse;
+ struct pixman_f_transform tf_transform, tf_inverse;
+ Bool overflow = FALSE;
+
+ if (!transform) transform = &t_transform;
+ if (!f_transform) f_transform = &tf_transform;
+ if (!f_inverse) f_inverse = &tf_inverse;
+
+ pixman_transform_init_identity (transform);
+ pixman_transform_init_identity (&inverse);
+ pixman_f_transform_init_identity (f_transform);
+ pixman_f_transform_init_identity (f_inverse);
+ if (rotation != RR_Rotate_0)
+ {
+ double f_rot_cos, f_rot_sin, f_rot_dx, f_rot_dy;
+ double f_scale_x, f_scale_y, f_scale_dx, f_scale_dy;
+ xFixed rot_cos, rot_sin, rot_dx, rot_dy;
+ xFixed scale_x, scale_y, scale_dx, scale_dy;
+
+ /* rotation */
+ switch (rotation & 0xf) {
+ default:
+ case RR_Rotate_0:
+ f_rot_cos = 1; f_rot_sin = 0;
+ f_rot_dx = 0; f_rot_dy = 0;
+ rot_cos = F ( 1); rot_sin = F ( 0);
+ rot_dx = F ( 0); rot_dy = F ( 0);
+ break;
+ case RR_Rotate_90:
+ f_rot_cos = 0; f_rot_sin = 1;
+ f_rot_dx = height-1; f_rot_dy = 0;
+ rot_cos = F ( 0); rot_sin = F ( 1);
+ rot_dx = F (height-1); rot_dy = F (0);
+ break;
+ case RR_Rotate_180:
+ f_rot_cos = -1; f_rot_sin = 0;
+ f_rot_dx = width - 1; f_rot_dy = height - 1;
+ rot_cos = F (-1); rot_sin = F ( 0);
+ rot_dx = F (width-1); rot_dy = F ( height-1);
+ break;
+ case RR_Rotate_270:
+ f_rot_cos = 0; f_rot_sin = -1;
+ f_rot_dx = 0; f_rot_dy = width-1;
+ rot_cos = F ( 0); rot_sin = F (-1);
+ rot_dx = F ( 0); rot_dy = F ( width-1);
+ break;
+ }
+
+ pixman_transform_rotate (transform, &inverse, rot_cos, rot_sin);
+ pixman_transform_translate (transform, &inverse, rot_dx, rot_dy);
+ pixman_f_transform_rotate (f_transform, f_inverse, f_rot_cos, f_rot_sin);
+ pixman_f_transform_translate (f_transform, f_inverse, f_rot_dx, f_rot_dy);
+
+ /* reflection */
+ f_scale_x = 1;
+ f_scale_dx = 0;
+ f_scale_y = 1;
+ f_scale_dy = 0;
+ scale_x = F (1);
+ scale_dx = 0;
+ scale_y = F (1);
+ scale_dy = 0;
+ if (rotation & RR_Reflect_X)
+ {
+ f_scale_x = -1;
+ scale_x = F(-1);
+ if (rotation & (RR_Rotate_0|RR_Rotate_180)) {
+ f_scale_dx = width-1;
+ scale_dx = F(width-1);
+ } else {
+ f_scale_dx = height-1;
+ scale_dx = F(height-1);
+ }
+ }
+ if (rotation & RR_Reflect_Y)
+ {
+ f_scale_y = -1;
+ scale_y = F(-1);
+ if (rotation & (RR_Rotate_0|RR_Rotate_180)) {
+ f_scale_dy = height-1;
+ scale_dy = F(height-1);
+ } else {
+ f_scale_dy = width-1;
+ scale_dy = F(width-1);
+ }
+ }
+
+ pixman_transform_scale (transform, &inverse, scale_x, scale_y);
+ pixman_f_transform_scale (f_transform, f_inverse, f_scale_x, f_scale_y);
+ pixman_transform_translate (transform, &inverse, scale_dx, scale_dy);
+ pixman_f_transform_translate (f_transform, f_inverse, f_scale_dx, f_scale_dy);
+ }
+
+#ifdef RANDR_12_INTERFACE
+ if (rr_transform)
+ {
+ if (!pixman_transform_multiply (transform, transform, &rr_transform->transform))
+ overflow = TRUE;
+ pixman_f_transform_multiply (f_transform, f_transform, &rr_transform->f_transform);
+ pixman_f_transform_multiply (f_inverse, &rr_transform->f_inverse, f_inverse);
+ }
+#endif
+ /*
+ * Compute the class of the resulting transform
+ */
+ if (!overflow && pixman_transform_is_identity (transform))
+ {
+ pixman_transform_init_translate (transform, F ( x), F ( y));
+
+ pixman_f_transform_init_translate (f_transform, x, y);
+ pixman_f_transform_init_translate (f_inverse, -x, -y);
+ return FALSE;
+ }
+ else
+ {
+ pixman_f_transform_translate (f_transform, f_inverse, x, y);
+ if (!pixman_transform_translate (transform, &inverse, F(x), F(y)))
+ overflow = TRUE;
+ if (overflow)
+ {
+ struct pixman_f_transform f_scaled;
+ f_scaled = *f_transform;
+ RRTransformRescale(&f_scaled, 16384.0);
+ pixman_transform_from_pixman_f_transform(transform, &f_scaled);
+ }
+ return TRUE;
+ }
+}
diff --git a/xorg-server/randr/rrtransform.h b/xorg-server/randr/rrtransform.h
new file mode 100644
index 000000000..92d3ee7be
--- /dev/null
+++ b/xorg-server/randr/rrtransform.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright © 2007 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _RRTRANSFORM_H_
+#define _RRTRANSFORM_H_
+
+#include <X11/extensions/randr.h>
+#include "picturestr.h"
+
+typedef struct _rrTransform RRTransformRec, *RRTransformPtr;
+
+struct _rrTransform {
+ PictTransform transform;
+ struct pict_f_transform f_transform;
+ struct pict_f_transform f_inverse;
+ PictFilterPtr filter;
+ xFixed *params;
+ int nparams;
+ int width;
+ int height;
+};
+
+void
+RRTransformInit (RRTransformPtr transform);
+
+void
+RRTransformFini (RRTransformPtr transform);
+
+Bool
+RRTransformEqual (RRTransformPtr a, RRTransformPtr b);
+
+Bool
+RRTransformSetFilter (RRTransformPtr dst,
+ PictFilterPtr filter,
+ xFixed *params,
+ int nparams,
+ int width,
+ int height);
+
+Bool
+RRTransformCopy (RRTransformPtr dst, RRTransformPtr src);
+
+Bool
+RRTransformCompute (int x,
+ int y,
+ int width,
+ int height,
+ Rotation rotation,
+ RRTransformPtr rr_transform,
+
+ PictTransformPtr transform,
+ struct pict_f_transform *f_transform,
+ struct pict_f_transform *f_inverse);
+
+
+#endif /* _RRTRANSFORM_H_ */
diff --git a/xorg-server/randr/rrxinerama.c b/xorg-server/randr/rrxinerama.c
index e6acd5e57..36135c6c1 100644
--- a/xorg-server/randr/rrxinerama.c
+++ b/xorg-server/randr/rrxinerama.c
@@ -260,6 +260,44 @@ ProcRRXineramaIsActive(ClientPtr client)
return client->noClientException;
}
+static void
+RRXineramaWriteCrtc(ClientPtr client, RRCrtcPtr crtc)
+{
+ xXineramaScreenInfo scratch;
+
+ if (RRXineramaCrtcActive (crtc))
+ {
+ ScreenPtr pScreen = crtc->pScreen;
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(pScreen);
+ BoxRec panned_area;
+
+ /* Check to see if crtc is panned and return the full area when applicable. */
+ if (pScrPriv && pScrPriv->rrGetPanning &&
+ pScrPriv->rrGetPanning (pScreen, crtc, &panned_area, NULL, NULL) &&
+ (panned_area.x2 > panned_area.x1) && (panned_area.y2 > panned_area.y1)) {
+ scratch.x_org = panned_area.x1;
+ scratch.y_org = panned_area.y1;
+ scratch.width = panned_area.x2 - panned_area.x1;
+ scratch.height = panned_area.y2 - panned_area.y1;
+ } else {
+ int width, height;
+ RRCrtcGetScanoutSize (crtc, &width, &height);
+ scratch.x_org = crtc->x;
+ scratch.y_org = crtc->y;
+ scratch.width = width;
+ scratch.height = height;
+ }
+ if(client->swapped) {
+ register int n;
+ swaps(&scratch.x_org, n);
+ swaps(&scratch.y_org, n);
+ swaps(&scratch.width, n);
+ swaps(&scratch.height, n);
+ }
+ WriteToClient(client, sz_XineramaScreenInfo, &scratch);
+ }
+}
+
int
ProcRRXineramaQueryScreens(ClientPtr client)
{
@@ -269,12 +307,8 @@ ProcRRXineramaQueryScreens(ClientPtr client)
REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
if (RRXineramaScreenActive (pScreen))
- {
- rrScrPriv(pScreen);
- if (pScrPriv->numCrtcs == 0 || pScrPriv->numOutputs == 0)
- RRGetInfo (pScreen);
- }
-
+ RRGetInfo (pScreen, FALSE);
+
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.number = RRXineramaScreenCount (pScreen);
@@ -289,28 +323,22 @@ ProcRRXineramaQueryScreens(ClientPtr client)
if(rep.number) {
rrScrPriv(pScreen);
- xXineramaScreenInfo scratch;
int i;
+ int has_primary = 0;
+
+ if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) {
+ has_primary = 1;
+ RRXineramaWriteCrtc(client, pScrPriv->primaryOutput->crtc);
+ }
for(i = 0; i < pScrPriv->numCrtcs; i++) {
- RRCrtcPtr crtc = pScrPriv->crtcs[i];
- if (RRXineramaCrtcActive (crtc))
+ if (has_primary &&
+ pScrPriv->primaryOutput->crtc == pScrPriv->crtcs[i])
{
- int width, height;
- RRCrtcGetScanoutSize (crtc, &width, &height);
- scratch.x_org = crtc->x;
- scratch.y_org = crtc->y;
- scratch.width = width;
- scratch.height = height;
- if(client->swapped) {
- register int n;
- swaps(&scratch.x_org, n);
- swaps(&scratch.y_org, n);
- swaps(&scratch.width, n);
- swaps(&scratch.height, n);
- }
- WriteToClient(client, sz_XineramaScreenInfo, (char *)&scratch);
+ has_primary = 0;
+ continue;
}
+ RRXineramaWriteCrtc(client, pScrPriv->crtcs[i]);
}
}
@@ -425,11 +453,6 @@ SProcRRXineramaDispatch(ClientPtr client)
return BadRequest;
}
-static void
-RRXineramaResetProc(ExtensionEntry* extEntry)
-{
-}
-
void
RRXineramaExtensionInit(void)
{
@@ -449,6 +472,6 @@ RRXineramaExtensionInit(void)
(void) AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0,
ProcRRXineramaDispatch,
SProcRRXineramaDispatch,
- RRXineramaResetProc,
+ NULL,
StandardMinorOpcode);
}