All of lore.kernel.org
 help / color / mirror / Atom feed
From: Florian Mickler <florian@mickler.org>
To: xorg-devel@lists.x.org, ajax@redhat.com
Cc: intel-gfx@lists.freedesktop.org
Subject: [PATCH] change initial modesetting if outputs are aligned in 1 dimension
Date: Wed,  1 Jun 2011 12:06:38 +0200	[thread overview]
Message-ID: <1306922798-29344-1-git-send-email-florian@mickler.org> (raw)
In-Reply-To: <20110518190320.51800988@schatten.dmk.lab>

Recently the kernel started reporting my outputs in a different ordering due to

    commit cb0953d734
    (drm/i915: Initialize LVDS and eDP outputs before anything else)

Which made X choose a "wrong" resolution for my VGA display. Since they are
aligned horizontally, I wish them to be aligned in vertical
Resolution only.

Before this patch, the sum of squared distances would force my VGA display
(1680x1050 native resolution) to 1280x1024 (non-native) due to my internal
display beeing considered first and 1400x1050 as native resolution.

This was not an issue the other way around (VGA beeing first) because 1400x1050
is nearest to 1680x1050 anyway.

This patch changes the heuristic to only align resolution vertically if the
displays are horizontally aligned, or vice versa.

Signed-off-by: Florian Mickler <florian@mickler.org>
---

Ok, Adam... seems I lost the staring contest... :)
What about something like this?

 hw/xfree86/modes/xf86Crtc.c |  115 ++++++++++++++++++++++++++++++++++++-------
 1 files changed, 96 insertions(+), 19 deletions(-)

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 4e3f6bf..96c6c62 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -872,15 +872,92 @@ xf86DefaultMode (xf86OutputPtr output, int width, int height)
     return target_mode;
 }
 
+static Bool
+xf86GetOptRelation(xf86OutputPtr output, OutputOpts *relation, char **relative_name)
+{
+	int r;
+	static const OutputOpts	relations[] = {
+	    OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF
+	};
+
+	*relation = 0;
+	*relative_name = NULL;
+
+	for (r = 0; r < 4; r++)
+	{
+	    *relation = relations[r];
+	    *relative_name = xf86GetOptValString (output->options,
+						     *relation);
+	    if (*relative_name)
+		break;
+	}
+	return (*relative_name != NULL);
+}
+
+static Bool
+xf86OutputsRelatedHorizontal(xf86OutputPtr out1, xf86OutputPtr out2)
+{
+	OutputOpts relation;
+	char *other_name;
+	Bool ret = FALSE;
+
+	if (xf86GetOptRelation(out1, &relation, &other_name) &&
+			strcmp(other_name, out2->name) == 0) {
+		/*
+		 * out1 related to out2
+		 */
+		ret = (relation == OPTION_RIGHT_OF ||
+			relation == OPTION_LEFT_OF);
+	}
+	if (!ret && xf86GetOptRelation(out2, &relation, &other_name) &&
+			strcmp(other_name, out1->name) == 0) {
+		/*
+		 * out2 related to out1
+		 */
+		ret = (relation == OPTION_RIGHT_OF ||
+			relation == OPTION_LEFT_OF);
+	}
+
+	return ret;
+
+}
+
+static Bool
+xf86OutputsRelatedVertical(xf86OutputPtr out1, xf86OutputPtr out2)
+{
+	OutputOpts relation;
+	char *other_name;
+	Bool ret = FALSE;
+
+	if (xf86GetOptRelation(out1, &relation, &other_name) &&
+			strcmp(other_name, out2->name) == 0) {
+		/*
+		 * out1 related to out2
+		 */
+		ret = (relation == OPTION_ABOVE ||
+			relation == OPTION_BELOW);
+	}
+	if (!ret && xf86GetOptRelation(out2, &relation, &other_name) &&
+			strcmp(other_name, out1->name) == 0) {
+		/*
+		 * out2 related to out1
+		 */
+		ret = (relation == OPTION_ABOVE ||
+			relation == OPTION_BELOW);
+	}
+
+	return ret;
+}
+
 static DisplayModePtr
