OLD | NEW |
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/display/output_configurator.h" | 5 #include "chromeos/display/output_configurator.h" |
6 | 6 |
7 #include <X11/Xlib.h> | 7 #include <X11/Xlib.h> |
8 #include <X11/extensions/dpms.h> | 8 #include <X11/extensions/dpms.h> |
9 #include <X11/extensions/Xrandr.h> | 9 #include <X11/extensions/Xrandr.h> |
10 | 10 |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 output_state_ == STATE_SINGLE) | 387 output_state_ == STATE_SINGLE) |
388 return false; | 388 return false; |
389 | 389 |
390 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); | 390 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); |
391 CHECK(display != NULL); | 391 CHECK(display != NULL); |
392 XGrabServer(display); | 392 XGrabServer(display); |
393 Window window = DefaultRootWindow(display); | 393 Window window = DefaultRootWindow(display); |
394 XRRScreenResources* screen = XRRGetScreenResources(display, window); | 394 XRRScreenResources* screen = XRRGetScreenResources(display, window); |
395 CHECK(screen != NULL); | 395 CHECK(screen != NULL); |
396 | 396 |
| 397 // We are about to act on the cached output data but it could be stale so |
| 398 // force the outputs to be recached. |
| 399 ForceRecacheOutputs(display, screen); |
397 UpdateCacheAndXrandrToState(display, | 400 UpdateCacheAndXrandrToState(display, |
398 screen, | 401 screen, |
399 window, | 402 window, |
400 new_state); | 403 new_state); |
401 XRRFreeScreenResources(screen); | 404 XRRFreeScreenResources(screen); |
402 XUngrabServer(display); | 405 XUngrabServer(display); |
403 | 406 |
404 MessageLoop::current()->PostTask( | 407 MessageLoop::current()->PostTask( |
405 FROM_HERE, base::Bind(&OutputConfigurator::NotifyOnDisplayChanged, | 408 FROM_HERE, base::Bind(&OutputConfigurator::NotifyOnDisplayChanged, |
406 base::Unretained(this))); | 409 base::Unretained(this))); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 outputs_did_change = (now_connected != output_cache_[i].is_connected); | 459 outputs_did_change = (now_connected != output_cache_[i].is_connected); |
457 XRRFreeOutputInfo(output); | 460 XRRFreeOutputInfo(output); |
458 | 461 |
459 if (output_cache_[i].is_connected) | 462 if (output_cache_[i].is_connected) |
460 previous_connected_count += 1; | 463 previous_connected_count += 1; |
461 if (now_connected) | 464 if (now_connected) |
462 new_connected_count += 1; | 465 new_connected_count += 1; |
463 } | 466 } |
464 } | 467 } |
465 | 468 |
466 if (!outputs_did_change) | 469 if (outputs_did_change) { |
467 return false; | 470 // We now know that we need to recache so free and re-alloc the buffer. |
468 // We now know that we need to recache so free and re-alloc the buffer. | 471 ForceRecacheOutputs(display, screen); |
| 472 } |
| 473 return outputs_did_change; |
| 474 } |
| 475 |
| 476 void OutputConfigurator::ForceRecacheOutputs(Display* display, |
| 477 XRRScreenResources* screen) { |
469 output_count_ = screen->noutput; | 478 output_count_ = screen->noutput; |
470 if (output_count_ == 0) { | 479 if (output_count_ == 0) { |
471 output_cache_.reset(NULL); | 480 output_cache_.reset(NULL); |
472 } else { | 481 } else { |
473 // Ideally, this would be allocated inline in the OutputConfigurator | 482 // Ideally, this would be allocated inline in the OutputConfigurator |
474 // instance since we support at most 2 connected outputs but this dynamic | 483 // instance since we support at most 2 connected outputs but this dynamic |
475 // allocation was specifically requested. | 484 // allocation was specifically requested. |
476 output_cache_.reset(new CachedOutputDescription[output_count_]); | 485 output_cache_.reset(new CachedOutputDescription[output_count_]); |
477 } | 486 } |
478 | 487 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
563 output_cache_[secondary_output_index_].output, | 572 output_cache_[secondary_output_index_].output, |
564 &output_cache_[primary_output_index_].mirror_mode, | 573 &output_cache_[primary_output_index_].mirror_mode, |
565 &output_cache_[secondary_output_index_].mirror_mode); | 574 &output_cache_[secondary_output_index_].mirror_mode); |
566 | 575 |
567 RRMode primary_mode = output_cache_[primary_output_index_].mirror_mode; | 576 RRMode primary_mode = output_cache_[primary_output_index_].mirror_mode; |
568 RRMode second_mode = output_cache_[secondary_output_index_].mirror_mode; | 577 RRMode second_mode = output_cache_[secondary_output_index_].mirror_mode; |
569 VLOG(1) << "Mirror mode supported " << mirror_supported_ | 578 VLOG(1) << "Mirror mode supported " << mirror_supported_ |
570 << " primary " << primary_mode | 579 << " primary " << primary_mode |
571 << " secondary " << second_mode; | 580 << " secondary " << second_mode; |
572 } | 581 } |
573 return outputs_did_change; | |
574 } | 582 } |
575 | 583 |
576 void OutputConfigurator::UpdateCacheAndXrandrToState( | 584 void OutputConfigurator::UpdateCacheAndXrandrToState( |
577 Display* display, | 585 Display* display, |
578 XRRScreenResources* screen, | 586 XRRScreenResources* screen, |
579 Window window, | 587 Window window, |
580 OutputState new_state) { | 588 OutputState new_state) { |
581 // Default rules: | 589 // Default rules: |
582 // - single display = rebuild framebuffer and set to ideal_mode. | 590 // - single display = rebuild framebuffer and set to ideal_mode. |
583 // - multi display = rebuild framebuffer and set to mirror_mode. | 591 // - multi display = rebuild framebuffer and set to mirror_mode. |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
855 &method_call, | 863 &method_call, |
856 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | 864 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
857 dbus::ObjectProxy::EmptyResponseCallback()); | 865 dbus::ObjectProxy::EmptyResponseCallback()); |
858 } | 866 } |
859 | 867 |
860 void OutputConfigurator::NotifyOnDisplayChanged() { | 868 void OutputConfigurator::NotifyOnDisplayChanged() { |
861 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChanged()); | 869 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChanged()); |
862 } | 870 } |
863 | 871 |
864 } // namespace chromeos | 872 } // namespace chromeos |
OLD | NEW |