diff options
author | Adam Jackson <ajax@redhat.com> | 2009-10-28 15:44:37 -0400 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2009-11-03 13:26:44 +1000 |
commit | 9c87ede1d621bd7d69be81bdfdd2b18d47c68983 (patch) | |
tree | aa3573ddd8ad1bf480d9c31097315c061b715c40 | |
parent | f61376b1365b558cf4d05e370cbea807ae168b27 (diff) |
modes: Fix duplicate detection, and do it more consistently
Signed-off-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit 7c0803f555782dbf451b7c79112d7deae02e5c9f)
-rw-r--r-- | hw/xfree86/modes/xf86Crtc.c | 31 | ||||
-rw-r--r-- | hw/xfree86/modes/xf86EdidModes.c | 2 | ||||
-rw-r--r-- | hw/xfree86/modes/xf86Modes.c | 34 | ||||
-rw-r--r-- | hw/xfree86/modes/xf86Modes.h | 3 |
4 files changed, 39 insertions, 31 deletions
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 506fbb9cb..937064003 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -1377,34 +1377,6 @@ xf86InitialPanning (ScrnInfoPtr scrn) } } -/* - * XXX walk the monitor mode list and prune out duplicates that - * are inserted by xf86DDCMonitorSet. In an ideal world, that - * function would do this work by itself. - */ - -static void -xf86PruneDuplicateMonitorModes (MonPtr Monitor) -{ - DisplayModePtr master, clone, next; - - for (master = Monitor->Modes; - master && master != Monitor->Last; - master = master->next) - { - for (clone = master->next; clone && clone != Monitor->Modes; clone = next) - { - next = clone->next; - if (xf86ModesEqual (master, clone)) - { - if (Monitor->Last == clone) - Monitor->Last = clone->prev; - xf86DeleteMode (&Monitor->Modes, clone); - } - } - } -} - /** Return - 0 + if a should be earlier, same or later than b in list */ static int @@ -1539,9 +1511,6 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) maxY = config->maxHeight; } - /* Elide duplicate modes before defaulting code uses them */ - xf86PruneDuplicateMonitorModes (scrn->monitor); - /* Probe the list of modes for each output. */ for (o = 0; o < config->num_output; o++) { diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c index 5992d95da..93d9f664a 100644 --- a/hw/xfree86/modes/xf86EdidModes.c +++ b/hw/xfree86/modes/xf86EdidModes.c @@ -975,6 +975,8 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) if (quirks & DDC_QUIRK_PREFER_LARGE_75) xf86DDCSetPreferredRefresh(scrnIndex, Modes, 75); + Modes = xf86PruneDuplicateModes(Modes); + return Modes; } diff --git a/hw/xfree86/modes/xf86Modes.c b/hw/xfree86/modes/xf86Modes.c index d105b48ab..862a4734b 100644 --- a/hw/xfree86/modes/xf86Modes.c +++ b/hw/xfree86/modes/xf86Modes.c @@ -689,3 +689,37 @@ xf86GetDefaultModes (void) } return head; } + +/* + * Walk a mode list and prune out duplicates. Will preserve the preferred + * mode of an otherwise-duplicate pair. + * + * Probably best to call this on lists that are all of a single class + * (driver, default, user, etc.), otherwise, which mode gets deleted is + * not especially well defined. + * + * Returns the new list. + */ + +DisplayModePtr +xf86PruneDuplicateModes(DisplayModePtr modes) +{ + DisplayModePtr m, n, o; + +top: + for (m = modes; m; m = m->next) { + for (n = m->next; n; n = o) { + o = n->next; + if (xf86ModesEqual(m, n)) { + if (n->type & M_T_PREFERRED) { + xf86DeleteMode(&modes, m); + goto top; + } + else + xf86DeleteMode(&modes, n); + } + } + } + + return modes; +} diff --git a/hw/xfree86/modes/xf86Modes.h b/hw/xfree86/modes/xf86Modes.h index 908f59b48..38927b128 100644 --- a/hw/xfree86/modes/xf86Modes.h +++ b/hw/xfree86/modes/xf86Modes.h @@ -95,6 +95,9 @@ extern _X_EXPORT void xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList, Bool verbose); +extern _X_EXPORT DisplayModePtr +xf86PruneDuplicateModes(DisplayModePtr modes); + extern _X_EXPORT void xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, int flags); |