blob: 52a7da390fcee7d0dc757fb37e594b274e10a109 [file] [log] [blame]
// 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,
Mode* lcd_resolution,
Mode* external_resolution,
Mode* 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];
external_resolution->name.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];
lcd_resolution->name.clear();
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,
Mode* larger_resolution,
Mode* smaller_resolution,
Mode* 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];
*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;
return true;
}
}
LOG(WARNING) << "Failed to find a resolution from larger device "
<< "exceeding chosen resolution from smaller device ("
<< smaller_resolution->name << ")";
return false;
}
} // namespace monitor_reconfig