From 1d8f821ba4e851026b1ce93dda8554966c568ec7 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sep 26 2007 07:33:55 +0000 Subject: * Wed Sep 26 2007 Dave Airlie 1.3.0.0-25 - xserver-1.3.0-randr-updates.patch: Backport randr from server git This contains a lot of fixes since 1.3.0 went out, and saves us backporting each fix individually - xserver-1.3.0-less-randr-fakerama.patch - dropped - xorg-x11-server-1.2.0-maxpixclock-option.patch - dropped - xserver-1.3.0-edid-quirk-backports.patch - dropped - xserver-1.2.0-honor-displaysize.patch - dropped - xserver-1.3.0-honor-displaysize.patch - reapply to new code layout - xserver-1.3.0-randr12-config-hack.patch - rebased --- diff --git a/xorg-x11-server-1.2.0-maxpixclock-option.patch b/xorg-x11-server-1.2.0-maxpixclock-option.patch deleted file mode 100644 index c01137c..0000000 --- a/xorg-x11-server-1.2.0-maxpixclock-option.patch +++ /dev/null @@ -1,76 +0,0 @@ ---- xorg-server-1.2.0/hw/xfree86/ddc/ddcProperty.c.maxpixclock 2007-01-22 22:13:15.000000000 -0500 -+++ xorg-server-1.2.0/hw/xfree86/ddc/ddcProperty.c 2007-01-23 12:35:00.000000000 -0500 -@@ -303,7 +303,7 @@ - { - DisplayModePtr Modes = NULL, Mode; - int i, clock; -- Bool have_hsync = FALSE, have_vrefresh = FALSE; -+ Bool have_hsync = FALSE, have_vrefresh = FALSE, have_maxpixclock = FALSE; - int preferred; - - if (!Monitor || !DDC) -@@ -332,6 +332,7 @@ - /* Skip EDID ranges if they were specified in the config file */ - have_hsync = (Monitor->nHsync != 0); - have_vrefresh = (Monitor->nVrefresh != 0); -+ have_maxpixclock = (Monitor->maxPixClock != 0); - - /* Go through the detailed monitor sections */ - for (i = 0; i < DET_TIMINGS; i++) -@@ -366,7 +367,7 @@ - } - - clock = DDC->det_mon[i].section.ranges.max_clock * 1000; -- if (clock > Monitor->maxPixClock) -+ if (!have_maxpixclock && clock > Monitor->maxPixClock) - Monitor->maxPixClock = clock; - - break; ---- xorg-server-1.2.0/hw/xfree86/common/xf86Mode.c.maxpixclock 2007-01-22 22:13:15.000000000 -0500 -+++ xorg-server-1.2.0/hw/xfree86/common/xf86Mode.c 2007-01-23 12:33:41.000000000 -0500 -@@ -1408,6 +1408,12 @@ - scrp->monitor->vrefresh[i].lo, - scrp->monitor->vrefresh[i].hi); - } -+ if (scrp->monitor->maxPixClock) { -+ xf86DrvMsg(scrp->scrnIndex, X_INFO, -+ "%s: Using maximum pixel clock of %.2f MHz\n", -+ scrp->monitor->id, -+ (float)scrp->monitor->maxPixClock / 1000.0); -+ } - } - - /* ---- xorg-server-1.2.0/hw/xfree86/common/xf86Config.c.maxpixclock 2007-01-22 22:13:15.000000000 -0500 -+++ xorg-server-1.2.0/hw/xfree86/common/xf86Config.c 2007-01-23 12:33:41.000000000 -0500 -@@ -2211,12 +2211,15 @@ - } - - typedef enum { -- MON_REDUCEDBLANKING -+ MON_REDUCEDBLANKING, -+ MON_MAX_PIX_CLOCK, - } MonitorValues; - - static OptionInfoRec MonitorOptions[] = { - { MON_REDUCEDBLANKING, "ReducedBlanking", OPTV_BOOLEAN, - {0}, FALSE }, -+ { MON_MAX_PIX_CLOCK, "MaxPixClock", OPTV_FREQ, -+ {0}, FALSE }, - { -1, NULL, OPTV_NONE, - {0}, FALSE }, - }; -@@ -2363,11 +2366,11 @@ - return FALSE; - } - -- /* Check wether this Monitor accepts Reduced Blanking modelines */ - xf86ProcessOptions(-1, monitorp->options, MonitorOptions); -- - xf86GetOptValBool(MonitorOptions, MON_REDUCEDBLANKING, - &monitorp->reducedblanking); -+ xf86GetOptValFreq(MonitorOptions, MON_MAX_PIX_CLOCK, OPTUNITS_KHZ, -+ &monitorp->maxPixClock); - return TRUE; - } - diff --git a/xorg-x11-server.spec b/xorg-x11-server.spec index 10acdb0..1019345 100644 --- a/xorg-x11-server.spec +++ b/xorg-x11-server.spec @@ -9,7 +9,7 @@ Summary: X.Org X11 X server Name: xorg-x11-server Version: 1.3.0.0 -Release: 24%{?dist} +Release: 25%{?dist} URL: http://www.x.org License: MIT/X11 Group: User Interface/X @@ -52,24 +52,22 @@ Patch1005: xorg-x11-server-1.1.1-builtin-fonts.patch Patch1006: xorg-x11-server-1.1.1-no-scanpci.patch Patch1007: xorg-x11-server-1.1.1-spurious-libxf1bpp-link.patch Patch1008: xorg-x11-server-1.2.0-xf86config-comment-less.patch -Patch1009: xorg-x11-server-1.2.0-maxpixclock-option.patch Patch1010: xserver-1.3.0-no-prerelease-warning.patch Patch1011: xserver-1.3.0-composite-version.patch Patch1012: xserver-1.3.0-mesa7.patch Patch1013: xserver-1.3.0-exaupgrade.patch Patch1014: xserver-1.3.0-newglx-offscreen-pixmaps.patch +Patch1015: xserver-1.3.0-randr-updates.patch Patch1022: xserver-1.3.0-default-dpi.patch Patch2001: xserver-1.2.0-geode-mmx.patch Patch2002: xserver-1.2.0-xephyr-keysym-madness.patch Patch2003: xserver-1.2.0-vfprintf.patch -Patch2004: xserver-1.2.0-honor-displaysize.patch -Patch2006: xserver-1.3.0-less-randr-fakerama.patch +Patch2004: xserver-1.3.0-honor-displaysize.patch Patch2007: xserver-1.3.0-randr12-config-hack.patch Patch2008: xserver-1.3.0-randrama-no-zero-screens.patch Patch2009: xserver-1.3.0-arm-iopl.patch Patch2010: xserver-1.3.0-idletime.patch -Patch2011: xserver-1.3.0-edid-quirk-backports.patch Patch2012: xserver-1.3.0-add-really-slow-bcopy.patch Patch2013: xserver-1.3.0-document-fontpath-correctly.patch @@ -313,24 +311,22 @@ Xserver source code needed to build VNC server (Xvnc) %patch1006 -p1 -b .no-scanpci %patch1007 -p1 -b .xf1bpp %patch1008 -p1 -b .comment-less -%patch1009 -p1 -b .maxpixclock %patch1010 -p1 -b .prerelease-warning %patch1011 -p1 -b .composite-version %patch1012 -p1 -b .newmesa %patch1013 -p1 -b .newexa %patch1014 -p1 -b .offscreen-pixmaps +%patch1015 -p1 -b .randr-update %patch1022 -p1 -b .dpi %patch2001 -p1 -b .geode-mmx %patch2002 -p1 -b .xephyr-keysym %patch2003 -p1 -b .vfprintf %patch2004 -p1 -b .displaysize -%patch2006 -p1 -b .fakerama %patch2007 -p1 -b .randrconfig %patch2008 -p1 -b .randrama-zero-screens %patch2009 -p1 -b .arm %patch2010 -p1 -b .idletime -%patch2011 -p1 -b .edid-quirks %patch2012 -p1 -b .slow-bcopy %patch2013 -p1 -b .fontpath-doc @@ -608,6 +604,17 @@ rm -rf $RPM_BUILD_ROOT %changelog +* Wed Sep 26 2007 Dave Airlie 1.3.0.0-25 +- xserver-1.3.0-randr-updates.patch: Backport randr from server git + This contains a lot of fixes since 1.3.0 went out, and saves + us backporting each fix individually +- xserver-1.3.0-less-randr-fakerama.patch - dropped +- xorg-x11-server-1.2.0-maxpixclock-option.patch - dropped +- xserver-1.3.0-edid-quirk-backports.patch - dropped +- xserver-1.2.0-honor-displaysize.patch - dropped +- xserver-1.3.0-honor-displaysize.patch - reapply to new code layout +- xserver-1.3.0-randr12-config-hack.patch - rebased + * Mon Sep 17 2007 Adam Jackson 1.3.0.0-24 - xserver-1.3.0-edid-quirk-backports.patch: Update the EDID quirks code to match current git. diff --git a/xserver-1.2.0-honor-displaysize.patch b/xserver-1.2.0-honor-displaysize.patch deleted file mode 100644 index b81b9d7..0000000 --- a/xserver-1.2.0-honor-displaysize.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- xorg-server-1.2.0/hw/xfree86/ddc/ddcProperty.c.jx 2007-02-26 13:39:00.000000000 -0500 -+++ xorg-server-1.2.0/hw/xfree86/ddc/ddcProperty.c 2007-02-26 14:37:33.000000000 -0500 -@@ -313,8 +313,10 @@ - - preferred = PREFERRED_TIMING_MODE(DDC->features.msc); - -- Monitor->widthmm = 10 * DDC->features.hsize; -- Monitor->heightmm = 10 * DDC->features.vsize; -+ if (Monitor->widthmm <= 0 && Monitor->heightmm <= 0) { -+ Monitor->widthmm = 10 * DDC->features.hsize; -+ Monitor->heightmm = 10 * DDC->features.vsize; -+ } - - /* If this is a digital display, then we can use reduced blanking */ - if (DDC->features.input_type) diff --git a/xserver-1.3.0-edid-quirk-backports.patch b/xserver-1.3.0-edid-quirk-backports.patch deleted file mode 100644 index 22c9be5..0000000 --- a/xserver-1.3.0-edid-quirk-backports.patch +++ /dev/null @@ -1,90 +0,0 @@ -diff -up xorg-server-1.3.0.0/hw/xfree86/modes/xf86EdidModes.c.edid-quirks xorg-server-1.3.0.0/hw/xfree86/modes/xf86EdidModes.c ---- xorg-server-1.3.0.0/hw/xfree86/modes/xf86EdidModes.c.edid-quirks 2007-04-18 00:33:14.000000000 -0400 -+++ xorg-server-1.3.0.0/hw/xfree86/modes/xf86EdidModes.c 2007-09-17 14:37:36.000000000 -0400 -@@ -49,32 +49,12 @@ - - typedef enum { - DDC_QUIRK_NONE = 0, -- /* Force detailed sync polarity to -h +v */ -- DDC_QUIRK_DT_SYNC_HM_VP = 1 << 0, - /* First detailed mode is bogus, prefer largest mode at 60hz */ -- DDC_QUIRK_PREFER_LARGE_60 = 1 << 1, -+ DDC_QUIRK_PREFER_LARGE_60 = 1 << 0, - /* 135MHz clock is too high, drop a bit */ -- DDC_QUIRK_135_CLOCK_TOO_HIGH = 1 << 2 -+ DDC_QUIRK_135_CLOCK_TOO_HIGH = 1 << 1 - } ddc_quirk_t; - --static Bool quirk_dt_sync_hm_vp (int scrnIndex, xf86MonPtr DDC) --{ -- /* Belinea 1924S1W */ -- if (memcmp (DDC->vendor.name, "MAX", 4) == 0 && -- DDC->vendor.prod_id == 1932) -- return TRUE; -- /* Belinea 10 20 30W */ -- if (memcmp (DDC->vendor.name, "MAX", 4) == 0 && -- DDC->vendor.prod_id == 2007) -- return TRUE; -- /* ViewSonic VX2025wm (bug #9941) */ -- if (memcmp (DDC->vendor.name, "VSC", 4) == 0 && -- DDC->vendor.prod_id == 58653) -- return TRUE; -- -- return FALSE; --} -- - static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC) - { - /* Belinea 10 15 55 */ -@@ -87,9 +67,10 @@ static Bool quirk_prefer_large_60 (int s - DDC->vendor.prod_id == 44358) - return TRUE; - -- /* Samsung SyncMaster 226BW */ -+ /* Samsung SyncMaster 22[56]BW */ - if (memcmp (DDC->vendor.name, "SAM", 4) == 0 && -- DDC->vendor.prod_id == 638) -+ (DDC->vendor.prod_id == 638 || -+ DDC->vendor.prod_id == 596)) - return TRUE; - - return FALSE; -@@ -112,10 +93,6 @@ typedef struct { - } ddc_quirk_map_t; - - static const ddc_quirk_map_t ddc_quirks[] = { -- { -- quirk_dt_sync_hm_vp, DDC_QUIRK_DT_SYNC_HM_VP, -- "Set detailed timing sync polarity to -h +v" -- }, - { - quirk_prefer_large_60, DDC_QUIRK_PREFER_LARGE_60, - "Detailed timing is not preferred, use largest mode at 60Hz" -@@ -251,20 +228,15 @@ DDCModeFromDetailedTiming(int scrnIndex, - if (timing->interlaced) - Mode->Flags |= V_INTERLACE; - -- if (quirks & DDC_QUIRK_DT_SYNC_HM_VP) -- Mode->Flags |= V_NHSYNC | V_PVSYNC; -+ if (timing->misc & 0x02) -+ Mode->Flags |= V_PVSYNC; - else -- { -- if (timing->misc & 0x02) -- Mode->Flags |= V_PHSYNC; -- else -- Mode->Flags |= V_NHSYNC; -+ Mode->Flags |= V_NVSYNC; - -- if (timing->misc & 0x01) -- Mode->Flags |= V_PVSYNC; -- else -- Mode->Flags |= V_NVSYNC; -- } -+ if (timing->misc & 0x01) -+ Mode->Flags |= V_PHSYNC; -+ else -+ Mode->Flags |= V_NHSYNC; - - return Mode; - } diff --git a/xserver-1.3.0-honor-displaysize.patch b/xserver-1.3.0-honor-displaysize.patch new file mode 100644 index 0000000..e0dcb01 --- /dev/null +++ b/xserver-1.3.0-honor-displaysize.patch @@ -0,0 +1,16 @@ +diff -up xorg-server-1.3.0.0/hw/xfree86/modes/xf86EdidModes.c.da xorg-server-1.3.0.0/hw/xfree86/modes/xf86EdidModes.c +--- xorg-server-1.3.0.0/hw/xfree86/modes/xf86EdidModes.c.da 2007-09-26 17:04:02.000000000 +1000 ++++ xorg-server-1.3.0.0/hw/xfree86/modes/xf86EdidModes.c 2007-09-26 17:04:27.000000000 +1000 +@@ -401,8 +401,10 @@ xf86DDCMonitorSet(int scrnIndex, MonPtr + + Monitor->DDC = DDC; + +- Monitor->widthmm = 10 * DDC->features.hsize; +- Monitor->heightmm = 10 * DDC->features.vsize; ++ if (Monitor->widthmm <= 0 && Monitor->heightmm <= 0) { ++ Monitor->widthmm = 10 * DDC->features.hsize; ++ Monitor->heightmm = 10 * DDC->features.vsize; ++ } + + /* If this is a digital display, then we can use reduced blanking */ + if (DDC->features.input_type) diff --git a/xserver-1.3.0-less-randr-fakerama.patch b/xserver-1.3.0-less-randr-fakerama.patch deleted file mode 100644 index f8c1dee..0000000 --- a/xserver-1.3.0-less-randr-fakerama.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- xorg-server-1.3.0.0/randr/rrxinerama.c.jx 2007-01-30 02:01:52.000000000 -0500 -+++ xorg-server-1.3.0.0/randr/rrxinerama.c 2007-04-25 13:26:23.000000000 -0400 -@@ -425,6 +425,14 @@ - return; - #endif - -+ /* -+ * Xinerama isn't capable enough to have multiple protocol screens each -+ * with their own output geometry. So if there's more than one protocol -+ * screen, just don't even try. -+ */ -+ if (screenInfo.numScreens > 1) -+ return; -+ - (void) AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0, - ProcRRXineramaDispatch, - SProcRRXineramaDispatch, diff --git a/xserver-1.3.0-randr-updates.patch b/xserver-1.3.0-randr-updates.patch new file mode 100644 index 0000000..e492afe --- /dev/null +++ b/xserver-1.3.0-randr-updates.patch @@ -0,0 +1,3726 @@ +diff --git a/hw/xfree86/modes/Makefile.am b/hw/xfree86/modes/Makefile.am +index 0841a6d..1f82068 100644 +--- a/hw/xfree86/modes/Makefile.am ++++ b/hw/xfree86/modes/Makefile.am +@@ -26,4 +26,4 @@ sdk_HEADERS = \ + xf86RandR12.h \ + xf86Rename.h + +-AM_CFLAGS = $(XORG_CFLAGS) ++AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) +diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c +index 2d8a7ad..064ff16 100644 +--- a/hw/xfree86/modes/xf86Crtc.c ++++ b/hw/xfree86/modes/xf86Crtc.c +@@ -45,13 +45,15 @@ + #include "picturestr.h" + #endif + ++#include "xf86xv.h" ++ + /* + * Initialize xf86CrtcConfig structure + */ + + int xf86CrtcConfigPrivateIndex = -1; + +-void ++_X_EXPORT void + xf86CrtcConfigInit (ScrnInfoPtr scrn, + const xf86CrtcConfigFuncsRec *funcs) + { +@@ -66,7 +68,7 @@ xf86CrtcConfigInit (ScrnInfoPtr scrn, + scrn->privates[xf86CrtcConfigPrivateIndex].ptr = config; + } + +-void ++_X_EXPORT void + xf86CrtcSetSizeRange (ScrnInfoPtr scrn, + int minWidth, int minHeight, + int maxWidth, int maxHeight) +@@ -82,7 +84,7 @@ xf86CrtcSetSizeRange (ScrnInfoPtr scrn, + /* + * Crtc functions + */ +-xf86CrtcPtr ++_X_EXPORT xf86CrtcPtr + xf86CrtcCreate (ScrnInfoPtr scrn, + const xf86CrtcFuncsRec *funcs) + { +@@ -114,7 +116,7 @@ xf86CrtcCreate (ScrnInfoPtr scrn, + return crtc; + } + +-void ++_X_EXPORT void + xf86CrtcDestroy (xf86CrtcPtr crtc) + { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); +@@ -126,7 +128,7 @@ xf86CrtcDestroy (xf86CrtcPtr crtc) + { + memmove (&xf86_config->crtc[c], + &xf86_config->crtc[c+1], +- xf86_config->num_crtc - (c + 1)); ++ ((xf86_config->num_crtc - (c + 1)) * sizeof(void*))); + xf86_config->num_crtc--; + break; + } +@@ -138,7 +140,7 @@ xf86CrtcDestroy (xf86CrtcPtr crtc) + * Return whether any outputs are connected to the specified pipe + */ + +-Bool ++_X_EXPORT Bool + xf86CrtcInUse (xf86CrtcPtr crtc) + { + ScrnInfoPtr pScrn = crtc->scrn; +@@ -151,7 +153,7 @@ xf86CrtcInUse (xf86CrtcPtr crtc) + return FALSE; + } + +-void ++_X_EXPORT void + xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen) + { + #ifdef RENDER +@@ -219,7 +221,7 @@ xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen) + /** + * Sets the given video mode on the given crtc + */ +-Bool ++_X_EXPORT Bool + xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, + int x, int y) + { +@@ -377,6 +379,15 @@ static OptionInfoRec xf86OutputOptions[] = { + {-1, NULL, OPTV_NONE, {0}, FALSE }, + }; + ++enum { ++ OPTION_MODEDEBUG, ++}; ++ ++static OptionInfoRec xf86DeviceOptions[] = { ++ {OPTION_MODEDEBUG, "ModeDebug", OPTV_STRING, {0}, FALSE }, ++ {-1, NULL, OPTV_NONE, {0}, FALSE }, ++}; ++ + static void + xf86OutputSetMonitor (xf86OutputPtr output) + { +@@ -481,7 +492,7 @@ xf86OutputInitialRotation (xf86OutputPtr output) + return RR_Rotate_0; + } + +-xf86OutputPtr ++_X_EXPORT xf86OutputPtr + xf86OutputCreate (ScrnInfoPtr scrn, + const xf86OutputFuncsRec *funcs, + const char *name) +@@ -541,7 +552,7 @@ xf86OutputCreate (ScrnInfoPtr scrn, + return output; + } + +-Bool ++_X_EXPORT Bool + xf86OutputRename (xf86OutputPtr output, const char *name) + { + int len = strlen(name) + 1; +@@ -560,7 +571,7 @@ xf86OutputRename (xf86OutputPtr output, const char *name) + return TRUE; + } + +-void ++_X_EXPORT void + xf86OutputUseScreenMonitor (xf86OutputPtr output, Bool use_screen_monitor) + { + if (use_screen_monitor != output->use_screen_monitor) +@@ -570,7 +581,7 @@ xf86OutputUseScreenMonitor (xf86OutputPtr output, Bool use_screen_monitor) + } + } + +-void ++_X_EXPORT void + xf86OutputDestroy (xf86OutputPtr output) + { + ScrnInfoPtr scrn = output->scrn; +@@ -585,7 +596,7 @@ xf86OutputDestroy (xf86OutputPtr output) + { + memmove (&xf86_config->output[o], + &xf86_config->output[o+1], +- xf86_config->num_output - (o + 1)); ++ ((xf86_config->num_output - (o + 1)) * sizeof(void*))); + xf86_config->num_output--; + break; + } +@@ -646,7 +657,7 @@ xf86CrtcCloseScreen (int index, ScreenPtr screen) + /* + * Called at ScreenInit time to set up + */ +-Bool ++_X_EXPORT Bool + xf86CrtcScreenInit (ScreenPtr screen) + { + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; +@@ -667,7 +678,8 @@ xf86CrtcScreenInit (ScreenPtr screen) + } + if (c == config->num_crtc) + xf86RandR12SetRotations (screen, RR_Rotate_0 | RR_Rotate_90 | +- RR_Rotate_180 | RR_Rotate_270); ++ RR_Rotate_180 | RR_Rotate_270 | ++ RR_Reflect_X | RR_Reflect_Y); + else + xf86RandR12SetRotations (screen, RR_Rotate_0); + +@@ -1202,16 +1214,21 @@ xf86SortModes (DisplayModePtr input) + return output; + } + +-#define DEBUG_REPROBE 1 +- +-void ++_X_EXPORT void + xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) + { + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int o; + +- if (maxX == 0 || maxY == 0) +- xf86RandR12GetOriginalVirtualSize (scrn, &maxX, &maxY); ++ /* When canGrow was TRUE in the initial configuration we have to ++ * compare against the maximum values so that we don't drop modes. ++ * When canGrow was FALSE, the maximum values would have been clamped ++ * anyway. ++ */ ++ if (maxX == 0 || maxY == 0) { ++ maxX = config->maxWidth; ++ maxY = config->maxHeight; ++ } + + /* Elide duplicate modes before defaulting code uses them */ + xf86PruneDuplicateMonitorModes (scrn->monitor); +@@ -1239,7 +1256,7 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) + */ + output->status = (*output->funcs->detect)(output); + +- if (!xf86OutputEnabled (output)) ++ if (output->status == XF86OutputStatusDisconnected) + { + xf86OutputSetEDID (output, NULL); + continue; +@@ -1372,7 +1389,8 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) + if (mode->status == MODE_OK) + mode->status = (*output->funcs->mode_valid)(output, mode); + +- xf86PruneInvalidModes(scrn, &output->probed_modes, TRUE); ++ xf86PruneInvalidModes(scrn, &output->probed_modes, ++ config->debug_modes); + + output->probed_modes = xf86SortModes (output->probed_modes); + +@@ -1398,24 +1416,25 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) + output->probed_modes = mode; + } + mode->type |= M_T_PREFERRED; +- break; + } ++ else ++ mode->type &= ~M_T_PREFERRED; + } + } + + output->initial_rotation = xf86OutputInitialRotation (output); + +-#ifdef DEBUG_REPROBE +- if (output->probed_modes != NULL) { +- xf86DrvMsg(scrn->scrnIndex, X_INFO, +- "Printing probed modes for output %s\n", +- output->name); +- } else { +- xf86DrvMsg(scrn->scrnIndex, X_INFO, +- "No remaining probed modes for output %s\n", +- output->name); ++ if (config->debug_modes) { ++ if (output->probed_modes != NULL) { ++ xf86DrvMsg(scrn->scrnIndex, X_INFO, ++ "Printing probed modes for output %s\n", ++ output->name); ++ } else { ++ xf86DrvMsg(scrn->scrnIndex, X_INFO, ++ "No remaining probed modes for output %s\n", ++ output->name); ++ } + } +-#endif + for (mode = output->probed_modes; mode != NULL; mode = mode->next) + { + /* The code to choose the best mode per pipe later on will require +@@ -1424,9 +1443,8 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) + mode->VRefresh = xf86ModeVRefresh(mode); + xf86SetModeCrtc(mode, INTERLACE_HALVE_V); + +-#ifdef DEBUG_REPROBE +- xf86PrintModeline(scrn->scrnIndex, mode); +-#endif ++ if (config->debug_modes) ++ xf86PrintModeline(scrn->scrnIndex, mode); + } + } + } +@@ -1437,10 +1455,10 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) + */ + + /* XXX where does this function belong? Here? */ +-void ++_X_EXPORT void + xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr scrn, int *x, int *y); + +-void ++_X_EXPORT void + xf86SetScrnInfoModes (ScrnInfoPtr scrn) + { + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); +@@ -1508,7 +1526,7 @@ xf86SetScrnInfoModes (ScrnInfoPtr scrn) + * accordingly. + */ + +-Bool ++_X_EXPORT Bool + xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow) + { + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); +@@ -1521,6 +1539,15 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow) + int width; + int height; + ++ /* Set up the device options */ ++ config->options = xnfalloc (sizeof (xf86DeviceOptions)); ++ memcpy (config->options, xf86DeviceOptions, sizeof (xf86DeviceOptions)); ++ xf86ProcessOptions (scrn->scrnIndex, ++ scrn->options, ++ config->options); ++ config->debug_modes = xf86ReturnOptValBool (config->options, ++ OPTION_MODEDEBUG, FALSE); ++ + if (scrn->display->virtualX) + width = scrn->display->virtualX; + else +@@ -1703,12 +1730,30 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow) + * modes (used in EnterVT functions, or at server startup) + */ + +-Bool ++_X_EXPORT Bool + xf86SetDesiredModes (ScrnInfoPtr scrn) + { + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); +- int c; ++ int c, o; + ++ /* ++ * Turn off everything so mode setting is done ++ * with hardware in a consistent state ++ */ ++ for (o = 0; o < config->num_output; o++) ++ { ++ xf86OutputPtr output = config->output[o]; ++ (*output->funcs->dpms)(output, DPMSModeOff); ++ } ++ ++ for (c = 0; c < config->num_crtc; c++) ++ { ++ xf86CrtcPtr crtc = config->crtc[c]; ++ ++ crtc->funcs->dpms(crtc, DPMSModeOff); ++ memset(&crtc->mode, 0, sizeof(crtc->mode)); ++ } ++ + for (c = 0; c < config->num_crtc; c++) + { + xf86CrtcPtr crtc = config->crtc[c]; +@@ -1765,7 +1810,7 @@ xf86SetDesiredModes (ScrnInfoPtr scrn) + * - Closer in refresh rate to the requested mode. + */ + +-DisplayModePtr ++_X_EXPORT DisplayModePtr + xf86OutputFindClosestMode (xf86OutputPtr output, DisplayModePtr desired) + { + DisplayModePtr best = NULL, scan = NULL; +@@ -1828,7 +1873,7 @@ xf86OutputFindClosestMode (xf86OutputPtr output, DisplayModePtr desired) + * mode across all outputs that are currently active. + */ + +-Bool ++_X_EXPORT Bool + xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation) + { + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); +@@ -1900,7 +1945,7 @@ xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation) + * If the new mode is off, it will turn off outputs and then CRTCs. + * Otherwise, it will affect CRTCs before outputs. + */ +-void ++_X_EXPORT void + xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags) + { + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); +@@ -1938,7 +1983,7 @@ xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags) + * Even for monitors with no DPMS support, by the definition of our DPMS hooks, + * the outputs will still get disabled (blanked). + */ +-Bool ++_X_EXPORT Bool + xf86SaveScreen(ScreenPtr pScreen, int mode) + { + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +@@ -1954,7 +1999,7 @@ xf86SaveScreen(ScreenPtr pScreen, int mode) + /** + * Disable all inactive crtcs and outputs + */ +-void ++_X_EXPORT void + xf86DisableUnusedFunctions(ScrnInfoPtr pScrn) + { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); +@@ -1989,7 +2034,7 @@ xf86DisableUnusedFunctions(ScrnInfoPtr pScrn) + static void + xf86OutputSetEDIDProperty (xf86OutputPtr output, void *data, int data_len) + { +- Atom edid_atom = MakeAtom(EDID_ATOM_NAME, sizeof(EDID_ATOM_NAME), TRUE); ++ Atom edid_atom = MakeAtom(EDID_ATOM_NAME, sizeof(EDID_ATOM_NAME) - 1, TRUE); + + /* This may get called before the RandR resources have been created */ + if (output->randr_output == NULL) +@@ -2008,7 +2053,7 @@ xf86OutputSetEDIDProperty (xf86OutputPtr output, void *data, int data_len) + /** + * Set the EDID information for the specified output + */ +-void ++_X_EXPORT void + xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon) + { + ScrnInfoPtr scrn = output->scrn; +@@ -2023,10 +2068,12 @@ xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon) + + output->MonInfo = edid_mon; + +- /* Debug info for now, at least */ +- xf86DrvMsg(scrn->scrnIndex, X_INFO, "EDID for output %s\n", output->name); +- xf86PrintEDID(edid_mon); +- ++ if (config->debug_modes) { ++ xf86DrvMsg(scrn->scrnIndex, X_INFO, "EDID for output %s\n", ++ output->name); ++ xf86PrintEDID(edid_mon); ++ } ++ + /* Set the DDC properties for the 'compat' output */ + if (output == config->output[config->compat_output]) + xf86SetDDCproperties(scrn, edid_mon); +@@ -2072,7 +2119,7 @@ xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon) + * Return the list of modes supported by the EDID information + * stored in 'output' + */ +-DisplayModePtr ++_X_EXPORT DisplayModePtr + xf86OutputGetEDIDModes (xf86OutputPtr output) + { + ScrnInfoPtr scrn = output->scrn; +@@ -2083,7 +2130,7 @@ xf86OutputGetEDIDModes (xf86OutputPtr output) + return xf86DDCGetModes(scrn->scrnIndex, edid_mon); + } + +-xf86MonPtr ++_X_EXPORT xf86MonPtr + xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus) + { + ScrnInfoPtr scrn = output->scrn; +@@ -2094,8 +2141,127 @@ xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus) + static char *_xf86ConnectorNames[] = { "None", "VGA", "DVI-I", "DVI-D", + "DVI-A", "Composite", "S-Video", + "Component", "LFP", "Proprietary" }; +-char * ++_X_EXPORT char * + xf86ConnectorGetName(xf86ConnectorType connector) + { + return _xf86ConnectorNames[connector]; + } ++ ++static void ++x86_crtc_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b) ++{ ++ dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1; ++ dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2; ++ dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1; ++ dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2; ++ ++ if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2) ++ dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0; ++} ++ ++static void ++x86_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box) ++{ ++ if (crtc->enabled) { ++ crtc_box->x1 = crtc->x; ++ crtc_box->x2 = crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation); ++ crtc_box->y1 = crtc->y; ++ crtc_box->y2 = crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation); ++ } else ++ crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0; ++} ++ ++static int ++xf86_crtc_box_area(BoxPtr box) ++{ ++ return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1); ++} ++ ++/* ++ * Return the crtc covering 'box'. If two crtcs cover a portion of ++ * 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc ++ * with greater coverage ++ */ ++ ++static xf86CrtcPtr ++xf86_covering_crtc(ScrnInfoPtr pScrn, ++ BoxPtr box, ++ xf86CrtcPtr desired, ++ BoxPtr crtc_box_ret) ++{ ++ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); ++ xf86CrtcPtr crtc, best_crtc; ++ int coverage, best_coverage; ++ int c; ++ BoxRec crtc_box, cover_box; ++ ++ best_crtc = NULL; ++ best_coverage = 0; ++ crtc_box_ret->x1 = 0; ++ crtc_box_ret->x2 = 0; ++ crtc_box_ret->y1 = 0; ++ crtc_box_ret->y2 = 0; ++ for (c = 0; c < xf86_config->num_crtc; c++) { ++ crtc = xf86_config->crtc[c]; ++ x86_crtc_box(crtc, &crtc_box); ++ x86_crtc_box_intersect(&cover_box, &crtc_box, box); ++ coverage = xf86_crtc_box_area(&cover_box); ++ if (coverage && crtc == desired) { ++ *crtc_box_ret = crtc_box; ++ return crtc; ++ } else if (coverage > best_coverage) { ++ *crtc_box_ret = crtc_box; ++ best_crtc = crtc; ++ best_coverage = coverage; ++ } ++ } ++ return best_crtc; ++} ++ ++/* ++ * For overlay video, compute the relevant CRTC and ++ * clip video to that. ++ * ++ * returning FALSE means there was a memory failure of some kind, ++ * not that the video shouldn't be displayed ++ */ ++ ++_X_EXPORT Bool ++xf86_crtc_clip_video_helper(ScrnInfoPtr pScrn, ++ xf86CrtcPtr *crtc_ret, ++ xf86CrtcPtr desired_crtc, ++ BoxPtr dst, ++ INT32 *xa, ++ INT32 *xb, ++ INT32 *ya, ++ INT32 *yb, ++ RegionPtr reg, ++ INT32 width, ++ INT32 height) ++{ ++ Bool ret; ++ RegionRec crtc_region_local; ++ RegionPtr crtc_region = reg; ++ ++ if (crtc_ret) { ++ BoxRec crtc_box; ++ xf86CrtcPtr crtc = xf86_covering_crtc(pScrn, dst, ++ desired_crtc, ++ &crtc_box); ++ ++ if (crtc) { ++ REGION_INIT (pScreen, &crtc_region_local, &crtc_box, 1); ++ crtc_region = &crtc_region_local; ++ REGION_INTERSECT (pScreen, crtc_region, crtc_region, reg); ++ } ++ *crtc_ret = crtc; ++ } ++ ++ ret = xf86XVClipVideoHelper(dst, xa, xb, ya, yb, ++ crtc_region, width, height); ++ ++ if (crtc_region != reg) ++ REGION_UNINIT (pScreen, &crtc_region_local); ++ ++ return ret; ++} +diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h +index e64ce1e..9693e12 100644 +--- a/hw/xfree86/modes/xf86Crtc.h ++++ b/hw/xfree86/modes/xf86Crtc.h +@@ -30,6 +30,7 @@ + #include "xf86Modes.h" + #include "xf86Cursor.h" + #include "damage.h" ++#include "picturestr.h" + + /* Compat definitions for older X Servers. */ + #ifndef M_T_PREFERRED +@@ -279,6 +280,17 @@ struct _xf86Crtc { + * Track state of cursor associated with this CRTC + */ + Bool cursor_shown; ++ ++ /** ++ * Current transformation matrix ++ */ ++ PictTransform crtc_to_framebuffer; ++ PictTransform framebuffer_to_crtc; ++ Bool transform_in_use; ++ /** ++ * Bounding box in screen space ++ */ ++ BoxRec bounds; + }; + + typedef struct _xf86OutputFuncs { +@@ -555,6 +567,17 @@ typedef struct _xf86CrtcConfig { + CARD8 *cursor_image; + Bool cursor_on; + CARD32 cursor_fg, cursor_bg; ++ ++ /** ++ * Options parsed from the related device section ++ */ ++ OptionInfoPtr options; ++ ++ Bool debug_modes; ++ ++ /* wrap screen BlockHandler for rotation */ ++ ScreenBlockHandlerProcPtr BlockHandler; ++ + } xf86CrtcConfigRec, *xf86CrtcConfigPtr; + + extern int xf86CrtcConfigPrivateIndex; +@@ -742,5 +765,24 @@ xf86_hide_cursors (ScrnInfoPtr scrn); + */ + void + xf86_cursors_fini (ScreenPtr screen); ++ ++/* ++ * For overlay video, compute the relevant CRTC and ++ * clip video to that. ++ * wraps xf86XVClipVideoHelper() ++ */ ++ ++Bool ++xf86_crtc_clip_video_helper(ScrnInfoPtr pScrn, ++ xf86CrtcPtr *crtc_ret, ++ xf86CrtcPtr desired_crtc, ++ BoxPtr dst, ++ INT32 *xa, ++ INT32 *xb, ++ INT32 *ya, ++ INT32 *yb, ++ RegionPtr reg, ++ INT32 width, ++ INT32 height); + + #endif /* _XF86CRTC_H_ */ +diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c +index 009cccf..b510164 100644 +--- a/hw/xfree86/modes/xf86Cursors.c ++++ b/hw/xfree86/modes/xf86Cursors.c +@@ -58,29 +58,73 @@ xf86_crtc_rotate_coord (Rotation rotation, + int *x_src, + int *y_src) + { ++ int t; ++ ++ switch (rotation & 0xf) { ++ case RR_Rotate_0: ++ break; ++ case RR_Rotate_90: ++ t = x_dst; ++ x_dst = height - y_dst - 1; ++ y_dst = t; ++ break; ++ case RR_Rotate_180: ++ x_dst = width - x_dst - 1; ++ y_dst = height - y_dst - 1; ++ break; ++ case RR_Rotate_270: ++ t = x_dst; ++ x_dst = y_dst; ++ y_dst = width - t - 1; ++ break; ++ } + if (rotation & RR_Reflect_X) + x_dst = width - x_dst - 1; + if (rotation & RR_Reflect_Y) + y_dst = height - y_dst - 1; ++ *x_src = x_dst; ++ *y_src = y_dst; ++} ++ ++/* ++ * Given a cursor source coordinate, rotate to a screen coordinate ++ */ ++static void ++xf86_crtc_rotate_coord_back (Rotation rotation, ++ int width, ++ int height, ++ int x_dst, ++ int y_dst, ++ int *x_src, ++ int *y_src) ++{ ++ int t; + ++ if (rotation & RR_Reflect_X) ++ x_dst = width - x_dst - 1; ++ if (rotation & RR_Reflect_Y) ++ y_dst = height - y_dst - 1; ++ + switch (rotation & 0xf) { + case RR_Rotate_0: +- *x_src = x_dst; +- *y_src = y_dst; + break; + case RR_Rotate_90: +- *x_src = height - y_dst - 1; +- *y_src = x_dst; ++ t = x_dst; ++ x_dst = y_dst; ++ y_dst = width - t - 1; + break; + case RR_Rotate_180: +- *x_src = width - x_dst - 1; +- *y_src = height - y_dst - 1; ++ x_dst = width - x_dst - 1; ++ y_dst = height - y_dst - 1; + break; + case RR_Rotate_270: +- *x_src = y_dst; +- *y_src = width - x_dst - 1; ++ t = x_dst; ++ x_dst = height - y_dst - 1; ++ y_dst = t; + break; + } ++ *x_src = x_dst; ++ *y_src = y_dst; + } + + /* +@@ -212,7 +256,7 @@ xf86_crtc_hide_cursor (xf86CrtcPtr crtc) + } + } + +-void ++_X_EXPORT void + xf86_hide_cursors (ScrnInfoPtr scrn) + { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); +@@ -238,7 +282,7 @@ xf86_crtc_show_cursor (xf86CrtcPtr crtc) + } + } + +-void ++_X_EXPORT void + xf86_show_cursors (ScrnInfoPtr scrn) + { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); +@@ -261,49 +305,33 @@ xf86_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y) + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; + DisplayModePtr mode = &crtc->mode; +- int x_temp; +- int y_temp; + Bool in_range; ++ int dx, dy; + +- /* +- * Move to crtc coordinate space +- */ +- x -= crtc->x; +- y -= crtc->y; +- + /* +- * Rotate ++ * Transform position of cursor on screen + */ +- switch ((crtc->rotation) & 0xf) { +- case RR_Rotate_0: +- break; +- case RR_Rotate_90: +- x_temp = y; +- y_temp = mode->VDisplay - cursor_info->MaxWidth - x; +- x = x_temp; +- y = y_temp; +- break; +- case RR_Rotate_180: +- x_temp = mode->HDisplay - cursor_info->MaxWidth - x; +- y_temp = mode->VDisplay - cursor_info->MaxHeight - y; +- x = x_temp; +- y = y_temp; +- break; +- case RR_Rotate_270: +- x_temp = mode->HDisplay - cursor_info->MaxHeight - y; +- y_temp = x; +- x = x_temp; +- y = y_temp; +- break; ++ if (crtc->transform_in_use) ++ { ++ PictVector v; ++ v.vector[0] = IntToxFixed (x); v.vector[1] = IntToxFixed (y); v.vector[2] = IntToxFixed(1); ++ PictureTransformPoint (&crtc->framebuffer_to_crtc, &v); ++ x = xFixedToInt (v.vector[0]); y = xFixedToInt (v.vector[1]); ++ } ++ else ++ { ++ x -= crtc->x; ++ y -= crtc->y; + } +- + /* +- * Reflect ++ * Transform position of cursor upper left corner + */ +- if (crtc->rotation & RR_Reflect_X) +- x = mode->HDisplay - cursor_info->MaxWidth - x; +- if (crtc->rotation & RR_Reflect_Y) +- y = mode->VDisplay - cursor_info->MaxHeight - y; ++ xf86_crtc_rotate_coord_back (crtc->rotation, ++ cursor_info->MaxWidth, ++ cursor_info->MaxHeight, ++ 0, 0, &dx, &dy); ++ x -= dx; ++ y -= dy; + + /* + * Disable the cursor when it is outside the viewport +@@ -419,7 +447,10 @@ xf86_use_hw_cursor (ScreenPtr screen, CursorPtr cursor) + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; + ++ if (xf86_config->cursor) ++ FreeCursor (xf86_config->cursor, None); + xf86_config->cursor = cursor; ++ ++cursor->refcnt; + + if (cursor->bits->width > cursor_info->MaxWidth || + cursor->bits->height> cursor_info->MaxHeight) +@@ -435,7 +466,10 @@ xf86_use_hw_cursor_argb (ScreenPtr screen, CursorPtr cursor) + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; + ++ if (xf86_config->cursor) ++ FreeCursor (xf86_config->cursor, None); + xf86_config->cursor = cursor; ++ ++cursor->refcnt; + + /* Make sure ARGB support is available */ + if ((cursor_info->Flags & HARDWARE_CURSOR_ARGB) == 0) +@@ -494,7 +528,7 @@ xf86_load_cursor_argb (ScrnInfoPtr scrn, CursorPtr cursor) + } + } + +-Bool ++_X_EXPORT Bool + xf86_cursors_init (ScreenPtr screen, int max_width, int max_height, int flags) + { + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; +@@ -545,7 +579,7 @@ xf86_cursors_init (ScreenPtr screen, int max_width, int max_height, int flags) + * Reloads cursor images as needed, then adjusts cursor positions + */ + +-void ++_X_EXPORT void + xf86_reload_cursors (ScreenPtr screen) + { + ScrnInfoPtr scrn; +@@ -588,7 +622,7 @@ xf86_reload_cursors (ScreenPtr screen) + /** + * Clean up CRTC-based cursor code + */ +-void ++_X_EXPORT void + xf86_cursors_fini (ScreenPtr screen) + { + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; +@@ -604,4 +638,9 @@ xf86_cursors_fini (ScreenPtr screen) + xfree (xf86_config->cursor_image); + xf86_config->cursor_image = NULL; + } ++ if (xf86_config->cursor) ++ { ++ FreeCursor (xf86_config->cursor, None); ++ xf86_config->cursor = NULL; ++ } + } +diff --git a/hw/xfree86/modes/xf86DiDGA.c b/hw/xfree86/modes/xf86DiDGA.c +index 0964cef..f40d0ab 100644 +--- a/hw/xfree86/modes/xf86DiDGA.c ++++ b/hw/xfree86/modes/xf86DiDGA.c +@@ -255,7 +255,7 @@ static DGAFunctionRec xf86_dga_funcs = { + NULL + }; + +-Bool ++_X_EXPORT Bool + xf86DiDGAReInit (ScreenPtr pScreen) + { + ScrnInfoPtr scrn = xf86Screens[pScreen->myNum]; +@@ -267,7 +267,7 @@ xf86DiDGAReInit (ScreenPtr pScreen) + return DGAReInitModes (pScreen, xf86_config->dga_modes, xf86_config->dga_nmode); + } + +-Bool ++_X_EXPORT Bool + xf86DiDGAInit (ScreenPtr pScreen, unsigned long dga_address) + { + ScrnInfoPtr scrn = xf86Screens[pScreen->myNum]; +diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c +index edcd636..8b5e69d 100644 +--- a/hw/xfree86/modes/xf86EdidModes.c ++++ b/hw/xfree86/modes/xf86EdidModes.c +@@ -22,8 +22,9 @@ + */ + + /** +- * @file This is a copy of edid_modes.c from the X Server, for compatibility +- * with old X Servers. ++ * @file This file covers code to convert a xf86MonPtr containing EDID-probed ++ * information into a list of modes, including applying monitor-specific ++ * quirks to fix broken EDID data. + */ + #ifdef HAVE_XORG_CONFIG_H + #include +@@ -49,32 +50,12 @@ + + typedef enum { + DDC_QUIRK_NONE = 0, +- /* Force detailed sync polarity to -h +v */ +- DDC_QUIRK_DT_SYNC_HM_VP = 1 << 0, + /* First detailed mode is bogus, prefer largest mode at 60hz */ +- DDC_QUIRK_PREFER_LARGE_60 = 1 << 1, ++ DDC_QUIRK_PREFER_LARGE_60 = 1 << 0, + /* 135MHz clock is too high, drop a bit */ +- DDC_QUIRK_135_CLOCK_TOO_HIGH = 1 << 2 ++ DDC_QUIRK_135_CLOCK_TOO_HIGH = 1 << 1, + } ddc_quirk_t; + +-static Bool quirk_dt_sync_hm_vp (int scrnIndex, xf86MonPtr DDC) +-{ +- /* Belinea 1924S1W */ +- if (memcmp (DDC->vendor.name, "MAX", 4) == 0 && +- DDC->vendor.prod_id == 1932) +- return TRUE; +- /* Belinea 10 20 30W */ +- if (memcmp (DDC->vendor.name, "MAX", 4) == 0 && +- DDC->vendor.prod_id == 2007) +- return TRUE; +- /* ViewSonic VX2025wm (bug #9941) */ +- if (memcmp (DDC->vendor.name, "VSC", 4) == 0 && +- DDC->vendor.prod_id == 58653) +- return TRUE; +- +- return FALSE; +-} +- + static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC) + { + /* Belinea 10 15 55 */ +@@ -87,11 +68,16 @@ static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC) + DDC->vendor.prod_id == 44358) + return TRUE; + +- /* Samsung SyncMaster 226BW */ ++ /* Bug #10814: Samsung SyncMaster 225BW */ ++ if (memcmp (DDC->vendor.name, "SAM", 4) == 0 && ++ DDC->vendor.prod_id == 596) ++ return TRUE; ++ ++ /* Bug #10545: Samsung SyncMaster 226BW */ + if (memcmp (DDC->vendor.name, "SAM", 4) == 0 && + DDC->vendor.prod_id == 638) + return TRUE; +- ++ + return FALSE; + } + +@@ -112,10 +98,6 @@ typedef struct { + } ddc_quirk_map_t; + + static const ddc_quirk_map_t ddc_quirks[] = { +- { +- quirk_dt_sync_hm_vp, DDC_QUIRK_DT_SYNC_HM_VP, +- "Set detailed timing sync polarity to -h +v" +- }, + { + quirk_prefer_large_60, DDC_QUIRK_PREFER_LARGE_60, + "Detailed timing is not preferred, use largest mode at 60Hz" +@@ -207,6 +189,19 @@ DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing, + { + DisplayModePtr Mode; + ++ /* ++ * Refuse to create modes that are insufficiently large. 64 is a random ++ * number, maybe the spec says something about what the minimum is. In ++ * particular I see this frequently with _old_ EDID, 1.0 or so, so maybe ++ * our parser is just being too aggresive there. ++ */ ++ if (timing->h_active < 64 || timing->v_active < 64) { ++ xf86DrvMsg(scrnIndex, X_INFO, ++ "%s: Ignoring tiny %dx%d mode\n", __func__, ++ timing->h_active, timing->v_active); ++ return NULL; ++ } ++ + /* We don't do stereo */ + if (timing->stereo) { + xf86DrvMsg(scrnIndex, X_INFO, +@@ -251,25 +246,64 @@ DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing, + if (timing->interlaced) + Mode->Flags |= V_INTERLACE; + +- if (quirks & DDC_QUIRK_DT_SYNC_HM_VP) +- Mode->Flags |= V_NHSYNC | V_PVSYNC; ++ if (timing->misc & 0x02) ++ Mode->Flags |= V_PVSYNC; + else +- { +- if (timing->misc & 0x02) +- Mode->Flags |= V_PHSYNC; +- else +- Mode->Flags |= V_NHSYNC; +- +- if (timing->misc & 0x01) +- Mode->Flags |= V_PVSYNC; +- else +- Mode->Flags |= V_NVSYNC; +- } ++ Mode->Flags |= V_NVSYNC; ++ ++ if (timing->misc & 0x01) ++ Mode->Flags |= V_PHSYNC; ++ else ++ Mode->Flags |= V_NHSYNC; + + return Mode; + } + +-DisplayModePtr ++/* ++ * ++ */ ++static void ++DDCGuessRangesFromModes(int scrnIndex, MonPtr Monitor, DisplayModePtr Modes) ++{ ++ DisplayModePtr Mode = Modes; ++ ++ if (!Monitor || !Modes) ++ return; ++ ++ /* set up the ranges for scanning through the modes */ ++ Monitor->nHsync = 1; ++ Monitor->hsync[0].lo = 1024.0; ++ Monitor->hsync[0].hi = 0.0; ++ ++ Monitor->nVrefresh = 1; ++ Monitor->vrefresh[0].lo = 1024.0; ++ Monitor->vrefresh[0].hi = 0.0; ++ ++ while (Mode) { ++ if (!Mode->HSync) ++ Mode->HSync = ((float) Mode->Clock ) / ((float) Mode->HTotal); ++ ++ if (!Mode->VRefresh) ++ Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) / ++ ((float) (Mode->HTotal * Mode->VTotal)); ++ ++ if (Mode->HSync < Monitor->hsync[0].lo) ++ Monitor->hsync[0].lo = Mode->HSync; ++ ++ if (Mode->HSync > Monitor->hsync[0].hi) ++ Monitor->hsync[0].hi = Mode->HSync; ++ ++ if (Mode->VRefresh < Monitor->vrefresh[0].lo) ++ Monitor->vrefresh[0].lo = Mode->VRefresh; ++ ++ if (Mode->VRefresh > Monitor->vrefresh[0].hi) ++ Monitor->vrefresh[0].hi = Mode->VRefresh; ++ ++ Mode = Mode->next; ++ } ++} ++ ++_X_EXPORT DisplayModePtr + xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) + { + int preferred, i; +@@ -351,3 +385,107 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) + } + return Modes; + } ++ ++/* ++ * Fill out MonPtr with xf86MonPtr information. ++ */ ++_X_EXPORT void ++xf86DDCMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC) ++{ ++ DisplayModePtr Modes = NULL, Mode; ++ int i, clock; ++ Bool have_hsync = FALSE, have_vrefresh = FALSE, have_maxpixclock = FALSE; ++ ++ if (!Monitor || !DDC) ++ return; ++ ++ Monitor->DDC = DDC; ++ ++ Monitor->widthmm = 10 * DDC->features.hsize; ++ Monitor->heightmm = 10 * DDC->features.vsize; ++ ++ /* If this is a digital display, then we can use reduced blanking */ ++ if (DDC->features.input_type) ++ Monitor->reducedblanking = TRUE; ++ /* Allow the user to also enable this through config */ ++ ++ Modes = xf86DDCGetModes(scrnIndex, DDC); ++ ++ /* Skip EDID ranges if they were specified in the config file */ ++ have_hsync = (Monitor->nHsync != 0); ++ have_vrefresh = (Monitor->nVrefresh != 0); ++ have_maxpixclock = (Monitor->maxPixClock != 0); ++ ++ /* Go through the detailed monitor sections */ ++ for (i = 0; i < DET_TIMINGS; i++) { ++ switch (DDC->det_mon[i].type) { ++ case DS_RANGES: ++ if (!have_hsync) { ++ if (!Monitor->nHsync) ++ xf86DrvMsg(scrnIndex, X_INFO, ++ "Using EDID range info for horizontal sync\n"); ++ Monitor->hsync[Monitor->nHsync].lo = ++ DDC->det_mon[i].section.ranges.min_h; ++ Monitor->hsync[Monitor->nHsync].hi = ++ DDC->det_mon[i].section.ranges.max_h; ++ Monitor->nHsync++; ++ } else { ++ xf86DrvMsg(scrnIndex, X_INFO, ++ "Using hsync ranges from config file\n"); ++ } ++ ++ if (!have_vrefresh) { ++ if (!Monitor->nVrefresh) ++ xf86DrvMsg(scrnIndex, X_INFO, ++ "Using EDID range info for vertical refresh\n"); ++ Monitor->vrefresh[Monitor->nVrefresh].lo = ++ DDC->det_mon[i].section.ranges.min_v; ++ Monitor->vrefresh[Monitor->nVrefresh].hi = ++ DDC->det_mon[i].section.ranges.max_v; ++ Monitor->nVrefresh++; ++ } else { ++ xf86DrvMsg(scrnIndex, X_INFO, ++ "Using vrefresh ranges from config file\n"); ++ } ++ ++ clock = DDC->det_mon[i].section.ranges.max_clock * 1000; ++ if (!have_maxpixclock && clock > Monitor->maxPixClock) ++ Monitor->maxPixClock = clock; ++ ++ break; ++ default: ++ break; ++ } ++ } ++ ++ if (Modes) { ++ /* Print Modes */ ++ xf86DrvMsg(scrnIndex, X_INFO, "Printing DDC gathered Modelines:\n"); ++ ++ Mode = Modes; ++ while (Mode) { ++ xf86PrintModeline(scrnIndex, Mode); ++ Mode = Mode->next; ++ } ++ ++ /* Do we still need ranges to be filled in? */ ++ if (!Monitor->nHsync || !Monitor->nVrefresh) ++ DDCGuessRangesFromModes(scrnIndex, Monitor, Modes); ++ ++ /* look for last Mode */ ++ Mode = Modes; ++ ++ while (Mode->next) ++ Mode = Mode->next; ++ ++ /* add to MonPtr */ ++ if (Monitor->Modes) { ++ Monitor->Last->next = Modes; ++ Modes->prev = Monitor->Last; ++ Monitor->Last = Mode; ++ } else { ++ Monitor->Modes = Modes; ++ Monitor->Last = Mode; ++ } ++ } ++} +diff --git a/hw/xfree86/modes/xf86Modes.c b/hw/xfree86/modes/xf86Modes.c +index 5b52bd7..f49c292 100644 +--- a/hw/xfree86/modes/xf86Modes.c ++++ b/hw/xfree86/modes/xf86Modes.c +@@ -1,6 +1,3 @@ +-/* -*- c-basic-offset: 4 -*- */ +-/* $XdotOrg: xserver/xorg/hw/xfree86/common/xf86Mode.c,v 1.10 2006/03/07 16:00:57 libv Exp $ */ +-/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86Mode.c,v 1.69 2003/10/08 14:58:28 dawes Exp $ */ + /* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * +@@ -52,7 +49,7 @@ extern XF86ConfigPtr xf86configptr; + * + * Exact copy of xf86Mode.c's. + */ +-double ++_X_EXPORT double + xf86ModeHSync(DisplayModePtr mode) + { + double hsync = 0.0; +@@ -70,7 +67,7 @@ xf86ModeHSync(DisplayModePtr mode) + * + * Exact copy of xf86Mode.c's. + */ +-double ++_X_EXPORT double + xf86ModeVRefresh(DisplayModePtr mode) + { + double refresh = 0.0; +@@ -89,7 +86,7 @@ xf86ModeVRefresh(DisplayModePtr mode) + return refresh; + } + +-int ++_X_EXPORT int + xf86ModeWidth (DisplayModePtr mode, Rotation rotation) + { + switch (rotation & 0xf) { +@@ -104,7 +101,7 @@ xf86ModeWidth (DisplayModePtr mode, Rotation rotation) + } + } + +-int ++_X_EXPORT int + xf86ModeHeight (DisplayModePtr mode, Rotation rotation) + { + switch (rotation & 0xf) { +@@ -120,7 +117,7 @@ xf86ModeHeight (DisplayModePtr mode, Rotation rotation) + } + + /** Sets a default mode name of x on a mode. */ +-void ++_X_EXPORT void + xf86SetModeDefaultName(DisplayModePtr mode) + { + if (mode->name != NULL) +@@ -137,7 +134,7 @@ xf86SetModeDefaultName(DisplayModePtr mode) + * + * Exact copy of xf86Mode.c's. + */ +-void ++_X_EXPORT void + xf86SetModeCrtc(DisplayModePtr p, int adjustFlags) + { + if ((p == NULL) || ((p->type & M_T_CRTC_C) == M_T_BUILTIN)) +@@ -188,7 +185,7 @@ xf86SetModeCrtc(DisplayModePtr p, int adjustFlags) + /** + * Allocates and returns a copy of pMode, including pointers within pMode. + */ +-DisplayModePtr ++_X_EXPORT DisplayModePtr + xf86DuplicateMode(DisplayModePtr pMode) + { + DisplayModePtr pNew; +@@ -212,7 +209,7 @@ xf86DuplicateMode(DisplayModePtr pMode) + * + * \param modeList doubly-linked mode list + */ +-DisplayModePtr ++_X_EXPORT DisplayModePtr + xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList) + { + DisplayModePtr first = NULL, last = NULL; +@@ -246,7 +243,7 @@ xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList) + * + * This isn't in xf86Modes.c, but it might deserve to be there. + */ +-Bool ++_X_EXPORT Bool + xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2) + { + if (pMode1->Clock == pMode2->Clock && +@@ -282,7 +279,7 @@ add(char **p, char *new) + * + * Convenient VRefresh printing was added, though, compared to xf86Mode.c + */ +-void ++_X_EXPORT void + xf86PrintModeline(int scrnIndex,DisplayModePtr mode) + { + char tmp[256]; +@@ -330,7 +327,7 @@ xf86PrintModeline(int scrnIndex,DisplayModePtr mode) + * + * This is not in xf86Modes.c, but would be part of the proposed new API. + */ +-void ++_X_EXPORT void + xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, + int flags) + { +@@ -351,7 +348,7 @@ xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, + * + * This is not in xf86Modes.c, but would be part of the proposed new API. + */ +-void ++_X_EXPORT void + xf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList, + int maxX, int maxY, int maxPitch) + { +@@ -380,7 +377,7 @@ xf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList, + * + * This is not in xf86Modes.c, but would be part of the proposed new API. + */ +-void ++_X_EXPORT void + xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList, + MonPtr mon) + { +@@ -427,7 +424,7 @@ xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList, + * + * This is not in xf86Modes.c, but would be part of the proposed new API. + */ +-void ++_X_EXPORT void + xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList, + int *min, int *max, int n_ranges) + { +@@ -461,7 +458,7 @@ xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList, + * + * This is not in xf86Modes.c, but would be part of the proposed new API. + */ +-void ++_X_EXPORT void + xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList) + { + DisplayModePtr mode; +@@ -495,7 +492,7 @@ xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList) + * + * This is not in xf86Modes.c, but would be part of the proposed new API. + */ +-void ++_X_EXPORT void + xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList, + Bool verbose) + { +@@ -529,7 +526,7 @@ xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList, + * + * \param modes doubly-linked mode list. + */ +-DisplayModePtr ++_X_EXPORT DisplayModePtr + xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new) + { + if (modes == NULL) +@@ -595,7 +592,7 @@ xf86GetConfigModes (XF86ConfModeLinePtr conf_mode) + /** + * Build a mode list from a monitor configuration + */ +-DisplayModePtr ++_X_EXPORT DisplayModePtr + xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor) + { + DisplayModePtr modes = NULL; +@@ -627,7 +624,7 @@ xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor) + /** + * Build a mode list containing all of the default modes + */ +-DisplayModePtr ++_X_EXPORT DisplayModePtr + xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed) + { + DisplayModePtr head = NULL, prev = NULL, mode; +diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c +index 90de585..38435c9 100644 +--- a/hw/xfree86/modes/xf86RandR12.c ++++ b/hw/xfree86/modes/xf86RandR12.c +@@ -1,7 +1,4 @@ +-/* $XdotOrg: xc/programs/Xserver/hw/xfree86/common/xf86RandR.c,v 1.3 2004/07/30 21:53:09 eich Exp $ */ + /* +- * $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86RandR.c,v 1.7tsi Exp $ +- * + * Copyright � 2002 Keith Packard, member of The XFree86 Project, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its +@@ -96,9 +93,12 @@ xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations) + } + + /* Re-probe the outputs for new monitors or modes */ +- xf86ProbeOutputModes (scrp, 0, 0); +- xf86SetScrnInfoModes (scrp); +- xf86DiDGAReInit (pScreen); ++ if (scrp->vtSema) ++ { ++ xf86ProbeOutputModes (scrp, 0, 0); ++ xf86SetScrnInfoModes (scrp); ++ xf86DiDGAReInit (pScreen); ++ } + + for (mode = scrp->modes; ; mode = mode->next) + { +@@ -244,7 +244,7 @@ xf86RandR12SetMode (ScreenPtr pScreen, + return ret; + } + +-Bool ++_X_EXPORT Bool + xf86RandR12SetConfig (ScreenPtr pScreen, + Rotation rotation, + int rate, +@@ -337,6 +337,7 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen, + ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + WindowPtr pRoot = WindowTable[pScreen->myNum]; ++ PixmapPtr pScrnPix = (*pScreen->GetScreenPixmap)(pScreen); + Bool ret = FALSE; + + if (randrp->virtualX == -1 || randrp->virtualY == -1) +@@ -344,7 +345,7 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen, + randrp->virtualX = pScrn->virtualX; + randrp->virtualY = pScrn->virtualY; + } +- if (pRoot) ++ if (pRoot && pScrn->vtSema) + (*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE); + + /* Let the driver update virtualX and virtualY */ +@@ -353,8 +354,8 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen, + + ret = TRUE; + +- pScreen->width = width; +- pScreen->height = height; ++ pScreen->width = pScrnPix->drawable.width = width; ++ pScreen->height = pScrnPix->drawable.height = height; + pScreen->mmWidth = mmWidth; + pScreen->mmHeight = mmHeight; + +@@ -362,7 +363,7 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen, + xf86SetViewport (pScreen, 0, 0); + + finish: +- if (pRoot) ++ if (pRoot && pScrn->vtSema) + (*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE); + #if RANDR_12_INTERFACE + if (WindowTable[pScreen->myNum] && ret) +@@ -371,7 +372,7 @@ finish: + return ret; + } + +-Rotation ++_X_EXPORT Rotation + xf86RandR12GetRotation(ScreenPtr pScreen) + { + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); +@@ -379,7 +380,7 @@ xf86RandR12GetRotation(ScreenPtr pScreen) + return randrp->rotation; + } + +-Bool ++_X_EXPORT Bool + xf86RandR12CreateScreenResources (ScreenPtr pScreen) + { + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +@@ -469,7 +470,7 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen) + } + + +-Bool ++_X_EXPORT Bool + xf86RandR12Init (ScreenPtr pScreen) + { + rrScrPrivPtr rp; +@@ -519,7 +520,7 @@ xf86RandR12Init (ScreenPtr pScreen) + return TRUE; + } + +-void ++_X_EXPORT void + xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations) + { + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); +@@ -537,7 +538,7 @@ xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations) + randrp->supported_rotations = rotations; + } + +-void ++_X_EXPORT void + xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y) + { + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; +@@ -715,7 +716,7 @@ xf86RandR12CrtcSet (ScreenPtr pScreen, + xf86CrtcPtr *save_crtcs; + Bool save_enabled = crtc->enabled; + +- save_crtcs = ALLOCATE_LOCAL(config->num_crtc * sizeof (xf86CrtcPtr)); ++ save_crtcs = ALLOCATE_LOCAL(config->num_output * sizeof (xf86CrtcPtr)); + if ((randr_mode != NULL) != crtc->enabled) + changed = TRUE; + else if (randr_mode && !xf86RandRModeMatches (randr_mode, &crtc->mode)) +@@ -749,6 +750,10 @@ xf86RandR12CrtcSet (ScreenPtr pScreen, + output->crtc = new_crtc; + } + } ++ for (ro = 0; ro < num_randr_outputs; ro++) ++ if (randr_outputs[ro]->pendingProperties) ++ changed = TRUE; ++ + /* XXX need device-independent mode setting code through an API */ + if (changed) + { +@@ -793,6 +798,9 @@ xf86RandR12CrtcSetGamma (ScreenPtr pScreen, + if (crtc->funcs->gamma_set == NULL) + return FALSE; + ++ if (!crtc->scrn->vtSema) ++ return TRUE; ++ + crtc->funcs->gamma_set(crtc, randr_crtc->gammaRed, randr_crtc->gammaGreen, + randr_crtc->gammaBlue, randr_crtc->gammaSize); + +@@ -813,6 +821,11 @@ xf86RandR12OutputSetProperty (ScreenPtr pScreen, + if (output->funcs->set_property == NULL) + return TRUE; + ++ /* ++ * This function gets called even when vtSema is FALSE, as ++ * drivers will need to remember the correct value to apply ++ * when the VT switch occurs ++ */ + return output->funcs->set_property(output, property, value); + } + +@@ -826,6 +839,11 @@ xf86RandR12OutputValidateMode (ScreenPtr pScreen, + DisplayModeRec mode; + + xf86RandRModeConvert (pScrn, randr_mode, &mode); ++ /* ++ * This function may be called when vtSema is FALSE, so ++ * the underlying function must either avoid touching the hardware ++ * or return FALSE when vtSema is FALSE ++ */ + if (output->funcs->mode_valid (output, &mode) != MODE_OK) + return FALSE; + return TRUE; +@@ -933,7 +951,6 @@ xf86RandR12SetInfo12 (ScreenPtr pScreen) + return FALSE; + } + +- RROutputSetCrtc (output->randr_output, randr_crtc); + RROutputSetPhysicalSize(output->randr_output, + output->mm_width, + output->mm_height); +@@ -987,6 +1004,8 @@ xf86RandR12GetInfo12 (ScreenPtr pScreen, Rotation *rotations) + { + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + ++ if (!pScrn->vtSema) ++ return TRUE; + xf86ProbeOutputModes (pScrn, 0, 0); + xf86SetScrnInfoModes (pScrn); + xf86DiDGAReInit (pScreen); +@@ -1053,7 +1072,7 @@ xf86RandR12CreateScreenResources12 (ScreenPtr pScreen) + * to DGA, VidMode or hot key. Tell RandR + */ + +-void ++_X_EXPORT void + xf86RandR12TellChanged (ScreenPtr pScreen) + { + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +@@ -1103,7 +1122,7 @@ xf86RandR12Init12 (ScreenPtr pScreen) + + #endif + +-Bool ++_X_EXPORT Bool + xf86RandR12PreInit (ScrnInfoPtr pScrn) + { + return TRUE; +diff --git a/hw/xfree86/modes/xf86RandR12.h b/hw/xfree86/modes/xf86RandR12.h +index 0d3346a..4fd855c 100644 +--- a/hw/xfree86/modes/xf86RandR12.h ++++ b/hw/xfree86/modes/xf86RandR12.h +@@ -24,6 +24,9 @@ + #define _XF86_RANDR_H_ + #include + #include ++#if XF86_MODES_RENAME ++#include "xf86Rename.h" ++#endif + + Bool xf86RandR12CreateScreenResources (ScreenPtr pScreen); + Bool xf86RandR12Init(ScreenPtr pScreen); +diff --git a/hw/xfree86/modes/xf86Rename.h b/hw/xfree86/modes/xf86Rename.h +index 9dcfef5..b8c1d70 100644 +--- a/hw/xfree86/modes/xf86Rename.h ++++ b/hw/xfree86/modes/xf86Rename.h +@@ -25,6 +25,12 @@ + + #include "local_xf86Rename.h" + ++#define xf86_cursors_fini XF86NAME(xf86_cursors_fini) ++#define xf86_cursors_init XF86NAME(xf86_cursors_init) ++#define xf86_hide_cursors XF86NAME(xf86_hide_cursors) ++#define xf86_reload_cursors XF86NAME(xf86_reload_cursors) ++#define xf86_show_cursors XF86NAME(xf86_show_cursors) ++#define xf86ConnectorGetName XF86NAME(xf86ConnectorGetName) + #define xf86CrtcConfigInit XF86NAME(xf86CrtcConfigInit) + #define xf86CrtcConfigPrivateIndex XF86NAME(xf86CrtcConfigPrivateIndex) + #define xf86CrtcCreate XF86NAME(xf86CrtcCreate) +@@ -35,6 +41,7 @@ + #define xf86CrtcSetMode XF86NAME(xf86CrtcSetMode) + #define xf86CrtcSetSizeRange XF86NAME(xf86CrtcSetSizeRange) + #define xf86CVTMode XF86NAME(xf86CVTMode) ++#define xf86DDCMonitorSet XF86NAME(xf86DDCMonitorSet) + #define xf86DisableUnusedFunctions XF86NAME(xf86DisableUnusedFunctions) + #define xf86DPMSSet XF86NAME(xf86DPMSSet) + #define xf86DuplicateMode XF86NAME(xf86DuplicateMode) +@@ -52,9 +59,11 @@ + #define xf86OutputGetEDIDModes XF86NAME(xf86OutputGetEDIDModes) + #define xf86OutputRename XF86NAME(xf86OutputRename) + #define xf86OutputSetEDID XF86NAME(xf86OutputSetEDID) ++#define xf86OutputUseScreenMonitor XF86NAME(xf86OutputUseScreenMonitor) + #define xf86PrintModeline XF86NAME(xf86PrintModeline) + #define xf86ProbeOutputModes XF86NAME(xf86ProbeOutputModes) + #define xf86PruneInvalidModes XF86NAME(xf86PruneInvalidModes) ++#define xf86RotateCloseScreen XF86NAME(xf86RotateCloseScreen) + #define xf86SetModeCrtc XF86NAME(xf86SetModeCrtc) + #define xf86SetModeDefaultName XF86NAME(xf86SetModeDefaultName) + #define xf86SetScrnInfoModes XF86NAME(xf86SetScrnInfoModes) +diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c +index 359501e..380478f 100644 +--- a/hw/xfree86/modes/xf86Rotate.c ++++ b/hw/xfree86/modes/xf86Rotate.c +@@ -68,57 +68,204 @@ compWindowFormat (WindowPtr pWin) + compGetWindowVisual (pWin)); + } + ++#define F(x) IntToxFixed(x) ++ + static void +-xf86TranslateBox (BoxPtr b, int dx, int dy) ++PictureTransformIdentity (PictTransformPtr matrix) ++{ ++ int i; ++ memset (matrix, '\0', sizeof (PictTransform)); ++ for (i = 0; i < 3; i++) ++ matrix->matrix[i][i] = F(1); ++} ++ ++static Bool ++PictureTransformMultiply (PictTransformPtr dst, PictTransformPtr l, PictTransformPtr r) + { +- b->x1 += dx; +- b->y1 += dy; +- b->x2 += dx; +- b->y2 += dy; ++ PictTransform d; ++ int dx, dy; ++ int o; ++ ++ for (dy = 0; dy < 3; dy++) ++ for (dx = 0; dx < 3; dx++) ++ { ++ xFixed_48_16 v; ++ xFixed_32_32 partial; ++ v = 0; ++ for (o = 0; o < 3; o++) ++ { ++ partial = (xFixed_32_32) l->matrix[dy][o] * (xFixed_32_32) r->matrix[o][dx]; ++ v += partial >> 16; ++ } ++ if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16) ++ return FALSE; ++ d.matrix[dy][dx] = (xFixed) v; ++ } ++ *dst = d; ++ return TRUE; + } + + static void +-xf86TransformBox (BoxPtr dst, BoxPtr src, Rotation rotation, +- int xoff, int yoff, +- int dest_width, int dest_height) ++PictureTransformInitScale (PictTransformPtr t, xFixed sx, xFixed sy) ++{ ++ memset (t, '\0', sizeof (PictTransform)); ++ t->matrix[0][0] = sx; ++ t->matrix[1][1] = sy; ++ t->matrix[2][2] = F (1); ++} ++ ++static xFixed ++fixed_inverse (xFixed x) ++{ ++ return (xFixed) ((((xFixed_48_16) F(1)) * F(1)) / x); ++} ++ ++static Bool ++PictureTransformScale (PictTransformPtr forward, ++ PictTransformPtr reverse, ++ xFixed sx, xFixed sy) + { +- BoxRec stmp = *src; ++ PictTransform t; + +- xf86TranslateBox (&stmp, -xoff, -yoff); +- switch (rotation & 0xf) { +- default: +- case RR_Rotate_0: +- *dst = stmp; +- break; +- case RR_Rotate_90: +- dst->x1 = stmp.y1; +- dst->y1 = dest_height - stmp.x2; +- dst->x2 = stmp.y2; +- dst->y2 = dest_height - stmp.x1; +- break; +- case RR_Rotate_180: +- dst->x1 = dest_width - stmp.x2; +- dst->y1 = dest_height - stmp.y2; +- dst->x2 = dest_width - stmp.x1; +- dst->y2 = dest_height - stmp.y1; +- break; +- case RR_Rotate_270: +- dst->x1 = dest_width - stmp.y2; +- dst->y1 = stmp.x1; +- dst->y2 = stmp.x2; +- dst->x2 = dest_width - stmp.y1; +- break; +- } +- if (rotation & RR_Reflect_X) { +- int x1 = dst->x1; +- dst->x1 = dest_width - dst->x2; +- dst->x2 = dest_width - x1; ++ PictureTransformInitScale (&t, sx, sy); ++ if (!PictureTransformMultiply (forward, &t, forward)) ++ return FALSE; ++ PictureTransformInitScale (&t, fixed_inverse (sx), fixed_inverse (sy)); ++ if (!PictureTransformMultiply (reverse, reverse, &t)) ++ return FALSE; ++ return TRUE; ++} ++ ++static void ++PictureTransformInitRotate (PictTransformPtr t, xFixed c, xFixed s) ++{ ++ memset (t, '\0', sizeof (PictTransform)); ++ t->matrix[0][0] = c; ++ t->matrix[0][1] = -s; ++ t->matrix[1][0] = s; ++ t->matrix[1][1] = c; ++ t->matrix[2][2] = F (1); ++} ++ ++static Bool ++PictureTransformRotate (PictTransformPtr forward, ++ PictTransformPtr reverse, ++ xFixed c, xFixed s) ++{ ++ PictTransform t; ++ PictureTransformInitRotate (&t, c, s); ++ if (!PictureTransformMultiply (forward, &t, forward)) ++ return FALSE; ++ ++ PictureTransformInitRotate (&t, c, -s); ++ if (!PictureTransformMultiply (reverse, reverse, &t)) ++ return FALSE; ++ return TRUE; ++} ++ ++static void ++PictureTransformInitTranslate (PictTransformPtr t, xFixed tx, xFixed ty) ++{ ++ memset (t, '\0', sizeof (PictTransform)); ++ t->matrix[0][0] = F (1); ++ t->matrix[0][2] = tx; ++ t->matrix[1][1] = F (1); ++ t->matrix[1][2] = ty; ++ t->matrix[2][2] = F (1); ++} ++ ++static Bool ++PictureTransformTranslate (PictTransformPtr forward, ++ PictTransformPtr reverse, ++ xFixed tx, xFixed ty) ++{ ++ PictTransform t; ++ PictureTransformInitTranslate (&t, tx, ty); ++ if (!PictureTransformMultiply (forward, &t, forward)) ++ return FALSE; ++ ++ PictureTransformInitTranslate (&t, -tx, -ty); ++ if (!PictureTransformMultiply (reverse, reverse, &t)) ++ return FALSE; ++ return TRUE; ++} ++ ++static void ++PictureTransformBounds (BoxPtr b, PictTransformPtr matrix) ++{ ++ PictVector v[4]; ++ int i; ++ int x1, y1, x2, y2; ++ ++ v[0].vector[0] = F (b->x1); v[0].vector[1] = F (b->y1); v[0].vector[2] = F(1); ++ v[1].vector[0] = F (b->x2); v[1].vector[1] = F (b->y1); v[1].vector[2] = F(1); ++ v[2].vector[0] = F (b->x2); v[2].vector[1] = F (b->y2); v[2].vector[2] = F(1); ++ v[3].vector[0] = F (b->x1); v[3].vector[1] = F (b->y2); v[3].vector[2] = F(1); ++ for (i = 0; i < 4; i++) ++ { ++ PictureTransformPoint (matrix, &v[i]); ++ x1 = xFixedToInt (v[i].vector[0]); ++ y1 = xFixedToInt (v[i].vector[1]); ++ x2 = xFixedToInt (xFixedCeil (v[i].vector[0])); ++ y2 = xFixedToInt (xFixedCeil (v[i].vector[1])); ++ if (i == 0) ++ { ++ b->x1 = x1; b->y1 = y1; ++ b->x2 = x2; b->y2 = y2; ++ } ++ else ++ { ++ if (x1 < b->x1) b->x1 = x1; ++ if (y1 < b->y1) b->y1 = y1; ++ if (x2 > b->x2) b->x2 = x2; ++ if (y2 > b->y2) b->y2 = y2; ++ } + } +- if (rotation & RR_Reflect_Y) { +- int y1 = dst->y1; +- dst->y1 = dest_height - dst->y2; +- dst->y2 = dest_height - y1; ++} ++ ++static Bool ++PictureTransformIsIdentity(PictTransform *t) ++{ ++ return ((t->matrix[0][0] == t->matrix[1][1]) && ++ (t->matrix[0][0] == t->matrix[2][2]) && ++ (t->matrix[0][0] != 0) && ++ (t->matrix[0][1] == 0) && ++ (t->matrix[0][2] == 0) && ++ (t->matrix[1][0] == 0) && ++ (t->matrix[1][2] == 0) && ++ (t->matrix[2][0] == 0) && ++ (t->matrix[2][1] == 0)); ++} ++ ++#define toF(x) ((float) (x) / 65536.0f) ++ ++static void ++PictureTransformErrorF (PictTransform *t) ++{ ++ ErrorF ("{ { %f %f %f } { %f %f %f } { %f %f %f } }", ++ toF(t->matrix[0][0]), toF(t->matrix[0][1]), toF(t->matrix[0][2]), ++ toF(t->matrix[1][0]), toF(t->matrix[1][1]), toF(t->matrix[1][2]), ++ toF(t->matrix[2][0]), toF(t->matrix[2][1]), toF(t->matrix[2][2])); ++} ++ ++static Bool ++PictureTransformIsInverse (char *where, PictTransform *a, PictTransform *b) ++{ ++ PictTransform t; ++ ++ PictureTransformMultiply (&t, a, b); ++ if (!PictureTransformIsIdentity (&t)) ++ { ++ ErrorF ("%s: ", where); ++ PictureTransformErrorF (a); ++ ErrorF (" * "); ++ PictureTransformErrorF (b); ++ ErrorF (" = "); ++ PictureTransformErrorF (a); ++ ErrorF ("\n"); ++ return FALSE; + } ++ return TRUE; + } + + static void +@@ -131,7 +278,6 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region) + PictFormatPtr format = compWindowFormat (WindowTable[screen->myNum]); + int error; + PicturePtr src, dst; +- PictTransform transform; + int n = REGION_NUM_RECTS(region); + BoxPtr b = REGION_RECTS(region); + XID include_inferiors = IncludeInferiors; +@@ -156,45 +302,7 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region) + if (!dst) + return; + +- memset (&transform, '\0', sizeof (transform)); +- transform.matrix[2][2] = IntToxFixed(1); +- transform.matrix[0][2] = IntToxFixed(crtc->x); +- transform.matrix[1][2] = IntToxFixed(crtc->y); +- switch (crtc->rotation & 0xf) { +- default: +- case RR_Rotate_0: +- transform.matrix[0][0] = IntToxFixed(1); +- transform.matrix[1][1] = IntToxFixed(1); +- break; +- case RR_Rotate_90: +- transform.matrix[0][1] = IntToxFixed(-1); +- transform.matrix[1][0] = IntToxFixed(1); +- transform.matrix[0][2] += IntToxFixed(crtc->mode.VDisplay); +- break; +- case RR_Rotate_180: +- transform.matrix[0][0] = IntToxFixed(-1); +- transform.matrix[1][1] = IntToxFixed(-1); +- transform.matrix[0][2] += IntToxFixed(crtc->mode.HDisplay); +- transform.matrix[1][2] += IntToxFixed(crtc->mode.VDisplay); +- break; +- case RR_Rotate_270: +- transform.matrix[0][1] = IntToxFixed(1); +- transform.matrix[1][0] = IntToxFixed(-1); +- transform.matrix[1][2] += IntToxFixed(crtc->mode.HDisplay); +- break; +- } +- +- /* handle reflection */ +- if (crtc->rotation & RR_Reflect_X) +- { +- /* XXX figure this out */ +- } +- if (crtc->rotation & RR_Reflect_Y) +- { +- /* XXX figure this out too */ +- } +- +- error = SetPictureTransform (src, &transform); ++ error = SetPictureTransform (src, &crtc->crtc_to_framebuffer); + if (error) + return; + +@@ -202,9 +310,8 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region) + { + BoxRec dst_box; + +- xf86TransformBox (&dst_box, b, crtc->rotation, +- crtc->x, crtc->y, +- crtc->mode.HDisplay, crtc->mode.VDisplay); ++ dst_box = *b; ++ PictureTransformBounds (&dst_box, &crtc->framebuffer_to_crtc); + CompositePicture (PictOpSrc, + src, NULL, dst, + dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1, +@@ -264,7 +371,7 @@ xf86RotatePrepare (ScreenPtr pScreen) + } + } + +-static void ++static Bool + xf86RotateRedisplay(ScreenPtr pScreen) + { + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +@@ -273,7 +380,7 @@ xf86RotateRedisplay(ScreenPtr pScreen) + RegionPtr region; + + if (!damage) +- return; ++ return FALSE; + xf86RotatePrepare (pScreen); + region = DamageRegion(damage); + if (REGION_NOTEMPTY(pScreen, region)) +@@ -296,15 +403,10 @@ xf86RotateRedisplay(ScreenPtr pScreen) + + if (crtc->rotation != RR_Rotate_0 && crtc->enabled) + { +- BoxRec box; + RegionRec crtc_damage; + + /* compute portion of damage that overlaps crtc */ +- box.x1 = crtc->x; +- box.x2 = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation); +- box.y1 = crtc->y; +- box.y2 = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation); +- REGION_INIT(pScreen, &crtc_damage, &box, 1); ++ REGION_INIT(pScreen, &crtc_damage, &crtc->bounds, 1); + REGION_INTERSECT (pScreen, &crtc_damage, &crtc_damage, region); + + /* update damaged region */ +@@ -317,19 +419,25 @@ xf86RotateRedisplay(ScreenPtr pScreen) + pScreen->SourceValidate = SourceValidate; + DamageEmpty(damage); + } ++ return TRUE; + } + + static void +-xf86RotateBlockHandler(pointer data, OSTimePtr pTimeout, pointer pRead) ++xf86RotateBlockHandler(int screenNum, pointer blockData, ++ pointer pTimeout, pointer pReadmask) + { +- ScreenPtr pScreen = (ScreenPtr) data; +- +- xf86RotateRedisplay(pScreen); +-} ++ ScreenPtr pScreen = screenInfo.screens[screenNum]; ++ ScrnInfoPtr pScrn = xf86Screens[screenNum]; ++ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + +-static void +-xf86RotateWakeupHandler(pointer data, int i, pointer LastSelectMask) +-{ ++ pScreen->BlockHandler = xf86_config->BlockHandler; ++ (*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask); ++ if (xf86RotateRedisplay(pScreen)) ++ { ++ /* Re-wrap if rotation is still happening */ ++ xf86_config->BlockHandler = pScreen->BlockHandler; ++ pScreen->BlockHandler = xf86RotateBlockHandler; ++ } + } + + static void +@@ -367,14 +475,10 @@ xf86RotateDestroy (xf86CrtcPtr crtc) + } + DamageDestroy (xf86_config->rotation_damage); + xf86_config->rotation_damage = NULL; +- /* Free block/wakeup handler */ +- RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler, +- xf86RotateWakeupHandler, +- (pointer) pScreen); + } + } + +-void ++_X_EXPORT void + xf86RotateCloseScreen (ScreenPtr screen) + { + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; +@@ -385,19 +489,99 @@ xf86RotateCloseScreen (ScreenPtr screen) + xf86RotateDestroy (xf86_config->crtc[c]); + } + +-Bool ++_X_EXPORT Bool + xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation) + { + ScrnInfoPtr pScrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + ScreenPtr pScreen = pScrn->pScreen; ++ PictTransform crtc_to_fb, fb_to_crtc; ++ ++ PictureTransformIdentity (&crtc_to_fb); ++ PictureTransformIdentity (&fb_to_crtc); ++ PictureTransformIsInverse ("identity", &crtc_to_fb, &fb_to_crtc); ++ if (rotation != RR_Rotate_0) ++ { ++ xFixed rot_cos, rot_sin, rot_dx, rot_dy; ++ xFixed scale_x, scale_y, scale_dx, scale_dy; ++ int mode_w = crtc->mode.HDisplay; ++ int mode_h = crtc->mode.VDisplay; ++ ++ /* rotation */ ++ switch (rotation & 0xf) { ++ default: ++ case RR_Rotate_0: ++ rot_cos = F ( 1); rot_sin = F ( 0); ++ rot_dx = F ( 0); rot_dy = F ( 0); ++ break; ++ case RR_Rotate_90: ++ rot_cos = F ( 0); rot_sin = F ( 1); ++ rot_dx = F ( mode_h); rot_dy = F (0); ++ break; ++ case RR_Rotate_180: ++ rot_cos = F (-1); rot_sin = F ( 0); ++ rot_dx = F (mode_w); rot_dy = F ( mode_h); ++ break; ++ case RR_Rotate_270: ++ rot_cos = F ( 0); rot_sin = F (-1); ++ rot_dx = F ( 0); rot_dy = F ( mode_w); ++ break; ++ } ++ ++ PictureTransformRotate (&crtc_to_fb, &fb_to_crtc, rot_cos, rot_sin); ++ PictureTransformIsInverse ("rotate", &crtc_to_fb, &fb_to_crtc); ++ ++ PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, rot_dx, rot_dy); ++ PictureTransformIsInverse ("rotate translate", &crtc_to_fb, &fb_to_crtc); ++ ++ /* reflection */ ++ scale_x = F (1); ++ scale_dx = 0; ++ scale_y = F (1); ++ scale_dy = 0; ++ if (rotation & RR_Reflect_X) ++ { ++ scale_x = F(-1); ++ if (rotation & (RR_Rotate_0|RR_Rotate_180)) ++ scale_dx = F(mode_w); ++ else ++ scale_dx = F(mode_h); ++ } ++ if (rotation & RR_Reflect_Y) ++ { ++ scale_y = F(-1); ++ if (rotation & (RR_Rotate_0|RR_Rotate_180)) ++ scale_dy = F(mode_h); ++ else ++ scale_dy = F(mode_w); ++ } ++ ++ PictureTransformScale (&crtc_to_fb, &fb_to_crtc, scale_x, scale_y); ++ PictureTransformIsInverse ("scale", &crtc_to_fb, &fb_to_crtc); ++ ++ PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, scale_dx, scale_dy); ++ PictureTransformIsInverse ("scale translate", &crtc_to_fb, &fb_to_crtc); ++ ++ } + +- if (rotation == RR_Rotate_0) ++ /* ++ * If the untranslated transformation is the identity, ++ * disable the shadow buffer ++ */ ++ if (PictureTransformIsIdentity (&crtc_to_fb)) + { ++ crtc->transform_in_use = FALSE; ++ PictureTransformInitTranslate (&crtc->crtc_to_framebuffer, ++ F (-crtc->x), F (-crtc->y)); ++ PictureTransformInitTranslate (&crtc->framebuffer_to_crtc, ++ F ( crtc->x), F ( crtc->y)); + xf86RotateDestroy (crtc); + } + else + { ++ PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, crtc->x, crtc->y); ++ PictureTransformIsInverse ("offset", &crtc_to_fb, &fb_to_crtc); ++ + /* + * these are the size of the shadow pixmap, which + * matches the mode, not the pre-rotated copy in the +@@ -440,28 +624,20 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation) + if (!xf86_config->rotation_damage) + goto bail2; + +- /* Assign block/wakeup handler */ +- if (!RegisterBlockAndWakeupHandlers (xf86RotateBlockHandler, +- xf86RotateWakeupHandler, +- (pointer) pScreen)) +- { +- goto bail3; +- } ++ /* Wrap block handler */ ++ xf86_config->BlockHandler = pScreen->BlockHandler; ++ pScreen->BlockHandler = xf86RotateBlockHandler; + } + if (0) + { +-bail3: +- DamageDestroy (xf86_config->rotation_damage); +- xf86_config->rotation_damage = NULL; +- +-bail2: ++ bail2: + if (shadow || shadowData) + { + crtc->funcs->shadow_destroy (crtc, shadow, shadowData); + crtc->rotatedPixmap = NULL; + crtc->rotatedData = NULL; + } +-bail1: ++ bail1: + if (old_width && old_height) + crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc, + NULL, +@@ -469,6 +645,14 @@ bail1: + old_height); + return FALSE; + } ++ crtc->transform_in_use = TRUE; ++ crtc->crtc_to_framebuffer = crtc_to_fb; ++ crtc->framebuffer_to_crtc = fb_to_crtc; ++ crtc->bounds.x1 = 0; ++ crtc->bounds.x2 = crtc->mode.HDisplay; ++ crtc->bounds.y1 = 0; ++ crtc->bounds.y2 = crtc->mode.VDisplay; ++ PictureTransformBounds (&crtc->bounds, &crtc_to_fb); + } + + /* All done */ +diff --git a/hw/xfree86/ddc/Makefile.am b/hw/xfree86/ddc/Makefile.am +index 3b36f55..cd146c5 100644 +--- a/hw/xfree86/ddc/Makefile.am ++++ b/hw/xfree86/ddc/Makefile.am +@@ -1,12 +1,12 @@ +-sdk_HEADERS = edid.h vdif.h xf86DDC.h ++sdk_HEADERS = edid.h xf86DDC.h + + noinst_LIBRARIES = libddc.a + + libddc_a_SOURCES = xf86DDC.c edid.c interpret_edid.c print_edid.c \ +- interpret_vdif.c print_vdif.c ddcProperty.c ++ ddcProperty.c + + INCLUDES = $(XORG_INCS) -I$(srcdir)/../i2c + +-AM_CFLAGS = $(XORG_CFLAGS) ++AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) + + EXTRA_DIST = ddcPriv.h DDC.HOWTO +diff --git a/hw/xfree86/ddc/ddcProperty.c b/hw/xfree86/ddc/ddcProperty.c +index c68dd08..67351d3 100644 +--- a/hw/xfree86/ddc/ddcProperty.c ++++ b/hw/xfree86/ddc/ddcProperty.c +@@ -33,395 +33,8 @@ + #include "xf86DDC.h" + #include "xf86_ansic.h" + +-/* +- * xf86Mode.c should have a some more DisplayModePtr list handling. +- */ +-static DisplayModePtr +-xf86ModesAdd(DisplayModePtr Modes, DisplayModePtr Additions) +-{ +- if (!Modes) { +- if (Additions) +- return Additions; +- else +- return NULL; +- } +- +- if (Additions) { +- DisplayModePtr Mode = Modes; +- +- while (Mode->next) +- Mode = Mode->next; +- +- Mode->next = Additions; +- Additions->prev = Mode; +- } +- +- return Modes; +-} +- +-static DisplayModePtr +-xf86ModeCopy(DisplayModePtr Mode) +-{ +- DisplayModePtr New; +- +- if (!Mode) +- return NULL; +- +- New = xnfalloc(sizeof(DisplayModeRec)); +- +- memcpy(New, Mode, sizeof(DisplayModeRec)); +- +- New->name = xnfalloc(strlen(Mode->name) + 1); +- memcpy(New->name, Mode->name, strlen(Mode->name) + 1); +- +- /* We ignore privates as DDC code doesn't use it currently */ +- return New; +-} +- +-/* +- * Temporary. +- */ +-static void +-add(char **p, char *new) +-{ +- *p = xnfrealloc(*p, strlen(*p) + strlen(new) + 2); +- strcat(*p, " "); +- strcat(*p, new); +-} +- +-static void +-PrintModeline(int scrnIndex,DisplayModePtr mode) +-{ +- char tmp[256]; +- char *flags = xnfcalloc(1, 1); +- +- if (mode->HSkew) { +- snprintf(tmp, 256, "hskew %i", mode->HSkew); +- add(&flags, tmp); +- } +- if (mode->VScan) { +- snprintf(tmp, 256, "vscan %i", mode->VScan); +- add(&flags, tmp); +- } +- if (mode->Flags & V_INTERLACE) add(&flags, "interlace"); +- if (mode->Flags & V_CSYNC) add(&flags, "composite"); +- if (mode->Flags & V_DBLSCAN) add(&flags, "doublescan"); +- if (mode->Flags & V_BCAST) add(&flags, "bcast"); +- if (mode->Flags & V_PHSYNC) add(&flags, "+hsync"); +- if (mode->Flags & V_NHSYNC) add(&flags, "-hsync"); +- if (mode->Flags & V_PVSYNC) add(&flags, "+vsync"); +- if (mode->Flags & V_NVSYNC) add(&flags, "-vsync"); +- if (mode->Flags & V_PCSYNC) add(&flags, "+csync"); +- if (mode->Flags & V_NCSYNC) add(&flags, "-csync"); +-#if 0 +- if (mode->Flags & V_CLKDIV2) add(&flags, "vclk/2"); +-#endif +- xf86DrvMsgVerb(scrnIndex, X_INFO, 3, +- "Modeline \"%s\" %6.2f %i %i %i %i %i %i %i %i%s\n", +- mode->name, mode->Clock/1000., mode->HDisplay, +- mode->HSyncStart, mode->HSyncEnd, mode->HTotal, +- mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, +- mode->VTotal, flags); +- xfree(flags); +-} +- +-/* +- * TODO: +- * - for those with access to the VESA DMT standard; review please. +- */ +-#define MODEPREFIX(name) NULL, NULL, name, 0,M_T_DRIVER +-#define MODESUFFIX 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0 +- +-DisplayModeRec DDCEstablishedModes[17] = { +- { MODEPREFIX("800x600"), 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@60Hz */ +- { MODEPREFIX("800x600"), 36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@56Hz */ +- { MODEPREFIX("640x480"), 31500, 640, 656, 720, 840, 0, 480, 481, 484, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@75Hz */ +- { MODEPREFIX("640x480"), 31500, 640, 664, 704, 832, 0, 480, 489, 491, 520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@72Hz */ +- { MODEPREFIX("640x480"), 30240, 640, 704, 768, 864, 0, 480, 483, 486, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@67Hz */ +- { MODEPREFIX("640x480"), 25200, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@60Hz */ +- { MODEPREFIX("720x400"), 35500, 720, 738, 846, 900, 0, 400, 421, 423, 449, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 720x400@88Hz */ +- { MODEPREFIX("720x400"), 28320, 720, 738, 846, 900, 0, 400, 412, 414, 449, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400@70Hz */ +- { MODEPREFIX("1280x1024"), 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@75Hz */ +- { MODEPREFIX("1024x768"), 78800, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@75Hz */ +- { MODEPREFIX("1024x768"), 75000, 1024, 1048, 1184, 1328, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@70Hz */ +- { MODEPREFIX("1024x768"), 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@60Hz */ +- { MODEPREFIX("1024x768"), 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 776, 817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768@43Hz */ +- { MODEPREFIX("832x624"), 57284, 832, 864, 928, 1152, 0, 624, 625, 628, 667, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 832x624@75Hz */ +- { MODEPREFIX("800x600"), 49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@75Hz */ +- { MODEPREFIX("800x600"), 50000, 800, 856, 976, 1040, 0, 600, 637, 643, 666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@72Hz */ +- { MODEPREFIX("1152x864"), 108000, 1152, 1216, 1344, 1600, 0, 864, 865, 868, 900, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1152x864@75Hz */ +-}; +- +-static DisplayModePtr +-DDCModesFromEstablished(int scrnIndex, struct established_timings *timing) +-{ +- DisplayModePtr Modes = NULL, Mode = NULL; +- CARD32 bits = (timing->t1) | (timing->t2 << 8) | +- ((timing->t_manu & 0x80) << 9); +- int i; +- +- for (i = 0; i < 17; i++) +- if (bits & (0x01 << i)) { +- Mode = xf86ModeCopy(&(DDCEstablishedModes[i])); +- Modes = xf86ModesAdd(Modes, Mode); +- } +- +- return Modes; +-} +- +-/* +- * +- */ +-static DisplayModePtr +-DDCModesFromStandardTiming(int scrnIndex, struct std_timings *timing) +-{ +- DisplayModePtr Modes = NULL, Mode = NULL; +- int i; +- +- for (i = 0; i < STD_TIMINGS; i++) +- if (timing[i].hsize && timing[i].vsize && timing[i].refresh) { +- Mode = xf86CVTMode(timing[i].hsize, timing[i].vsize, +- timing[i].refresh, FALSE, FALSE); +- Mode->type = M_T_DRIVER; +- Modes = xf86ModesAdd(Modes, Mode); +- } +- +- return Modes; +-} +- +-/* +- * +- */ +-static DisplayModePtr +-DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing, +- int preferred) +-{ +- DisplayModePtr Mode; +- +- /* We don't do stereo */ +- if (timing->stereo) { +- xf86DrvMsg(scrnIndex, X_INFO, "%s: Ignoring: We don't handle stereo.\n", +- __func__); +- return NULL; +- } +- +- /* We only do seperate sync currently */ +- if (timing->sync != 0x03) { +- xf86DrvMsg(scrnIndex, X_INFO, "%s: %dx%d Warning: We only handle seperate" +- " sync.\n", __func__, timing->h_active, timing->v_active); +- } +- +- Mode = xnfalloc(sizeof(DisplayModeRec)); +- memset(Mode, 0, sizeof(DisplayModeRec)); +- +- Mode->name = xnfalloc(10); /* "1234x1234" */ +- xf86snprintf(Mode->name, 20, "%dx%d", timing->h_active, +- timing->v_active); +- +- Mode->type = M_T_DRIVER; +- if (preferred) +- Mode->type |= M_T_PREFERRED; +- +- Mode->Clock = timing->clock / 1000.0; +- +- Mode->HDisplay = timing->h_active; +- Mode->HSyncStart = timing->h_active + timing->h_sync_off; +- Mode->HSyncEnd = Mode->HSyncStart + timing->h_sync_width; +- Mode->HTotal = timing->h_active + timing->h_blanking; +- +- Mode->VDisplay = timing->v_active; +- Mode->VSyncStart = timing->v_active + timing->v_sync_off; +- Mode->VSyncEnd = Mode->VSyncStart + timing->v_sync_width; +- Mode->VTotal = timing->v_active + timing->v_blanking; +- +- /* We ignore h/v_size and h/v_border for now. */ +- +- if (timing->interlaced) +- Mode->Flags |= V_INTERLACE; +- +- if (timing->misc & 0x02) +- Mode->Flags |= V_PHSYNC; +- else +- Mode->Flags |= V_NHSYNC; +- +- if (timing->misc & 0x01) +- Mode->Flags |= V_PVSYNC; +- else +- Mode->Flags |= V_NVSYNC; +- +- return Mode; +-} +- +-/* +- * +- */ +-static void +-DDCGuessRangesFromModes(int scrnIndex, MonPtr Monitor, DisplayModePtr Modes) +-{ +- DisplayModePtr Mode = Modes; +- +- if (!Monitor || !Modes) +- return; +- +- /* set up the ranges for scanning through the modes */ +- Monitor->nHsync = 1; +- Monitor->hsync[0].lo = 1024.0; +- Monitor->hsync[0].hi = 0.0; +- +- Monitor->nVrefresh = 1; +- Monitor->vrefresh[0].lo = 1024.0; +- Monitor->vrefresh[0].hi = 0.0; +- +- while (Mode) { +- if (!Mode->HSync) +- Mode->HSync = ((float) Mode->Clock ) / ((float) Mode->HTotal); +- +- if (!Mode->VRefresh) +- Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) / +- ((float) (Mode->HTotal * Mode->VTotal)); +- +- if (Mode->HSync < Monitor->hsync[0].lo) +- Monitor->hsync[0].lo = Mode->HSync; +- +- if (Mode->HSync > Monitor->hsync[0].hi) +- Monitor->hsync[0].hi = Mode->HSync; +- +- if (Mode->VRefresh < Monitor->vrefresh[0].lo) +- Monitor->vrefresh[0].lo = Mode->VRefresh; +- +- if (Mode->VRefresh > Monitor->vrefresh[0].hi) +- Monitor->vrefresh[0].hi = Mode->VRefresh; +- +- Mode = Mode->next; +- } +-} +- +-/* +- * Fill out MonPtr with xf86MonPtr information. +- */ +-void +-xf86DDCMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC) +-{ +- DisplayModePtr Modes = NULL, Mode; +- int i, clock; +- Bool have_hsync = FALSE, have_vrefresh = FALSE; +- int preferred; +- +- if (!Monitor || !DDC) +- return; +- +- Monitor->DDC = DDC; +- +- preferred = PREFERRED_TIMING_MODE(DDC->features.msc); +- +- Monitor->widthmm = 10 * DDC->features.hsize; +- Monitor->heightmm = 10 * DDC->features.vsize; +- +- /* If this is a digital display, then we can use reduced blanking */ +- if (DDC->features.input_type) +- Monitor->reducedblanking = TRUE; +- /* Allow the user to also enable this through config */ +- +- /* Add established timings */ +- Mode = DDCModesFromEstablished(scrnIndex, &DDC->timings1); +- Modes = xf86ModesAdd(Modes, Mode); +- +- /* Add standard timings */ +- Mode = DDCModesFromStandardTiming(scrnIndex, DDC->timings2); +- Modes = xf86ModesAdd(Modes, Mode); +- +- /* Skip EDID ranges if they were specified in the config file */ +- have_hsync = (Monitor->nHsync != 0); +- have_vrefresh = (Monitor->nVrefresh != 0); +- +- /* Go through the detailed monitor sections */ +- for (i = 0; i < DET_TIMINGS; i++) +- switch (DDC->det_mon[i].type) { +- case DS_RANGES: +- if (!have_hsync) { +- if (!Monitor->nHsync) +- xf86DrvMsg(scrnIndex, X_INFO, +- "Using EDID range info for horizontal sync\n"); +- Monitor->hsync[Monitor->nHsync].lo = +- DDC->det_mon[i].section.ranges.min_h; +- Monitor->hsync[Monitor->nHsync].hi = +- DDC->det_mon[i].section.ranges.max_h; +- Monitor->nHsync++; +- } else { +- xf86DrvMsg(scrnIndex, X_INFO, +- "Using hsync ranges from config file\n"); +- } +- +- if (!have_vrefresh) { +- if (!Monitor->nVrefresh) +- xf86DrvMsg(scrnIndex, X_INFO, +- "Using EDID range info for vertical refresh\n"); +- Monitor->vrefresh[Monitor->nVrefresh].lo = +- DDC->det_mon[i].section.ranges.min_v; +- Monitor->vrefresh[Monitor->nVrefresh].hi = +- DDC->det_mon[i].section.ranges.max_v; +- Monitor->nVrefresh++; +- } else { +- xf86DrvMsg(scrnIndex, X_INFO, +- "Using vrefresh ranges from config file\n"); +- } +- +- clock = DDC->det_mon[i].section.ranges.max_clock * 1000; +- if (clock > Monitor->maxPixClock) +- Monitor->maxPixClock = clock; +- +- break; +- case DT: +- Mode = DDCModeFromDetailedTiming(scrnIndex, +- &DDC->det_mon[i].section.d_timings, +- preferred); +- preferred = 0; +- Modes = xf86ModesAdd(Modes, Mode); +- break; +- case DS_STD_TIMINGS: +- Mode = DDCModesFromStandardTiming(scrnIndex, +- DDC->det_mon[i].section.std_t); +- Modes = xf86ModesAdd(Modes, Mode); +- break; +- default: +- break; +- } +- +- if (Modes) { +- /* Print Modes */ +- xf86DrvMsg(scrnIndex, X_INFO, "Printing DDC gathered Modelines:\n"); +- +- Mode = Modes; +- while (Mode) { +- PrintModeline(scrnIndex, Mode); +- Mode = Mode->next; +- } +- +- /* Do we still need ranges to be filled in? */ +- if (!Monitor->nHsync || !Monitor->nVrefresh) +- DDCGuessRangesFromModes(scrnIndex, Monitor, Modes); +- +- /* look for last Mode */ +- Mode = Modes; +- +- while (Mode->next) +- Mode = Mode->next; +- +- /* add to MonPtr */ +- if (Monitor->Modes) { +- Monitor->Last->next = Modes; +- Modes->prev = Monitor->Last; +- Monitor->Last = Mode; +- } else { +- Monitor->Modes = Modes; +- Monitor->Last = Mode; +- } +- } +-} +- + #define EDID1_ATOM_NAME "XFree86_DDC_EDID1_RAWDATA" + #define EDID2_ATOM_NAME "XFree86_DDC_EDID2_RAWDATA" +-#define VDIF_ATOM_NAME "XFree86_DDC_VDIF_RAWDATA" + + static void + addRootWindowProperties(ScrnInfoPtr pScrn, xf86MonPtr DDC) +@@ -474,7 +87,7 @@ addRootWindowProperties(ScrnInfoPtr pScrn, xf86MonPtr DDC) + if ((EDID1rawdata = xalloc(128*sizeof(CARD8)))==NULL) + return; + +- EDID1Atom = MakeAtom(EDID1_ATOM_NAME, sizeof(EDID1_ATOM_NAME), TRUE); ++ EDID1Atom = MakeAtom(EDID1_ATOM_NAME, sizeof(EDID1_ATOM_NAME) - 1, TRUE); + memcpy(EDID1rawdata, DDC->rawData, 128); + xf86RegisterRootWindowProperty(scrnIndex, EDID1Atom, XA_INTEGER, 8, + 128, (unsigned char *)EDID1rawdata); +@@ -485,20 +98,10 @@ addRootWindowProperties(ScrnInfoPtr pScrn, xf86MonPtr DDC) + return; + + memcpy(EDID2rawdata, DDC->rawData, 256); +- EDID2Atom = MakeAtom(EDID2_ATOM_NAME, sizeof(EDID2_ATOM_NAME), TRUE); ++ EDID2Atom = MakeAtom(EDID2_ATOM_NAME, sizeof(EDID2_ATOM_NAME) - 1, TRUE); + xf86RegisterRootWindowProperty(scrnIndex, EDID2Atom, XA_INTEGER, 8, + 256, (unsigned char *)EDID2rawdata); + } +- +-#if 0 +- if (DDC->vdif) { +-#define VDIF_DUMMY_STRING "setting dummy VDIF property - please insert correct values\n" +- +- VDIFAtom = MakeAtom(VDIF_ATOM_NAME, sizeof(VDIF_ATOM_NAME), TRUE); +- xf86RegisterRootWindowProperty(scrnIndex, VDIFAtom, XA_STRING, 8, +- strlen(VDIF_DUMMY_STRING), VDIF_DUMMY_STRING); +- } +-#endif + } + + Bool +diff --git a/hw/xfree86/ddc/edid.h b/hw/xfree86/ddc/edid.h +index 30499a6..4487273 100644 +--- a/hw/xfree86/ddc/edid.h ++++ b/hw/xfree86/ddc/edid.h +@@ -12,8 +12,6 @@ + #ifndef _EDID_H_ + #define _EDID_H_ + +-#include "vdif.h" +- + /* read complete EDID record */ + #define EDID1_LEN 128 + #define BITS_PER_BYTE 9 +@@ -192,7 +190,14 @@ + + + /* EDID Ver. >= 1.2 */ +-#define _IS_MONITOR_DESC(x) (x[0] == 0 && x[1] == 0 && x[2] == 0 && x[4] == 0) ++/** ++ * Returns true if the pointer is the start of a monitor descriptor block ++ * instead of a detailed timing descriptor. ++ * ++ * Checking the reserved pad fields for zeroes fails on some monitors with ++ * broken empty ASCII strings. Only the first two bytes are reliable. ++ */ ++#define _IS_MONITOR_DESC(x) (x[0] == 0 && x[1] == 0) + #define IS_MONITOR_DESC _IS_MONITOR_DESC(c) + #define _PIXEL_CLOCK(x) (x[0] + (x[1] << 8)) * 10000 + #define PIXEL_CLOCK _PIXEL_CLOCK(c) +@@ -453,7 +458,7 @@ typedef struct { + struct established_timings timings1; + struct std_timings timings2[8]; + struct detailed_monitor_section det_mon[4]; +- xf86vdifPtr vdif; ++ void *vdif; /* unused */ + int no_sections; + Uchar *rawData; + } xf86Monitor, *xf86MonPtr; +diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c +index c58bb2f..7b4b2b9 100644 +--- a/hw/xfree86/ddc/interpret_edid.c ++++ b/hw/xfree86/ddc/interpret_edid.c +@@ -304,16 +304,18 @@ get_detailed_timing_section(Uchar *c, struct detailed_timings *r) + r->misc = MISC; + } + ++#define MAX_EDID_MINOR 3 + + static Bool + validate_version(int scrnIndex, struct edid_version *r) + { + if (r->version != 1) + return FALSE; +- if (r->revision > 3) { +- xf86DrvMsg(scrnIndex, X_ERROR,"EDID Version 1.%i not yet supported\n", +- r->revision); +- return FALSE; +- } ++ ++ if (r->revision > MAX_EDID_MINOR) ++ xf86DrvMsg(scrnIndex, X_WARNING, ++ "Assuming version 1.%d is compatible with 1.%d\n", ++ r->revision, MAX_EDID_MINOR); ++ + return TRUE; + } +diff --git a/hw/xfree86/ddc/interpret_vdif.c b/hw/xfree86/ddc/interpret_vdif.c +deleted file mode 100644 +index 3a17e2f..0000000 +--- a/hw/xfree86/ddc/interpret_vdif.c ++++ /dev/null +@@ -1,132 +0,0 @@ +- +-#ifdef HAVE_XORG_CONFIG_H +-#include +-#endif +- +-#include +-#include "xf86DDC.h" +-#include "vdif.h" +- +-static xf86VdifLimitsPtr* get_limits(CARD8 *c); +-static xf86VdifGammaPtr* get_gamma(CARD8 *c); +-static xf86VdifTimingPtr* get_timings(CARD8 *c); +-#if X_BYTE_ORDER == X_BIG_ENDIAN +-static CARD32 swap_byte_order(CARD32 c); +-#endif +- +-xf86vdifPtr +-xf86InterpretVdif(CARD8 *c) +-{ +- xf86VdifPtr p = (xf86VdifPtr)c; +- xf86vdifPtr vdif; +- int i; +-#if X_BYTE_ORDER == X_BIG_ENDIAN +- int length; +-#endif +- unsigned long l = 0; +- +- if (c == NULL) return NULL; +-#if X_BYTE_ORDER == X_BIG_ENDIAN +- length = swap_byte_order(p->FileLength); +- for (i = 0; i < (length >>2); i++) +- ((CARD32*)c)[i] = swap_byte_order(((CARD32*)c)[i]) ; +-#endif +- if (p->VDIFId[0] != 'V' || p->VDIFId[1] != 'D' || p->VDIFId[2] != 'I' +- || p->VDIFId[3] != 'F') return NULL; +- for ( i = 12; i < p->FileLength; i++) +- l += c[i]; +- if ( l != p->Checksum) return NULL; +- vdif = xalloc(sizeof(xf86vdif)); +- vdif->vdif = p; +- vdif->limits = get_limits(c); +- vdif->timings = get_timings(c); +- vdif->gamma = get_gamma(c); +- vdif->strings = VDIF_STRING(((xf86VdifPtr)c),0); +- xfree(c); +- return vdif; +-} +- +-static xf86VdifLimitsPtr* +-get_limits(CARD8 *c) +-{ +- int num, i, j; +- xf86VdifLimitsPtr *pp; +- xf86VdifLimitsPtr p; +- +- num = ((xf86VdifPtr)c)->NumberOperationalLimits; +- pp = xalloc(sizeof(xf86VdifLimitsPtr) * (num+1)); +- p = VDIF_OPERATIONAL_LIMITS(((xf86VdifPtr)c)); +- j = 0; +- for ( i = 0; iHeader.ScnTag == VDIF_OPERATIONAL_LIMITS_TAG) +- pp[j++] = p; +- VDIF_NEXT_OPERATIONAL_LIMITS(p); +- } +- pp[j] = NULL; +- return pp; +-} +- +-static xf86VdifGammaPtr* +-get_gamma(CARD8 *c) +-{ +- int num, i, j; +- xf86VdifGammaPtr *pp; +- xf86VdifGammaPtr p; +- +- num = ((xf86VdifPtr)c)->NumberOptions; +- pp = xalloc(sizeof(xf86VdifGammaPtr) * (num+1)); +- p = (xf86VdifGammaPtr)VDIF_OPTIONS(((xf86VdifPtr)c)); +- j = 0; +- for ( i = 0; iHeader.ScnTag == VDIF_GAMMA_TABLE_TAG) +- pp[j++] = p; +- VDIF_NEXT_OPTIONS(p); +- } +- pp[j] = NULL; +- return pp; +-} +- +-static xf86VdifTimingPtr* +-get_timings(CARD8 *c) +-{ +- int num, num_limits; +- int i,j,k; +- xf86VdifLimitsPtr lp; +- xf86VdifTimingPtr *pp; +- xf86VdifTimingPtr p; +- +- num = ((xf86VdifPtr)c)->NumberOperationalLimits; +- lp = VDIF_OPERATIONAL_LIMITS(((xf86VdifPtr)c)); +- num_limits = 0; +- for (i = 0; i < num; i++) { +- if (lp->Header.ScnTag == VDIF_OPERATIONAL_LIMITS_TAG) +- num_limits += lp->NumberPreadjustedTimings; +- VDIF_NEXT_OPERATIONAL_LIMITS(lp); +- } +- pp = xalloc(sizeof(xf86VdifTimingPtr) +- * (num_limits+1)); +- j = 0; +- lp = VDIF_OPERATIONAL_LIMITS(((xf86VdifPtr) c)); +- for (i = 0; i < num; i++) { +- p = VDIF_PREADJUSTED_TIMING(lp); +- for (k = 0; k < lp->NumberPreadjustedTimings; k++) { +- if (p->Header.ScnTag == VDIF_PREADJUSTED_TIMING_TAG) +- pp[j++] = p; +- VDIF_NEXT_PREADJUSTED_TIMING(p); +- } +- VDIF_NEXT_OPERATIONAL_LIMITS(lp); +- } +- pp[j] = NULL; +- return pp; +-} +- +-#if X_BYTE_ORDER == X_BIG_ENDIAN +-static CARD32 +-swap_byte_order(CARD32 c) +-{ +- return ((c & 0xFF000000) >> 24) | ((c & 0xFF0000) >> 8) +- | ((c & 0xFF00) << 8) | ((c & 0xFF) << 24); +-} +- +-#endif +diff --git a/hw/xfree86/ddc/print_vdif.c b/hw/xfree86/ddc/print_vdif.c +deleted file mode 100644 +index 13cd3ab..0000000 +--- a/hw/xfree86/ddc/print_vdif.c ++++ /dev/null +@@ -1,225 +0,0 @@ +- +-#ifdef HAVE_XORG_CONFIG_H +-#include +-#endif +- +-#include "vdif.h" +-#include "misc.h" +-#include "xf86DDC.h" +- +-static void print_vdif(xf86VdifPtr l, char *s); +-static void print_timings(xf86VdifTimingPtr *pt); +-static void print_limits(xf86VdifLimitsPtr *pl); +-static void print_gamma(xf86VdifGammaPtr *pg); +-static void print_type(CARD8 c); +-static void print_polarity(CARD8 c); +- +-void +-xf86print_vdif(xf86vdifPtr v) +-{ +- print_vdif(v->vdif,v->strings); +- print_limits(v->limits); +- print_timings(v->timings); +- print_gamma(v->gamma); +-} +- +-static void +-print_vdif(xf86VdifPtr l, char *s) +-{ +- ErrorF("Version %i.%i",l->VDIFVersion,l->VDIFRevision); +- ErrorF(" Date: %i/%i/%i, Manufactured: %i/%i/%i\n",l->Date[0], +- l->Date[1],l->Date[2],l->DateManufactured[0], +- l->DateManufactured[1],l->DateManufactured[2]); +- ErrorF("File Revision: %i",l->FileRevision); +- ErrorF("Manufacturer: %s\n",s + l->Manufacturer); +- ErrorF("ModelNumber: %s\n",s + l->ModelNumber); +- ErrorF("VDIFIndex: %s\n",s +l->MinVDIFIndex); +- ErrorF("Version: %s\n",s + l->Version); +- ErrorF("SerialNumber %s\n",s + l->SerialNumber); +- ErrorF("MonitorType: "); +- switch (l->MonitorType) { +- case VDIF_MONITOR_MONOCHROME: +- ErrorF("Mono\n"); +- break; +- case VDIF_MONITOR_COLOR: +- ErrorF("Color\n"); +- break; +- } +- ErrorF("CRT Size: %i inches\n",l->CRTSize); +- switch (l->MonitorType) { +- case VDIF_MONITOR_MONOCHROME: +- ErrorF("Border: %i percent\n", +- l->BorderRed); +- ErrorF("Phosphor Decay: 1: %i,",l->RedPhosphorDecay); +- if (l->GreenPhosphorDecay !=0) +- ErrorF(" 2: %i,",l->GreenPhosphorDecay); +- if (l->BluePhosphorDecay !=0) +- ErrorF(" 3: %i",l->BluePhosphorDecay); +- ErrorF(" ms\n"); +- if (l->RedChromaticity_x) +- ErrorF("Chromaticity: 1: x:%f, y:%f; ", +- l->RedChromaticity_x/1000.0,l->RedChromaticity_y/1000.0); +- if (l->GreenChromaticity_x) +- ErrorF("Chromaticity: 2: x:%f, y:%f; ", +- l->GreenChromaticity_x/1000.0,l->GreenChromaticity_y/1000.0); +- if (l->BlueChromaticity_x) +- ErrorF("Chromaticity: 3: x:%f, y:%f ", +- l->BlueChromaticity_x/1000.0,l->BlueChromaticity_y/1000.0); +- ErrorF("\n"); +- ErrorF("Gamma: %f\n",l->RedGamma/1000.0); +- break; +- case VDIF_MONITOR_COLOR: +- ErrorF("Border: Red: %i Green: %i Blue: %i percent\n", +- l->BorderRed,l->BorderGreen,l->BorderBlue); +- ErrorF("Phosphor Decay: Red: %i, Green: %i, Blue: %i ms\n", +- l->RedPhosphorDecay,l->GreenPhosphorDecay,l->BluePhosphorDecay); +- ErrorF("Chromaticity: Red: x:%f, y:%f; Green: x:%f, y:%f; " +- "Blue: x:%f, y:%f\n", +- l->RedChromaticity_x/1000.0,l->RedChromaticity_y/1000.0, +- l->GreenChromaticity_x/1000.0,l->GreenChromaticity_y/1000.0, +- l->BlueChromaticity_x/1000.0,l->BlueChromaticity_y/1000.0); +- ErrorF("Gamma: Red:%f, Green:%f, Blue:%f\n",l->RedGamma/1000.0, +- l->GreenGamma/1000.0,l->BlueGamma/1000.0); +- break; +- } +- ErrorF("White Point: x: %f y: %f Y: %f\n",l->WhitePoint_x/1000.0, +- l->WhitePoint_y/1000.0,l->WhitePoint_Y/1000.0); +-} +- +-static void +-print_limits(xf86VdifLimitsPtr *pl) +-{ +- int i = 0; +- xf86VdifLimitsPtr l; +- +- while((l = pl[i]) != NULL) { +- ErrorF("Max display resolution: %i x %i pixel\n",l->MaxHorPixel, +- l->MaxVerPixel); +- ErrorF("Size of active area: %i x %i millimeters\n",l->MaxHorActiveLength, +- l->MaxVerActiveHeight); +- ErrorF("Video Type: "); +- print_type(l->VideoType); +- ErrorF("Sync Type: "); +- print_type(l->SyncType); +- ErrorF("Sync Configuration "); +- switch (l->SyncConfiguration) { +- case VDIF_SYNC_SEPARATE: +- ErrorF("separate\n"); +- break; +- case VDIF_SYNC_C: +- ErrorF("composite C\n"); +- break; +- case VDIF_SYNC_CP: +- ErrorF("composite CP\n"); +- break; +- case VDIF_SYNC_G: +- ErrorF("composite G\n"); +- break; +- case VDIF_SYNC_GP: +- ErrorF("composite GP\n"); +- break; +- case VDIF_SYNC_OTHER: +- ErrorF("other\n"); +- break; +- } +- ErrorF("Termination Resistance: %i\n",l->TerminationResistance); +- ErrorF("Levels: white: %i, black: %i, blank: %i, sync: %i mV\n", +- l->WhiteLevel,l->BlackLevel,l->BlankLevel,l->SyncLevel); +- ErrorF("Max. Pixel Clock: %f MHz\n",l->MaxPixelClock/1000.0); +- ErrorF("Freq. Range: Hor.: %f - %f kHz, Ver.: %f - %f Hz\n", +- l->MaxHorFrequency/1000.0,l->MinHorFrequency/1000.0, +- l->MaxVerFrequency/1000.0,l->MinVerFrequency/1000.0); +- ErrorF("Retrace time: Hor: %f us, Ver: %f ms\n",l->MinHorRetrace/1000.0, +- l->MinVerRetrace/1000.0); +- } +-} +- +-static void +-print_timings(xf86VdifTimingPtr *pt) +-{ +- int i = 0; +- xf86VdifTimingPtr t; +- +- while((t = pt[i]) != NULL) { +- ErrorF("SVGA / SVPMI mode number: %i\n",t->PreadjustedTimingName); +- ErrorF("Mode %i x %i\n",t->HorPixel,t->VerPixel); +- ErrorF("Size: %i x %i mm\n",t->HorAddrLength,t->VerAddrHeight); +- ErrorF("Ratios: %i/%i\n",t->PixelWidthRatio,t->PixelHeightRatio); +- ErrorF("Character width: %i",t->CharacterWidth); +- ErrorF("Clock: %f MHz HFreq.: %f kHz, VFreq: %f Hz\n",t->PixelClock/1000.0, +- t->HorFrequency/1000.0,t->VerFrequency/1000.0); +- ErrorF("Htotal: %f us, Vtotal %f ms\n", t->HorTotalTime/1000.0, +- t->VerTotalTime/1000.0); +- ErrorF("HDisp: %f, HBlankStart: %f, HBlankLength: %f, " +- "HSyncStart: %f HSyncEnd: %f us\n",t->HorAddrTime/1000.0, +- t->HorBlankStart/1000.0,t->HorBlankTime/1000.0, +- t->HorSyncStart/1000.0,t->HorSyncTime/1000.0); +- ErrorF("VDisp: %f, VBlankStart: %f, VBlankLength: %f, " +- "VSyncStart: %f VSyncEnd: %f us\n",t->VerAddrTime/1000.0, +- t->VerBlankStart/1000.0,t->VerBlankTime/1000.0, +- t->VerSyncStart/1000.0,t->VerSyncTime/1000.0); +- ErrorF("Scan Type: "); +- switch (t->ScanType) { +- case VDIF_SCAN_INTERLACED: +- ErrorF("interlaced "); +- break; +- case VDIF_SCAN_NONINTERLACED: +- ErrorF("non interlaced "); +- break; +- case VDIF_SCAN_OTHER: +- ErrorF("other "); +- break; +- } +- ErrorF("Polarity: H: "); +- print_polarity(t->HorSyncPolarity); +- ErrorF("V: "); +- print_polarity(t->VerSyncPolarity); +- ErrorF("\n"); +- } +-} +- +-static void +-print_gamma(xf86VdifGammaPtr *pg) +-{ +- int i = 0; +- xf86VdifGammaPtr g; +- +- while((g = pg[i]) != NULL) { +- ErrorF("Gamma Table Entries: %i\n",g->GammaTableEntries); +- } +-} +- +-static void +-print_type(CARD8 c) +-{ +- switch (c) { +- case VDIF_VIDEO_TTL : +- ErrorF("TTL\n"); +- break; +- case VDIF_VIDEO_ANALOG : +- ErrorF("Analog\n"); +- break; +- case VDIF_VIDEO_ECL: +- ErrorF("ECL\n"); +- break; +- case VDIF_VIDEO_DECL: +- ErrorF("DECL\n"); +- break; +- case VDIF_VIDEO_OTHER: +- ErrorF("other\n"); +- break; +- } +-} +- +-static void +-print_polarity(CARD8 c) +-{ +- switch (c) { +- case VDIF_POLARITY_NEGATIVE: +- ErrorF(" Neg."); +- break; +- case VDIF_POLARITY_POSITIVE: +- ErrorF(" Pos."); +- break; +- } +-} +diff --git a/hw/xfree86/ddc/vdif.h b/hw/xfree86/ddc/vdif.h +deleted file mode 100644 +index 1777b68..0000000 +--- a/hw/xfree86/ddc/vdif.h ++++ /dev/null +@@ -1,174 +0,0 @@ +- +-#ifndef _VDIF_H +-#define _VDIF_H +- +-#define VDIF_MONITOR_MONOCHROME 0 +-#define VDIF_MONITOR_COLOR 1 +-#define VDIF_VIDEO_TTL 0 +-#define VDIF_VIDEO_ANALOG 1 +-#define VDIF_VIDEO_ECL 2 +-#define VDIF_VIDEO_DECL 3 +-#define VDIF_VIDEO_OTHER 4 +-#define VDIF_SYNC_SEPARATE 0 +-#define VDIF_SYNC_C 1 +-#define VDIF_SYNC_CP 2 +-#define VDIF_SYNC_G 3 +-#define VDIF_SYNC_GP 4 +-#define VDIF_SYNC_OTHER 5 +-#define VDIF_SCAN_NONINTERLACED 0 +-#define VDIF_SCAN_INTERLACED 1 +-#define VDIF_SCAN_OTHER 2 +-#define VDIF_POLARITY_NEGATIVE 0 +-#define VDIF_POLARITY_POSITIVE 1 +- +-#include +- +-#undef CARD32 +-#define CARD32 unsigned int /* ... on all supported platforms */ +- +-typedef struct _VDIF { /* Monitor Description: */ +- CARD8 VDIFId[4]; /* alway "VDIF" */ +- CARD32 FileLength; /* lenght of the whole file */ +- CARD32 Checksum; /* sum of all bytes in the file after*/ +- /* this field */ +- CARD16 VDIFVersion; /* structure version number */ +- CARD16 VDIFRevision; /* structure revision number */ +- CARD16 Date[3]; /* file date Year/Month/Day */ +- CARD16 DateManufactured[3]; /* date Year/Month/Day */ +- CARD32 FileRevision; /* file revision string */ +- CARD32 Manufacturer; /* ASCII ID of the manufacturer */ +- CARD32 ModelNumber; /* ASCII ID of the model */ +- CARD32 MinVDIFIndex; /* ASCII ID of Minimum VDIF index */ +- CARD32 Version; /* ASCII ID of the model version */ +- CARD32 SerialNumber; /* ASCII ID of the serial number */ +- CARD8 MonitorType; /* Monochrome or Color */ +- CARD8 CRTSize; /* inches */ +- CARD8 BorderRed; /* percent */ +- CARD8 BorderGreen; /* percent */ +- CARD8 BorderBlue; /* percent */ +- CARD8 Reserved1; /* padding */ +- CARD16 Reserved2; /* padding */ +- CARD32 RedPhosphorDecay; /* microseconds */ +- CARD32 GreenPhosphorDecay; /* microseconds */ +- CARD32 BluePhosphorDecay; /* microseconds */ +- CARD16 WhitePoint_x; /* WhitePoint in CIExyY (scale 1000) */ +- CARD16 WhitePoint_y; +- CARD16 WhitePoint_Y; +- CARD16 RedChromaticity_x; /* Red chromaticity in x,y */ +- CARD16 RedChromaticity_y; +- CARD16 GreenChromaticity_x; /* Green chromaticity in x,y */ +- CARD16 GreenChromaticity_y; +- CARD16 BlueChromaticity_x; /* Blue chromaticity in x,y */ +- CARD16 BlueChromaticity_y; +- CARD16 RedGamma; /* Gamme curve exponent (scale 1000) */ +- CARD16 GreenGamma; +- CARD16 BlueGamma; +- CARD32 NumberOperationalLimits; +- CARD32 OffsetOperationalLimits; +- CARD32 NumberOptions; /* optinal sections (gamma table) */ +- CARD32 OffsetOptions; +- CARD32 OffsetStringTable; +-} xf86VdifRec, *xf86VdifPtr; +- +-typedef enum { /* Tags for section identification */ +- VDIF_OPERATIONAL_LIMITS_TAG = 1, +- VDIF_PREADJUSTED_TIMING_TAG, +- VDIF_GAMMA_TABLE_TAG +-} VDIFScnTag; +- +-typedef struct _VDIFScnHdr { /* Generic Section Header: */ +- CARD32 ScnLength; /* lenght of section */ +- CARD32 ScnTag; /* tag for section identification */ +-} VDIFScnHdrRec, *VDIFScnHdrPtr; +- +-typedef struct _VDIFLimits { /* Operational Limits: */ +- VDIFScnHdrRec Header; /* common section info */ +- CARD16 MaxHorPixel; /* pixels */ +- CARD16 MaxVerPixel; /* lines */ +- CARD16 MaxHorActiveLength; /* millimeters */ +- CARD16 MaxVerActiveHeight; /* millimeters */ +- CARD8 VideoType; /* TTL / Analog / ECL / DECL */ +- CARD8 SyncType; /* TTL / Analog / ECL / DECL */ +- CARD8 SyncConfiguration; /* separate / composite / other */ +- CARD8 Reserved1; /* padding */ +- CARD16 Reserved2; /* padding */ +- CARD16 TerminationResistance; /* */ +- CARD16 WhiteLevel; /* millivolts */ +- CARD16 BlackLevel; /* millivolts */ +- CARD16 BlankLevel; /* millivolts */ +- CARD16 SyncLevel; /* millivolts */ +- CARD32 MaxPixelClock; /* kiloHertz */ +- CARD32 MinHorFrequency; /* Hertz */ +- CARD32 MaxHorFrequency; /* Hertz */ +- CARD32 MinVerFrequency; /* milliHertz */ +- CARD32 MaxVerFrequency; /* milliHertz */ +- CARD16 MinHorRetrace; /* nanoseconds */ +- CARD16 MinVerRetrace; /* microseconds */ +- CARD32 NumberPreadjustedTimings; +- CARD32 OffsetNextLimits; +-} xf86VdifLimitsRec, *xf86VdifLimitsPtr; +- +-typedef struct _VDIFTiming { /* Preadjusted Timing: */ +- VDIFScnHdrRec Header; /* common section info */ +- CARD32 PreadjustedTimingName; /* SVGA/SVPMI mode number */ +- CARD16 HorPixel; /* pixels */ +- CARD16 VerPixel; /* lines */ +- CARD16 HorAddrLength; /* millimeters */ +- CARD16 VerAddrHeight; /* millimeters */ +- CARD8 PixelWidthRatio; /* gives H:V */ +- CARD8 PixelHeightRatio; +- CARD8 Reserved1; /* padding */ +- CARD8 ScanType; /* noninterlaced / interlaced / other*/ +- CARD8 HorSyncPolarity; /* negative / positive */ +- CARD8 VerSyncPolarity; /* negative / positive */ +- CARD16 CharacterWidth; /* pixels */ +- CARD32 PixelClock; /* kiloHertz */ +- CARD32 HorFrequency; /* Hertz */ +- CARD32 VerFrequency; /* milliHertz */ +- CARD32 HorTotalTime; /* nanoseconds */ +- CARD32 VerTotalTime; /* microseconds */ +- CARD16 HorAddrTime; /* nanoseconds */ +- CARD16 HorBlankStart; /* nanoseconds */ +- CARD16 HorBlankTime; /* nanoseconds */ +- CARD16 HorSyncStart; /* nanoseconds */ +- CARD16 HorSyncTime; /* nanoseconds */ +- CARD16 VerAddrTime; /* microseconds */ +- CARD16 VerBlankStart; /* microseconds */ +- CARD16 VerBlankTime; /* microseconds */ +- CARD16 VerSyncStart; /* microseconds */ +- CARD16 VerSyncTime; /* microseconds */ +-} xf86VdifTimingRec, *xf86VdifTimingPtr; +- +-typedef struct _VDIFGamma { /* Gamma Table: */ +- VDIFScnHdrRec Header; /* common section info */ +- CARD16 GammaTableEntries; /* count of grays or RGB 3-tuples */ +- CARD16 Unused1; +-} xf86VdifGammaRec, *xf86VdifGammaPtr; +- +-/* access macros */ +-#define VDIF_OPERATIONAL_LIMITS(vdif) \ +-((xf86VdifLimitsPtr)((char*)(vdif) + (vdif)->OffsetOperationalLimits)) +-#define VDIF_NEXT_OPERATIONAL_LIMITS(limits) limits = \ +- ((xf86VdifLimitsPtr)((char*)(limits) + (limits)->OffsetNextLimits)) +-#define VDIF_PREADJUSTED_TIMING(limits) \ +-((xf86VdifTimingPtr)((char*)(limits) + (limits)->Header.ScnLength)) +-#define VDIF_NEXT_PREADJUSTED_TIMING(timing) timing = \ +- ((xf86VdifTimingPtr)((char*)(timing) + (timing)->Header.ScnLength)) +-#define VDIF_OPTIONS(vdif) \ +- ((VDIFScnHdrPtr)((char*)(vdif) + (vdif)->OffsetOptions)) +-#define VDIF_NEXT_OPTIONS(options) options = \ +- ((xf86VdifGammaPtr)((char*)(options) + (options)->Header.ScnLength)) +-#define VDIF_STRING(vdif, string) \ +- ((char*)((char*)vdif + vdif->OffsetStringTable + (string))) +- +-typedef struct _vdif { +- xf86VdifPtr vdif; +- xf86VdifLimitsPtr *limits; +- xf86VdifTimingPtr *timings; +- xf86VdifGammaPtr *gamma; +- char * strings; +-} xf86vdif, *xf86vdifPtr; +- +-#undef CARD32 +- +-#endif +diff --git a/hw/xfree86/ddc/xf86DDC.c b/hw/xfree86/ddc/xf86DDC.c +index 8080c8d..e47b8b8 100644 +--- a/hw/xfree86/ddc/xf86DDC.c ++++ b/hw/xfree86/ddc/xf86DDC.c +@@ -15,52 +15,6 @@ + + static const OptionInfoRec *DDCAvailableOptions(void *unused); + +-#if DDC_MODULE +- +-static MODULESETUPPROTO(ddcSetup); +- +-static XF86ModuleVersionInfo ddcVersRec = +-{ +- "ddc", +- MODULEVENDORSTRING, +- MODINFOSTRING1, +- MODINFOSTRING2, +- XORG_VERSION_CURRENT, +- 1, 0, 0, +- ABI_CLASS_VIDEODRV, /* needs the video driver ABI */ +- ABI_VIDEODRV_VERSION, +- MOD_CLASS_NONE, +- {0,0,0,0} +-}; +- +-_X_EXPORT XF86ModuleData ddcModuleData = { &ddcVersRec, ddcSetup, NULL }; +- +-ModuleInfoRec DDC = { +- 1, +- "DDC", +- NULL, +- 0, +- DDCAvailableOptions, +-}; +- +-static pointer +-ddcSetup(pointer module, pointer opts, int *errmaj, int *errmin) +-{ +- static Bool setupDone = FALSE; +- +- if (!setupDone) { +- setupDone = TRUE; +- xf86AddModuleInfo(&DDC, module); +- } +- /* +- * The return value must be non-NULL on success even though there +- * is no TearDownProc. +- */ +- return (pointer)1; +-} +- +-#endif +- + #define RETRIES 4 + + static unsigned char *EDIDRead_DDC1( +@@ -84,12 +38,6 @@ static unsigned char* EDID1Read_DDC2( + I2CBusPtr pBus + ); + +-static unsigned char * VDIFRead( +- int scrnIndex, +- I2CBusPtr pBus, +- int start +-); +- + static unsigned char * DDCRead_DDC2( + int scrnIndex, + I2CBusPtr pBus, +@@ -184,7 +132,6 @@ xf86DoEDID_DDC2(int scrnIndex, I2CBusPtr pBus) + { + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + unsigned char *EDID_block = NULL; +- unsigned char *VDIF_Block = NULL; + xf86MonPtr tmp = NULL; + /* Default DDC and DDC2 to enabled. */ + Bool noddc = FALSE, noddc2 = FALSE; +@@ -217,11 +164,6 @@ xf86DoEDID_DDC2(int scrnIndex, I2CBusPtr pBus) + else + ErrorF("Sections to follow: %i\n",tmp->no_sections); + #endif +- if (tmp) { +- VDIF_Block = +- VDIFRead(scrnIndex, pBus, EDID1_LEN * (tmp->no_sections + 1)); +- tmp->vdif = xf86InterpretVdif(VDIF_Block); +- } + + return tmp; + } +@@ -299,35 +241,6 @@ EDID1Read_DDC2(int scrnIndex, I2CBusPtr pBus) + return DDCRead_DDC2(scrnIndex, pBus, 0, EDID1_LEN); + } + +-static unsigned char* +-VDIFRead(int scrnIndex, I2CBusPtr pBus, int start) +-{ +- unsigned char * Buffer, *v_buffer = NULL, *v_bufferp = NULL; +- int i, num = 0; +- +- /* read VDIF length in 64 byte blocks */ +- Buffer = DDCRead_DDC2(scrnIndex, pBus,start,64); +- if (Buffer == NULL) +- return NULL; +-#ifdef DEBUG +- ErrorF("number of 64 bit blocks: %i\n",Buffer[0]); +-#endif +- if ((num = Buffer[0]) > 0) +- v_buffer = v_bufferp = xalloc(sizeof(unsigned char) * 64 * num); +- +- for (i = 0; i < num; i++) { +- Buffer = DDCRead_DDC2(scrnIndex, pBus,start,64); +- if (Buffer == NULL) { +- xfree (v_buffer); +- return NULL; +- } +- memcpy(v_bufferp,Buffer,63); /* 64th byte is checksum */ +- xfree(Buffer); +- v_bufferp += 63; +- } +- return v_buffer; +-} +- + static unsigned char * + DDCRead_DDC2(int scrnIndex, I2CBusPtr pBus, int start, int len) + { +diff --git a/hw/xfree86/ddc/xf86DDC.h b/hw/xfree86/ddc/xf86DDC.h +index 5def97a..3b072dd 100644 +--- a/hw/xfree86/ddc/xf86DDC.h ++++ b/hw/xfree86/ddc/xf86DDC.h +@@ -43,10 +43,6 @@ extern xf86MonPtr xf86InterpretEDID( + int screenIndex, Uchar *block + ); + +-extern xf86vdifPtr xf86InterpretVdif( +- CARD8 *c +-); +- + extern void + xf86DDCMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC); + +@@ -55,9 +51,7 @@ extern Bool xf86SetDDCproperties( + xf86MonPtr DDC + ); + +-extern void xf86print_vdif( +- xf86vdifPtr v +-); ++DisplayModePtr xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC); + + #endif + +diff --git a/hw/xfree86/loader/xf86sym.c b/hw/xfree86/loader/xf86sym.c +index 09d6681..185eb80 100644 +--- a/hw/xfree86/loader/xf86sym.c ++++ b/hw/xfree86/loader/xf86sym.c +@@ -1237,13 +1203,12 @@ _X_HIDDEN void *xfree86LookupTab[] = { + SYMFUNC(xf86_show_cursors) + SYMFUNC(xf86_hide_cursors) + SYMFUNC(xf86_cursors_fini) ++ SYMFUNC(xf86_crtc_clip_video_helper) + + SYMFUNC(xf86DoEDID_DDC1) + SYMFUNC(xf86DoEDID_DDC2) + SYMFUNC(xf86InterpretEDID) + SYMFUNC(xf86PrintEDID) +- SYMFUNC(xf86InterpretVdif) +- SYMFUNC(xf86print_vdif) + SYMFUNC(xf86DDCMonitorSet) + SYMFUNC(xf86SetDDCproperties) + +diff --git a/randr/Makefile.am b/randr/Makefile.am +index 9bf0e65..20b0f72 100644 +--- a/randr/Makefile.am ++++ b/randr/Makefile.am +@@ -2,6 +2,8 @@ noinst_LTLIBRARIES = librandr.la + + AM_CFLAGS = $(DIX_CFLAGS) + ++XINERAMA_SRCS = rrxinerama.c ++ + if XORG + sdk_HEADERS = randrstr.h + endif +@@ -18,5 +20,9 @@ librandr_la_SOURCES = \ + rrpointer.c \ + rrproperty.c \ + rrscreen.c \ +- rrsdispatch.c \ +- rrxinerama.c ++ rrsdispatch.c ++ ++if XINERAMA ++librandr_la_SOURCES += ${XINERAMA_SRCS} ++endif ++ +diff --git a/randr/randr.c b/randr/randr.c +index 4dd0ee5..958f9c1 100644 +--- a/randr/randr.c ++++ b/randr/randr.c +@@ -358,8 +358,9 @@ RRExtensionInit (void) + SRRScreenChangeNotifyEvent; + EventSwapVector[RREventBase + RRNotify] = (EventSwapPtr) + SRRNotifyEvent; +- ++#ifdef PANORAMIX + RRXineramaExtensionInit(); ++#endif + } + + static int +diff --git a/randr/randrstr.h b/randr/randrstr.h +index 6deaf47..bd19fe9 100644 +--- a/randr/randrstr.h ++++ b/randr/randrstr.h +@@ -564,6 +564,7 @@ RRCrtcGammaSetSize (RRCrtcPtr crtc, + * Return the area of the frame buffer scanned out by the crtc, + * taking into account the current mode and rotation + */ ++ + void + RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height); + +@@ -693,9 +694,6 @@ RROutputSetCrtcs (RROutputPtr output, + RRCrtcPtr *crtcs, + int numCrtcs); + +-void +-RROutputSetCrtc (RROutputPtr output, RRCrtcPtr crtc); +- + Bool + RROutputSetConnection (RROutputPtr output, + CARD8 connection); +@@ -801,7 +799,6 @@ Query state: + 1.2: + RRScreenSetSizeRange + RROutputSetCrtcs +- RROutputSetCrtc + RRModeGet + RROutputSetModes + RROutputSetConnection +@@ -821,7 +818,6 @@ Query state: + RRCrtcCreate + RROutputCreate + RROutputSetCrtcs +- RROutputSetCrtc + RROutputSetConnection + RROutputSetSubpixelOrder + RROldModeAdd • This adds modes one-at-a-time +diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c +index 63da829..db5007e 100644 +--- a/randr/rrcrtc.c ++++ b/randr/rrcrtc.c +@@ -134,6 +134,7 @@ RRCrtcNotify (RRCrtcPtr crtc, + break; + if (j == crtc->numOutputs) + { ++ outputs[i]->crtc = crtc; + RROutputChanged (outputs[i], FALSE); + RRCrtcChanged (crtc, FALSE); + } +@@ -149,6 +150,7 @@ RRCrtcNotify (RRCrtcPtr crtc, + break; + if (i == numOutputs) + { ++ crtc->outputs[j]->crtc = NULL; + RROutputChanged (crtc->outputs[j], FALSE); + RRCrtcChanged (crtc, FALSE); + } +@@ -507,7 +509,7 @@ RRCrtcInit (void) + int + ProcRRGetCrtcInfo (ClientPtr client) + { +- REQUEST(xRRGetCrtcInfoReq);; ++ REQUEST(xRRGetCrtcInfoReq); + xRRGetCrtcInfoReply rep; + RRCrtcPtr crtc; + CARD8 *extra; +@@ -794,7 +796,7 @@ ProcRRSetCrtcConfig (ClientPtr client) + int source_width = mode->mode.width; + int source_height = mode->mode.height; + +- if (rotation == RR_Rotate_90 || rotation == RR_Rotate_270) ++ if ((rotation & 0xf) == RR_Rotate_90 || (rotation & 0xf) == RR_Rotate_270) + { + source_width = mode->mode.height; + source_height = mode->mode.width; +diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c +index 6b61b9c..5525427 100644 +--- a/randr/rrdispatch.c ++++ b/randr/rrdispatch.c +@@ -22,6 +22,9 @@ + + #include "randrstr.h" + ++#define SERVER_RANDR_MAJOR 1 ++#define SERVER_RANDR_MINOR 2 ++ + Bool + RRClientKnowsRates (ClientPtr pClient) + { +@@ -49,8 +52,8 @@ ProcRRQueryVersion (ClientPtr client) + * Report the current version; the current + * spec says they're all compatible after 1.0 + */ +- rep.majorVersion = RANDR_MAJOR; +- rep.minorVersion = RANDR_MINOR; ++ rep.majorVersion = SERVER_RANDR_MAJOR; ++ rep.minorVersion = SERVER_RANDR_MINOR; + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); +diff --git a/randr/rrinfo.c b/randr/rrinfo.c +index 5ef1a6b..7e77d39 100644 +--- a/randr/rrinfo.c ++++ b/randr/rrinfo.c +@@ -98,17 +98,18 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) + if (!output) + return; + RROutputSetCrtcs (output, &crtc, 1); +- RROutputSetCrtc (output, crtc); + RROutputSetConnection (output, RR_Connected); + #ifdef RENDER + RROutputSetSubpixelOrder (output, PictureGetSubpixelOrder (pScreen)); + #endif + } + +- output = RRFirstOutput (pScreen); ++ output = pScrPriv->outputs[0]; + if (!output) + return; +- crtc = output->crtc; ++ crtc = pScrPriv->crtcs[0]; ++ if (!crtc) ++ return; + + /* check rotations */ + if (rotations != crtc->rotations) +@@ -168,7 +169,7 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) + + /* notice current mode */ + if (newMode) +- RRCrtcNotify (output->crtc, newMode, 0, 0, pScrPriv->rotation, ++ RRCrtcNotify (crtc, newMode, 0, 0, pScrPriv->rotation, + 1, &output); + } + #endif +diff --git a/randr/rroutput.c b/randr/rroutput.c +index c773279..a67e493 100644 +--- a/randr/rroutput.c ++++ b/randr/rroutput.c +@@ -249,6 +249,7 @@ RROutputDeleteUserMode (RROutputPtr output, + + memmove (output->userModes + m, output->userModes + m + 1, + (output->numUserModes - m - 1) * sizeof (RRModePtr)); ++ output->numUserModes--; + RRModeDestroy (mode); + return Success; + } +@@ -286,15 +287,6 @@ RROutputSetCrtcs (RROutputPtr output, + return TRUE; + } + +-void +-RROutputSetCrtc (RROutputPtr output, RRCrtcPtr crtc) +-{ +- if (output->crtc == crtc) +- return; +- output->crtc = crtc; +- RROutputChanged (output, FALSE); +-} +- + Bool + RROutputSetConnection (RROutputPtr output, + CARD8 connection) +@@ -438,7 +430,7 @@ RROutputInit (void) + int + ProcRRGetOutputInfo (ClientPtr client) + { +- REQUEST(xRRGetOutputInfoReq);; ++ REQUEST(xRRGetOutputInfoReq); + xRRGetOutputInfoReply rep; + RROutputPtr output; + CARD8 *extra; +diff --git a/randr/rrpointer.c b/randr/rrpointer.c +index 802dcb2..c88a0f8 100644 +--- a/randr/rrpointer.c ++++ b/randr/rrpointer.c +@@ -103,7 +103,7 @@ void + RRPointerMoved (ScreenPtr pScreen, int x, int y) + { + rrScrPriv (pScreen); +- RRCrtcPtr pointerCrtc = pScrPriv->pointerCrtc;; ++ RRCrtcPtr pointerCrtc = pScrPriv->pointerCrtc; + int c; + + /* Check last known CRTC */ +diff --git a/randr/rrscreen.c b/randr/rrscreen.c +index f2981b0..8798b42 100644 +--- a/randr/rrscreen.c ++++ b/randr/rrscreen.c +@@ -116,11 +116,19 @@ RRDeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen) + + se.sequenceNumber = client->sequence; + se.sizeID = RR10CurrentSizeID (pScreen); +- +- se.widthInPixels = pScreen->width; +- se.heightInPixels = pScreen->height; +- se.widthInMillimeters = pScreen->mmWidth; +- se.heightInMillimeters = pScreen->mmHeight; ++ ++ if (se.rotation & (RR_Rotate_90 | RR_Rotate_270)) { ++ se.widthInPixels = pScreen->height; ++ se.heightInPixels = pScreen->width; ++ se.widthInMillimeters = pScreen->mmHeight; ++ se.heightInMillimeters = pScreen->mmWidth; ++ } else { ++ se.widthInPixels = pScreen->width; ++ se.heightInPixels = pScreen->height; ++ se.widthInMillimeters = pScreen->mmWidth; ++ se.heightInMillimeters = pScreen->mmHeight; ++ } ++ + WriteEventsToClient (client, 1, (xEvent *) &se); + } + +@@ -738,6 +738,7 @@ ProcRRSetScreenConfig (ClientPtr client) + int rate; + Bool has_rate; + RROutputPtr output; ++ RRCrtcPtr crtc; + RRModePtr mode; + RR10DataPtr pData = NULL; + RRScreenSizePtr pSize; +@@ -782,7 +784,9 @@ ProcRRSetScreenConfig (ClientPtr client) + rep.status = RRSetConfigFailed; + goto sendReply; + } +- ++ ++ crtc = output->crtc; ++ + /* + * if the client's config timestamp is not the same as the last config + * timestamp, then the config information isn't up-to-date and +@@ -830,7 +834,7 @@ ProcRRSetScreenConfig (ClientPtr client) + return BadValue; + } + +- if ((~output->crtc->rotations) & rotation) ++ if ((~crtc->rotations) & rotation) + { + /* + * requested rotation or reflection not supported by screen +@@ -913,7 +917,7 @@ ProcRRSetScreenConfig (ClientPtr client) + } + } + +- if (!RRCrtcSet (output->crtc, mode, 0, 0, stuff->rotation, 1, &output)) ++ if (!RRCrtcSet (crtc, mode, 0, 0, stuff->rotation, 1, &output)) + rep.status = RRSetConfigFailed; + else + rep.status = RRSetConfigSuccess; +diff --git a/randr/rrxinerama.c b/randr/rrxinerama.c +index 63a34b5..2a57e4e 100644 +--- a/randr/rrxinerama.c ++++ b/randr/rrxinerama.c +@@ -425,6 +428,14 @@ RRXineramaExtensionInit(void) + return; + #endif + ++ /* ++ * Xinerama isn't capable enough to have multiple protocol screens each ++ * with their own output geometry. So if there's more than one protocol ++ * screen, just don't even try. ++ */ ++ if (screenInfo.numScreens > 1) ++ return; ++ + (void) AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0, + ProcRRXineramaDispatch, + SProcRRXineramaDispatch, diff --git a/xserver-1.3.0-randr12-config-hack.patch b/xserver-1.3.0-randr12-config-hack.patch index c0c8028..a626e60 100644 --- a/xserver-1.3.0-randr12-config-hack.patch +++ b/xserver-1.3.0-randr12-config-hack.patch @@ -1,6 +1,7 @@ ---- xorg-server-1.3.0.0/hw/xfree86/modes/xf86Crtc.c.jx 2007-04-16 12:53:50.000000000 -0400 -+++ xorg-server-1.3.0.0/hw/xfree86/modes/xf86Crtc.c 2007-05-02 14:03:28.000000000 -0400 -@@ -1202,6 +1202,23 @@ +diff -up xorg-server-1.3.0.0/hw/xfree86/modes/xf86Crtc.c.da xorg-server-1.3.0.0/hw/xfree86/modes/xf86Crtc.c +--- xorg-server-1.3.0.0/hw/xfree86/modes/xf86Crtc.c.da 2007-09-26 17:12:44.000000000 +1000 ++++ xorg-server-1.3.0.0/hw/xfree86/modes/xf86Crtc.c 2007-09-26 17:14:44.000000000 +1000 +@@ -1214,6 +1214,23 @@ xf86SortModes (DisplayModePtr input) return output; } @@ -21,10 +22,10 @@ + return preferred_mode; +} + - #define DEBUG_REPROBE 1 - - void -@@ -1377,8 +1394,7 @@ + _X_EXPORT void + xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) + { +@@ -1395,8 +1412,7 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, output->probed_modes = xf86SortModes (output->probed_modes); /* Check for a configured preference for a particular mode */