xserver: Branch 'master' - 3 commits
Alex Deucher
agd5f at kemper.freedesktop.org
Thu Nov 13 12:05:08 PST 2008
hw/xfree86/modes/xf86Crtc.c | 162 ++++++++++++++++++++++++++------------------
1 file changed, 99 insertions(+), 63 deletions(-)
New commits:
commit ba4e08244ed3923eecf26842dfc1df17c696e053
Merge: 81fd17f... 5bad5d2...
Author: Alex Deucher <alexdeucher at gmail.com>
Date: Thu Nov 13 15:04:18 2008 -0500
Merge branch 'master' of git+ssh://agd5f@git.freedesktop.org/git/xorg/./xserver
commit 81fd17f5f49cdd2c10d0bf3b7ddeb8b5953886a5
Author: Alex Deucher <alexdeucher at gmail.com>
Date: Thu Nov 13 15:00:30 2008 -0500
Only add default modes if EDID supports continuous-frequency
When an EDID is present, only add the default mode pool if the
continuous-frequency bit is set in the EDID. Should fix bugs
like 18512.
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 74ffce3..251b800 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1418,7 +1418,7 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
{
xf86OutputPtr output = config->output[o];
DisplayModePtr mode;
- DisplayModePtr config_modes = NULL, output_modes, default_modes;
+ DisplayModePtr config_modes = NULL, output_modes, default_modes = NULL;
char *preferred_mode;
xf86MonPtr edid_monitor;
XF86ConfMonitorPtr conf_monitor;
@@ -1426,6 +1426,7 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
int min_clock = 0;
int max_clock = 0;
double clock;
+ Bool add_default_modes = TRUE;
enum { sync_config, sync_edid, sync_default } sync_source = sync_default;
while (output->probed_modes != NULL)
@@ -1476,6 +1477,11 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
int i;
Bool set_hsync = mon_rec.nHsync == 0;
Bool set_vrefresh = mon_rec.nVrefresh == 0;
+ struct disp_features *features = &edid_monitor->features;
+
+ /* if display is not continuous-frequency, don't add default modes */
+ if (!GTF_SUPPORTED(features->msc))
+ add_default_modes = FALSE;
for (i = 0; i < sizeof (edid_monitor->det_mon) / sizeof (edid_monitor->det_mon[0]); i++)
{
@@ -1532,8 +1538,10 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
mon_rec.vrefresh[0].hi = 62.0;
mon_rec.nVrefresh = 1;
}
- default_modes = xf86GetDefaultModes (output->interlaceAllowed,
- output->doubleScanAllowed);
+
+ if (add_default_modes)
+ default_modes = xf86GetDefaultModes (output->interlaceAllowed,
+ output->doubleScanAllowed);
/*
* If this is not an RB monitor, remove RB modes from the default
commit c232f3d673fb00d7fceb8e82741349d64e5ac0ad
Author: Adam Jackson <ajax at nwnk.net>
Date: Thu Nov 13 14:58:21 2008 -0500
xf86TargetExact should try harder if there's only one monitor attached.
If there's no preferred mode, but only one monitor, pick the
biggest mode for its aspect ratio, assuming one exists.
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index f072109..74ffce3 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1820,6 +1820,66 @@ nextEnabledOutput(xf86CrtcConfigPtr config, Bool *enabled, int *index)
}
static Bool
+aspectMatch(float a, float b)
+{
+ return fabs(1 - (a / b)) < 0.05;
+}
+
+static DisplayModePtr
+nextAspectMode(xf86OutputPtr o, DisplayModePtr last, float aspect)
+{
+ DisplayModePtr m = NULL;
+
+ if (!o)
+ return NULL;
+
+ if (!last)
+ m = o->probed_modes;
+ else
+ m = last->next;
+
+ for (; m; m = m->next)
+ if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay))
+ return m;
+
+ return NULL;
+}
+
+static DisplayModePtr
+bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
+{
+ int o = -1, p;
+ DisplayModePtr mode = NULL, test = NULL, match = NULL;
+
+ if (!nextEnabledOutput(config, enabled, &o))
+ return NULL;
+ while ((mode = nextAspectMode(config->output[o], mode, aspect))) {
+ test = mode;
+ for (p = o; nextEnabledOutput(config, enabled, &p); ) {
+ test = xf86OutputFindClosestMode(config->output[p], mode);
+ if (!test)
+ break;
+ if (test->HDisplay != mode->HDisplay ||
+ test->VDisplay != mode->VDisplay) {
+ test = NULL;
+ break;
+ }
+ }
+
+ /* if we didn't match it on all outputs, try the next one */
+ if (!test)
+ continue;
+
+ /* if it's bigger than the last one, save it */
+ if (!match || (test->HDisplay > match->HDisplay))
+ match = test;
+ }
+
+ /* return the biggest one found */
+ return match;
+}
+
+static Bool
xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
DisplayModePtr *modes, Bool *enabled,
int width, int height)
@@ -1871,75 +1931,43 @@ xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
}
}
- if (ret) {
- /* oh good, there is a match. stash the selected modes and return. */
- memcpy(modes, preferred_match,
- config->num_output * sizeof(DisplayModePtr));
- }
-
- xfree(preferred);
- xfree(preferred_match);
- return ret;
-}
+ /*
+ * If there's no preferred mode, but only one monitor, pick the
+ * biggest mode for its aspect ratio, assuming one exists.
+ */
+ if (!ret) do {
+ int i = 0;
+ float aspect = 0.0;
-static Bool
-aspectMatch(float a, float b)
-{
- return fabs(1 - (a / b)) < 0.05;
-}
+ /* count the number of enabled outputs */
+ for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ;
-static DisplayModePtr
-nextAspectMode(xf86OutputPtr o, DisplayModePtr last, float aspect)
-{
- DisplayModePtr m = NULL;
+ if (i != 1)
+ break;
- if (!o)
- return NULL;
+ p = -1;
+ nextEnabledOutput(config, enabled, &p);
+ if (config->output[p]->mm_height)
+ aspect = (float)config->output[p]->mm_width /
+ (float)config->output[p]->mm_height;
- if (!last)
- m = o->probed_modes;
- else
- m = last->next;
+ if (aspect)
+ preferred_match[0] = bestModeForAspect(config, enabled, aspect);
- for (; m; m = m->next)
- if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay))
- return m;
+ if (preferred_match[0])
+ ret = TRUE;
- return NULL;
-}
+ } while (0);
-static DisplayModePtr
-bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
-{
- int o = -1, p;
- DisplayModePtr mode = NULL, test = NULL, match = NULL;
-
- if (!nextEnabledOutput(config, enabled, &o))
- return NULL;
- while ((mode = nextAspectMode(config->output[o], mode, aspect))) {
- test = mode;
- for (p = o; nextEnabledOutput(config, enabled, &p); ) {
- test = xf86OutputFindClosestMode(config->output[p], mode);
- if (!test)
- break;
- if (test->HDisplay != mode->HDisplay ||
- test->VDisplay != mode->VDisplay) {
- test = NULL;
- break;
- }
- }
-
- /* if we didn't match it on all outputs, try the next one */
- if (!test)
- continue;
-
- /* if it's bigger than the last one, save it */
- if (!match || (test->HDisplay > match->HDisplay))
- match = test;
+ if (ret) {
+ /* oh good, there is a match. stash the selected modes and return. */
+ memcpy(modes, preferred_match,
+ config->num_output * sizeof(DisplayModePtr));
}
- /* return the biggest one found */
- return match;
+ xfree(preferred);
+ xfree(preferred_match);
+ return ret;
}
static Bool
More information about the xorg-commit
mailing list