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::SetTitle(const base::string16
& title
) {
89 void DrmWindowHost::SetCapture() {
90 window_manager_
->GrabEvents(widget_
);
93 void DrmWindowHost::ReleaseCapture() {
94 window_manager_
->UngrabEvents(widget_
);
97 void DrmWindowHost::ToggleFullscreen() {
100 void DrmWindowHost::Maximize() {
103 void DrmWindowHost::Minimize() {
106 void DrmWindowHost::Restore() {
109 void DrmWindowHost::SetCursor(PlatformCursor cursor
) {
110 cursor_
->SetCursor(widget_
, cursor
);
113 void DrmWindowHost::MoveCursorTo(const gfx::Point
& location
) {
114 event_factory_
->WarpCursorTo(widget_
, location
);
117 void DrmWindowHost::ConfineCursorToBounds(const gfx::Rect
& bounds
) {
118 if (cursor_confined_bounds_
== bounds
)
121 cursor_confined_bounds_
= bounds
;
122 cursor_
->CommitBoundsChange(widget_
, bounds_
, bounds
);
125 PlatformImeController
* DrmWindowHost::GetPlatformImeController() {
129 bool DrmWindowHost::CanDispatchEvent(const PlatformEvent
& ne
) {
131 Event
* event
= static_cast<Event
*>(ne
);
133 // If there is a grab, capture events here.
134 gfx::AcceleratedWidget grabber
= window_manager_
->event_grabber();
135 if (grabber
!= gfx::kNullAcceleratedWidget
)
136 return grabber
== widget_
;
138 if (event
->IsTouchEvent()) {
139 // Dispatch the event if it is from the touchscreen associated with the
140 // DrmWindowHost. We cannot check the event's location because if the
141 // touchscreen has a bezel, touches in the bezel have a location outside of
144 DeviceDataManager::GetInstance()->GetTargetDisplayForTouchDevice(
145 event
->source_device_id());
147 if (display_id
== gfx::Display::kInvalidDisplayID
)
150 DrmDisplayHost
* display
= display_manager_
->GetDisplay(display_id
);
154 DisplaySnapshot
* snapshot
= display
->snapshot();
155 if (!snapshot
->current_mode())
158 gfx::Rect
display_bounds(snapshot
->origin(),
159 snapshot
->current_mode()->size());
160 return display_bounds
== bounds_
;
161 } else if (event
->IsLocatedEvent()) {
162 LocatedEvent
* located_event
= static_cast<LocatedEvent
*>(event
);
163 return bounds_
.Contains(gfx::ToFlooredPoint(located_event
->location()));
166 // TODO(spang): For non-ash builds we would need smarter keyboard focus.
170 uint32_t DrmWindowHost::DispatchEvent(const PlatformEvent
& native_event
) {
171 DCHECK(native_event
);
173 Event
* event
= static_cast<Event
*>(native_event
);
174 if (event
->IsLocatedEvent()) {
175 // Make the event location relative to this window's origin.
176 LocatedEvent
* located_event
= static_cast<LocatedEvent
*>(event
);
177 gfx::PointF location
= located_event
->location();
178 location
-= bounds_
.OffsetFromOrigin();
179 located_event
->set_location(location
);
180 located_event
->set_root_location(location
);
182 DispatchEventFromNativeUiEvent(
183 native_event
, base::Bind(&PlatformWindowDelegate::DispatchEvent
,
184 base::Unretained(delegate_
)));
185 return POST_DISPATCH_STOP_PROPAGATION
;
188 void DrmWindowHost::OnChannelEstablished() {
189 sender_
->Send(new OzoneGpuMsg_CreateWindow(widget_
));
193 void DrmWindowHost::OnChannelDestroyed() {
196 void DrmWindowHost::SendBoundsChange() {
197 // Update the cursor before the window so that the cursor stays within the
198 // window bounds when the window size shrinks.
199 cursor_
->CommitBoundsChange(widget_
, bounds_
, GetCursorConfinedBounds());
200 sender_
->Send(new OzoneGpuMsg_WindowBoundsChanged(widget_
, bounds_
));