Index: resolution_selector.cc |
diff --git a/resolution_selector.cc b/resolution_selector.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ac4e31b5c685471cdd9db5fd7b78cecf0ff35bcc |
--- /dev/null |
+++ b/resolution_selector.cc |
@@ -0,0 +1,91 @@ |
+// Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "monitor_reconfig/resolution_selector.h" |
+ |
+#include "base/logging.h" |
+ |
+namespace monitor_reconfig { |
+ |
+using std::string; |
+using std::vector; |
+ |
+ |
+const int ResolutionSelector::kMaxProjectorPixels = 1280 * 720; |
+ |
+ |
+bool ResolutionSelector::FindBestResolutions( |
+ const vector<Mode>& lcd_modes, |
+ const vector<Mode>& external_modes, |
+ string* lcd_resolution, |
+ string* external_resolution, |
+ string* screen_resolution) { |
+ DCHECK(!lcd_modes.empty()); |
+ |
+ // If there's no external display, just use the highest resolution |
+ // available from the LCD. |
+ if (external_modes.empty()) { |
+ *lcd_resolution = *screen_resolution = lcd_modes[0].name; |
+ external_resolution->clear(); |
+ return true; |
+ } |
+ |
+ const int max_lcd_size = lcd_modes[0].width * lcd_modes[0].height; |
+ const int max_external_size = |
+ external_modes[0].width * external_modes[0].height; |
+ |
+ if (max_lcd_size >= max_external_size) { |
+ return FindNearestResolutions( |
+ lcd_modes, external_modes, |
+ lcd_resolution, external_resolution, screen_resolution); |
+ } else { |
+ // If the external output is large enough that we think it's a monitor |
+ // (as opposed to a projector), then we just use its max resolution and |
+ // forget about trying to choose a screen size that'll fit on the |
+ // built-in display. |
+ if (max_external_size > kMaxProjectorPixels) { |
+ *external_resolution = *screen_resolution = external_modes[0].name; |
+ *lcd_resolution = lcd_modes[0].name; |
+ return true; |
+ } |
+ return FindNearestResolutions( |
+ external_modes, lcd_modes, |
+ external_resolution, lcd_resolution, screen_resolution); |
+ } |
+} |
+ |
+bool ResolutionSelector::FindNearestResolutions( |
+ const vector<Mode>& larger_device_modes, |
+ const vector<Mode>& smaller_device_modes, |
+ std::string* larger_resolution, |
+ std::string* smaller_resolution, |
+ std::string* screen_resolution) { |
+ DCHECK(!larger_device_modes.empty()); |
+ DCHECK(!smaller_device_modes.empty()); |
+ DCHECK(larger_resolution); |
+ DCHECK(smaller_resolution); |
+ DCHECK(screen_resolution); |
+ |
+ // Start with the best that the smaller device has to offer. |
+ *smaller_resolution = smaller_device_modes[0].name; |
+ *screen_resolution = *smaller_resolution; |
+ int smaller_width = smaller_device_modes[0].width; |
+ int smaller_height = smaller_device_modes[0].height; |
+ |
+ for (vector<Mode>::const_reverse_iterator it = |
+ larger_device_modes.rbegin(); |
+ it != larger_device_modes.rend(); ++it) { |
+ if (it->width >= smaller_width && it->height >= smaller_height) { |
+ *larger_resolution = it->name; |
+ return true; |
+ } |
+ } |
+ |
+ LOG(WARNING) << "Failed to find a resolution from larger device " |
+ << "exceeding chosen resolution from smaller device (" |
+ << *smaller_resolution << ")"; |
+ return false; |
+} |
+ |
+} // namespace monitor_reconfig |