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 "ash/display/display_manager.h" | 5 #include "ash/display/display_manager.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <set> | 8 #include <set> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 } | 96 } |
97 | 97 |
98 void MaybeInitInternalDisplay(int64 id) { | 98 void MaybeInitInternalDisplay(int64 id) { |
99 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 99 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
100 if (command_line->HasSwitch(switches::kAshUseFirstDisplayAsInternal)) | 100 if (command_line->HasSwitch(switches::kAshUseFirstDisplayAsInternal)) |
101 gfx::Display::SetInternalDisplayId(id); | 101 gfx::Display::SetInternalDisplayId(id); |
102 } | 102 } |
103 | 103 |
104 // Scoped objects used to either create or close the mirror window | 104 // Scoped objects used to either create or close the mirror window |
105 // at specific timing. | 105 // at specific timing. |
106 class MirrorWindowCreator { | 106 class MirrorWindowUpdater { |
107 public: | 107 public: |
108 MirrorWindowCreator(DisplayManager::Delegate* delegate, | 108 MirrorWindowUpdater(DisplayManager* manager, |
109 const DisplayInfo& display_info) | 109 DisplayManager::Delegate* delegate) |
110 : delegate_(delegate), | 110 : manager_(manager), |
111 display_info_(display_info) { | 111 delegate_(delegate), |
| 112 enabled_(manager_->software_mirroring_enabled() && |
| 113 manager_->mirrored_display().is_valid()) { |
112 } | 114 } |
113 | 115 |
114 virtual ~MirrorWindowCreator() { | 116 ~MirrorWindowUpdater() { |
115 if (delegate_) | 117 if (!delegate_) |
116 delegate_->CreateOrUpdateMirrorWindow(display_info_); | 118 return; |
| 119 |
| 120 if (enabled_) { |
| 121 DisplayInfo display_info = manager_->GetDisplayInfo( |
| 122 manager_->mirrored_display().id()); |
| 123 delegate_->CreateOrUpdateMirrorWindow(display_info); |
| 124 } else { |
| 125 delegate_->CloseMirrorWindow(); |
| 126 } |
117 } | 127 } |
118 | 128 |
119 private: | 129 bool enabled() const { return enabled_; } |
120 DisplayManager::Delegate* delegate_; | |
121 const DisplayInfo display_info_; | |
122 DISALLOW_COPY_AND_ASSIGN(MirrorWindowCreator); | |
123 }; | |
124 | |
125 class MirrorWindowCloser { | |
126 public: | |
127 explicit MirrorWindowCloser(DisplayManager::Delegate* delegate) | |
128 : delegate_(delegate) {} | |
129 | |
130 virtual ~MirrorWindowCloser() { | |
131 if (delegate_) | |
132 delegate_->CloseMirrorWindow(); | |
133 } | |
134 | 130 |
135 private: | 131 private: |
| 132 DisplayManager* manager_; |
136 DisplayManager::Delegate* delegate_; | 133 DisplayManager::Delegate* delegate_; |
137 | 134 bool enabled_; |
138 DISALLOW_COPY_AND_ASSIGN(MirrorWindowCloser); | 135 DISALLOW_COPY_AND_ASSIGN(MirrorWindowUpdater); |
139 }; | 136 }; |
140 | 137 |
141 } // namespace | 138 } // namespace |
142 | 139 |
143 using std::string; | 140 using std::string; |
144 using std::vector; | 141 using std::vector; |
145 | 142 |
146 DisplayManager::DisplayManager() | 143 DisplayManager::DisplayManager() |
147 : delegate_(NULL), | 144 : delegate_(NULL), |
148 layout_store_(new DisplayLayoutStore), | 145 layout_store_(new DisplayLayoutStore), |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 return scales[i - 1]; | 196 return scales[i - 1]; |
200 return scales[i]; | 197 return scales[i]; |
201 } | 198 } |
202 } | 199 } |
203 // Fallback to 1.0f if the |scale| wasn't in the list. | 200 // Fallback to 1.0f if the |scale| wasn't in the list. |
204 return 1.0f; | 201 return 1.0f; |
205 } | 202 } |
206 | 203 |
207 void DisplayManager::InitFromCommandLine() { | 204 void DisplayManager::InitFromCommandLine() { |
208 DisplayInfoList info_list; | 205 DisplayInfoList info_list; |
209 | 206 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
210 const string size_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 207 const string size_str = |
211 switches::kAshHostWindowBounds); | 208 command_line->GetSwitchValueASCII(switches::kAshHostWindowBounds); |
212 vector<string> parts; | 209 vector<string> parts; |
213 base::SplitString(size_str, ',', &parts); | 210 base::SplitString(size_str, ',', &parts); |
214 for (vector<string>::const_iterator iter = parts.begin(); | 211 for (vector<string>::const_iterator iter = parts.begin(); |
215 iter != parts.end(); ++iter) { | 212 iter != parts.end(); ++iter) { |
216 info_list.push_back(DisplayInfo::CreateFromSpec(*iter)); | 213 info_list.push_back(DisplayInfo::CreateFromSpec(*iter)); |
217 } | 214 } |
218 if (info_list.size()) | 215 if (info_list.size()) |
219 MaybeInitInternalDisplay(info_list[0].id()); | 216 MaybeInitInternalDisplay(info_list[0].id()); |
| 217 if (info_list.size() > 1 && |
| 218 command_line->HasSwitch(switches::kAshEnableSoftwareMirroring)) { |
| 219 SetSoftwareMirroring(true); |
| 220 } |
220 OnNativeDisplaysChanged(info_list); | 221 OnNativeDisplaysChanged(info_list); |
221 } | 222 } |
222 | 223 |
223 // static | 224 // static |
224 void DisplayManager::UpdateDisplayBoundsForLayoutById( | 225 void DisplayManager::UpdateDisplayBoundsForLayoutById( |
225 const DisplayLayout& layout, | 226 const DisplayLayout& layout, |
226 const gfx::Display& primary_display, | 227 const gfx::Display& primary_display, |
227 int64 secondary_display_id) { | 228 int64 secondary_display_id) { |
228 DCHECK_NE(gfx::Display::kInvalidDisplayID, secondary_display_id); | 229 DCHECK_NE(gfx::Display::kInvalidDisplayID, secondary_display_id); |
229 UpdateDisplayBoundsForLayout( | 230 UpdateDisplayBoundsForLayout( |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 DisplayInfoSortFunctor()); | 532 DisplayInfoSortFunctor()); |
532 DisplayList removed_displays; | 533 DisplayList removed_displays; |
533 std::vector<size_t> changed_display_indices; | 534 std::vector<size_t> changed_display_indices; |
534 std::vector<size_t> added_display_indices; | 535 std::vector<size_t> added_display_indices; |
535 | 536 |
536 DisplayList::iterator curr_iter = displays_.begin(); | 537 DisplayList::iterator curr_iter = displays_.begin(); |
537 DisplayInfoList::const_iterator new_info_iter = new_display_info_list.begin(); | 538 DisplayInfoList::const_iterator new_info_iter = new_display_info_list.begin(); |
538 | 539 |
539 DisplayList new_displays; | 540 DisplayList new_displays; |
540 | 541 |
541 scoped_ptr<MirrorWindowCreator> mirror_window_creater; | |
542 | |
543 // Use the internal display or 1st as the mirror source, then scale | 542 // Use the internal display or 1st as the mirror source, then scale |
544 // the root window so that it matches the external display's | 543 // the root window so that it matches the external display's |
545 // resolution. This is necessary in order for scaling to work while | 544 // resolution. This is necessary in order for scaling to work while |
546 // mirrored. | 545 // mirrored. |
547 int64 mirrored_display_id = gfx::Display::kInvalidDisplayID; | 546 int64 mirrored_display_id = gfx::Display::kInvalidDisplayID; |
548 if (software_mirroring_enabled_ && new_display_info_list.size() == 2) | 547 if (software_mirroring_enabled_ && new_display_info_list.size() == 2) |
549 mirrored_display_id = new_display_info_list[1].id(); | 548 mirrored_display_id = new_display_info_list[1].id(); |
550 | 549 |
551 while (curr_iter != displays_.end() || | 550 while (curr_iter != displays_.end() || |
552 new_info_iter != new_display_info_list.end()) { | 551 new_info_iter != new_display_info_list.end()) { |
553 if (new_info_iter != new_display_info_list.end() && | 552 if (new_info_iter != new_display_info_list.end() && |
554 mirrored_display_id == new_info_iter->id()) { | 553 mirrored_display_id == new_info_iter->id()) { |
555 DisplayInfo info = *new_info_iter; | 554 DisplayInfo info = *new_info_iter; |
556 info.SetOverscanInsets(gfx::Insets()); | 555 info.SetOverscanInsets(gfx::Insets()); |
557 InsertAndUpdateDisplayInfo(info); | 556 InsertAndUpdateDisplayInfo(info); |
558 | |
559 mirrored_display_ = CreateDisplayFromDisplayInfoById(new_info_iter->id()); | 557 mirrored_display_ = CreateDisplayFromDisplayInfoById(new_info_iter->id()); |
560 mirror_window_creater.reset(new MirrorWindowCreator( | |
561 delegate_, display_info_[new_info_iter->id()])); | |
562 ++new_info_iter; | 558 ++new_info_iter; |
563 // Remove existing external dispaly if it is going to be mirrored. | 559 // Remove existing external dispaly if it is going to be mirrored. |
564 if (curr_iter != displays_.end() && | 560 if (curr_iter != displays_.end() && |
565 curr_iter->id() == mirrored_display_id) { | 561 curr_iter->id() == mirrored_display_id) { |
566 removed_displays.push_back(*curr_iter); | 562 removed_displays.push_back(*curr_iter); |
567 ++curr_iter; | 563 ++curr_iter; |
568 } | 564 } |
569 continue; | 565 continue; |
570 } | 566 } |
571 | 567 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
616 } else { | 612 } else { |
617 // more displays in new list between ids, which means it is added. | 613 // more displays in new list between ids, which means it is added. |
618 added_display_indices.push_back(new_displays.size()); | 614 added_display_indices.push_back(new_displays.size()); |
619 InsertAndUpdateDisplayInfo(*new_info_iter); | 615 InsertAndUpdateDisplayInfo(*new_info_iter); |
620 new_displays.push_back( | 616 new_displays.push_back( |
621 CreateDisplayFromDisplayInfoById(new_info_iter->id())); | 617 CreateDisplayFromDisplayInfoById(new_info_iter->id())); |
622 ++new_info_iter; | 618 ++new_info_iter; |
623 } | 619 } |
624 } | 620 } |
625 | 621 |
626 scoped_ptr<MirrorWindowCloser> mirror_window_closer; | 622 scoped_ptr<MirrorWindowUpdater> mirror_window_updater( |
627 // Try to close mirror window unless mirror window is necessary. | 623 new MirrorWindowUpdater(this, delegate_)); |
628 if (!mirror_window_creater.get()) | |
629 mirror_window_closer.reset(new MirrorWindowCloser(delegate_)); | |
630 | 624 |
631 // Do not update |displays_| if there's nothing to be updated. Without this, | 625 // Do not update |displays_| if there's nothing to be updated. Without this, |
632 // it will not update the display layout, which causes the bug | 626 // it will not update the display layout, which causes the bug |
633 // http://crbug.com/155948. | 627 // http://crbug.com/155948. |
634 if (changed_display_indices.empty() && added_display_indices.empty() && | 628 if (changed_display_indices.empty() && added_display_indices.empty() && |
635 removed_displays.empty()) { | 629 removed_displays.empty()) { |
636 return; | 630 return; |
637 } | 631 } |
638 if (delegate_) | 632 if (delegate_) |
639 delegate_->PreDisplayConfigurationChange(!removed_displays.empty()); | 633 delegate_->PreDisplayConfigurationChange(!removed_displays.empty()); |
(...skipping 18 matching lines...) Expand all Loading... |
658 displays_.insert(displays_.end(), removed_displays.begin(), | 652 displays_.insert(displays_.end(), removed_displays.begin(), |
659 removed_displays.end()); | 653 removed_displays.end()); |
660 | 654 |
661 for (DisplayList::const_reverse_iterator iter = removed_displays.rbegin(); | 655 for (DisplayList::const_reverse_iterator iter = removed_displays.rbegin(); |
662 iter != removed_displays.rend(); ++iter) { | 656 iter != removed_displays.rend(); ++iter) { |
663 Shell::GetInstance()->screen()->NotifyDisplayRemoved(displays_.back()); | 657 Shell::GetInstance()->screen()->NotifyDisplayRemoved(displays_.back()); |
664 displays_.pop_back(); | 658 displays_.pop_back(); |
665 } | 659 } |
666 // Close the mirror window here to avoid creating two compositor on | 660 // Close the mirror window here to avoid creating two compositor on |
667 // one display. | 661 // one display. |
668 mirror_window_closer.reset(); | 662 if (!mirror_window_updater->enabled()) |
| 663 mirror_window_updater.reset(); |
669 for (std::vector<size_t>::iterator iter = added_display_indices.begin(); | 664 for (std::vector<size_t>::iterator iter = added_display_indices.begin(); |
670 iter != added_display_indices.end(); ++iter) { | 665 iter != added_display_indices.end(); ++iter) { |
671 Shell::GetInstance()->screen()->NotifyDisplayAdded(displays_[*iter]); | 666 Shell::GetInstance()->screen()->NotifyDisplayAdded(displays_[*iter]); |
672 } | 667 } |
673 // Create the mirror window after all displays are added so that | 668 // Create the mirror window after all displays are added so that |
674 // it can mirror the display newly added. This can happen when switching | 669 // it can mirror the display newly added. This can happen when switching |
675 // from dock mode to software mirror mode. | 670 // from dock mode to software mirror mode. |
676 mirror_window_creater.reset(); | 671 mirror_window_updater.reset(); |
677 for (std::vector<size_t>::iterator iter = changed_display_indices.begin(); | 672 for (std::vector<size_t>::iterator iter = changed_display_indices.begin(); |
678 iter != changed_display_indices.end(); ++iter) { | 673 iter != changed_display_indices.end(); ++iter) { |
679 Shell::GetInstance()->screen()->NotifyBoundsChanged(displays_[*iter]); | 674 Shell::GetInstance()->screen()->NotifyBoundsChanged(displays_[*iter]); |
680 } | 675 } |
681 if (delegate_) | 676 if (delegate_) |
682 delegate_->PostDisplayConfigurationChange(); | 677 delegate_->PostDisplayConfigurationChange(); |
683 | 678 |
684 #if defined(USE_X11) && defined(OS_CHROMEOS) | 679 #if defined(USE_X11) && defined(OS_CHROMEOS) |
685 if (!changed_display_indices.empty() && base::chromeos::IsRunningOnChromeOS()) | 680 if (!changed_display_indices.empty() && base::chromeos::IsRunningOnChromeOS()) |
686 ui::ClearX11DefaultRootWindow(); | 681 ui::ClearX11DefaultRootWindow(); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 if (software_mirroring_enabled_ && mirrored_display_.id() == display_id) | 805 if (software_mirroring_enabled_ && mirrored_display_.id() == display_id) |
811 return false; | 806 return false; |
812 gfx::Display* display = FindDisplayForId(display_id); | 807 gfx::Display* display = FindDisplayForId(display_id); |
813 display->SetSize(display_info_[display_id].size_in_pixel()); | 808 display->SetSize(display_info_[display_id].size_in_pixel()); |
814 Shell::GetInstance()->screen()->NotifyBoundsChanged(*display); | 809 Shell::GetInstance()->screen()->NotifyBoundsChanged(*display); |
815 return true; | 810 return true; |
816 } | 811 } |
817 return false; | 812 return false; |
818 } | 813 } |
819 | 814 |
| 815 void DisplayManager::CreateMirrorWindowIfAny() { |
| 816 MirrorWindowUpdater updater(this, delegate_); |
| 817 } |
| 818 |
820 gfx::Display* DisplayManager::FindDisplayForId(int64 id) { | 819 gfx::Display* DisplayManager::FindDisplayForId(int64 id) { |
821 for (DisplayList::iterator iter = displays_.begin(); | 820 for (DisplayList::iterator iter = displays_.begin(); |
822 iter != displays_.end(); ++iter) { | 821 iter != displays_.end(); ++iter) { |
823 if ((*iter).id() == id) | 822 if ((*iter).id() == id) |
824 return &(*iter); | 823 return &(*iter); |
825 } | 824 } |
826 DLOG(WARNING) << "Could not find display:" << id; | 825 DLOG(WARNING) << "Could not find display:" << id; |
827 return NULL; | 826 return NULL; |
828 } | 827 } |
829 | 828 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
893 gfx::Rect bounds = | 892 gfx::Rect bounds = |
894 GetDisplayForId(displays->at(secondary_index).id()).bounds(); | 893 GetDisplayForId(displays->at(secondary_index).id()).bounds(); |
895 UpdateDisplayBoundsForLayout( | 894 UpdateDisplayBoundsForLayout( |
896 layout, displays->at(primary_index), &displays->at(secondary_index)); | 895 layout, displays->at(primary_index), &displays->at(secondary_index)); |
897 *updated_index = secondary_index; | 896 *updated_index = secondary_index; |
898 return bounds != displays->at(secondary_index).bounds(); | 897 return bounds != displays->at(secondary_index).bounds(); |
899 } | 898 } |
900 return false; | 899 return false; |
901 } | 900 } |
902 | 901 |
| 902 |
903 // static | 903 // static |
904 void DisplayManager::UpdateDisplayBoundsForLayout( | 904 void DisplayManager::UpdateDisplayBoundsForLayout( |
905 const DisplayLayout& layout, | 905 const DisplayLayout& layout, |
906 const gfx::Display& primary_display, | 906 const gfx::Display& primary_display, |
907 gfx::Display* secondary_display) { | 907 gfx::Display* secondary_display) { |
908 DCHECK_EQ("0,0", primary_display.bounds().origin().ToString()); | 908 DCHECK_EQ("0,0", primary_display.bounds().origin().ToString()); |
909 | 909 |
910 const gfx::Rect& primary_bounds = primary_display.bounds(); | 910 const gfx::Rect& primary_bounds = primary_display.bounds(); |
911 const gfx::Rect& secondary_bounds = secondary_display->bounds(); | 911 const gfx::Rect& secondary_bounds = secondary_display->bounds(); |
912 gfx::Point new_secondary_origin = primary_bounds.origin(); | 912 gfx::Point new_secondary_origin = primary_bounds.origin(); |
(...skipping 29 matching lines...) Expand all Loading... |
942 break; | 942 break; |
943 } | 943 } |
944 gfx::Insets insets = secondary_display->GetWorkAreaInsets(); | 944 gfx::Insets insets = secondary_display->GetWorkAreaInsets(); |
945 secondary_display->set_bounds( | 945 secondary_display->set_bounds( |
946 gfx::Rect(new_secondary_origin, secondary_bounds.size())); | 946 gfx::Rect(new_secondary_origin, secondary_bounds.size())); |
947 secondary_display->UpdateWorkAreaFromInsets(insets); | 947 secondary_display->UpdateWorkAreaFromInsets(insets); |
948 } | 948 } |
949 | 949 |
950 } // namespace internal | 950 } // namespace internal |
951 } // namespace ash | 951 } // namespace ash |
OLD | NEW |