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

Side by Side Diff: chromeos/monitor/output_configurator.cc

Issue 10532053: Detect output state at startup to avoid changes (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 6 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
« no previous file with comments | « chromeos/monitor/output_configurator.h ('k') | no next file » | 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium 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 "chromeos/monitor/output_configurator.h" 5 #include "chromeos/monitor/output_configurator.h"
6 6
7 #include "base/chromeos/chromeos_version.h" 7 #include "base/chromeos/chromeos_version.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_pump_aurax11.h" 9 #include "base/message_pump_aurax11.h"
10 #include "chromeos/dbus/dbus_thread_manager.h" 10 #include "chromeos/dbus/dbus_thread_manager.h"
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 screen->crtcs[i], 151 screen->crtcs[i],
152 x, 152 x,
153 y, 153 y,
154 kMode, 154 kMode,
155 kOutput); 155 kOutput);
156 } 156 }
157 int mm_width = width * kPixelsToMmScale; 157 int mm_width = width * kPixelsToMmScale;
158 int mm_height = height * kPixelsToMmScale; 158 int mm_height = height * kPixelsToMmScale;
159 XRRSetScreenSize(display, window, width, height, mm_width, mm_height); 159 XRRSetScreenSize(display, window, width, height, mm_width, mm_height);
160 } 160 }
161
162 // A helper to get the current CRTC, Mode, and height for a given output. This
163 // is read from the XRandR configuration and not any of our caches.
164 static void GetOutputConfiguration(Display* display,
165 XRRScreenResources* screen,
166 RROutput output,
167 RRCrtc* crtc,
168 RRMode* mode,
169 int* height) {
170 XRROutputInfo* output_info = XRRGetOutputInfo(display, screen, output);
171 CHECK(output_info != NULL);
172 *crtc = output_info->crtc;
173 XRRCrtcInfo* crtc_info = XRRGetCrtcInfo(display, screen, *crtc);
174 if (crtc_info != NULL) {
175 *mode = crtc_info->mode;
176 *height = crtc_info->height;
177 XRRFreeCrtcInfo(crtc_info);
178 }
179 XRRFreeOutputInfo(output_info);
180 }
161 } // namespace 181 } // namespace
162 182
163 bool OutputConfigurator::TryRecacheOutputs(Display* display, 183 bool OutputConfigurator::TryRecacheOutputs(Display* display,
164 XRRScreenResources* screen) { 184 XRRScreenResources* screen) {
165 bool outputs_did_change = false; 185 bool outputs_did_change = false;
166 int previous_connected_count = 0; 186 int previous_connected_count = 0;
167 int new_connected_count = 0; 187 int new_connected_count = 0;
168 188
169 if (output_count_ != screen->noutput) { 189 if (output_count_ != screen->noutput) {
170 outputs_did_change = true; 190 outputs_did_change = true;
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 333
314 // Cache the initial output state. 334 // Cache the initial output state.
315 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); 335 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay();
316 CHECK(display != NULL); 336 CHECK(display != NULL);
317 XGrabServer(display); 337 XGrabServer(display);
318 Window window = DefaultRootWindow(display); 338 Window window = DefaultRootWindow(display);
319 XRRScreenResources* screen = XRRGetScreenResources(display, window); 339 XRRScreenResources* screen = XRRGetScreenResources(display, window);
320 CHECK(screen != NULL); 340 CHECK(screen != NULL);
321 bool did_detect_outputs = TryRecacheOutputs(display, screen); 341 bool did_detect_outputs = TryRecacheOutputs(display, screen);
322 CHECK(did_detect_outputs); 342 CHECK(did_detect_outputs);
323 State state = GetDefaultState(); 343 State current_state = InferCurrentState(display, screen);
324 UpdateCacheAndXrandrToState(display, screen, window, state); 344 if (current_state == STATE_INVALID) {
345 // Unknown state. Transition into the default state.
346 State state = GetDefaultState();
347 UpdateCacheAndXrandrToState(display, screen, window, state);
348 } else {
349 // This is a valid state so just save it to |output_state_|.
350 output_state_ = current_state;
351 }
325 // Find xrandr_event_base_ since we need it to interpret events, later. 352 // Find xrandr_event_base_ since we need it to interpret events, later.
326 int error_base_ignored = 0; 353 int error_base_ignored = 0;
327 XRRQueryExtension(display, &xrandr_event_base_, &error_base_ignored); 354 XRRQueryExtension(display, &xrandr_event_base_, &error_base_ignored);
328 // Relinquish X resources. 355 // Relinquish X resources.
329 XRRFreeScreenResources(screen); 356 XRRFreeScreenResources(screen);
330 XUngrabServer(display); 357 XUngrabServer(display);
331 } 358 }
332 } 359 }
333 360
334 OutputConfigurator::~OutputConfigurator() { 361 OutputConfigurator::~OutputConfigurator() {
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 State state = STATE_HEADLESS; 493 State state = STATE_HEADLESS;
467 if (-1 != primary_output_index_) { 494 if (-1 != primary_output_index_) {
468 if (-1 != secondary_output_index_) 495 if (-1 != secondary_output_index_)
469 state = mirror_supported_ ? STATE_DUAL_MIRROR : STATE_DUAL_PRIMARY_ONLY; 496 state = mirror_supported_ ? STATE_DUAL_MIRROR : STATE_DUAL_PRIMARY_ONLY;
470 else 497 else
471 state = STATE_SINGLE; 498 state = STATE_SINGLE;
472 } 499 }
473 return state; 500 return state;
474 } 501 }
475 502
503 State OutputConfigurator::InferCurrentState(Display* display,
504 XRRScreenResources* screen) const {
505 // STATE_INVALID will be our default or "unknown" state.
506 State state = STATE_INVALID;
507 // First step: count the number of connected outputs.
508 if (secondary_output_index_ == -1) {
509 // No secondary display.
510 if (primary_output_index_ == -1) {
511 // No primary display implies HEADLESS.
512 state = STATE_HEADLESS;
513 } else {
514 // The common case of primary-only.
515 // The only sanity check we require in this case is that the current mode
516 // of the output's CRTC is the ideal mode we determined for it.
517 RRCrtc primary_crtc = None;
518 RRMode primary_mode = None;
519 int primary_height = 0;
520 GetOutputConfiguration(display,
521 screen,
522 output_cache_[primary_output_index_].output,
523 &primary_crtc,
524 &primary_mode,
525 &primary_height);
526 if (primary_mode == output_cache_[primary_output_index_].ideal_mode) {
Daniel Erat 2012/06/07 19:17:40 nit: remove curly braces
disher 2012/06/07 19:40:23 Done.
527 state = STATE_SINGLE;
528 }
529 }
530 } else {
531 // We have two displays attached so we need to look at their configuration.
532 // Note that, for simplicity, we will only detect the states that we would
533 // have used and will assume anything unexpected is INVALID (which should
534 // not happen in any expected usage scenario).
535 RRCrtc primary_crtc = None;
536 RRMode primary_mode = None;
537 int primary_height = 0;
538 GetOutputConfiguration(display,
539 screen,
540 output_cache_[primary_output_index_].output,
541 &primary_crtc,
542 &primary_mode,
543 &primary_height);
544 RRCrtc secondary_crtc = None;
545 RRMode secondary_mode = None;
546 int secondary_height = 0;
547 GetOutputConfiguration(display,
548 screen,
549 output_cache_[secondary_output_index_].output,
550 &secondary_crtc,
551 &secondary_mode,
552 &secondary_height);
553 // Make sure the CRTCs are matched to the expected outputs.
554 if ((output_cache_[primary_output_index_].crtc == primary_crtc) &&
555 (output_cache_[secondary_output_index_].crtc == secondary_crtc)) {
556 // Check the mode matching: either both mirror or both ideal.
557 if ((output_cache_[primary_output_index_].mirror_mode == primary_mode) &&
558 (output_cache_[secondary_output_index_].mirror_mode ==
559 secondary_mode)) {
560 // We are already in mirror mode.
561 state = STATE_DUAL_MIRROR;
562 } else if ((output_cache_[primary_output_index_].ideal_mode ==
563 primary_mode) &&
564 (output_cache_[secondary_output_index_].ideal_mode ==
565 secondary_mode)) {
566 // Both outputs are in their "ideal" mode so check their Y-offsets to
567 // see which "ideal" configuration this is.
568 if (primary_height == output_cache_[secondary_output_index_].y) {
569 // Secondary is tiled first.
570 state = STATE_DUAL_SECONDARY_ONLY;
571 } else if (secondary_height == output_cache_[primary_output_index_].y) {
572 // Primary is tiled first.
573 state = STATE_DUAL_PRIMARY_ONLY;
574 }
575 }
576 }
577 }
578
579 return state;
580 }
581
476 bool OutputConfigurator::CycleDisplayMode() { 582 bool OutputConfigurator::CycleDisplayMode() {
477 VLOG(1) << "CycleDisplayMode"; 583 VLOG(1) << "CycleDisplayMode";
478 bool did_change = false; 584 bool did_change = false;
479 if (is_running_on_chrome_os_) { 585 if (is_running_on_chrome_os_) {
480 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); 586 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay();
481 CHECK(display != NULL); 587 CHECK(display != NULL);
482 XGrabServer(display); 588 XGrabServer(display);
483 Window window = DefaultRootWindow(display); 589 Window window = DefaultRootWindow(display);
484 XRRScreenResources* screen = XRRGetScreenResources(display, window); 590 XRRScreenResources* screen = XRRGetScreenResources(display, window);
485 CHECK(screen != NULL); 591 CHECK(screen != NULL);
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 RecacheAndUseDefaultState(); 698 RecacheAndUseDefaultState();
593 } 699 }
594 // Ignore the case of RR_UnkownConnection. 700 // Ignore the case of RR_UnkownConnection.
595 } 701 }
596 } 702 }
597 return true; 703 return true;
598 } 704 }
599 705
600 } // namespace chromeos 706 } // namespace chromeos
601 707
OLDNEW
« no previous file with comments | « chromeos/monitor/output_configurator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698