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

Side by Side Diff: ash/display/display_controller.cc

Issue 12746002: Re-implement overscan & Implement Display Rotation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 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
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 "ash/display/display_controller.h" 5 #include "ash/display/display_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "ash/ash_switches.h" 9 #include "ash/ash_switches.h"
10 #include "ash/display/display_manager.h" 10 #include "ash/display/display_manager.h"
(...skipping 18 matching lines...) Expand all
29 29
30 #if defined(OS_CHROMEOS) 30 #if defined(OS_CHROMEOS)
31 #include "ash/display/output_configurator_animation.h" 31 #include "ash/display/output_configurator_animation.h"
32 #include "base/chromeos/chromeos_version.h" 32 #include "base/chromeos/chromeos_version.h"
33 #include "base/string_number_conversions.h" 33 #include "base/string_number_conversions.h"
34 #include "base/time.h" 34 #include "base/time.h"
35 #include "chromeos/display/output_configurator.h" 35 #include "chromeos/display/output_configurator.h"
36 #include "ui/base/x/x11_util.h" 36 #include "ui/base/x/x11_util.h"
37 #endif // defined(OS_CHROMEOS) 37 #endif // defined(OS_CHROMEOS)
38 38
39
40 namespace ash { 39 namespace ash {
41 namespace { 40 namespace {
42 41
43 // Primary display stored in global object as it can be 42 // Primary display stored in global object as it can be
44 // accessed after Shell is deleted. A separate display instance is created 43 // accessed after Shell is deleted. A separate display instance is created
45 // during the shutdown instead of always keeping two display instances 44 // during the shutdown instead of always keeping two display instances
46 // (one here and another one in display_manager) in sync, which is error prone. 45 // (one here and another one in display_manager) in sync, which is error prone.
47 int64 primary_display_id = gfx::Display::kInvalidDisplayID; 46 int64 primary_display_id = gfx::Display::kInvalidDisplayID;
48 gfx::Display* primary_display_for_shutdown = NULL; 47 gfx::Display* primary_display_for_shutdown = NULL;
49 // Keeps the number of displays during the shutdown after 48 // Keeps the number of displays during the shutdown after
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 case DisplayLayout::LEFT: 97 case DisplayLayout::LEFT:
99 return std::string("left"); 98 return std::string("left");
100 } 99 }
101 return std::string("unknown"); 100 return std::string("unknown");
102 } 101 }
103 102
104 internal::DisplayManager* GetDisplayManager() { 103 internal::DisplayManager* GetDisplayManager() {
105 return Shell::GetInstance()->display_manager(); 104 return Shell::GetInstance()->display_manager();
106 } 105 }
107 106
107 void RotateRootWindow(aura::RootWindow* root_window,
108 const gfx::Display& display,
109 const internal::DisplayInfo& info) {
110 // TODO(oshima): Add animation. (crossfade+rotation, or just cross-fade)
111 gfx::Transform rotate;
112 gfx::Transform translate;
113 switch (info.rotation()) {
114 case internal::DisplayInfo::Rotate0:
115 break;
116 case internal::DisplayInfo::Rotate90:
117 rotate.Rotate(90);
118 translate.Translate(display.bounds().height(), 0);
119 break;
120 case internal::DisplayInfo::Rotate270:
121 rotate.Rotate(270);
122 translate.Translate(0, display.bounds().width());
123 break;
124 case internal::DisplayInfo::Rotate180:
125 rotate.Rotate(180);
126 translate.Translate(display.bounds().width(), display.bounds().height());
127 break;
128 }
129 root_window->SetTransform(translate* rotate);
130 }
131
108 void SetDisplayPropertiesOnHostWindow(aura::RootWindow* root, 132 void SetDisplayPropertiesOnHostWindow(aura::RootWindow* root,
109 const gfx::Display& display) { 133 const gfx::Display& display) {
110 #if defined(OS_CHROMEOS) 134 #if defined(OS_CHROMEOS)
111 // Native window property (Atom in X11) that specifies the display's 135 // Native window property (Atom in X11) that specifies the display's
112 // rotation and scale factor. They are read and used by 136 // rotation and scale factor. They are read and used by
113 // touchpad/mouse driver directly on X (contact adlr@ for more 137 // touchpad/mouse driver directly on X (contact adlr@ for more
114 // details on touchpad/mouse driver side). The value of the rotation 138 // details on touchpad/mouse driver side). The value of the rotation
115 // is one of 0 (normal), 1 (90 degrees clockwise), 2 (180 degree) or 139 // is one of 0 (normal), 1 (90 degrees clockwise), 2 (180 degree) or
116 // 3 (270 degrees clockwise). The value of the scale factor is in 140 // 3 (270 degrees clockwise). The value of the scale factor is in
117 // percent (100, 140, 200 etc). 141 // percent (100, 140, 200 etc).
(...skipping 12 matching lines...) Expand all
130 if (rotation < 0 || rotation > 3) 154 if (rotation < 0 || rotation > 3)
131 rotation = 0; 155 rotation = 0;
132 } 156 }
133 gfx::AcceleratedWidget xwindow = root->GetAcceleratedWidget(); 157 gfx::AcceleratedWidget xwindow = root->GetAcceleratedWidget();
134 ui::SetIntProperty(xwindow, kRotationProp, kCARDINAL, rotation); 158 ui::SetIntProperty(xwindow, kRotationProp, kCARDINAL, rotation);
135 ui::SetIntProperty(xwindow, 159 ui::SetIntProperty(xwindow,
136 kScaleFactorProp, 160 kScaleFactorProp,
137 kCARDINAL, 161 kCARDINAL,
138 100 * display.device_scale_factor()); 162 100 * display.device_scale_factor());
139 #endif 163 #endif
164 RotateRootWindow(root, display, GetDisplayManager()->GetDisplayInfo(display));
140 } 165 }
141 166
142 } // namespace 167 } // namespace
143 168
144 //////////////////////////////////////////////////////////////////////////////// 169 ////////////////////////////////////////////////////////////////////////////////
145 // DisplayLayout 170 // DisplayLayout
146 171
147 DisplayLayout::DisplayLayout() 172 DisplayLayout::DisplayLayout()
148 : position(RIGHT), 173 : position(RIGHT),
149 offset(0) {} 174 offset(0) {}
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 bool DisplayController::DisplayChangeLimiter::IsThrottled() const { 255 bool DisplayController::DisplayChangeLimiter::IsThrottled() const {
231 return base::Time::Now() < throttle_timeout_; 256 return base::Time::Now() < throttle_timeout_;
232 } 257 }
233 258
234 //////////////////////////////////////////////////////////////////////////////// 259 ////////////////////////////////////////////////////////////////////////////////
235 // DisplayController 260 // DisplayController
236 261
237 DisplayController::DisplayController() 262 DisplayController::DisplayController()
238 : desired_primary_display_id_(gfx::Display::kInvalidDisplayID), 263 : desired_primary_display_id_(gfx::Display::kInvalidDisplayID),
239 primary_root_window_for_replace_(NULL) { 264 primary_root_window_for_replace_(NULL) {
265 CommandLine* command_line = CommandLine::ForCurrentProcess();
240 #if defined(OS_CHROMEOS) 266 #if defined(OS_CHROMEOS)
241 CommandLine* command_line = CommandLine::ForCurrentProcess();
242 if (!command_line->HasSwitch(switches::kAshDisableDisplayChangeLimiter) && 267 if (!command_line->HasSwitch(switches::kAshDisableDisplayChangeLimiter) &&
243 base::chromeos::IsRunningOnChromeOS()) 268 base::chromeos::IsRunningOnChromeOS())
244 limiter_.reset(new DisplayChangeLimiter); 269 limiter_.reset(new DisplayChangeLimiter);
245 #endif 270 #endif
271 if (command_line->HasSwitch(switches::kAshSecondaryDisplayLayout)) {
272 std::string value = command_line->GetSwitchValueASCII(
273 switches::kAshSecondaryDisplayLayout);
274 char layout;
275 int offset = 0;
276 if (sscanf(value.c_str(), "%c,%d", &layout, &offset) == 2) {
277 if (layout == 't')
278 default_display_layout_.position = DisplayLayout::TOP;
279 else if (layout == 'b')
280 default_display_layout_.position = DisplayLayout::BOTTOM;
281 else if (layout == 'r')
282 default_display_layout_.position = DisplayLayout::RIGHT;
283 else if (layout == 'l')
284 default_display_layout_.position = DisplayLayout::LEFT;
285 default_display_layout_.offset = offset;
286 }
287 }
246 // Reset primary display to make sure that tests don't use 288 // Reset primary display to make sure that tests don't use
247 // stale display info from previous tests. 289 // stale display info from previous tests.
248 primary_display_id = gfx::Display::kInvalidDisplayID; 290 primary_display_id = gfx::Display::kInvalidDisplayID;
249 delete primary_display_for_shutdown; 291 delete primary_display_for_shutdown;
250 primary_display_for_shutdown = NULL; 292 primary_display_for_shutdown = NULL;
251 num_displays_for_shutdown = -1; 293 num_displays_for_shutdown = -1;
252 294
253 Shell::GetScreen()->AddObserver(this); 295 Shell::GetScreen()->AddObserver(this);
254 } 296 }
255 297
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 347
306 void DisplayController::InitSecondaryDisplays() { 348 void DisplayController::InitSecondaryDisplays() {
307 internal::DisplayManager* display_manager = GetDisplayManager(); 349 internal::DisplayManager* display_manager = GetDisplayManager();
308 for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) { 350 for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
309 const gfx::Display* display = display_manager->GetDisplayAt(i); 351 const gfx::Display* display = display_manager->GetDisplayAt(i);
310 if (primary_display_id != display->id()) { 352 if (primary_display_id != display->id()) {
311 aura::RootWindow* root = AddRootWindowForDisplay(*display); 353 aura::RootWindow* root = AddRootWindowForDisplay(*display);
312 Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root); 354 Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root);
313 } 355 }
314 } 356 }
315 CommandLine* command_line = CommandLine::ForCurrentProcess();
316 if (command_line->HasSwitch(switches::kAshSecondaryDisplayLayout)) {
317 std::string value = command_line->GetSwitchValueASCII(
318 switches::kAshSecondaryDisplayLayout);
319 char layout;
320 int offset;
321 if (sscanf(value.c_str(), "%c,%d", &layout, &offset) == 2) {
322 if (layout == 't')
323 default_display_layout_.position = DisplayLayout::TOP;
324 else if (layout == 'b')
325 default_display_layout_.position = DisplayLayout::BOTTOM;
326 else if (layout == 'r')
327 default_display_layout_.position = DisplayLayout::RIGHT;
328 else if (layout == 'l')
329 default_display_layout_.position = DisplayLayout::LEFT;
330 default_display_layout_.offset = offset;
331 }
332 }
333 UpdateDisplayBoundsForLayout(); 357 UpdateDisplayBoundsForLayout();
334 } 358 }
335 359
336 void DisplayController::AddObserver(Observer* observer) { 360 void DisplayController::AddObserver(Observer* observer) {
337 observers_.AddObserver(observer); 361 observers_.AddObserver(observer);
338 } 362 }
339 363
340 void DisplayController::RemoveObserver(Observer* observer) { 364 void DisplayController::RemoveObserver(Observer* observer) {
341 observers_.RemoveObserver(observer); 365 observers_.RemoveObserver(observer);
342 } 366 }
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 gfx::Display* DisplayController::GetSecondaryDisplay() { 625 gfx::Display* DisplayController::GetSecondaryDisplay() {
602 internal::DisplayManager* display_manager = GetDisplayManager(); 626 internal::DisplayManager* display_manager = GetDisplayManager();
603 CHECK_EQ(2U, display_manager->GetNumDisplays()); 627 CHECK_EQ(2U, display_manager->GetNumDisplays());
604 return display_manager->GetDisplayAt(0)->id() == primary_display_id ? 628 return display_manager->GetDisplayAt(0)->id() == primary_display_id ?
605 display_manager->GetDisplayAt(1) : display_manager->GetDisplayAt(0); 629 display_manager->GetDisplayAt(1) : display_manager->GetDisplayAt(0);
606 } 630 }
607 631
608 void DisplayController::OnDisplayBoundsChanged(const gfx::Display& display) { 632 void DisplayController::OnDisplayBoundsChanged(const gfx::Display& display) {
609 if (limiter_.get()) 633 if (limiter_.get())
610 limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs); 634 limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs);
611 DCHECK(!GetDisplayManager()->GetDisplayInfo(display). 635 const internal::DisplayInfo& display_info =
612 bounds_in_pixel().IsEmpty()); 636 GetDisplayManager()->GetDisplayInfo(display);
637 DCHECK(!display_info.bounds_in_pixel().IsEmpty());
613 638
614 NotifyDisplayConfigurationChanging(); 639 NotifyDisplayConfigurationChanging();
615 UpdateDisplayBoundsForLayout(); 640 UpdateDisplayBoundsForLayout();
616 aura::RootWindow* root = root_windows_[display.id()]; 641 aura::RootWindow* root = root_windows_[display.id()];
642 root->SetHostBoundsAndInsets(display_info.bounds_in_pixel(),
643 display_info.GetOverscanInsetsInPixel());
617 SetDisplayPropertiesOnHostWindow(root, display); 644 SetDisplayPropertiesOnHostWindow(root, display);
618 root->SetHostBounds(
619 GetDisplayManager()->GetDisplayInfo(display).bounds_in_pixel());
620 } 645 }
621 646
622 void DisplayController::OnDisplayAdded(const gfx::Display& display) { 647 void DisplayController::OnDisplayAdded(const gfx::Display& display) {
623 if (limiter_.get()) 648 if (limiter_.get())
624 limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs); 649 limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs);
625 650
626 NotifyDisplayConfigurationChanging(); 651 NotifyDisplayConfigurationChanging();
627 if (primary_root_window_for_replace_) { 652 if (primary_root_window_for_replace_) {
628 DCHECK(root_windows_.empty()); 653 DCHECK(root_windows_.empty());
629 primary_display_id = display.id(); 654 primary_display_id = display.id();
630 root_windows_[display.id()] = primary_root_window_for_replace_; 655 root_windows_[display.id()] = primary_root_window_for_replace_;
631 primary_root_window_for_replace_->SetProperty( 656 primary_root_window_for_replace_->SetProperty(
632 internal::kDisplayIdKey, display.id()); 657 internal::kDisplayIdKey, display.id());
633 primary_root_window_for_replace_ = NULL; 658 primary_root_window_for_replace_ = NULL;
634 UpdateDisplayBoundsForLayout(); 659 UpdateDisplayBoundsForLayout();
635 root_windows_[display.id()]->SetHostBounds( 660 const internal::DisplayInfo& display_info =
636 GetDisplayManager()->GetDisplayInfo(display).bounds_in_pixel()); 661 GetDisplayManager()->GetDisplayInfo(display);
662 root_windows_[display.id()]->SetHostBoundsAndInsets(
663 display_info.bounds_in_pixel(),
664 display_info.GetOverscanInsetsInPixel());
637 } else { 665 } else {
638 DCHECK(!root_windows_.empty()); 666 DCHECK(!root_windows_.empty());
639 aura::RootWindow* root = AddRootWindowForDisplay(display); 667 aura::RootWindow* root = AddRootWindowForDisplay(display);
640 UpdateDisplayBoundsForLayout(); 668 UpdateDisplayBoundsForLayout();
641 if (desired_primary_display_id_ == display.id()) 669 if (desired_primary_display_id_ == display.id())
642 SetPrimaryDisplay(display); 670 SetPrimaryDisplay(display);
643 Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root); 671 Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root);
644 } 672 }
645 } 673 }
646 674
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 switches::kAshConstrainPointerToRoot); 732 switches::kAshConstrainPointerToRoot);
705 if (base::chromeos::IsRunningOnChromeOS() || force_constrain_pointer_to_root) 733 if (base::chromeos::IsRunningOnChromeOS() || force_constrain_pointer_to_root)
706 root->ConfineCursorToWindow(); 734 root->ConfineCursorToWindow();
707 #endif 735 #endif
708 return root; 736 return root;
709 } 737 }
710 738
711 void DisplayController::UpdateDisplayBoundsForLayout() { 739 void DisplayController::UpdateDisplayBoundsForLayout() {
712 if (Shell::GetScreen()->GetNumDisplays() <= 1) 740 if (Shell::GetScreen()->GetNumDisplays() <= 1)
713 return; 741 return;
714
715 DCHECK_EQ(2, Shell::GetScreen()->GetNumDisplays()); 742 DCHECK_EQ(2, Shell::GetScreen()->GetNumDisplays());
716 const gfx::Rect& primary_bounds = GetPrimaryDisplay().bounds(); 743 const gfx::Rect& primary_bounds = GetPrimaryDisplay().bounds();
717 744
718 gfx::Display* secondary_display = GetSecondaryDisplay(); 745 gfx::Display* secondary_display = GetSecondaryDisplay();
719 const gfx::Rect& secondary_bounds = secondary_display->bounds(); 746 const gfx::Rect& secondary_bounds = secondary_display->bounds();
720 gfx::Point new_secondary_origin = primary_bounds.origin(); 747 gfx::Point new_secondary_origin = primary_bounds.origin();
721 748
722 const DisplayLayout layout = GetCurrentDisplayLayout(); 749 const DisplayLayout layout = GetCurrentDisplayLayout();
723 DisplayLayout::Position position = layout.position; 750 DisplayLayout::Position position = layout.position;
724 751
(...skipping 18 matching lines...) Expand all
743 case DisplayLayout::RIGHT: 770 case DisplayLayout::RIGHT:
744 new_secondary_origin.Offset(primary_bounds.width(), offset); 771 new_secondary_origin.Offset(primary_bounds.width(), offset);
745 break; 772 break;
746 case DisplayLayout::BOTTOM: 773 case DisplayLayout::BOTTOM:
747 new_secondary_origin.Offset(offset, primary_bounds.height()); 774 new_secondary_origin.Offset(offset, primary_bounds.height());
748 break; 775 break;
749 case DisplayLayout::LEFT: 776 case DisplayLayout::LEFT:
750 new_secondary_origin.Offset(-secondary_bounds.width(), offset); 777 new_secondary_origin.Offset(-secondary_bounds.width(), offset);
751 break; 778 break;
752 } 779 }
780
753 gfx::Insets insets = secondary_display->GetWorkAreaInsets(); 781 gfx::Insets insets = secondary_display->GetWorkAreaInsets();
754 secondary_display->set_bounds( 782 secondary_display->set_bounds(
755 gfx::Rect(new_secondary_origin, secondary_bounds.size())); 783 gfx::Rect(new_secondary_origin, secondary_bounds.size()));
756 secondary_display->UpdateWorkAreaFromInsets(insets); 784 secondary_display->UpdateWorkAreaFromInsets(insets);
757 } 785 }
758 786
759 void DisplayController::NotifyDisplayConfigurationChanging() { 787 void DisplayController::NotifyDisplayConfigurationChanging() {
760 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanging()); 788 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanging());
761 } 789 }
762 790
763 void DisplayController::RegisterLayoutForDisplayIdPairInternal( 791 void DisplayController::RegisterLayoutForDisplayIdPairInternal(
764 int64 id1, 792 int64 id1,
765 int64 id2, 793 int64 id2,
766 const DisplayLayout& layout, 794 const DisplayLayout& layout,
767 bool override) { 795 bool override) {
768 DisplayIdPair pair; 796 DisplayIdPair pair;
769 pair.first = id1; 797 pair.first = id1;
770 pair.second = id2; 798 pair.second = id2;
771 if (override || paired_layouts_.find(pair) == paired_layouts_.end()) 799 if (override || paired_layouts_.find(pair) == paired_layouts_.end())
772 paired_layouts_[pair] = layout; 800 paired_layouts_[pair] = layout;
773 } 801 }
774 802
775 } // namespace ash 803 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698