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
3 // found in the LICENSE file.
5 #include "ui/ozone/platform/drm/host/drm_window_host.h"
8 #include "ui/events/devices/device_data_manager.h"
9 #include "ui/events/event.h"
10 #include "ui/events/ozone/evdev/event_factory_evdev.h"
11 #include "ui/events/ozone/events_ozone.h"
12 #include "ui/events/platform/platform_event_source.h"
13 #include "ui/gfx/display.h"
14 #include "ui/ozone/common/gpu/ozone_gpu_messages.h"
15 #include "ui/ozone/platform/drm/host/drm_cursor.h"
16 #include "ui/ozone/platform/drm/host/drm_display_host.h"
17 #include "ui/ozone/platform/drm/host/drm_display_host_manager.h"
18 #include "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h"
19 #include "ui/ozone/platform/drm/host/drm_window_host_manager.h"
20 #include "ui/platform_window/platform_window_delegate.h"
24 DrmWindowHost::DrmWindowHost(PlatformWindowDelegate
* delegate
,
25 const gfx::Rect
& bounds
,
26 DrmGpuPlatformSupportHost
* sender
,
27 EventFactoryEvdev
* event_factory
,
29 DrmWindowHostManager
* window_manager
,
30 DrmDisplayHostManager
* display_manager
)
31 : delegate_(delegate
),
33 event_factory_(event_factory
),
35 window_manager_(window_manager
),
36 display_manager_(display_manager
),
38 widget_(window_manager
->NextAcceleratedWidget()) {
39 window_manager_
->AddWindow(widget_
, this);
42 DrmWindowHost::~DrmWindowHost() {
43 PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
44 window_manager_
->RemoveWindow(widget_
);
45 cursor_
->OnWindowRemoved(widget_
);
47 sender_
->RemoveChannelObserver(this);
48 sender_
->Send(new OzoneGpuMsg_DestroyWindow(widget_
));
51 void DrmWindowHost::Initialize() {
52 sender_
->AddChannelObserver(this);
53 PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
54 cursor_
->OnWindowAdded(widget_
, bounds_
, GetCursorConfinedBounds());
55 delegate_
->OnAcceleratedWidgetAvailable(widget_
, 1.f
);
58 gfx::AcceleratedWidget
DrmWindowHost::GetAcceleratedWidget() {
62 gfx::Rect
DrmWindowHost::GetCursorConfinedBounds() const {
63 return cursor_confined_bounds_
.IsEmpty() ? gfx::Rect(bounds_
.size())
64 : cursor_confined_bounds_
;
67 void DrmWindowHost::Show() {
70 void DrmWindowHost::Hide() {
73 void DrmWindowHost::Close() {
76 void DrmWindowHost::SetBounds(const gfx::Rect
& bounds
) {
78 delegate_
->OnBoundsChanged(bounds
);
82 gfx::Rect
DrmWindowHost::GetBounds() {
86 void DrmWindowHost::SetCapture() {
87 window_manager_
->GrabEvents(widget_
);
90 void DrmWindowHost::ReleaseCapture() {
91 window_manager_
->UngrabEvents(widget_
);
94 void DrmWindowHost::ToggleFullscreen() {
97 void DrmWindowHost::Maximize() {
100 void DrmWindowHost::Minimize() {
103 void DrmWindowHost::Restore() {
106 void DrmWindowHost::SetCursor(PlatformCursor cursor
) {
107 cursor_
->SetCursor(widget_
, cursor
);
110 void DrmWindowHost::MoveCursorTo(const gfx::Point
& location
) {
111 event_factory_
->WarpCursorTo(widget_
, location
);
114 void DrmWindowHost::ConfineCursorToBounds(const gfx::Rect
& bounds
) {
115 if (cursor_confined_bounds_
== bounds
)
118 cursor_confined_bounds_
= bounds
;
119 cursor_
->CommitBoundsChange(widget_
, bounds_
, bounds
);
122 bool DrmWindowHost::CanDispatchEvent(const PlatformEvent
& ne
) {
124 Event
* event
= static_cast<Event
*>(ne
);
126 // If there is a grab, capture events here.
127 gfx::AcceleratedWidget grabber
= window_manager_
->event_grabber();
128 if (grabber
!= gfx::kNullAcceleratedWidget
)
129 return grabber
== widget_
;
131 if (event
->IsTouchEvent()) {
132 // Dispatch the event if it is from the touchscreen associated with the
133 // DrmWindowHost. We cannot check the event's location because if the
134 // touchscreen has a bezel, touches in the bezel have a location outside of
137 DeviceDataManager::GetInstance()->GetTargetDisplayForTouchDevice(
138 event
->source_device_id());
140 if (display_id
== gfx::Display::kInvalidDisplayID
)
143 DrmDisplayHost
* display
= display_manager_
->GetDisplay(display_id
);
147 DisplaySnapshot
* snapshot
= display
->snapshot();
148 if (!snapshot
->current_mode())
151 gfx::Rect
display_bounds(snapshot
->origin(),
152 snapshot
->current_mode()->size());
153 return display_bounds
== bounds_
;
154 } else if (event
->IsLocatedEvent()) {
155 LocatedEvent
* located_event
= static_cast<LocatedEvent
*>(event
);
156 return bounds_
.Contains(gfx::ToFlooredPoint(located_event
->location()));
159 // TODO(spang): For non-ash builds we would need smarter keyboard focus.
163 uint32_t DrmWindowHost::DispatchEvent(const PlatformEvent
& native_event
) {
164 DCHECK(native_event
);
166 Event
* event
= static_cast<Event
*>(native_event
);
167 if (event
->IsLocatedEvent()) {
168 // Make the event location relative to this window's origin.
169 LocatedEvent
* located_event
= static_cast<LocatedEvent
*>(event
);
170 gfx::PointF location
= located_event
->location();
171 location
-= bounds_
.OffsetFromOrigin();
172 located_event
->set_location(location
);
173 located_event
->set_root_location(location
);
175 DispatchEventFromNativeUiEvent(
176 native_event
, base::Bind(&PlatformWindowDelegate::DispatchEvent
,
177 base::Unretained(delegate_
)));
178 return POST_DISPATCH_STOP_PROPAGATION
;
181 void DrmWindowHost::OnChannelEstablished() {
182 sender_
->Send(new OzoneGpuMsg_CreateWindow(widget_
));
186 void DrmWindowHost::OnChannelDestroyed() {
189 void DrmWindowHost::SendBoundsChange() {
190 // Update the cursor before the window so that the cursor stays within the
191 // window bounds when the window size shrinks.
192 cursor_
->CommitBoundsChange(widget_
, bounds_
, GetCursorConfinedBounds());
193 sender_
->Send(new OzoneGpuMsg_WindowBoundsChanged(widget_
, bounds_
));