Chromium Code Reviews| Index: remoting/host/chromeos/display_rotation_filter_ozone.cc |
| diff --git a/remoting/host/chromeos/display_rotation_filter_ozone.cc b/remoting/host/chromeos/display_rotation_filter_ozone.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..45ab5551396c6dd1cfeb0c5c0f49b3fcfccd4a14 |
| --- /dev/null |
| +++ b/remoting/host/chromeos/display_rotation_filter_ozone.cc |
| @@ -0,0 +1,80 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "remoting/host/display_rotation_filter.h" |
|
Wez
2014/11/26 02:28:34
nit: We typically leave the platform-specific impl
kelvinp
2014/12/02 00:12:26
Done.
|
| + |
| +#include "ash/shell.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "remoting/proto/internal.pb.h" |
| +#include "ui/aura/window_tree_host.h" |
| +#include "ui/compositor/dip_util.h" |
| + |
| +namespace { |
| + |
| +using remoting::protocol::MouseEvent; |
| +using remoting::protocol::InputFilter; |
| +using remoting::protocol::InputStub; |
| + |
| +// When the host display is rotated (e.g from 1280 x 850 -> 850 x 1280), |
| +// the client sends mouse locations in the rotated co-ordinates system |
| +// (850 x 1280). However, Ozone still expects all ui::Event locations to be |
| +// encoded in the original co-ordinates system (1280 x 850) prior to the |
| +// rotation. This class serves to map the rotated mouse co-ordinates back to |
| +// the original ones in Ozone. |
|
Wez
2014/11/26 02:28:34
This is confusingly worded; IIUC what you're sayin
|
| +class DisplayRotationFilterOzone : public InputFilter { |
| + public: |
| + explicit DisplayRotationFilterOzone(InputStub* input_stub); |
| + void InjectMouseEvent(const MouseEvent& event) override; |
| + |
| + private: |
| + aura::Window* root_window_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(DisplayRotationFilterOzone); |
| +}; |
| + |
| +DisplayRotationFilterOzone::DisplayRotationFilterOzone(InputStub* input_stub) |
| + : InputFilter(input_stub) { |
| + if (ash::Shell::HasInstance()) { |
| + root_window_ = ash::Shell::GetPrimaryRootWindow(); |
| + DCHECK(root_window_); |
|
Wez
2014/11/26 02:28:33
Why DCHECK here, if the rest of the code always ha
kelvinp
2014/12/02 00:12:26
This is mainly to allow the test not to crash in U
|
| + } |
| +} |
| + |
| +void DisplayRotationFilterOzone::InjectMouseEvent(const MouseEvent& event) { |
| + if (!event.has_x() || !event.has_y() || !root_window_) { |
| + InputFilter::InjectMouseEvent(event); |
| + return; |
| + } |
| + |
| + float scale = ui::GetDeviceScaleFactor(root_window_->layer()); |
| + |
| + gfx::Transform transform; |
| + // event.x() and event.y() are expressed in device pixels whereas |
| + // root_window_->layer()->transform() assumes device independence pixels. |
| + // Since display rotation involves a translation of the origin, it must be |
| + // performed in the correct units. |
| + transform.Scale(scale, scale); |
| + transform *= root_window_->layer()->transform(); |
| + transform.Scale(1 / scale, 1 / scale); |
|
Wez
2014/11/26 02:28:33
You're scaling by the device scale factor, applyin
kelvinp
2014/12/02 00:12:26
Done.
|
| + |
| + gfx::Point3F rotated_location(event.x(), event.y(), 0); |
| + transform.TransformPoint(&rotated_location); |
| + |
| + MouseEvent transformed_event(event); |
| + transformed_event.set_x(rotated_location.x()); |
| + transformed_event.set_y(rotated_location.y()); |
| + |
| + InputFilter::InjectMouseEvent(transformed_event); |
| +} |
| + |
| +} // namespace |
| + |
| +namespace remoting { |
| + |
| +// static |
| +scoped_ptr<InputFilter> CreateDisplayRotationFilter(InputStub* input_stub) { |
| + return make_scoped_ptr(new DisplayRotationFilterOzone(input_stub)); |
| +} |
| + |
| +} // namespace remoting |