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

Side by Side Diff: monitor_reconfigure_main.cc

Issue 3304011: monitor_reconfig: Handle external monitors and add tests. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222//monitor_reconfig.git
Patch Set: apply review feedback Created 10 years, 3 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « monitor_reconfigure_main.h ('k') | resolution_selector.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "monitor_reconfig/monitor_reconfigure_main.h" 5 #include "monitor_reconfig/monitor_reconfigure_main.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cstdio> 8 #include <cstdio>
9 #include <cstdlib> 9 #include <cstdlib>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/string_util.h" 12 #include "base/string_util.h"
13 13
14 using std::map; 14 using std::map;
15 using std::sort; 15 using std::sort;
16 using std::string; 16 using std::string;
17 using std::vector; 17 using std::vector;
18 18
19 namespace monitor_reconfig { 19 namespace monitor_reconfig {
20 20
21 static const char kLcdOutputName[] = "LVDS1";
22
21 MonitorReconfigureMain::MonitorReconfigureMain(Display* display, 23 MonitorReconfigureMain::MonitorReconfigureMain(Display* display,
22 XRRScreenResources* screen_info) 24 XRRScreenResources* screen_info)
23 : display_(display), 25 : display_(display),
24 screen_info_(screen_info), 26 screen_info_(screen_info),
25 lcd_output_(NULL), 27 lcd_output_(NULL),
26 external_output_(NULL) { 28 external_output_(NULL) {
27 for (int i = 0; i < screen_info_->nmode; ++i) { 29 for (int i = 0; i < screen_info_->nmode; ++i) {
28 XRRModeInfo* current_mode = &screen_info_->modes[i]; 30 XRRModeInfo* current_mode = &screen_info_->modes[i];
29 mode_map_[current_mode->id] = current_mode; 31 mode_map_[current_mode->id] = current_mode;
30 } 32 }
31 DetermineOutputs(); 33 DetermineOutputs();
32 } 34 }
33 35
36 void MonitorReconfigureMain::Run() {
37 vector<ResolutionSelector::Mode> lcd_modes;
38 SortModesByResolution(*lcd_output_, &lcd_modes);
39 DCHECK(!lcd_modes.empty());
40
41 vector<ResolutionSelector::Mode> external_modes;
42 if (IsExternalMonitorConnected()) {
43 SortModesByResolution(*external_output_, &external_modes);
44 DCHECK(!external_modes.empty());
45 }
46
47 ResolutionSelector selector;
48 string lcd_resolution, external_resolution, screen_resolution;
49 CHECK(selector.FindBestResolutions(lcd_modes,
50 external_modes,
51 &lcd_resolution,
52 &external_resolution,
53 &screen_resolution));
54
55 SetDeviceResolution(lcd_output_->name, lcd_resolution);
56 if (IsExternalMonitorConnected())
57 SetDeviceResolution(external_output_->name, external_resolution);
58 SetScreenResolution(screen_resolution);
59 }
60
34 void MonitorReconfigureMain::DetermineOutputs() { 61 void MonitorReconfigureMain::DetermineOutputs() {
62 CHECK(screen_info_->noutput > 1) << "Expected at least two outputs";
35 XRROutputInfo* first_output = 63 XRROutputInfo* first_output =
36 XRRGetOutputInfo(display_, screen_info_, screen_info_->outputs[0]); 64 XRRGetOutputInfo(display_, screen_info_, screen_info_->outputs[0]);
37 XRROutputInfo* second_output = 65 XRROutputInfo* second_output =
38 XRRGetOutputInfo(display_, screen_info_, screen_info_->outputs[1]); 66 XRRGetOutputInfo(display_, screen_info_, screen_info_->outputs[1]);
39 67
40 static const char* kLcdOutputName = "LVDS1";
41 if (strcmp(first_output->name, kLcdOutputName) == 0) { 68 if (strcmp(first_output->name, kLcdOutputName) == 0) {
42 lcd_output_ = first_output; 69 lcd_output_ = first_output;
43 external_output_ = second_output; 70 external_output_ = second_output;
44 } else { 71 } else {
45 lcd_output_ = second_output; 72 lcd_output_ = second_output;
46 external_output_ = first_output; 73 external_output_ = first_output;
47 } 74 }
48 75
49 LOG(INFO) << "LCD name: " << lcd_output_->name; 76 LOG(INFO) << "LCD name: " << lcd_output_->name;
50 for (int i = 0; i < lcd_output_->nmode; ++i) { 77 for (int i = 0; i < lcd_output_->nmode; ++i) {
51 XRRModeInfo* mode = mode_map_[lcd_output_->modes[i]]; 78 XRRModeInfo* mode = mode_map_[lcd_output_->modes[i]];
52 LOG(INFO) << " Mode: " << mode->width << "x" << mode->height; 79 LOG(INFO) << " Mode: " << mode->width << "x" << mode->height;
53 } 80 }
54 81
55 LOG(INFO) << "External name: " << external_output_->name; 82 LOG(INFO) << "External name: " << external_output_->name;
56 for (int i = 0; i < external_output_->nmode; ++i) { 83 for (int i = 0; i < external_output_->nmode; ++i) {
57 XRRModeInfo* mode = mode_map_[external_output_->modes[i]]; 84 XRRModeInfo* mode = mode_map_[external_output_->modes[i]];
58 LOG(INFO) << " Mode: " << mode->width << "x" << mode->height; 85 LOG(INFO) << " Mode: " << mode->width << "x" << mode->height;
59 } 86 }
60 } 87 }
61 88
62 bool MonitorReconfigureMain::IsExternalMonitorConnected() { 89 bool MonitorReconfigureMain::IsExternalMonitorConnected() {
63 return (external_output_->connection == RR_Connected); 90 return (external_output_->connection == RR_Connected);
64 } 91 }
65 92
66 void MonitorReconfigureMain::SortModesByResolution( 93 void MonitorReconfigureMain::SortModesByResolution(
67 const XRROutputInfo& output_info, vector<XRRModeInfo*>* modes_out) { 94 const XRROutputInfo& output_info,
95 vector<ResolutionSelector::Mode>* modes_out) {
68 modes_out->clear(); 96 modes_out->clear();
69 for (int i = 0; i < output_info.nmode; ++i)
70 modes_out->push_back(mode_map_[output_info.modes[i]]);
71 sort(modes_out->begin(), modes_out->end(), ModeResolutionComparator());
72 }
73 97
74 bool MonitorReconfigureMain::FindBestResolutions( 98 for (int i = 0; i < output_info.nmode; ++i) {
75 string* lcd_resolution, 99 const XRRModeInfo* mode = mode_map_[output_info.modes[i]];
76 string* external_resolution, 100 DCHECK(mode);
77 string* screen_resolution) { 101 modes_out->push_back(
78 DCHECK(lcd_resolution); 102 ResolutionSelector::Mode(mode->width, mode->height, mode->name));
79 DCHECK(external_resolution);
80 DCHECK(screen_resolution);
81
82 vector<XRRModeInfo*> lcd_modes, external_modes;
83 SortModesByResolution(*lcd_output_, &lcd_modes);
84 SortModesByResolution(*external_output_, &external_modes);
85 DCHECK(!lcd_modes.empty());
86 DCHECK(!external_modes.empty());
87
88 if ((lcd_modes[0]->width * lcd_modes[0]->height) >=
89 (external_modes[0]->width * external_modes[0]->height)) {
90 return FindNearestResolutions(
91 lcd_modes, external_modes,
92 lcd_resolution, external_resolution, screen_resolution);
93 } else {
94 return FindNearestResolutions(
95 external_modes, lcd_modes,
96 external_resolution, lcd_resolution, screen_resolution);
97 }
98 }
99
100 bool MonitorReconfigureMain::FindNearestResolutions(
101 const vector<XRRModeInfo*>& larger_device_modes,
102 const vector<XRRModeInfo*>& smaller_device_modes,
103 string* larger_resolution,
104 string* smaller_resolution,
105 string* screen_resolution) {
106 DCHECK(larger_resolution);
107 DCHECK(smaller_resolution);
108
109 // Start with the best that the smaller device has to offer.
110 smaller_resolution->assign(smaller_device_modes[0]->name);
111 *screen_resolution = *smaller_resolution;
112 int smaller_width = smaller_device_modes[0]->width;
113 int smaller_height = smaller_device_modes[0]->height;
114
115 for (vector<XRRModeInfo*>::const_reverse_iterator it =
116 larger_device_modes.rbegin();
117 it != larger_device_modes.rend(); ++it) {
118 if ((*it)->width >= smaller_width && (*it)->height >= smaller_height) {
119 larger_resolution->assign((*it)->name);
120 return true;
121 }
122 } 103 }
123 104
124 LOG(WARNING) << "Failed to find a resolution from larger device " 105 sort(modes_out->begin(), modes_out->end(),
125 << "exceeding chosen resolution from smaller device (" 106 ResolutionSelector::ModeResolutionComparator());
126 << *smaller_resolution << ")";
127 return false;
128 } 107 }
129 108
130 bool MonitorReconfigureMain::SetDeviceResolution( 109 bool MonitorReconfigureMain::SetDeviceResolution(
131 const std::string& device_name, const std::string& resolution) { 110 const std::string& device_name, const std::string& resolution) {
132 string command = StringPrintf("xrandr --output %s --mode %s", 111 string command = StringPrintf("xrandr --output %s --mode %s",
133 device_name.c_str(), resolution.c_str()); 112 device_name.c_str(), resolution.c_str());
134 LOG(INFO) << "Running " << command.c_str(); 113 LOG(INFO) << "Running " << command.c_str();
135 return system(command.c_str()) == 0; 114 return system(command.c_str()) == 0;
136 } 115 }
137 116
138 bool MonitorReconfigureMain::SetScreenResolution( 117 bool MonitorReconfigureMain::SetScreenResolution(
139 const std::string& resolution) { 118 const std::string& resolution) {
140 string command = StringPrintf("xrandr --fb %s", resolution.c_str()); 119 string command = StringPrintf("xrandr --fb %s", resolution.c_str());
141 LOG(INFO) << "Running " << command.c_str(); 120 LOG(INFO) << "Running " << command.c_str();
142 return system(command.c_str()) == 0; 121 return system(command.c_str()) == 0;
143 } 122 }
144 123
145 void MonitorReconfigureMain::Run() {
146 // If there's no external monitor connected, just use the highest resolution
147 // supported by the LCD.
148 if (!IsExternalMonitorConnected()) {
149 LOG(INFO) << "No external monitor connected; using max LCD resolution";
150 vector<XRRModeInfo*> lcd_modes;
151 SortModesByResolution(*lcd_output_, &lcd_modes);
152 CHECK(!lcd_modes.empty());
153 SetDeviceResolution(lcd_output_->name, lcd_modes[0]->name);
154 SetScreenResolution(lcd_modes[0]->name);
155 return;
156 }
157
158 string lcd_resolution, external_resolution, screen_resolution;
159 CHECK(FindBestResolutions(&lcd_resolution,
160 &external_resolution,
161 &screen_resolution));
162 SetDeviceResolution(lcd_output_->name, lcd_resolution);
163 SetDeviceResolution(external_output_->name, external_resolution);
164 SetScreenResolution(screen_resolution);
165 }
166
167 } // end namespace monitor_reconfig 124 } // end namespace monitor_reconfig
168 125
169 int main(int argc, char** argv) { 126 int main(int argc, char** argv) {
170 logging::InitLogging(NULL, 127 logging::InitLogging(NULL,
171 logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG, 128 logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG,
172 logging::DONT_LOCK_LOG_FILE, 129 logging::DONT_LOCK_LOG_FILE,
173 logging::APPEND_TO_OLD_LOG_FILE); 130 logging::APPEND_TO_OLD_LOG_FILE);
174 Display* display = XOpenDisplay(NULL); 131 Display* display = XOpenDisplay(NULL);
175 CHECK(display) << "Could not open display"; 132 CHECK(display) << "Could not open display";
176 133
177 Window window = RootWindow(display, DefaultScreen(display)); 134 Window window = RootWindow(display, DefaultScreen(display));
178 XRRScreenResources* screen_info = XRRGetScreenResources(display, window); 135 XRRScreenResources* screen_info = XRRGetScreenResources(display, window);
179 monitor_reconfig::MonitorReconfigureMain main_app(display, screen_info); 136 monitor_reconfig::MonitorReconfigureMain main_app(display, screen_info);
180
181 main_app.Run(); 137 main_app.Run();
182 return 0; 138 return 0;
183 } 139 }
OLDNEW
« no previous file with comments | « monitor_reconfigure_main.h ('k') | resolution_selector.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698