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

Side by Side Diff: monitor_reconfigure.cc

Issue 6854002: Merge monitor_reconfigure into powerd. (Closed) Base URL: ssh://gitrw.chromium.org:9222/power_manager.git@master
Patch Set: Address second round of comments. Created 9 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "power_manager/backlight_controller.h"
6 #include "power_manager/monitor_reconfigure.h"
7
8 #include <algorithm>
9 #include <cstdio>
10 #include <cstdlib>
11
12 #include "base/command_line.h"
13 #include "base/logging.h"
14 #include "base/string_util.h"
15 #include "power_manager/udev_listener.h"
16
tfarina 2011/04/14 15:11:41 extra line.
marcheu 2011/04/14 17:43:40 Done.
17
18 using std::map;
19 using std::sort;
20 using std::string;
21 using std::vector;
22
23 namespace power_manager {
24
25 static const char kLcdOutputName[] = "LVDS1";
tfarina 2011/04/14 15:11:41 please, move this to an unnamed namespace and remo
marcheu 2011/04/14 17:43:40 Done.
26 static const float kScreenDpi = 96.0;
27 static const float kInchInMm = 25.4;
28
29 void MonitorReconfigureCallback::Run(GIOChannel* /* source */,
30 GIOCondition /* condition */) {
31 monitor_reconfigure_->Run();
32 }
33
34 MonitorReconfigureMain::MonitorReconfigureMain()
35 : backlight_ctl_(NULL),
36 callback_(NULL),
37 listener_(NULL) {}
38
39 MonitorReconfigureMain::MonitorReconfigureMain(
40 BacklightController* backlight_ctl)
41 : backlight_ctl_(backlight_ctl),
42 callback_(NULL),
43 listener_(NULL) {}
44
45 MonitorReconfigureMain::~MonitorReconfigureMain() {
46 }
47
48 bool MonitorReconfigureMain::Init() {
49 callback_ = new MonitorReconfigureCallback(this);
50 listener_ = new UdevListener(callback_, std::string("drm"));
tfarina 2011/04/14 15:11:41 std::string("..") is needed? Can't you pass just "
marcheu 2011/04/14 17:43:40 Done.
51 return listener_->Init();
52 }
53
54 void MonitorReconfigureMain::Run()
55 {
tfarina 2011/04/14 15:11:41 the left brace "{" should be on the end of the pre
marcheu 2011/04/14 17:43:40 Done.
56 lcd_output_ = 0;
57 lcd_output_info_ = NULL;
58 external_output_ = 0;
59 external_output_info_ = NULL;
60 display_ = XOpenDisplay(NULL);
61 CHECK(display_) << "Could not open display";
62
63 window_ = RootWindow(display_, DefaultScreen(display_));
64 screen_info_ = XRRGetScreenResources(display_, window_);
65
66 for (int i = 0; i < screen_info_->nmode; ++i) {
67 XRRModeInfo* current_mode = &screen_info_->modes[i];
68 mode_map_[current_mode->id] = current_mode;
69 }
70 DetermineOutputs();
71 vector<ResolutionSelector::Mode> lcd_modes;
72 SortModesByResolution(lcd_output_, &lcd_modes);
73 DCHECK(!lcd_modes.empty());
74
75 vector<ResolutionSelector::Mode> external_modes;
76 if (IsExternalMonitorConnected()) {
77 SortModesByResolution(external_output_, &external_modes);
78 DCHECK(!external_modes.empty());
79 }
80
81 ResolutionSelector selector;
82 ResolutionSelector::Mode lcd_resolution;
83 ResolutionSelector::Mode external_resolution;
84 ResolutionSelector::Mode screen_resolution;
85
86 CHECK(selector.FindBestResolutions(lcd_modes,
87 external_modes,
88 &lcd_resolution,
89 &external_resolution,
90 &screen_resolution));
91 CHECK(!lcd_resolution.name.empty() || !external_resolution.name.empty());
92
93 // Disable the backlight before resizing anything on the screen.
94 if (lcd_resolution.name.empty())
95 backlight_ctl_->SetPowerState(BACKLIGHT_ACTIVE_OFF);
96
97 // Grab the server during mode changes.
98 XGrabServer(display_);
99
100 // Disable the LCD if we were told to do so (because we're using a higher
101 // resolution that'd be clipped on the LCD).
102 // Otherwise enable the LCD if appropriate.
103 if (lcd_resolution.name.empty())
104 DisableDevice(lcd_output_info_);
105 else
106 // FIXME: here set the gamma ramp.
107 SetDeviceResolution(lcd_output_, lcd_output_info_, lcd_resolution);
108
tfarina 2011/04/14 15:11:41 extra line.
marcheu 2011/04/14 17:43:40 Done.
109
110 // If there's no external output connected, disable the device before we try
111 // to set the screen resolution; otherwise xrandr will complain if we're
112 // trying to set the screen to a smaller size than what the now-unplugged
113 // device was using.
114 // Otherwise enable the external device if appropriate.
115 if (external_resolution.name.empty())
116 DisableDevice(external_output_info_);
117 else
118 SetDeviceResolution(external_output_, external_output_info_,
119 external_resolution);
120
121 // Set the fb resolution.
122 SetScreenResolution(screen_resolution);
123
124 // Now let the server go and sync all changes.
125 XUngrabServer(display_);
126 XSync(display_, False);
127
128 XRRFreeOutputInfo(lcd_output_info_);
129 XRRFreeOutputInfo(external_output_info_);
130 XRRFreeScreenResources(screen_info_);
131
132 // Enable the backlight. We do not want to do this before the resize is
133 // done so that we can hide the resize when going off->on.
134 if (!lcd_resolution.name.empty())
135 backlight_ctl_->SetPowerState(BACKLIGHT_ACTIVE_ON);
136 }
137
138 void MonitorReconfigureMain::DetermineOutputs() {
139 CHECK(screen_info_->noutput > 1) << "Expected at least two outputs";
140 CHECK(!lcd_output_info_);
141 CHECK(!external_output_info_);
142
143 RROutput first_output = screen_info_->outputs[0];
144 RROutput second_output = screen_info_->outputs[1];
145
146 XRROutputInfo* first_output_info =
147 XRRGetOutputInfo(display_, screen_info_, first_output);
148 XRROutputInfo* second_output_info =
149 XRRGetOutputInfo(display_, screen_info_, second_output);
150
151 if (strcmp(first_output_info->name, kLcdOutputName) == 0) {
152 lcd_output_ = first_output;
153 lcd_output_info_ = first_output_info;
154 external_output_ = second_output;
155 external_output_info_ = second_output_info;
156 } else {
157 lcd_output_ = second_output;
158 lcd_output_info_ = second_output_info;
159 external_output_ = first_output;
160 external_output_info_ = first_output_info;
161 }
162
163 LOG(INFO) << "LCD name: " << lcd_output_info_->name << " (xid "
164 << lcd_output_ << ")";
165 for (int i = 0; i < lcd_output_info_->nmode; ++i) {
166 XRRModeInfo* mode = mode_map_[lcd_output_info_->modes[i]];
167 LOG(INFO) << " Mode: " << mode->width << "x" << mode->height
168 << " (xid " << mode->id << ")";
169 }
170
171 LOG(INFO) << "External name: " << external_output_info_->name
172 << " (xid " << external_output_ << ")";
173 for (int i = 0; i < external_output_info_->nmode; ++i) {
174 XRRModeInfo* mode = mode_map_[external_output_info_->modes[i]];
175 LOG(INFO) << " Mode: " << mode->width << "x" << mode->height
176 << " (xid " << mode->id << ")";
177 }
178 }
179
180 bool MonitorReconfigureMain::IsExternalMonitorConnected() {
181 return (external_output_info_->connection == RR_Connected);
182 }
183
184 void MonitorReconfigureMain::SortModesByResolution(
185 RROutput output,
186 vector<ResolutionSelector::Mode>* modes_out) {
187 modes_out->clear();
188
189 XRROutputInfo* output_info = XRRGetOutputInfo(display_, screen_info_, output);
190 for (int i = 0; i < output_info->nmode; ++i) {
191 const XRRModeInfo* mode = mode_map_[output_info->modes[i]];
192 DCHECK(mode);
193 LOG(INFO) << "Adding mode " << mode->width << " " << mode->height
194 << " (xid " << mode->id << ")";
195 modes_out->push_back(
196 ResolutionSelector::Mode(mode->width, mode->height, mode->name,
197 mode->id));
198 }
199
200 sort(modes_out->begin(), modes_out->end(),
201 ResolutionSelector::ModeResolutionComparator());
202
203 XRRFreeOutputInfo(output_info);
204 }
205
206 bool MonitorReconfigureMain::SetDeviceResolution(
207 RROutput output, const XRROutputInfo* output_info,
tfarina 2011/04/14 15:11:41 please, when it doesn't fit, write one argument pe
marcheu 2011/04/14 17:43:40 Done.
208 const ResolutionSelector::Mode& resolution) {
209 Status s = XRRSetCrtcConfig(display_, screen_info_, output_info->crtcs[0],
210 CurrentTime, 0, 0, resolution.id, RR_Rotate_0,
211 &output, 1);
212 return (s == RRSetConfigSuccess);
213 }
214
215 bool MonitorReconfigureMain::SetScreenResolution(
216 const ResolutionSelector::Mode& resolution) {
217 LOG(INFO) << "Setting resolution " << resolution.name.c_str() << " "
218 << resolution.width << "x" << resolution.height;
219 // Do not switch resolutions if we don't need to, this avoids blinking.
220 int screen = DefaultScreen(display_);
221 if ( (resolution.width != DisplayWidth(display_, screen))||
222 (resolution.height != DisplayHeight(display_, screen)) )
223 XRRSetScreenSize(display_, window_,
224 resolution.width,
225 resolution.height,
226 resolution.width * kInchInMm / kScreenDpi,
227 resolution.height * kInchInMm / kScreenDpi);
228
229 return true;
230 }
231
232 bool MonitorReconfigureMain::DisableDevice(const XRROutputInfo* output_info) {
233 if (!output_info->crtc)
234 return true;
235 LOG(INFO) << "Disabling output " << output_info->name;
236 Status s = XRRSetCrtcConfig(display_, screen_info_, output_info->crtc,
237 CurrentTime, 0, 0, None, RR_Rotate_0, NULL, 0);
238 return (s == RRSetConfigSuccess);
239 }
240
241 } // end namespace power_manager
tfarina 2011/04/14 15:11:41 nit: } // namespace power_manager
marcheu 2011/04/14 17:43:40 Done.
242
tfarina 2011/04/14 15:11:41 get rid of this line.
marcheu 2011/04/14 17:43:40 Done.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698