990c9a0
From 8223378890b5cce20d79a58098221017f87e7e85 Mon Sep 17 00:00:00 2001
d0c7c3e
From: Adam Jackson <ajax@redhat.com>
d0c7c3e
Date: Thu, 14 Jan 2010 16:50:01 -0500
d0c7c3e
Subject: [PATCH] randr compat/primary unify
d0c7c3e
d0c7c3e
---
990c9a0
 hw/xfree86/common/xf86cmap.c   |   27 +++----
4dd4ecb
 hw/xfree86/modes/xf86Crtc.c    |  151 +++++++++++++++++++---------------------
d0c7c3e
 hw/xfree86/modes/xf86Crtc.h    |   18 +++--
4dd4ecb
 hw/xfree86/modes/xf86RandR12.c |    6 +-
990c9a0
 4 files changed, 98 insertions(+), 104 deletions(-)
d0c7c3e
d0c7c3e
diff --git a/hw/xfree86/common/xf86cmap.c b/hw/xfree86/common/xf86cmap.c
990c9a0
index edd5ae9..25ece4a 100644
d0c7c3e
--- a/hw/xfree86/common/xf86cmap.c
d0c7c3e
+++ b/hw/xfree86/common/xf86cmap.c
d0c7c3e
@@ -1001,8 +1001,7 @@ xf86ChangeGammaRamp(
d0c7c3e
     CMapLinkPtr pLink;
d0c7c3e
 
d0c7c3e
     if (xf86_crtc_supports_gamma(pScrn)) {
d0c7c3e
-	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
d0c7c3e
-	RRCrtcPtr crtc = config->output[config->compat_output]->crtc->randr_crtc;
4dd4ecb
+        RRCrtcPtr crtc = xf86GetPrimaryCrtc(pScrn)->randr_crtc;
d0c7c3e
 
990c9a0
 	if (crtc) {
990c9a0
 	    if (crtc->gammaSize != size)
990c9a0
@@ -1017,8 +1016,7 @@ xf86ChangeGammaRamp(
4dd4ecb
     if(CMapScreenKey == NULL)
4dd4ecb
         return BadImplementation;
4dd4ecb
 
4dd4ecb
-    pScreenPriv = (CMapScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
4dd4ecb
-						  CMapScreenKey);
4dd4ecb
+    pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, CMapScreenKey);
4dd4ecb
     if(!pScreenPriv)
4dd4ecb
         return BadImplementation;
4dd4ecb
 
990c9a0
@@ -1030,8 +1028,7 @@ xf86ChangeGammaRamp(
4dd4ecb
     /* mark all colormaps on this screen */
4dd4ecb
     pLink = pScreenPriv->maps;
4dd4ecb
     while(pLink) {
4dd4ecb
-    	pColPriv = (CMapColormapPtr)dixLookupPrivate(&pLink->cmap->devPrivates,
4dd4ecb
-						     CMapColormapKey);
990c9a0
+	pColPriv = dixLookupPrivate(&pLink->cmap->devPrivates, CMapColormapKey);
4dd4ecb
         pColPriv->recalculate = TRUE;
4dd4ecb
         pLink = pLink->next;
4dd4ecb
     }
990c9a0
@@ -1076,18 +1073,18 @@ xf86GetGammaRampSize(ScreenPtr pScreen)
d0c7c3e
     CMapScreenPtr pScreenPriv;
d0c7c3e
 
d0c7c3e
     if (xf86_crtc_supports_gamma(pScrn)) {
d0c7c3e
-	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
d0c7c3e
-	RRCrtcPtr crtc = config->output[config->compat_output]->crtc->randr_crtc;
4dd4ecb
+        RRCrtcPtr crtc = xf86GetPrimaryCrtc(pScrn)->randr_crtc;
990c9a0
 
990c9a0
 	if (crtc)
990c9a0
 	    return crtc->gammaSize;
d0c7c3e
     }
d0c7c3e
 
4dd4ecb
-    if(CMapScreenKey == NULL) return 0;
4dd4ecb
+    if (CMapScreenKey == NULL)
4dd4ecb
+        return 0;
4dd4ecb
 
4dd4ecb
-    pScreenPriv = (CMapScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
4dd4ecb
-						  CMapScreenKey);
4dd4ecb
-    if(!pScreenPriv) return 0;
4dd4ecb
+    pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, CMapScreenKey);
4dd4ecb
+    if (!pScreenPriv)
4dd4ecb
+        return 0;
4dd4ecb
 
4dd4ecb
     return pScreenPriv->gammaElements;
4dd4ecb
 }
990c9a0
@@ -1106,8 +1103,7 @@ xf86GetGammaRamp(
d0c7c3e
     int shift, sigbits;
d0c7c3e
 
d0c7c3e
     if (xf86_crtc_supports_gamma(pScrn)) {
d0c7c3e
-	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
d0c7c3e
-	RRCrtcPtr crtc = config->output[config->compat_output]->crtc->randr_crtc;
4dd4ecb
+        RRCrtcPtr crtc = xf86GetPrimaryCrtc(pScrn)->randr_crtc;
d0c7c3e
 
990c9a0
 	if (crtc) {
990c9a0
 	    if (crtc->gammaSize < size)
990c9a0
@@ -1127,8 +1123,7 @@ xf86GetGammaRamp(
4dd4ecb
     if(CMapScreenKey == NULL) 
4dd4ecb
 	return BadImplementation;
4dd4ecb
 
4dd4ecb
-    pScreenPriv = (CMapScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
4dd4ecb
-						  CMapScreenKey);
4dd4ecb
+    pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, CMapScreenKey);
4dd4ecb
     if(!pScreenPriv) 
4dd4ecb
 	return BadImplementation;
4dd4ecb
 
d0c7c3e
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
990c9a0
index 9370640..ef9cbb7 100644
d0c7c3e
--- a/hw/xfree86/modes/xf86Crtc.c
d0c7c3e
+++ b/hw/xfree86/modes/xf86Crtc.c
990c9a0
@@ -1780,88 +1780,74 @@ biggestMode(DisplayModePtr a, DisplayModePtr b)
d0c7c3e
     return b;
d0c7c3e
 }
d0c7c3e
 
d0c7c3e
-static xf86OutputPtr
d0c7c3e
-SetCompatOutput(xf86CrtcConfigPtr config)
d0c7c3e
+/*
d0c7c3e
+ * vidmode modeset has to operate on something.  give it the RANDR primary
d0c7c3e
+ * if defined, or else the first connected one.  There might not be any,
d0c7c3e
+ * in which case modeset will just have to fail, since where else are we
d0c7c3e
+ * going to get a mode list from.
4dd4ecb
+ *
4dd4ecb
+ * hilariously, this can get called before ->pScreen is filled in.  that's
4dd4ecb
+ * way early in screen init, so we'll assume it just doesn't matter yet.
d0c7c3e
+ */
d0c7c3e
+xf86OutputPtr
4dd4ecb
+xf86GetPrimaryOutput(ScrnInfoPtr scrn)
d0c7c3e
 {
d0c7c3e
-    xf86OutputPtr output = NULL, test = NULL;
d0c7c3e
-    DisplayModePtr maxmode = NULL, testmode, mode;
d0c7c3e
-    int o, compat = -1, count, mincount = 0;
4dd4ecb
+    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
4dd4ecb
+    int i;
d0c7c3e
 
d0c7c3e
-    /* Look for one that's definitely connected */
d0c7c3e
-    for (o = 0; o < config->num_output; o++)
d0c7c3e
-    {
d0c7c3e
-	test = config->output[o];
d0c7c3e
-	if (!test->crtc)
d0c7c3e
-	    continue;
d0c7c3e
-	if (test->status != XF86OutputStatusConnected)
d0c7c3e
-	    continue;
d0c7c3e
-	if (!test->probed_modes)
d0c7c3e
-	    continue;
4dd4ecb
+    if (scrn->pScreen) {
4dd4ecb
+        rrScrPrivPtr rrScrPriv = rrGetScrPriv(scrn->pScreen);
d0c7c3e
 
d0c7c3e
-	testmode = mode = test->probed_modes;
d0c7c3e
-	for (count = 0; mode; mode = mode->next, count++)
d0c7c3e
-	    testmode = biggestMode(testmode, mode);
d0c7c3e
-
d0c7c3e
-	if (!output) {
d0c7c3e
-	    output = test;
d0c7c3e
-	    compat = o;
d0c7c3e
-	    maxmode = testmode;
d0c7c3e
-	    mincount = count;
d0c7c3e
-	} else if (maxmode == biggestMode(maxmode, testmode)) {
d0c7c3e
-	    output = test;
d0c7c3e
-	    compat = o;
d0c7c3e
-	    maxmode = testmode;
d0c7c3e
-	    mincount = count;
d0c7c3e
-	} else if ((maxmode->HDisplay == testmode->HDisplay) && 
d0c7c3e
-		(maxmode->VDisplay == testmode->VDisplay) &&
d0c7c3e
-		count <= mincount) {
d0c7c3e
-	    output = test;
d0c7c3e
-	    compat = o;
d0c7c3e
-	    maxmode = testmode;
d0c7c3e
-	    mincount = count;
d0c7c3e
-	}
4dd4ecb
+        /* defaults to NULL */
4dd4ecb
+        if (rrScrPriv->primaryOutput)
4dd4ecb
+            return rrScrPriv->primaryOutput->devPrivate;
d0c7c3e
     }
d0c7c3e
 
d0c7c3e
-    /* If we didn't find one, take anything we can get */
d0c7c3e
-    if (!output)
d0c7c3e
-    {
d0c7c3e
-	for (o = 0; o < config->num_output; o++)
d0c7c3e
-	{
d0c7c3e
-	    test = config->output[o];
d0c7c3e
-	    if (!test->crtc)
d0c7c3e
-		continue;
d0c7c3e
-	    if (!test->probed_modes)
d0c7c3e
-		continue;
4dd4ecb
-
d0c7c3e
-	    if (!output) {
d0c7c3e
-		output = test;
d0c7c3e
-		compat = o;
d0c7c3e
-	    } else if (test->probed_modes->HDisplay < output->probed_modes->HDisplay) {
d0c7c3e
-		output = test;
d0c7c3e
-		compat = o;
d0c7c3e
-	    }
d0c7c3e
-	}
4dd4ecb
+    for (i = 0; i < config->num_output; i++) {
4dd4ecb
+        xf86OutputPtr output = config->output[i];
4dd4ecb
+        if (output->status == XF86OutputStatusConnected)
4dd4ecb
+            return output;
4dd4ecb
     }
4dd4ecb
 
4dd4ecb
-    if (compat >= 0) {
4dd4ecb
-	config->compat_output = compat;
4dd4ecb
-    } else {
4dd4ecb
-	/* Don't change the compat output when no valid outputs found */
4dd4ecb
-	output = config->output[config->compat_output];
990c9a0
+    /* desperation */
4dd4ecb
+    for (i = 0; i < config->num_output; i++) {
4dd4ecb
+        xf86OutputPtr output = config->output[i];
4dd4ecb
+        if (output->status == XF86OutputStatusUnknown)
4dd4ecb
+            return output;
4dd4ecb
     }
4dd4ecb
 
4dd4ecb
-    return output;
4dd4ecb
+    return NULL;
4dd4ecb
+}
4dd4ecb
+
d0c7c3e
+/*
d0c7c3e
+ * vidmode gamma, however, operates on a CRTC, and those always exist.  Pick
d0c7c3e
+ * the one attached to the vidmode primary output (as above), or else just
d0c7c3e
+ * the first one we've got.
4dd4ecb
+ *
4dd4ecb
+ * again, this can get called absurdly early, when there might be no routing
4dd4ecb
+ * yet; in which case, crtc 0 wins.
d0c7c3e
+ */
d0c7c3e
+xf86CrtcPtr
4dd4ecb
+xf86GetPrimaryCrtc(ScrnInfoPtr scrn)
d0c7c3e
+{
4dd4ecb
+    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
d0c7c3e
+    xf86OutputPtr output;
4dd4ecb
+
4dd4ecb
+    output = xf86GetPrimaryOutput(scrn);
4dd4ecb
+    if (output && output->randr_output && output->randr_output->crtc)
d0c7c3e
+        return output->randr_output->crtc->devPrivate;
4dd4ecb
+
4dd4ecb
+    return config->crtc[0];
d0c7c3e
 }
d0c7c3e
 
d0c7c3e
 void
d0c7c3e
 xf86SetScrnInfoModes (ScrnInfoPtr scrn)
d0c7c3e
 {
d0c7c3e
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
d0c7c3e
     xf86OutputPtr	output;
d0c7c3e
     xf86CrtcPtr		crtc;
d0c7c3e
     DisplayModePtr	last, mode = NULL;
d0c7c3e
 
d0c7c3e
-    output = SetCompatOutput(config);
4dd4ecb
+    output = xf86GetPrimaryOutput(scrn);
d0c7c3e
 
d0c7c3e
     if (!output)
d0c7c3e
 	return; /* punt */
990c9a0
@@ -2149,7 +2135,7 @@ xf86TargetFallback(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
d0c7c3e
     DisplayModePtr target_mode = NULL;
d0c7c3e
     Rotation target_rotation = RR_Rotate_0;
d0c7c3e
     DisplayModePtr default_mode;
d0c7c3e
-    int default_preferred, target_preferred = 0, o;
d0c7c3e
+    int o, default_preferred, target_preferred = 0, target_output = 0;
d0c7c3e
 
d0c7c3e
     /* User preferred > preferred > other modes */
d0c7c3e
     for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
990c9a0
@@ -2164,12 +2150,12 @@ xf86TargetFallback(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
d0c7c3e
 	    target_mode = default_mode;
d0c7c3e
 	    target_preferred = default_preferred;
d0c7c3e
 	    target_rotation = config->output[o]->initial_rotation;
d0c7c3e
-	    config->compat_output = o;
d0c7c3e
+            target_output = o;
d0c7c3e
 	}
d0c7c3e
     }
d0c7c3e
 
d0c7c3e
     if (target_mode)
d0c7c3e
-	modes[config->compat_output] = target_mode;
d0c7c3e
+	modes[target_output] = target_mode;
d0c7c3e
 
d0c7c3e
     /* Fill in other output modes */
d0c7c3e
     for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
990c9a0
@@ -2561,7 +2547,7 @@ xf86SetDesiredModes (ScrnInfoPtr scrn)
d0c7c3e
 
d0c7c3e
     for (c = 0; c < config->num_crtc; c++)
d0c7c3e
     {
d0c7c3e
-	xf86OutputPtr	output = NULL;
d0c7c3e
+	xf86OutputPtr	output = NULL, primary_output;
d0c7c3e
 	int		o;
d0c7c3e
 	RRTransformPtr	transform;
d0c7c3e
 
990c9a0
@@ -2571,8 +2557,9 @@ xf86SetDesiredModes (ScrnInfoPtr scrn)
d0c7c3e
 	if (!crtc->enabled)
d0c7c3e
 	    continue;
d0c7c3e
 
d0c7c3e
-	if (config->output[config->compat_output]->crtc == crtc)
d0c7c3e
-	    output = config->output[config->compat_output];
4dd4ecb
+        primary_output = xf86GetPrimaryOutput(scrn);
d0c7c3e
+        if (primary_output && primary_output->crtc == crtc)
d0c7c3e
+	    output = primary_output;
d0c7c3e
 	else
d0c7c3e
 	{
d0c7c3e
 	    for (o = 0; o < config->num_output; o++)
990c9a0
@@ -2681,7 +2668,7 @@ xf86OutputFindClosestMode (xf86OutputPtr output, DisplayModePtr desired)
d0c7c3e
 
d0c7c3e
 /**
d0c7c3e
  * When setting a mode through XFree86-VidModeExtension or XFree86-DGA,
d0c7c3e
- * take the specified mode and apply it to the crtc connected to the compat
d0c7c3e
+ * take the specified mode and apply it to the crtc connected to the primary
d0c7c3e
  * output. Then, find similar modes for the other outputs, as with the
d0c7c3e
  * InitialConfiguration code above. The goal is to clone the desired
d0c7c3e
  * mode across all outputs that are currently active.
990c9a0
@@ -2692,16 +2679,19 @@ xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation)
d0c7c3e
 {
d0c7c3e
     xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
d0c7c3e
     Bool		ok = TRUE;
d0c7c3e
-    xf86OutputPtr	compat_output = config->output[config->compat_output];
d0c7c3e
-    DisplayModePtr	compat_mode;
4dd4ecb
+    xf86OutputPtr	primary_output = xf86GetPrimaryOutput(pScrn);
d0c7c3e
+    DisplayModePtr	primary_mode;
d0c7c3e
     int			c;
d0c7c3e
 
d0c7c3e
+    if (!primary_output)
d0c7c3e
+        return FALSE;
d0c7c3e
+
d0c7c3e
     /*
d0c7c3e
      * Let the compat output drive the final mode selection
d0c7c3e
      */
d0c7c3e
-    compat_mode = xf86OutputFindClosestMode (compat_output, desired);
d0c7c3e
-    if (compat_mode)
d0c7c3e
-	desired = compat_mode;
d0c7c3e
+    primary_mode = xf86OutputFindClosestMode (primary_output, desired);
d0c7c3e
+    if (primary_mode)
d0c7c3e
+	desired = primary_mode;
d0c7c3e
     
d0c7c3e
     for (c = 0; c < config->num_crtc; c++)
d0c7c3e
     {
990c9a0
@@ -2878,6 +2868,7 @@ xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon)
d0c7c3e
     ScrnInfoPtr		scrn = output->scrn;
d0c7c3e
     xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
d0c7c3e
     int			i;
4dd4ecb
+    rrScrPrivPtr        rrScrPriv = NULL;
d0c7c3e
 #ifdef RANDR_12_INTERFACE
d0c7c3e
     int			size;
d0c7c3e
 #endif
990c9a0
@@ -2893,8 +2884,12 @@ xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon)
d0c7c3e
 	xf86PrintEDID(edid_mon);
d0c7c3e
     }
d0c7c3e
 
d0c7c3e
-    /* Set the DDC properties for the 'compat' output */
d0c7c3e
-    if (output == config->output[config->compat_output])
4dd4ecb
+    /* this gets called before pScreen is set, oi */
4dd4ecb
+    if (scrn->pScreen)
4dd4ecb
+        rrScrPriv = rrGetScrPriv(scrn->pScreen);
4dd4ecb
+
d0c7c3e
+    /* if this is the primary output, set the screen properties */
4dd4ecb
+    if (rrScrPriv && output->randr_output == rrScrPriv->primaryOutput)
d0c7c3e
         xf86SetDDCproperties(scrn, edid_mon);
d0c7c3e
 
d0c7c3e
 #ifdef RANDR_12_INTERFACE
d0c7c3e
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
4dd4ecb
index 9baa956..39ba81d 100644
d0c7c3e
--- a/hw/xfree86/modes/xf86Crtc.h
d0c7c3e
+++ b/hw/xfree86/modes/xf86Crtc.h
d0c7c3e
@@ -631,13 +631,7 @@ typedef void (*xf86_crtc_notify_proc_ptr) (ScreenPtr pScreen);
d0c7c3e
 typedef struct _xf86CrtcConfig {
d0c7c3e
     int			num_output;
d0c7c3e
     xf86OutputPtr	*output;
d0c7c3e
-    /**
d0c7c3e
-     * compat_output is used whenever we deal
d0c7c3e
-     * with legacy code that only understands a single
d0c7c3e
-     * output. pScrn->modes will be loaded from this output,
d0c7c3e
-     * adjust frame will whack this output, etc.
d0c7c3e
-     */
d0c7c3e
-    int			compat_output;
d0c7c3e
+    int			unused;
d0c7c3e
 
d0c7c3e
     int			num_crtc;
d0c7c3e
     xf86CrtcPtr		*crtc;
d0c7c3e
@@ -690,6 +684,16 @@ extern _X_EXPORT int xf86CrtcConfigPrivateIndex;
d0c7c3e
 #define XF86_CRTC_CONFIG_PTR(p)	((xf86CrtcConfigPtr) ((p)->privates[xf86CrtcConfigPrivateIndex].ptr))
d0c7c3e
 
d0c7c3e
 /*
d0c7c3e
+ * Compat functions
d0c7c3e
+ */
d0c7c3e
+
d0c7c3e
+extern _X_EXPORT xf86OutputPtr
4dd4ecb
+xf86GetPrimaryOutput(ScrnInfoPtr scrn);
d0c7c3e
+
d0c7c3e
+extern _X_EXPORT xf86CrtcPtr
4dd4ecb
+xf86GetPrimaryCrtc(ScrnInfoPtr scrn);
d0c7c3e
+
d0c7c3e
+/*
d0c7c3e
  * Initialize xf86CrtcConfig structure
d0c7c3e
  */
d0c7c3e
 
d0c7c3e
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
990c9a0
index 1fc63c4..e2ba4d6 100644
d0c7c3e
--- a/hw/xfree86/modes/xf86RandR12.c
d0c7c3e
+++ b/hw/xfree86/modes/xf86RandR12.c
4dd4ecb
@@ -805,7 +805,7 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen)
d0c7c3e
 	}
d0c7c3e
 	else
d0c7c3e
 	{
d0c7c3e
-	    xf86OutputPtr   output = config->output[config->compat_output];
4dd4ecb
+	    xf86OutputPtr output = xf86GetPrimaryOutput(pScrn);
d0c7c3e
 
d0c7c3e
 	    if (output->conf_monitor &&
d0c7c3e
 		(output->conf_monitor->mon_width  > 0 &&
4dd4ecb
@@ -1719,8 +1719,8 @@ xf86RandR12ChangeGamma(int scrnIndex, Gamma gamma)
d0c7c3e
 {
d0c7c3e
     CARD16 *points, *red, *green, *blue;
d0c7c3e
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
d0c7c3e
-    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
d0c7c3e
-    RRCrtcPtr crtc = config->output[config->compat_output]->crtc->randr_crtc;
4dd4ecb
+    RRCrtcPtr crtc = xf86GetPrimaryCrtc(pScrn)->randr_crtc;
d0c7c3e
+
d0c7c3e
     int size = max(0, crtc->gammaSize);
d0c7c3e
 
d0c7c3e
     if (!size)
d0c7c3e
-- 
990c9a0
1.6.6
d0c7c3e