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

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: Address nit 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)
527 state = STATE_SINGLE;
528 }
529 } else {
530 // We have two displays attached so we need to look at their configuration.
531 // Note that, for simplicity, we will only detect the states that we would
532 // have used and will assume anything unexpected is INVALID (which should
533 // not happen in any expected usage scenario).
534 RRCrtc primary_crtc = None;
535 RRMode primary_mode = None;
536 int primary_height = 0;
537 GetOutputConfiguration(display,
538 screen,
539 output_cache_[primary_output_index_].output,
540 &primary_crtc,
541 &primary_mode,
542 &primary_height);
543 RRCrtc secondary_crtc = None;
544 RRMode secondary_mode = None;
545 int secondary_height = 0;
546 GetOutputConfiguration(display,
547 screen,
548 output_cache_[secondary_output_index_].output,
549 &secondary_crtc,
550 &secondary_mode,
551 &secondary_height);
552 // Make sure the CRTCs are matched to the expected outputs.
553 if ((output_cache_[primary_output_index_].crtc == primary_crtc) &&
554 (output_cache_[secondary_output_index_].crtc == secondary_crtc)) {
555 // Check the mode matching: either both mirror or both ideal.
556 if ((output_cache_[primary_output_index_].mirror_mode == primary_mode) &&
557 (output_cache_[secondary_output_index_].mirror_mode ==
558 secondary_mode)) {
559 // We are already in mirror mode.
560 state = STATE_DUAL_MIRROR;
561 } else if ((output_cache_[primary_output_index_].ideal_mode ==
562 primary_mode) &&
563 (output_cache_[secondary_output_index_].ideal_mode ==
564 secondary_mode)) {
565 // Both outputs are in their "ideal" mode so check their Y-offsets to
566 // see which "ideal" configuration this is.
567 if (primary_height == output_cache_[secondary_output_index_].y) {
568 // Secondary is tiled first.
569 state = STATE_DUAL_SECONDARY_ONLY;
570 } else if (secondary_height == output_cache_[primary_output_index_].y) {
571 // Primary is tiled first.
572 state = STATE_DUAL_PRIMARY_ONLY;
573 }
574 }
575 }
576 }
577
578 return state;
579 }
580
476 bool OutputConfigurator::CycleDisplayMode() { 581 bool OutputConfigurator::CycleDisplayMode() {
477 VLOG(1) << "CycleDisplayMode"; 582 VLOG(1) << "CycleDisplayMode";
478 bool did_change = false; 583 bool did_change = false;
479 if (is_running_on_chrome_os_) { 584 if (is_running_on_chrome_os_) {
480 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); 585 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay();
481 CHECK(display != NULL); 586 CHECK(display != NULL);
482 XGrabServer(display); 587 XGrabServer(display);
483 Window window = DefaultRootWindow(display); 588 Window window = DefaultRootWindow(display);
484 XRRScreenResources* screen = XRRGetScreenResources(display, window); 589 XRRScreenResources* screen = XRRGetScreenResources(display, window);
485 CHECK(screen != NULL); 590 CHECK(screen != NULL);
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 RecacheAndUseDefaultState(); 697 RecacheAndUseDefaultState();
593 } 698 }
594 // Ignore the case of RR_UnkownConnection. 699 // Ignore the case of RR_UnkownConnection.
595 } 700 }
596 } 701 }
597 return true; 702 return true;
598 } 703 }
599 704
600 } // namespace chromeos 705 } // namespace chromeos
601 706
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