Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(808)

Unified Diff: src/platform/monitor_reconfig/monitor_reconfigure_main.cc

Issue 1646010: monitor_reconfigure: Try to improve resolution selection. (Closed)
Patch Set: apply review feedback Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/platform/monitor_reconfig/monitor_reconfigure_main.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/platform/monitor_reconfig/monitor_reconfigure_main.cc
diff --git a/src/platform/monitor_reconfig/monitor_reconfigure_main.cc b/src/platform/monitor_reconfig/monitor_reconfigure_main.cc
index 52f30fa461e851b4d18e1573e5fb50396f910ff4..e0e07a3c2b51e3dbedd18297ab61436c7eff7249 100644
--- a/src/platform/monitor_reconfig/monitor_reconfigure_main.cc
+++ b/src/platform/monitor_reconfig/monitor_reconfigure_main.cc
@@ -4,19 +4,26 @@
#include "monitor_reconfig/monitor_reconfigure_main.h"
+#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include "base/logging.h"
+#include "base/string_util.h"
using std::map;
+using std::sort;
+using std::string;
+using std::vector;
namespace monitor_reconfig {
MonitorReconfigureMain::MonitorReconfigureMain(Display* display,
XRRScreenResources* screen_info)
: display_(display),
- screen_info_(screen_info) {
+ screen_info_(screen_info),
+ lcd_output_(NULL),
+ external_output_(NULL) {
for (int i = 0; i < screen_info_->nmode; ++i) {
XRRModeInfo* current_mode = &screen_info_->modes[i];
mode_map_[current_mode->id] = current_mode;
@@ -30,126 +37,131 @@ void MonitorReconfigureMain::DetermineOutputs() {
XRROutputInfo* second_output =
XRRGetOutputInfo(display_, screen_info_, screen_info_->outputs[1]);
- static const char* kNotebookOutputName = "LVDS1";
- if (strcmp(first_output->name, kNotebookOutputName) == 0) {
- notebook_output_ = first_output;
+ static const char* kLcdOutputName = "LVDS1";
+ if (strcmp(first_output->name, kLcdOutputName) == 0) {
+ lcd_output_ = first_output;
external_output_ = second_output;
} else {
- notebook_output_ = second_output;
+ lcd_output_ = second_output;
external_output_ = first_output;
}
- for (int i = 0; i < notebook_output_->nmode; ++i) {
- XRRModeInfo* mode = mode_map_[notebook_output_->modes[i]];
- LOG(INFO) << "notebook mode: " << mode->width << "x" << mode->height;
+ LOG(INFO) << "LCD name: " << lcd_output_->name;
+ for (int i = 0; i < lcd_output_->nmode; ++i) {
+ XRRModeInfo* mode = mode_map_[lcd_output_->modes[i]];
+ LOG(INFO) << " Mode: " << mode->width << "x" << mode->height;
}
+
+ LOG(INFO) << "External name: " << external_output_->name;
for (int i = 0; i < external_output_->nmode; ++i) {
XRRModeInfo* mode = mode_map_[external_output_->modes[i]];
- LOG(INFO) << "external mode: " << mode->width << "x" << mode->height;
+ LOG(INFO) << " Mode: " << mode->width << "x" << mode->height;
}
}
-
-XRRModeInfo* MonitorReconfigureMain::FindMaxResolution(XRROutputInfo* output) {
- XRRModeInfo* mode_return = NULL;
- for (int i = 0; i < output->nmode; ++i) {
- XRRModeInfo* current_mode = mode_map_[output->modes[i]];
- if (mode_return == NULL) {
- mode_return = current_mode;
- } else {
- int n_size = mode_return->height * mode_return->width;
- int c_size = current_mode->height * current_mode->width;
- if (c_size > n_size) {
- mode_return = current_mode;
- }
- }
- }
- return mode_return;
-}
-
-bool MonitorReconfigureMain::IsEqual(XRRModeInfo* one, XRRModeInfo* two) {
- return (one->height * one->width) == (two->height * two->width);
+bool MonitorReconfigureMain::IsExternalMonitorConnected() {
+ return (external_output_->connection == RR_Connected);
}
-bool MonitorReconfigureMain::IsBiggerOrEqual(XRRModeInfo* target,
- XRRModeInfo* screen) {
- return ((target->width >= screen->width) &&
- (target->height >= screen->height));
+void MonitorReconfigureMain::SortModesByResolution(
+ const XRROutputInfo& output_info, vector<XRRModeInfo*>* modes_out) {
+ modes_out->clear();
+ for (int i = 0; i < output_info.nmode; ++i)
+ modes_out->push_back(mode_map_[output_info.modes[i]]);
+ sort(modes_out->begin(), modes_out->end(), ModeResolutionComparator());
}
-bool MonitorReconfigureMain::IsBetterMatching(XRRModeInfo* target,
- XRRModeInfo* to_match,
- XRRModeInfo* previous_best) {
- if (IsEqual(previous_best, to_match))
- return false;
- // If the current will have some of the display cut off
- // and the new choice doesn't, choose the new one
- if ((!IsBiggerOrEqual(previous_best, to_match)) &&
- (IsBiggerOrEqual(target, to_match))) {
- return true;
- // If the current one isn't cropped and the new one would
- // get cropped
- } else if (IsBiggerOrEqual(previous_best, to_match) &&
- !IsBiggerOrEqual(target, to_match)) {
- return false;
- // Case if the current is bigger than the matching but the new target falls
- // between the current and the matching (so it's closer to the matching)
- } else if (IsBiggerOrEqual(previous_best, to_match)) {
- return !IsBiggerOrEqual(target, previous_best);
+bool MonitorReconfigureMain::FindBestResolutions(
+ string* lcd_resolution,
+ string* external_resolution,
+ string* screen_resolution) {
+ DCHECK(lcd_resolution);
+ DCHECK(external_resolution);
+ DCHECK(screen_resolution);
+
+ vector<XRRModeInfo*> lcd_modes, external_modes;
+ SortModesByResolution(*lcd_output_, &lcd_modes);
+ SortModesByResolution(*external_output_, &external_modes);
+ DCHECK(!lcd_modes.empty());
+ DCHECK(!external_modes.empty());
+
+ if ((lcd_modes[0]->width * lcd_modes[0]->height) >=
+ (external_modes[0]->width * external_modes[0]->height)) {
+ return FindNearestResolutions(
+ lcd_modes, external_modes,
+ lcd_resolution, external_resolution, screen_resolution);
} else {
- // Final case, we know the current is smaller than the matching
- // We just need to check if the new will bring us closer to the matching
- return IsBiggerOrEqual(target, previous_best);
+ return FindNearestResolutions(
+ external_modes, lcd_modes,
+ external_resolution, lcd_resolution, screen_resolution);
}
}
-XRRModeInfo* MonitorReconfigureMain::FindBestMatchingResolution(
- XRRModeInfo* matching_mode) {
- // Need a min mode to increase from
- XRRModeInfo min_mode;
- min_mode.height = 0;
- min_mode.width = 0;
- XRRModeInfo* best_mode = &min_mode;
- // Match horizontal if notebook is wider, o/w match vertical
- for (int i = 0; i < external_output_->nmode; ++i) {
- XRRModeInfo* current_mode = mode_map_[external_output_->modes[i]];
- if (IsBetterMatching(current_mode, matching_mode, best_mode))
- best_mode = current_mode;
+bool MonitorReconfigureMain::FindNearestResolutions(
+ const vector<XRRModeInfo*>& larger_device_modes,
+ const vector<XRRModeInfo*>& smaller_device_modes,
+ string* larger_resolution,
+ string* smaller_resolution,
+ string* screen_resolution) {
+ DCHECK(larger_resolution);
+ DCHECK(smaller_resolution);
+
+ // Start with the best that the smaller device has to offer.
+ smaller_resolution->assign(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<XRRModeInfo*>::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->assign((*it)->name);
+ return true;
+ }
}
- if (best_mode == &min_mode)
- best_mode = NULL;
- return best_mode;
+
+ LOG(WARNING) << "Failed to find a resolution from larger device "
+ << "exceeding chosen resolution from smaller device ("
+ << *smaller_resolution << ")";
+ return false;
}
-void MonitorReconfigureMain::SetResolutions(XRRModeInfo* notebook_mode,
- XRRModeInfo* external_mode,
- XRRModeInfo* overall_screen_size) {
- // We use xrandr script to set modes
- char buffer[512];
- snprintf(buffer, sizeof(buffer), "xrandr --output %s --mode %s",
- external_output_->name, external_mode->name);
- system(buffer);
- snprintf(buffer, sizeof(buffer), "xrandr --output %s --mode %s",
- notebook_output_->name, notebook_mode->name);
- system(buffer);
- snprintf(buffer, sizeof(buffer), "xrandr --fb %s", overall_screen_size->name);
- system(buffer);
+bool MonitorReconfigureMain::SetDeviceResolution(
+ const std::string& device_name, const std::string& resolution) {
+ string command = StringPrintf("xrandr --output %s --mode %s",
+ device_name.c_str(), resolution.c_str());
+ LOG(INFO) << "Running " << command.c_str();
+ return system(command.c_str()) == 0;
+}
+
+bool MonitorReconfigureMain::SetScreenResolution(
+ const std::string& resolution) {
+ string command = StringPrintf("xrandr --fb %s", resolution.c_str());
+ LOG(INFO) << "Running " << command.c_str();
+ return system(command.c_str()) == 0;
}
void MonitorReconfigureMain::Run() {
- if (!IsExternalMonitorConnected())
+ // If there's no external monitor connected, just use the highest resolution
+ // supported by the LCD.
+ if (!IsExternalMonitorConnected()) {
+ LOG(INFO) << "No external monitor connected; using max LCD resolution";
+ vector<XRRModeInfo*> lcd_modes;
+ SortModesByResolution(*lcd_output_, &lcd_modes);
+ CHECK(!lcd_modes.empty());
+ SetDeviceResolution(lcd_output_->name, lcd_modes[0]->name);
+ SetScreenResolution(lcd_modes[0]->name);
return;
+ }
- // Find the max resolution for the notebook
- XRRModeInfo* notebook_mode = FindMaxResolution(notebook_output_);
- // Find the best mode for external output relative to above mode
- XRRModeInfo* external_mode = FindBestMatchingResolution(notebook_mode);
- // Set the resolutions accordingly
- SetResolutions(notebook_mode, external_mode, notebook_mode);
-}
-
-bool MonitorReconfigureMain::IsExternalMonitorConnected() {
- return (external_output_->connection == RR_Connected);
+ string lcd_resolution, external_resolution, screen_resolution;
+ CHECK(FindBestResolutions(&lcd_resolution,
+ &external_resolution,
+ &screen_resolution));
+ SetDeviceResolution(lcd_output_->name, lcd_resolution);
+ SetDeviceResolution(external_output_->name, external_resolution);
+ SetScreenResolution(screen_resolution);
}
} // end namespace monitor_reconfig
« no previous file with comments | « src/platform/monitor_reconfig/monitor_reconfigure_main.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698