|
|
06bf710 |
From 64a83ee98d0cde089857d92bdbc080f95a623543 Mon Sep 17 00:00:00 2001
|
|
|
06bf710 |
From: Adam Jackson <ajax@redhat.com>
|
|
|
06bf710 |
Date: Mon, 22 Dec 2008 12:17:32 -0500
|
|
|
06bf710 |
Subject: [PATCH] randr: try harder to do aspect match if there's only one head
|
|
|
06bf710 |
|
|
|
06bf710 |
---
|
|
|
06bf710 |
hw/xfree86/modes/xf86Crtc.c | 148 +++++++++++++++++++++++++-----------------
|
|
|
06bf710 |
1 files changed, 88 insertions(+), 60 deletions(-)
|
|
|
06bf710 |
|
|
|
06bf710 |
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
|
|
|
06bf710 |
index a6afd91..4d38955 100644
|
|
|
06bf710 |
--- a/hw/xfree86/modes/xf86Crtc.c
|
|
|
06bf710 |
+++ b/hw/xfree86/modes/xf86Crtc.c
|
|
|
06bf710 |
@@ -1818,6 +1818,66 @@ nextEnabledOutput(xf86CrtcConfigPtr config, Bool *enabled, int *index)
|
|
|
06bf710 |
}
|
|
|
06bf710 |
|
|
|
06bf710 |
static Bool
|
|
|
06bf710 |
+aspectMatch(float a, float b)
|
|
|
06bf710 |
+{
|
|
|
06bf710 |
+ return fabs(1 - (a / b)) < 0.05;
|
|
|
06bf710 |
+}
|
|
|
06bf710 |
+
|
|
|
06bf710 |
+static DisplayModePtr
|
|
|
06bf710 |
+nextAspectMode(xf86OutputPtr o, DisplayModePtr last, float aspect)
|
|
|
06bf710 |
+{
|
|
|
06bf710 |
+ DisplayModePtr m = NULL;
|
|
|
06bf710 |
+
|
|
|
06bf710 |
+ if (!o)
|
|
|
06bf710 |
+ return NULL;
|
|
|
06bf710 |
+
|
|
|
06bf710 |
+ if (!last)
|
|
|
06bf710 |
+ m = o->probed_modes;
|
|
|
06bf710 |
+ else
|
|
|
06bf710 |
+ m = last->next;
|
|
|
06bf710 |
+
|
|
|
06bf710 |
+ for (; m; m = m->next)
|
|
|
06bf710 |
+ if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay))
|
|
|
06bf710 |
+ return m;
|
|
|
06bf710 |
+
|
|
|
06bf710 |
+ return NULL;
|
|
|
06bf710 |
+}
|
|
|
06bf710 |
+
|
|
|
06bf710 |
+static DisplayModePtr
|
|
|
06bf710 |
+bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
|
|
|
06bf710 |
+{
|
|
|
06bf710 |
+ int o = -1, p;
|
|
|
06bf710 |
+ DisplayModePtr mode = NULL, test = NULL, match = NULL;
|
|
|
06bf710 |
+
|
|
|
06bf710 |
+ if (!nextEnabledOutput(config, enabled, &o))
|
|
|
06bf710 |
+ return NULL;
|
|
|
06bf710 |
+ while ((mode = nextAspectMode(config->output[o], mode, aspect))) {
|
|
|
06bf710 |
+ test = mode;
|
|
|
06bf710 |
+ for (p = o; nextEnabledOutput(config, enabled, &p); ) {
|
|
|
06bf710 |
+ test = xf86OutputFindClosestMode(config->output[p], mode);
|
|
|
06bf710 |
+ if (!test)
|
|
|
06bf710 |
+ break;
|
|
|
06bf710 |
+ if (test->HDisplay != mode->HDisplay ||
|
|
|
06bf710 |
+ test->VDisplay != mode->VDisplay) {
|
|
|
06bf710 |
+ test = NULL;
|
|
|
06bf710 |
+ break;
|
|
|
06bf710 |
+ }
|
|
|
06bf710 |
+ }
|
|
|
06bf710 |
+
|
|
|
06bf710 |
+ /* if we didn't match it on all outputs, try the next one */
|
|
|
06bf710 |
+ if (!test)
|
|
|
06bf710 |
+ continue;
|
|
|
06bf710 |
+
|
|
|
06bf710 |
+ /* if it's bigger than the last one, save it */
|
|
|
06bf710 |
+ if (!match || (test->HDisplay > match->HDisplay))
|
|
|
06bf710 |
+ match = test;
|
|
|
06bf710 |
+ }
|
|
|
06bf710 |
+
|
|
|
06bf710 |
+ /* return the biggest one found */
|
|
|
06bf710 |
+ return match;
|
|
|
06bf710 |
+}
|
|
|
06bf710 |
+
|
|
|
06bf710 |
+static Bool
|
|
|
06bf710 |
xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
|
|
|
06bf710 |
DisplayModePtr *modes, Bool *enabled,
|
|
|
06bf710 |
int width, int height)
|
|
|
06bf710 |
@@ -1869,75 +1929,43 @@ xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
|
|
|
06bf710 |
}
|
|
|
06bf710 |
}
|
|
|
06bf710 |
|
|
|
06bf710 |
- if (ret) {
|
|
|
06bf710 |
- /* oh good, there is a match. stash the selected modes and return. */
|
|
|
06bf710 |
- memcpy(modes, preferred_match,
|
|
|
06bf710 |
- config->num_output * sizeof(DisplayModePtr));
|
|
|
06bf710 |
- }
|
|
|
06bf710 |
-
|
|
|
06bf710 |
- xfree(preferred);
|
|
|
06bf710 |
- xfree(preferred_match);
|
|
|
06bf710 |
- return ret;
|
|
|
06bf710 |
-}
|
|
|
06bf710 |
+ /*
|
|
|
06bf710 |
+ * If there's no preferred mode, but only one monitor, pick the
|
|
|
06bf710 |
+ * biggest mode for its aspect ratio, assuming one exists.
|
|
|
06bf710 |
+ */
|
|
|
06bf710 |
+ if (!ret) do {
|
|
|
06bf710 |
+ int i = 0;
|
|
|
06bf710 |
+ float aspect = 0.0;
|
|
|
06bf710 |
|
|
|
06bf710 |
-static Bool
|
|
|
06bf710 |
-aspectMatch(float a, float b)
|
|
|
06bf710 |
-{
|
|
|
06bf710 |
- return fabs(1 - (a / b)) < 0.05;
|
|
|
06bf710 |
-}
|
|
|
06bf710 |
+ /* count the number of enabled outputs */
|
|
|
06bf710 |
+ for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ;
|
|
|
06bf710 |
|
|
|
06bf710 |
-static DisplayModePtr
|
|
|
06bf710 |
-nextAspectMode(xf86OutputPtr o, DisplayModePtr last, float aspect)
|
|
|
06bf710 |
-{
|
|
|
06bf710 |
- DisplayModePtr m = NULL;
|
|
|
06bf710 |
+ if (i != 1)
|
|
|
06bf710 |
+ break;
|
|
|
06bf710 |
|
|
|
06bf710 |
- if (!o)
|
|
|
06bf710 |
- return NULL;
|
|
|
06bf710 |
+ p = -1;
|
|
|
06bf710 |
+ nextEnabledOutput(config, enabled, &p);
|
|
|
06bf710 |
+ if (config->output[p]->mm_height)
|
|
|
06bf710 |
+ aspect = (float)config->output[p]->mm_width /
|
|
|
06bf710 |
+ (float)config->output[p]->mm_height;
|
|
|
06bf710 |
|
|
|
06bf710 |
- if (!last)
|
|
|
06bf710 |
- m = o->probed_modes;
|
|
|
06bf710 |
- else
|
|
|
06bf710 |
- m = last->next;
|
|
|
06bf710 |
+ if (aspect)
|
|
|
06bf710 |
+ preferred_match[0] = bestModeForAspect(config, enabled, aspect);
|
|
|
06bf710 |
|
|
|
06bf710 |
- for (; m; m = m->next)
|
|
|
06bf710 |
- if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay))
|
|
|
06bf710 |
- return m;
|
|
|
06bf710 |
+ if (preferred_match[0])
|
|
|
06bf710 |
+ ret = TRUE;
|
|
|
06bf710 |
|
|
|
06bf710 |
- return NULL;
|
|
|
06bf710 |
-}
|
|
|
06bf710 |
+ } while (0);
|
|
|
06bf710 |
|
|
|
06bf710 |
-static DisplayModePtr
|
|
|
06bf710 |
-bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
|
|
|
06bf710 |
-{
|
|
|
06bf710 |
- int o = -1, p;
|
|
|
06bf710 |
- DisplayModePtr mode = NULL, test = NULL, match = NULL;
|
|
|
06bf710 |
-
|
|
|
06bf710 |
- if (!nextEnabledOutput(config, enabled, &o))
|
|
|
06bf710 |
- return NULL;
|
|
|
06bf710 |
- while ((mode = nextAspectMode(config->output[o], mode, aspect))) {
|
|
|
06bf710 |
- test = mode;
|
|
|
06bf710 |
- for (p = o; nextEnabledOutput(config, enabled, &p); ) {
|
|
|
06bf710 |
- test = xf86OutputFindClosestMode(config->output[p], mode);
|
|
|
06bf710 |
- if (!test)
|
|
|
06bf710 |
- break;
|
|
|
06bf710 |
- if (test->HDisplay != mode->HDisplay ||
|
|
|
06bf710 |
- test->VDisplay != mode->VDisplay) {
|
|
|
06bf710 |
- test = NULL;
|
|
|
06bf710 |
- break;
|
|
|
06bf710 |
- }
|
|
|
06bf710 |
- }
|
|
|
06bf710 |
-
|
|
|
06bf710 |
- /* if we didn't match it on all outputs, try the next one */
|
|
|
06bf710 |
- if (!test)
|
|
|
06bf710 |
- continue;
|
|
|
06bf710 |
-
|
|
|
06bf710 |
- /* if it's bigger than the last one, save it */
|
|
|
06bf710 |
- if (!match || (test->HDisplay > match->HDisplay))
|
|
|
06bf710 |
- match = test;
|
|
|
06bf710 |
+ if (ret) {
|
|
|
06bf710 |
+ /* oh good, there is a match. stash the selected modes and return. */
|
|
|
06bf710 |
+ memcpy(modes, preferred_match,
|
|
|
06bf710 |
+ config->num_output * sizeof(DisplayModePtr));
|
|
|
06bf710 |
}
|
|
|
06bf710 |
|
|
|
06bf710 |
- /* return the biggest one found */
|
|
|
06bf710 |
- return match;
|
|
|
06bf710 |
+ xfree(preferred);
|
|
|
06bf710 |
+ xfree(preferred_match);
|
|
|
06bf710 |
+ return ret;
|
|
|
06bf710 |
}
|
|
|
06bf710 |
|
|
|
06bf710 |
static Bool
|
|
|
06bf710 |
--
|
|
|
06bf710 |
1.6.0.6
|
|
|
06bf710 |
|