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_manager.h"
17 #include "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h"
18 #include "ui/ozone/platform/drm/host/drm_window_host_manager.h"
19 #include "ui/platform_window/platform_window_delegate.h"
23 DrmWindowHost::DrmWindowHost(PlatformWindowDelegate
* delegate
,
24 const gfx::Rect
& bounds
,
25 DrmGpuPlatformSupportHost
* sender
,
26 EventFactoryEvdev
* event_factory
,
28 DrmWindowHostManager
* window_manager
,
29 DrmDisplayHostManager
* display_manager
)
30 : delegate_(delegate
),
32 event_factory_(event_factory
),
34 window_manager_(window_manager
),
35 display_manager_(display_manager
),
37 widget_(window_manager
->NextAcceleratedWidget()) {
38 window_manager_
->AddWindow(widget_
, this);
41 DrmWindowHost::~DrmWindowHost() {
42 PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
43 window_manager_
->RemoveWindow(widget_
);
44 cursor_
->OnWindowRemoved(widget_
);
46 sender_
->RemoveChannelObserver(this);
47 sender_
->Send(new OzoneGpuMsg_DestroyWindowDelegate(widget_
));
50 void DrmWindowHost::Initialize() {
51 sender_
->AddChannelObserver(this);
52 PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
53 cursor_
->OnWindowAdded(widget_
, bounds_
, GetCursorConfinedBounds());
54 delegate_
->OnAcceleratedWidgetAvailable(widget_
);
57 gfx::AcceleratedWidget
DrmWindowHost::GetAcceleratedWidget() {
61 gfx::Rect
DrmWindowHost::GetCursorConfinedBounds() const {
62 return cursor_confined_bounds_
.IsEmpty() ? gfx::Rect(bounds_
.size())
63 : cursor_confined_bounds_
;
66 void DrmWindowHost::Show() {
69 void DrmWindowHost::Hide() {
72 void DrmWindowHost::Close() {
75 void DrmWindowHost::SetBounds(const gfx::Rect
& bounds
) {
77 delegate_
->OnBoundsChanged(bounds
);
81 gfx::Rect
DrmWindowHost::GetBounds() {
85 void DrmWindowHost::SetCapture() {
86 window_manager_
->GrabEvents(widget_
);
89 void DrmWindowHost::ReleaseCapture() {
90 window_manager_
->UngrabEvents(widget_
);
93 void DrmWindowHost::ToggleFullscreen() {
96 void DrmWindowHost::Maximize() {
99 void DrmWindowHost::Minimize() {
102 void DrmWindowHost::Restore() {
105 void DrmWindowHost::SetCursor(PlatformCursor cursor
) {
106 cursor_
->SetCursor(widget_
, cursor
);
109 void DrmWindowHost::MoveCursorTo(const gfx::Point
& location
) {
110 event_factory_
->WarpCursorTo(widget_
, location
);
113 void DrmWindowHost::ConfineCursorToBounds(const gfx::Rect
& bounds
) {
114 if (cursor_confined_bounds_
== bounds
)
117 cursor_confined_bounds_
= bounds
;
118 cursor_
->CommitBoundsChange(widget_
, bounds_
, bounds
);
121 bool DrmWindowHost::CanDispatchEvent(const PlatformEvent
& ne
) {
123 Event
* event
= static_cast<Event
*>(ne
);
125 // If there is a grab, capture events here.
126 gfx::AcceleratedWidget grabber
= window_manager_
->event_grabber();
127 if (grabber
!= gfx::kNullAcceleratedWidget
)
128 return grabber
== widget_
;
130 if (event
->IsTouchEvent()) {
131 // Dispatch the event if it is from the touchscreen associated with the
132 // DrmWindowHost. We cannot check the event's location because if the
133 // touchscreen has a bezel, touches in the bezel have a location outside of
136 DeviceDataManager::GetInstance()->GetTargetDisplayForTouchDevice(
137 event
->source_device_id());
139 if (display_id
== gfx::Display::kInvalidDisplayID
)
142 DisplaySnapshot
* snapshot
= display_manager_
->GetDisplay(display_id
);
143 if (!snapshot
|| !snapshot
->current_mode())
146 gfx::Rect
display_bounds(snapshot
->origin(),
147 snapshot
->current_mode()->size());
148 return display_bounds
== bounds_
;
149 } else if (event
->IsLocatedEvent()) {
150 LocatedEvent
* located_event
= static_cast<LocatedEvent
*>(event
);
151 return bounds_
.Contains(gfx::ToFlooredPoint(located_event
->location()));
154 // TODO(spang): For non-ash builds we would need smarter keyboard focus.
158 uint32_t DrmWindowHost::DispatchEvent(const PlatformEvent
& native_event
) {
159 DCHECK(native_event
);
161 Event
* event
= static_cast<Event
*>(native_event
);
162 if (event
->IsLocatedEvent()) {
163 // Make the event location relative to this window's origin.
164 LocatedEvent
* located_event
= static_cast<LocatedEvent
*>(event
);
165 gfx::PointF location
= located_event
->location();
166 location
-= bounds_
.OffsetFromOrigin();
167 located_event
->set_location(location
);
168 located_event
->set_root_location(location
);
170 DispatchEventFromNativeUiEvent(
171 native_event
, base::Bind(&PlatformWindowDelegate::DispatchEvent
,
172 base::Unretained(delegate_
)));
173 return POST_DISPATCH_STOP_PROPAGATION
;
176 void DrmWindowHost::OnChannelEstablished() {
177 sender_
->Send(new OzoneGpuMsg_CreateWindowDelegate(widget_
));
181 void DrmWindowHost::OnChannelDestroyed() {
184 void DrmWindowHost::SendBoundsChange() {
185 // Update the cursor before the window so that the cursor stays within the
186 // window bounds when the window size shrinks.
187 cursor_
->CommitBoundsChange(widget_
, bounds_
, GetCursorConfinedBounds());
188 sender_
->Send(new OzoneGpuMsg_WindowBoundsChanged(widget_
, bounds_
));