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 |