diff options
author | Adam Jackson <ajax@redhat.com> | 2009-10-28 15:44:37 -0400 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2009-10-29 14:06:00 -0400 |
commit | 7c0803f555782dbf451b7c79112d7deae02e5c9f (patch) | |
tree | 9d9218fc3acf80bacd22de61ab3fabb508d77064 | |
parent | ba2d39dd5428cb5922b797a1d4ea45b859412b40 (diff) |
modes: Fix duplicate detection, and do it more consistently
Signed-off-by: Adam Jackson <ajax@redhat.com>
-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 138adc053..fad50a23b 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 @@ -1575,9 +1547,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 23d641689..15021a8e5 100644 --- a/hw/xfree86/modes/xf86EdidModes.c +++ b/hw/xfree86/modes/xf86EdidModes.c @@ -1082,6 +1082,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 ae6d95642..75aedaa99 100644 --- a/hw/xfree86/modes/xf86Modes.c +++ b/hw/xfree86/modes/xf86Modes.c @@ -691,3 +691,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); |