-xf86ClosestMode (xf86OutputPtr output, 
+xf86ClosestMode (xf86OutputPtr output, xf86OutputPtr match_output,
 		 DisplayModePtr match, Rotation match_rotation,
 		 int width, int height)
 {
     DisplayModePtr  target_mode = NULL;
     DisplayModePtr  mode;
     int		    target_diff = 0;
-    
+
     /*
      * Pick a mode closest to the specified mode
      */
@@ -892,15 +969,26 @@ xf86ClosestMode (xf86OutputPtr output,
 	if (xf86ModeWidth (mode, output->initial_rotation) > width ||
 	    xf86ModeHeight (mode, output->initial_rotation) > height)
 	    continue;
-	
+
 	/* exact matches are preferred */
 	if (output->initial_rotation == match_rotation &&
 	    xf86ModesEqual (mode, match))
 	    return mode;
-	
+
 	dx = xf86ModeWidth (match, match_rotation) - xf86ModeWidth (mode, output->initial_rotation);
 	dy = xf86ModeHeight (match, match_rotation) - xf86ModeHeight (mode, output->initial_rotation);
-	diff = dx * dx + dy * dy;
+
+	/*
+	 * If we are aligning screens horizontally or vertically use
+	 * only one dimension for matching
+	 */
+	if (xf86OutputsRelatedHorizontal(output, match_output))
+			diff = dy * dy;
+	else if (xf86OutputsRelatedVertical(output, match_output))
+			diff = dx * dx;
+	else
+		diff = dx * dx + dy * dy;
+
 	xf86DrvMsg (0, X_INFO,
 		"XF86ClosestMode: Output %s, Mode %s [ dx = %i, dy = %i, diff = %i ]\n",
 		output->name, mode->name, dx, dy, diff);
@@ -1122,10 +1210,6 @@ xf86UserConfiguredOutputs(ScrnInfoPtr scrn, DisplayModePtr *modes)
 	char	    *position;
 	char	    *relative_name;
 	OutputOpts	    relation;
-	int r;
-	static const OutputOpts	relations[] = {
-	    OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF
-	};
 
 	position = xf86GetOptValString (output->options,
 					OPTION_POSITION);
@@ -1137,15 +1221,7 @@ xf86UserConfiguredOutputs(ScrnInfoPtr scrn, DisplayModePtr *modes)
 	}
 	relation = 0;
 	relative_name = NULL;
-	for (r = 0; r < 4; r++)
-	{
-	    relation = relations[r];
-	    relative_name = xf86GetOptValString (output->options,
-						     relation);
-	    if (relative_name)
-		break;
-	}
-	if (relative_name) {
+	if (xf86GetOptRelation(output, &relation, &relative_name)) {
 	    user_conf = TRUE;
 	    xf86DrvMsg (scrn->scrnIndex, X_INFO,
 			"Output %s has user_conf due to relation: %s\n",
@@ -2245,7 +2321,8 @@ xf86TargetFallback(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
     /* Fill in other output modes */
     for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
 	if (!modes[o])
-	    modes[o] = xf86ClosestMode(config->output[o], target_mode,
+	    modes[o] = xf86ClosestMode(config->output[o],
+			    config->output[config->compat_output], target_mode,
 				       target_rotation, width, height);
     }
 
-- 
1.7.4.1

  reply	other threads:[~2011-06-01 10:07 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-18 13:41 since kernel commit cb0953d734: X chooses wrong resolution at startup Florian Mickler
2011-05-18 15:17 ` Adam Jackson
2011-05-18 16:15   ` Florian Mickler
2011-05-18 17:03     ` Florian Mickler
2011-06-01 10:06       ` Florian Mickler [this message]
2011-06-01 19:30         ` [PATCH] change initial modesetting if outputs are aligned in 1 dimension Adam Jackson
2011-06-01 20:44           ` Florian Mickler
2011-06-01 20:48             ` Adam Jackson
2011-06-01 21:06               ` Florian Mickler
2011-06-01 21:30                 ` Adam Jackson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1306922798-29344-1-git-send-email-florian@mickler.org \
    --to=florian@mickler.org \
    --cc=ajax@redhat.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=xorg-devel@lists.x.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.