OLD | NEW |
| (Empty) |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "ui/views/mus/screen_mus.h" | |
6 | |
7 #include "mojo/converters/geometry/geometry_type_converters.h" | |
8 #include "mojo/shell/public/cpp/application_connection.h" | |
9 #include "mojo/shell/public/cpp/application_impl.h" | |
10 #include "ui/gfx/display_finder.h" | |
11 #include "ui/gfx/display_observer.h" | |
12 | |
13 namespace mojo { | |
14 | |
15 template <> | |
16 struct TypeConverter<gfx::Display, mus::mojom::DisplayPtr> { | |
17 static gfx::Display Convert(const mus::mojom::DisplayPtr& input) { | |
18 gfx::Display result(input->id, input->bounds.To<gfx::Rect>()); | |
19 result.set_work_area(input->work_area.To<gfx::Rect>()); | |
20 result.set_device_scale_factor(input->device_pixel_ratio); | |
21 switch (input->rotation) { | |
22 case mus::mojom::Rotation::VALUE_0: | |
23 result.set_rotation(gfx::Display::ROTATE_0); | |
24 break; | |
25 case mus::mojom::Rotation::VALUE_90: | |
26 result.set_rotation(gfx::Display::ROTATE_90); | |
27 break; | |
28 case mus::mojom::Rotation::VALUE_180: | |
29 result.set_rotation(gfx::Display::ROTATE_180); | |
30 break; | |
31 case mus::mojom::Rotation::VALUE_270: | |
32 result.set_rotation(gfx::Display::ROTATE_270); | |
33 break; | |
34 } | |
35 switch (input->touch_support) { | |
36 case mus::mojom::TouchSupport::UNKNOWN: | |
37 result.set_touch_support(gfx::Display::TOUCH_SUPPORT_UNKNOWN); | |
38 break; | |
39 case mus::mojom::TouchSupport::AVAILABLE: | |
40 result.set_touch_support(gfx::Display::TOUCH_SUPPORT_AVAILABLE); | |
41 break; | |
42 case mus::mojom::TouchSupport::UNAVAILABLE: | |
43 result.set_touch_support(gfx::Display::TOUCH_SUPPORT_UNAVAILABLE); | |
44 break; | |
45 } | |
46 return result; | |
47 } | |
48 }; | |
49 | |
50 } // namespace mojo | |
51 | |
52 namespace views { | |
53 | |
54 ScreenMus::ScreenMus() | |
55 : primary_display_index_(0), display_manager_observer_binding_(this) {} | |
56 | |
57 ScreenMus::~ScreenMus() {} | |
58 | |
59 void ScreenMus::Init(mojo::ApplicationImpl* app) { | |
60 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, this); | |
61 | |
62 app->ConnectToService("mojo:mus", &display_manager_); | |
63 | |
64 display_manager_->AddObserver( | |
65 display_manager_observer_binding_.CreateInterfacePtrAndBind()); | |
66 // We need the set of displays before we can continue. Wait for it. | |
67 display_manager_observer_binding_.WaitForIncomingMethodCall(); | |
68 | |
69 // The WaitForIncomingMethodCall() should have supplied the set of Displays. | |
70 DCHECK(displays_.size()); | |
71 } | |
72 | |
73 int ScreenMus::FindDisplayIndexById(int64_t id) const { | |
74 for (size_t i = 0; i < displays_.size(); ++i) { | |
75 if (displays_[i].id() == id) | |
76 return static_cast<int>(i); | |
77 } | |
78 return -1; | |
79 } | |
80 | |
81 void ScreenMus::ProcessDisplayChanged(const gfx::Display& changed_display, | |
82 bool is_primary) { | |
83 const int display_index = FindDisplayIndexById(changed_display.id()); | |
84 if (display_index == -1) { | |
85 displays_.push_back(changed_display); | |
86 if (is_primary) | |
87 primary_display_index_ = static_cast<int>(displays_.size()) - 1; | |
88 FOR_EACH_OBSERVER(gfx::DisplayObserver, observers_, | |
89 OnDisplayAdded(changed_display)); | |
90 return; | |
91 } | |
92 | |
93 gfx::Display* local_display = &displays_[display_index]; | |
94 uint32_t changed_values = 0; | |
95 if (is_primary && display_index != primary_display_index_) { | |
96 primary_display_index_ = display_index; | |
97 // ash::DisplayManager only notifies for the Display gaining primary, not | |
98 // the one losing it. | |
99 changed_values |= gfx::DisplayObserver::DISPLAY_METRIC_PRIMARY; | |
100 } | |
101 if (local_display->bounds() != changed_display.bounds()) { | |
102 local_display->set_bounds(changed_display.bounds()); | |
103 changed_values |= gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS; | |
104 } | |
105 if (local_display->work_area() != changed_display.work_area()) { | |
106 local_display->set_work_area(changed_display.work_area()); | |
107 changed_values |= gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA; | |
108 } | |
109 if (local_display->rotation() != changed_display.rotation()) { | |
110 local_display->set_rotation(changed_display.rotation()); | |
111 changed_values |= gfx::DisplayObserver::DISPLAY_METRIC_ROTATION; | |
112 } | |
113 if (local_display->device_scale_factor() != | |
114 changed_display.device_scale_factor()) { | |
115 local_display->set_device_scale_factor( | |
116 changed_display.device_scale_factor()); | |
117 changed_values |= gfx::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR; | |
118 } | |
119 FOR_EACH_OBSERVER(gfx::DisplayObserver, observers_, | |
120 OnDisplayMetricsChanged(*local_display, changed_values)); | |
121 } | |
122 | |
123 gfx::Point ScreenMus::GetCursorScreenPoint() { | |
124 NOTIMPLEMENTED(); | |
125 return gfx::Point(); | |
126 } | |
127 | |
128 gfx::NativeWindow ScreenMus::GetWindowUnderCursor() { | |
129 NOTIMPLEMENTED(); | |
130 return nullptr; | |
131 } | |
132 | |
133 gfx::NativeWindow ScreenMus::GetWindowAtScreenPoint(const gfx::Point& point) { | |
134 NOTIMPLEMENTED(); | |
135 return nullptr; | |
136 } | |
137 | |
138 gfx::Display ScreenMus::GetPrimaryDisplay() const { | |
139 return displays_[primary_display_index_]; | |
140 } | |
141 | |
142 gfx::Display ScreenMus::GetDisplayNearestWindow(gfx::NativeView view) const { | |
143 NOTIMPLEMENTED(); | |
144 return GetPrimaryDisplay(); | |
145 } | |
146 | |
147 gfx::Display ScreenMus::GetDisplayNearestPoint(const gfx::Point& point) const { | |
148 return *gfx::FindDisplayNearestPoint(displays_, point); | |
149 } | |
150 | |
151 int ScreenMus::GetNumDisplays() const { | |
152 return static_cast<int>(displays_.size()); | |
153 } | |
154 | |
155 std::vector<gfx::Display> ScreenMus::GetAllDisplays() const { | |
156 return displays_; | |
157 } | |
158 | |
159 gfx::Display ScreenMus::GetDisplayMatching(const gfx::Rect& match_rect) const { | |
160 const gfx::Display* match = | |
161 gfx::FindDisplayWithBiggestIntersection(displays_, match_rect); | |
162 return match ? *match : GetPrimaryDisplay(); | |
163 } | |
164 | |
165 void ScreenMus::AddObserver(gfx::DisplayObserver* observer) { | |
166 observers_.AddObserver(observer); | |
167 } | |
168 | |
169 void ScreenMus::RemoveObserver(gfx::DisplayObserver* observer) { | |
170 observers_.RemoveObserver(observer); | |
171 } | |
172 | |
173 void ScreenMus::OnDisplays(mojo::Array<mus::mojom::DisplayPtr> displays) { | |
174 // This should only be called once from Init() before any observers have been | |
175 // added. | |
176 DCHECK(displays_.empty()); | |
177 displays_ = displays.To<std::vector<gfx::Display>>(); | |
178 for (size_t i = 0; i < displays.size(); ++i) { | |
179 if (displays[i]->is_primary) | |
180 primary_display_index_ = static_cast<int>(i); | |
181 } | |
182 } | |
183 | |
184 void ScreenMus::OnDisplaysChanged( | |
185 mojo::Array<mus::mojom::DisplayPtr> transport_displays) { | |
186 for (size_t i = 0; i < transport_displays.size(); ++i) { | |
187 const bool is_primary = transport_displays[i]->is_primary; | |
188 ProcessDisplayChanged(transport_displays[i].To<gfx::Display>(), is_primary); | |
189 } | |
190 } | |
191 | |
192 void ScreenMus::OnDisplayRemoved(int64_t id) { | |
193 const int index = FindDisplayIndexById(id); | |
194 DCHECK_NE(-1, index); | |
195 // Another display must become primary before the existing primary is | |
196 // removed. | |
197 DCHECK_NE(index, primary_display_index_); | |
198 const gfx::Display display = displays_[index]; | |
199 FOR_EACH_OBSERVER(gfx::DisplayObserver, observers_, | |
200 OnDisplayRemoved(display)); | |
201 } | |
202 | |
203 } // namespace views | |
OLD | NEW |