diff options
Diffstat (limited to 'xorg-server/randr')
-rw-r--r-- | xorg-server/randr/Makefile.am | 6 | ||||
-rw-r--r-- | xorg-server/randr/Makefile.in | 89 | ||||
-rw-r--r-- | xorg-server/randr/mirandr.c | 13 | ||||
-rw-r--r-- | xorg-server/randr/randr.c | 27 | ||||
-rw-r--r-- | xorg-server/randr/randrstr.h | 116 | ||||
-rw-r--r-- | xorg-server/randr/rrcrtc.c | 501 | ||||
-rw-r--r-- | xorg-server/randr/rrdispatch.c | 15 | ||||
-rw-r--r-- | xorg-server/randr/rrinfo.c | 12 | ||||
-rw-r--r-- | xorg-server/randr/rrmode.c | 3 | ||||
-rw-r--r-- | xorg-server/randr/rroutput.c | 107 | ||||
-rw-r--r-- | xorg-server/randr/rrpointer.c | 33 | ||||
-rw-r--r-- | xorg-server/randr/rrproperty.c | 26 | ||||
-rw-r--r-- | xorg-server/randr/rrscreen.c | 56 | ||||
-rw-r--r-- | xorg-server/randr/rrsdispatch.c | 107 | ||||
-rw-r--r-- | xorg-server/randr/rrtransform.c | 285 | ||||
-rw-r--r-- | xorg-server/randr/rrtransform.h | 75 | ||||
-rw-r--r-- | xorg-server/randr/rrxinerama.c | 81 |
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, ¤t->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 af456e93a..bb1620cfd 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 @@ -384,6 +385,9 @@ RROutputDestroyResource (pointer value, XID pid) { rrScrPriv(pScreen); int i; + + if (pScrPriv->primaryOutput == output) + pScrPriv->primaryOutput = NULL; for (i = 0; i < pScrPriv->numOutputs; i++) { @@ -431,7 +435,7 @@ RROutputInit (void) } #define OutputInfoExtra (SIZEOF(xRRGetOutputInfoReply) - 32) - + int ProcRRGetOutputInfo (ClientPtr client) { @@ -538,3 +542,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 e357189ca..4c7d35678 100644 --- a/xorg-server/randr/rrscreen.c +++ b/xorg-server/randr/rrscreen.c @@ -22,14 +22,12 @@ #include "randrstr.h" +static const int padlength[4] = {0, 3, 2, 1}; /* From render.h */ #ifndef SubPixelUnknown #define SubPixelUnknown 0 #endif -extern char *ConnectionInfo; - -static int padlength[4] = {0, 3, 2, 1}; static CARD16 RR10CurrentSizeID (ScreenPtr pScreen); @@ -231,7 +229,7 @@ ProcRRGetScreenSizeRange (ClientPtr client) if (pScrPriv) { - if (!RRGetInfo (pScreen)) + if (!RRGetInfo (pScreen, FALSE)) return BadAlloc; rep.minWidth = pScrPriv->minWidth; rep.minHeight = pScrPriv->minHeight; @@ -321,8 +319,8 @@ ProcRRSetScreenSize (ClientPtr client) return Success; } -int -ProcRRGetScreenResources (ClientPtr client) +static int +rrGetScreenResources(ClientPtr client, Bool query) { REQUEST(xRRGetScreenResourcesReq); xRRGetScreenResourcesReply rep; @@ -331,7 +329,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; @@ -346,8 +344,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) @@ -408,12 +406,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++) @@ -470,6 +482,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; @@ -596,7 +620,7 @@ ProcRRGetScreenInfo (ClientPtr client) rep.pad = 0; if (pScrPriv) - if (!RRGetInfo (pScreen)) + if (!RRGetInfo (pScreen, TRUE)) return BadAlloc; output = RRFirstOutput (pScreen); @@ -604,7 +628,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; @@ -777,7 +801,7 @@ ProcRRSetScreenConfig (ClientPtr client) rep.status = RRSetConfigFailed; goto sendReply; } - if (!RRGetInfo (pScreen)) + if (!RRGetInfo (pScreen, FALSE)) return BadAlloc; output = RRFirstOutput (pScreen); @@ -926,8 +950,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); } |