| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "services/ui/ws/platform_display.h" | 5 #include "services/ui/ws/platform_display.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include "base/memory/ptr_util.h" |
| 8 | 8 #include "services/ui/ws/platform_display_default.h" |
| 9 #include "base/numerics/safe_conversions.h" | |
| 10 #include "build/build_config.h" | |
| 11 #include "cc/ipc/quads.mojom.h" | |
| 12 #include "cc/output/copy_output_request.h" | |
| 13 #include "cc/output/delegated_frame_data.h" | |
| 14 #include "gpu/ipc/client/gpu_channel_host.h" | |
| 15 #include "services/service_manager/public/cpp/connection.h" | |
| 16 #include "services/service_manager/public/cpp/connector.h" | |
| 17 #include "services/ui/display/platform_screen.h" | |
| 18 #include "services/ui/surfaces/display_compositor.h" | |
| 19 #include "services/ui/ws/platform_display_factory.h" | 9 #include "services/ui/ws/platform_display_factory.h" |
| 20 #include "services/ui/ws/platform_display_init_params.h" | 10 #include "services/ui/ws/platform_display_init_params.h" |
| 21 #include "services/ui/ws/server_window.h" | |
| 22 #include "services/ui/ws/window_coordinate_conversions.h" | |
| 23 #include "third_party/skia/include/core/SkXfermode.h" | |
| 24 #include "ui/base/cursor/cursor_loader.h" | |
| 25 #include "ui/display/display.h" | |
| 26 #include "ui/events/event.h" | |
| 27 #include "ui/events/event_utils.h" | |
| 28 #include "ui/platform_window/platform_ime_controller.h" | |
| 29 #include "ui/platform_window/platform_window.h" | |
| 30 | |
| 31 #if defined(OS_WIN) | |
| 32 #include "ui/platform_window/win/win_window.h" | |
| 33 #elif defined(USE_X11) | |
| 34 #include "ui/platform_window/x11/x11_window.h" | |
| 35 #elif defined(OS_ANDROID) | |
| 36 #include "ui/platform_window/android/platform_window_android.h" | |
| 37 #elif defined(USE_OZONE) | |
| 38 #include "ui/ozone/public/ozone_platform.h" | |
| 39 #endif | |
| 40 | 11 |
| 41 namespace ui { | 12 namespace ui { |
| 42 | |
| 43 namespace ws { | 13 namespace ws { |
| 44 | 14 |
| 45 // static | 15 // static |
| 46 PlatformDisplayFactory* PlatformDisplay::factory_ = nullptr; | 16 PlatformDisplayFactory* PlatformDisplay::factory_ = nullptr; |
| 47 | 17 |
| 48 // static | 18 // static |
| 49 std::unique_ptr<PlatformDisplay> PlatformDisplay::Create( | 19 std::unique_ptr<PlatformDisplay> PlatformDisplay::Create( |
| 50 const PlatformDisplayInitParams& init_params) { | 20 const PlatformDisplayInitParams& init_params) { |
| 51 if (factory_) | 21 if (factory_) |
| 52 return factory_->CreatePlatformDisplay(); | 22 return factory_->CreatePlatformDisplay(); |
| 53 | 23 |
| 54 return base::MakeUnique<DefaultPlatformDisplay>(init_params); | 24 return base::MakeUnique<PlatformDisplayDefault>(init_params); |
| 55 } | |
| 56 | |
| 57 DefaultPlatformDisplay::DefaultPlatformDisplay( | |
| 58 const PlatformDisplayInitParams& init_params) | |
| 59 : id_(init_params.display_id), | |
| 60 #if !defined(OS_ANDROID) | |
| 61 cursor_loader_(ui::CursorLoader::Create()), | |
| 62 #endif | |
| 63 frame_generator_(new FrameGenerator(this, init_params.root_window)), | |
| 64 metrics_(init_params.metrics) { | |
| 65 } | |
| 66 | |
| 67 void DefaultPlatformDisplay::Init(PlatformDisplayDelegate* delegate) { | |
| 68 delegate_ = delegate; | |
| 69 | |
| 70 DCHECK(!metrics_.pixel_size.IsEmpty()); | |
| 71 | |
| 72 // TODO(kylechar): The origin here isn't right if any displays have | |
| 73 // scale_factor other than 1.0 but will prevent windows from being stacked. | |
| 74 gfx::Rect bounds(metrics_.bounds.origin(), metrics_.pixel_size); | |
| 75 #if defined(OS_WIN) | |
| 76 platform_window_ = base::MakeUnique<ui::WinWindow>(this, bounds); | |
| 77 #elif defined(USE_X11) | |
| 78 platform_window_ = base::MakeUnique<ui::X11Window>(this); | |
| 79 platform_window_->SetBounds(bounds); | |
| 80 #elif defined(OS_ANDROID) | |
| 81 platform_window_ = base::MakeUnique<ui::PlatformWindowAndroid>(this); | |
| 82 platform_window_->SetBounds(bounds); | |
| 83 #elif defined(USE_OZONE) | |
| 84 platform_window_ = | |
| 85 ui::OzonePlatform::GetInstance()->CreatePlatformWindow(this, bounds); | |
| 86 #else | |
| 87 NOTREACHED() << "Unsupported platform"; | |
| 88 #endif | |
| 89 | |
| 90 platform_window_->Show(); | |
| 91 } | |
| 92 | |
| 93 int64_t DefaultPlatformDisplay::GetId() const { | |
| 94 return id_; | |
| 95 } | |
| 96 | |
| 97 DefaultPlatformDisplay::~DefaultPlatformDisplay() { | |
| 98 // Don't notify the delegate from the destructor. | |
| 99 delegate_ = nullptr; | |
| 100 | |
| 101 frame_generator_.reset(); | |
| 102 // Destroy the PlatformWindow early on as it may call us back during | |
| 103 // destruction and we want to be in a known state. But destroy the surface | |
| 104 // first because it can still be using the platform window. | |
| 105 platform_window_.reset(); | |
| 106 } | |
| 107 | |
| 108 void DefaultPlatformDisplay::SetViewportSize(const gfx::Size& size) { | |
| 109 platform_window_->SetBounds(gfx::Rect(size)); | |
| 110 } | |
| 111 | |
| 112 void DefaultPlatformDisplay::SetTitle(const base::string16& title) { | |
| 113 platform_window_->SetTitle(title); | |
| 114 } | |
| 115 | |
| 116 void DefaultPlatformDisplay::SetCapture() { | |
| 117 platform_window_->SetCapture(); | |
| 118 } | |
| 119 | |
| 120 void DefaultPlatformDisplay::ReleaseCapture() { | |
| 121 platform_window_->ReleaseCapture(); | |
| 122 } | |
| 123 | |
| 124 void DefaultPlatformDisplay::SetCursorById(mojom::Cursor cursor_id) { | |
| 125 #if !defined(OS_ANDROID) | |
| 126 // TODO(erg): This still isn't sufficient, and will only use native cursors | |
| 127 // that chrome would use, not custom image cursors. For that, we should | |
| 128 // delegate to the window manager to load images from resource packs. | |
| 129 // | |
| 130 // We probably also need to deal with different DPIs. | |
| 131 ui::Cursor cursor(static_cast<int32_t>(cursor_id)); | |
| 132 cursor_loader_->SetPlatformCursor(&cursor); | |
| 133 platform_window_->SetCursor(cursor.platform()); | |
| 134 #endif | |
| 135 } | |
| 136 | |
| 137 void DefaultPlatformDisplay::UpdateTextInputState( | |
| 138 const ui::TextInputState& state) { | |
| 139 ui::PlatformImeController* ime = platform_window_->GetPlatformImeController(); | |
| 140 if (ime) | |
| 141 ime->UpdateTextInputState(state); | |
| 142 } | |
| 143 | |
| 144 void DefaultPlatformDisplay::SetImeVisibility(bool visible) { | |
| 145 ui::PlatformImeController* ime = platform_window_->GetPlatformImeController(); | |
| 146 if (ime) | |
| 147 ime->SetImeVisibility(visible); | |
| 148 } | |
| 149 | |
| 150 gfx::Rect DefaultPlatformDisplay::GetBounds() const { | |
| 151 return metrics_.bounds; | |
| 152 } | |
| 153 | |
| 154 bool DefaultPlatformDisplay::IsPrimaryDisplay() const { | |
| 155 return display::PlatformScreen::GetInstance()->GetPrimaryDisplayId() == id_; | |
| 156 } | |
| 157 | |
| 158 void DefaultPlatformDisplay::OnGpuChannelEstablished( | |
| 159 scoped_refptr<gpu::GpuChannelHost> channel) { | |
| 160 frame_generator_->OnGpuChannelEstablished(channel); | |
| 161 } | |
| 162 | |
| 163 bool DefaultPlatformDisplay::UpdateViewportMetrics( | |
| 164 const display::ViewportMetrics& metrics) { | |
| 165 if (metrics_ == metrics) | |
| 166 return false; | |
| 167 | |
| 168 gfx::Rect bounds = platform_window_->GetBounds(); | |
| 169 if (bounds.size() != metrics.pixel_size) { | |
| 170 bounds.set_size(metrics.pixel_size); | |
| 171 platform_window_->SetBounds(bounds); | |
| 172 } | |
| 173 | |
| 174 metrics_ = metrics; | |
| 175 return true; | |
| 176 } | |
| 177 | |
| 178 const display::ViewportMetrics& DefaultPlatformDisplay::GetViewportMetrics() | |
| 179 const { | |
| 180 return metrics_; | |
| 181 } | |
| 182 | |
| 183 void DefaultPlatformDisplay::UpdateEventRootLocation(ui::LocatedEvent* event) { | |
| 184 gfx::Point location = event->location(); | |
| 185 location.Offset(metrics_.bounds.x(), metrics_.bounds.y()); | |
| 186 event->set_root_location(location); | |
| 187 } | |
| 188 | |
| 189 void DefaultPlatformDisplay::OnBoundsChanged(const gfx::Rect& new_bounds) { | |
| 190 // We only care if the window size has changed. | |
| 191 if (new_bounds.size() == metrics_.pixel_size) | |
| 192 return; | |
| 193 | |
| 194 // TODO(kylechar): Maybe do something here. For CrOS we don't need to support | |
| 195 // PlatformWindow initiated resizes. For other platforms we need to do | |
| 196 // something but that isn't fully flushed out. | |
| 197 } | |
| 198 | |
| 199 void DefaultPlatformDisplay::OnDamageRect(const gfx::Rect& damaged_region) { | |
| 200 } | |
| 201 | |
| 202 void DefaultPlatformDisplay::DispatchEvent(ui::Event* event) { | |
| 203 if (event->IsLocatedEvent()) | |
| 204 UpdateEventRootLocation(event->AsLocatedEvent()); | |
| 205 | |
| 206 if (event->IsScrollEvent()) { | |
| 207 // TODO(moshayedi): crbug.com/602859. Dispatch scroll events as | |
| 208 // they are once we have proper support for scroll events. | |
| 209 delegate_->OnEvent( | |
| 210 ui::PointerEvent(ui::MouseWheelEvent(*event->AsScrollEvent()))); | |
| 211 } else if (event->IsMouseEvent()) { | |
| 212 delegate_->OnEvent(ui::PointerEvent(*event->AsMouseEvent())); | |
| 213 } else if (event->IsTouchEvent()) { | |
| 214 delegate_->OnEvent(ui::PointerEvent(*event->AsTouchEvent())); | |
| 215 } else { | |
| 216 delegate_->OnEvent(*event); | |
| 217 } | |
| 218 | |
| 219 #if defined(USE_X11) || defined(USE_OZONE) | |
| 220 // We want to emulate the WM_CHAR generation behaviour of Windows. | |
| 221 // | |
| 222 // On Linux, we've previously inserted characters by having | |
| 223 // InputMethodAuraLinux take all key down events and send a character event | |
| 224 // to the TextInputClient. This causes a mismatch in code that has to be | |
| 225 // shared between Windows and Linux, including blink code. Now that we're | |
| 226 // trying to have one way of doing things, we need to standardize on and | |
| 227 // emulate Windows character events. | |
| 228 // | |
| 229 // This is equivalent to what we're doing in the current Linux port, but | |
| 230 // done once instead of done multiple times in different places. | |
| 231 if (event->type() == ui::ET_KEY_PRESSED) { | |
| 232 ui::KeyEvent* key_press_event = event->AsKeyEvent(); | |
| 233 ui::KeyEvent char_event(key_press_event->GetCharacter(), | |
| 234 key_press_event->key_code(), | |
| 235 key_press_event->flags()); | |
| 236 // We don't check that GetCharacter() is equal because changing a key event | |
| 237 // with an accelerator to a character event can change the character, for | |
| 238 // example, from 'M' to '^M'. | |
| 239 DCHECK_EQ(key_press_event->key_code(), char_event.key_code()); | |
| 240 DCHECK_EQ(key_press_event->flags(), char_event.flags()); | |
| 241 delegate_->OnEvent(char_event); | |
| 242 } | |
| 243 #endif | |
| 244 } | |
| 245 | |
| 246 void DefaultPlatformDisplay::OnCloseRequest() { | |
| 247 display::PlatformScreen::GetInstance()->RequestCloseDisplay(GetId()); | |
| 248 } | |
| 249 | |
| 250 void DefaultPlatformDisplay::OnClosed() {} | |
| 251 | |
| 252 void DefaultPlatformDisplay::OnWindowStateChanged( | |
| 253 ui::PlatformWindowState new_state) {} | |
| 254 | |
| 255 void DefaultPlatformDisplay::OnLostCapture() { | |
| 256 delegate_->OnNativeCaptureLost(); | |
| 257 } | |
| 258 | |
| 259 void DefaultPlatformDisplay::OnAcceleratedWidgetAvailable( | |
| 260 gfx::AcceleratedWidget widget, | |
| 261 float device_scale_factor) { | |
| 262 // This will get called after Init() is called, either synchronously as part | |
| 263 // of the Init() callstack or async after Init() has returned, depending on | |
| 264 // the platform. | |
| 265 delegate_->OnAcceleratedWidgetAvailable(); | |
| 266 frame_generator_->OnAcceleratedWidgetAvailable(widget); | |
| 267 } | |
| 268 | |
| 269 void DefaultPlatformDisplay::OnAcceleratedWidgetDestroyed() { | |
| 270 NOTREACHED(); | |
| 271 } | |
| 272 | |
| 273 void DefaultPlatformDisplay::OnActivationChanged(bool active) {} | |
| 274 | |
| 275 bool DefaultPlatformDisplay::IsInHighContrastMode() { | |
| 276 return delegate_ ? delegate_->IsInHighContrastMode() : false; | |
| 277 } | 25 } |
| 278 | 26 |
| 279 } // namespace ws | 27 } // namespace ws |
| 280 | |
| 281 } // namespace ui | 28 } // namespace ui |
| OLD | NEW |