From: Adam Jackson <[email protected]>

This defaults to using right-of placement for picking modes. We've been 
shipping this in Fedora for 2-3 releases now, and I'd like to get it upstream.

ajax wrote the original, and I enhanced it to allow drivers to override the 
option and use clone (mainly for server chipsets where monitors are in 
different places), and also to not try and do it when we only have a single 
crtc.

This probably needs some discussion, the Fedora patch also added a define to 
let drivers know this support existed, but I suspect we just use video ABI 
versions for that.

Signed-off-by: Dave Airlie <[email protected]>
---
 hw/xfree86/common/xf86str.h |    3 ++
 hw/xfree86/modes/xf86Crtc.c |   77 +++++++++++++++++++++++++++++++++++++++----
 2 files changed, 73 insertions(+), 7 deletions(-)

diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index e18524d..8860fc4 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -777,6 +777,9 @@ typedef struct _ScrnInfoRec {
     /* -nr support */
     int                 canDoBGNoneRoot;
 
+    /* initial rightof support disable */
+    int                 preferClone;
+
     /*
      * These can be used when the minor ABI version is incremented.
      * The NUM_* parameters must be reduced appropriately to keep the
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 304d503..9fa9704 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1134,6 +1134,15 @@ xf86InitialOutputPositions (ScrnInfoPtr scrn, 
DisplayModePtr *modes)
     int                        o;
     int                        min_x, min_y;
     
+    /* check for initial right-of heuristic */
+    for (o = 0; o < config->num_output; o++)
+    {
+       xf86OutputPtr   output = config->output[o];
+
+       if (output->initial_x || output->initial_y)
+            return TRUE;
+    }
+
     for (o = 0; o < config->num_output; o++)
     {
        xf86OutputPtr   output = config->output[o];
@@ -2018,6 +2027,60 @@ bestModeForAspect(xf86CrtcConfigPtr config, Bool 
*enabled, float aspect)
     return match;
 }
 
+static int
+numEnabledOutputs(xf86CrtcConfigPtr config, Bool *enabled)
+{
+    int i = 0, p;
+
+    for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ;
+
+    return i;
+}
+
+static Bool
+xf86TargetRightOf(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
+                 DisplayModePtr *modes, Bool *enabled,
+                 int width, int height)
+{
+    int o;
+    int w = 0;
+
+    if (config->num_crtc == 1)
+       return FALSE;
+
+    if (scrn->preferClone)
+       return FALSE;
+
+    if (numEnabledOutputs(config, enabled) < 2)
+       return FALSE;
+
+    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+       DisplayModePtr mode =
+           xf86OutputHasPreferredMode(config->output[o], width, height);
+
+       if (!mode)
+           return FALSE;
+
+       w += mode->HDisplay;
+    }
+
+    if (w > width)
+       return FALSE;
+
+    w = 0;
+    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+       DisplayModePtr mode =
+           xf86OutputHasPreferredMode(config->output[o], width, height);
+
+       config->output[o]->initial_x = w;
+       w += mode->HDisplay;
+
+       modes[o] = mode;
+    }
+
+    return TRUE;
+}
+
 static Bool
 xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
                    DisplayModePtr *modes, Bool *enabled,
@@ -2075,13 +2138,9 @@ xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr 
config,
      * biggest mode for its aspect ratio, assuming one exists.
      */
     if (!ret) do {
-       int i = 0;
        float aspect = 0.0;
 
-       /* count the number of enabled outputs */
-       for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ;
-
-       if (i != 1)
+       if (numEnabledOutputs(config, enabled) != 1)
            break;
 
        p = -1;
@@ -2375,6 +2434,8 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
     } else {
        if (xf86TargetUserpref(scrn, config, modes, enabled, width, height))
            xf86DrvMsg(i, X_INFO, "Using user preference for initial modes\n");
+       else if (xf86TargetRightOf(scrn, config, modes, enabled, width, height))
+           xf86DrvMsg(i, X_INFO, "Using spanning desktop for initial modes\n");
        else if (xf86TargetPreferred(scrn, config, modes, enabled, width, 
height))
            xf86DrvMsg(i, X_INFO, "Using exact sizes for initial modes\n");
        else if (xf86TargetAspect(scrn, config, modes, enabled, width, height))
@@ -2392,8 +2453,10 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
                        config->output[o]->name);
        else
            xf86DrvMsg (scrn->scrnIndex, X_INFO,
-                       "Output %s using initial mode %s\n",
-                       config->output[o]->name, modes[o]->name);
+                       "Output %s using initial mode %s +%d+%d\n",
+                       config->output[o]->name, modes[o]->name,
+                        config->output[o]->initial_x,
+                        config->output[o]->initial_y);
     }
 
     /*
-- 
1.6.5.2

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to