diff options
author | rlp@chromium.org <rlp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-09 18:19:08 +0000 |
---|---|---|
committer | rlp@chromium.org <rlp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-09 18:19:08 +0000 |
commit | 08294a9c6545c8f75e9d7d43eaf05c9f2b3b5ab1 (patch) | |
tree | 6b720c121b6603d447dd53d96c39d412c6910630 /ash | |
parent | aad29ce82cf8273c5404262998c097c4036a8f4c (diff) | |
download | chromium_src-08294a9c6545c8f75e9d7d43eaf05c9f2b3b5ab1.zip chromium_src-08294a9c6545c8f75e9d7d43eaf05c9f2b3b5ab1.tar.gz chromium_src-08294a9c6545c8f75e9d7d43eaf05c9f2b3b5ab1.tar.bz2 |
Revert 269371 "Move touch CTM from X into Chrome"
Failed compile on Linux Builder
http://build.chromium.org/p/chromium.linux/builders/Linux%20Builder%20%28dbg%29%2832%29/builds/23859/steps/compile/logs/stdio
FAILED: /b/build/goma/gomacc c++ -Wl,-z,now -Wl,-z,relro -Wl,--fatal-warnings -pthread -Wl,-z,noexecstack -fPIC -m32 -Wl,--no-as-needed -Wl,-rpath=\$ORIGIN/lib/ -Wl,-rpath-link=lib/ -o cast_unittests -Wl,--start-group obj/media/base/cast_unittests.run_all_unittests.o obj/media/cast/audio_receiver/cast_unittests.audio_decoder_unittest.o obj/media/cast/audio_receiver/cast_unittests.audio_receiver_unittest.o obj/media/cast/audio_sender/cast_unittests.audio_encoder_unittest.o obj/media/cast/audio_sender/cast_unittests.audio_sender_unittest.o obj/media/cast/congestion_control/cast_unittests.congestion_control_unittest.o obj/media/cast/framer/cast_unittests.cast_message_builder_unittest.o obj/media/cast/framer/cast_unittests.frame_buffer_unittest.o obj/media/cast/framer/cast_unittests.framer_unittest.o obj/media/cast/logging/cast_unittests.encoding_event_subscriber_unittest.o obj/media/cast/logging/cast_unittests.serialize_deserialize_test.o obj/media/cast/logging/cast_unittests.logging_impl_unittest.o obj/media/cast/logging/cast_unittests.logging_raw_unittest.o obj/media/cast/logging/cast_unittests.receiver_time_offset_estimator_impl_unittest.o obj/media/cast/logging/cast_unittests.simple_event_subscriber_unittest.o obj/media/cast/logging/cast_unittests.stats_event_subscriber_unittest.o obj/media/cast/rtcp/cast_unittests.mock_rtcp_receiver_feedback.o obj/media/cast/rtcp/cast_unittests.mock_rtcp_sender_feedback.o obj/media/cast/rtcp/cast_unittests.rtcp_receiver_unittest.o obj/media/cast/rtcp/cast_unittests.rtcp_sender_unittest.o obj/media/cast/rtcp/cast_unittests.rtcp_unittest.o obj/media/cast/rtcp/cast_unittests.receiver_rtcp_event_subscriber_unittest.o obj/media/cast/rtcp/cast_unittests.sender_rtcp_event_subscriber_unittest.o obj/media/cast/rtcp/cast_unittests.test_rtcp_packet_builder.o obj/media/cast/rtp_receiver/cast_unittests.mock_rtp_payload_feedback.o obj/media/cast/rtp_receiver/cast_unittests.receiver_stats_unittest.o obj/media/cast/rtp_receiver/rtp_parser/test/cast_unittests.rtp_packet_builder.o obj/media/cast/rtp_receiver/rtp_parser/cast_unittests.rtp_parser_unittest.o obj/media/cast/test/cast_unittests.end2end_unittest.o obj/media/cast/test/cast_unittests.fake_receiver_time_offset_estimator.o obj/media/cast/test/cast_unittests.fake_single_thread_task_runner.o obj/media/cast/test/cast_unittests.fake_video_encode_accelerator.o obj/media/cast/test/utility/cast_unittests.audio_utility_unittest.o obj/media/cast/test/utility/cast_unittests.barcode_unittest.o obj/media/cast/transport/cast_unittests.cast_transport_sender_impl_unittest.o obj/media/cast/transport/pacing/cast_unittests.mock_paced_packet_sender.o obj/media/cast/transport/pacing/cast_unittests.paced_sender_unittest.o obj/media/cast/transport/rtp_sender/packet_storage/cast_unittests.packet_storage_unittest.o obj/media/cast/transport/rtp_sender/rtp_packetizer/cast_unittests.rtp_packetizer_unittest.o obj/media/cast/transport/rtp_sender/rtp_packetizer/test/cast_unittests.rtp_header_parser.o obj/media/cast/transport/transport/cast_unittests.udp_transport_unittest.o obj/media/cast/video_receiver/cast_unittests.video_decoder_unittest.o obj/media/cast/video_receiver/cast_unittests.video_receiver_unittest.o obj/media/cast/video_sender/cast_unittests.external_video_encoder_unittest.o obj/media/cast/video_sender/cast_unittests.video_encoder_impl_unittest.o obj/media/cast/video_sender/cast_unittests.video_sender_unittest.o obj/media/cast/libcast_base.a obj/media/cast/libcast_receiver.a obj/media/cast/libcast_rtcp.a obj/media/cast/libcast_sender.a obj/media/cast/libcast_test_utility.a obj/media/cast/libcast_transport.a obj/base/libtest_support_base.a obj/testing/libgmock.a obj/testing/libgtest.a obj/media/cast/libcast_logging_proto.a obj/third_party/opus/libopus.a obj/third_party/libvpx/libvpx.a obj/third_party/libvpx/libvpx_asm_offsets_vp8.a obj/third_party/libvpx/libvpx_intrinsics_mmx.a obj/third_party/libvpx/libvpx_intrinsics_sse2.a obj/third_party/libvpx/libvpx_intrinsics_ssse3.a libyuv.a obj/third_party/libjpeg_turbo/libjpeg_turbo.a obj/base/libbase_static.a obj/third_party/libxml/libxml2.a obj/third_party/zlib/libchrome_zlib.a obj/base/third_party/dynamic_annotations/libdynamic_annotations.a lib/libicuuc.so lib/libnet.so lib/libbase.so lib/libgfx_geometry.so lib/libprotobuf_lite.so lib/libshared_memory_support.so lib/libmedia.so lib/libbase_i18n.so lib/libcrcrypto.so -Wl,--end-group -lrt -ldl -lasound
lib//libevents_base.so: undefined reference to `ui::PlatformEventSource::RemovePlatformEventObserver(ui::PlatformEventObserver*)'
lib//libevents_base.so: undefined reference to `ui::PlatformEventSource::GetInstance()'
lib//libevents_base.so: undefined reference to `ui::PlatformEventSource::AddPlatformEventObserver(ui::PlatformEventObserver*)'
collect2: ld returned 1 exit status
ninja: build stopped: subcommand failed.
> Move touch CTM from X into Chrome
>
> Currently we compute the touch CTM in OutputConfigurator
> and push that into X. This CL makes computing the touch CTM
> in DisplayController, and pushing it
> into WindowTreeHostX11. This moves the functionality of
> touch CTM from X into Chrome.
>
> Basically, when there is output configuration change, we
> compute the TouchCTM for each touch device, and push the
> TouchCTM into the WindowTreeHostX11 that is associated
> with the touchscreen. Then when X events reaching root
> window, we use the CTM to map the events coordinate in
> framebuffer space into the root window's coordinate space.
>
>
> BUG=351019, chrome-os-partner:25788
> TEST=tested on Pixel/Clapper with external touch/non-touch displays
> on both extended/mirror mode. Touch events are correctly mapped to
> chrome window or discarded if it is from blank region from letterboxing/pillarboxing mirror mode.
>
> Review URL: https://codereview.chromium.org/191223007
TBR=miletus@chromium.org
Review URL: https://codereview.chromium.org/276013002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269376 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r-- | ash/DEPS | 3 | ||||
-rw-r--r-- | ash/ash.gyp | 9 | ||||
-rw-r--r-- | ash/display/display_change_observer_chromeos.cc | 1 | ||||
-rw-r--r-- | ash/display/display_controller.cc | 3 | ||||
-rw-r--r-- | ash/display/display_info.cc | 9 | ||||
-rw-r--r-- | ash/display/display_info.h | 7 | ||||
-rw-r--r-- | ash/host/ash_window_tree_host.h | 7 | ||||
-rw-r--r-- | ash/host/ash_window_tree_host_x11.cc | 250 | ||||
-rw-r--r-- | ash/host/ash_window_tree_host_x11.h | 19 | ||||
-rw-r--r-- | ash/host/ash_window_tree_host_x11_unittest.cc | 82 | ||||
-rw-r--r-- | ash/shell.cc | 12 | ||||
-rw-r--r-- | ash/shell.h | 7 | ||||
-rw-r--r-- | ash/touch/touch_transformer_controller.cc | 225 | ||||
-rw-r--r-- | ash/touch/touch_transformer_controller.h | 55 | ||||
-rw-r--r-- | ash/touch/touch_transformer_controller_unittest.cc | 206 |
15 files changed, 241 insertions, 654 deletions
@@ -21,7 +21,4 @@ specific_include_rules = { "root_window_controller\.*": [ "+ash/host" ], - "touch_transformer_controller\.*": [ - "+ash/host" - ], } diff --git a/ash/ash.gyp b/ash/ash.gyp index 7c2ece2..1b8212a 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -519,8 +519,6 @@ 'touch/touch_hud_projection.h', 'touch/touch_observer_hud.cc', 'touch/touch_observer_hud.h', - 'touch/touch_transformer_controller.cc', - 'touch/touch_transformer_controller.h', 'touch/touch_uma.cc', 'touch/touch_uma.h', 'volume_control_delegate.h', @@ -702,8 +700,6 @@ ['exclude', 'accelerators/magnifier_key_scroller.h'], ['exclude', 'accelerators/spoken_feedback_toggler.cc'], ['exclude', 'accelerators/spoken_feedback_toggler.h'], - ['exclude', 'touch/touch_transformer_controller.cc'], - ['exclude', 'touch/touch_transformer_controller.h'], ], }, { # else: use_x11==1 'dependencies': [ @@ -729,8 +725,6 @@ ['exclude', 'system/tray/media_security/media_capture_observer.h'], ['exclude', 'system/tray/media_security/multi_profile_media_tray_item.cc'], ['exclude', 'system/tray/media_security/multi_profile_media_tray_item.h'], - ['exclude', 'touch/touch_transformer_controller.cc'], - ['exclude', 'touch/touch_transformer_controller.h'], ], }], ], @@ -979,7 +973,6 @@ 'test/ash_unittests.cc', 'tooltips/tooltip_controller_unittest.cc', 'touch/touch_observer_hud_unittest.cc', - 'touch/touch_transformer_controller_unittest.cc', 'wm/app_list_controller_unittest.cc', 'wm/ash_native_cursor_manager_unittest.cc', 'wm/dock/docked_window_layout_manager_unittest.cc', @@ -1054,7 +1047,6 @@ 'sources/': [ ['exclude', 'accelerators/magnifier_key_scroller_unittest.cc'], ['exclude', 'accelerators/spoken_feedback_toggler_unittest.cc'], - ['exclude', 'touch/touch_transformer_controller_unittest.cc'], ], }], ['chromeos==1', { @@ -1072,7 +1064,6 @@ }, { # else: chromeos!=1 'sources/': [ ['exclude', 'display/resolution_notification_controller_unittest.cc'], - ['exclude', 'touch/touch_transformer_controller_unittest.cc'], ], }], ['OS=="linux" and component=="shared_library" and use_allocator!="none"', { diff --git a/ash/display/display_change_observer_chromeos.cc b/ash/display/display_change_observer_chromeos.cc index 40a1a37..ad6b029 100644 --- a/ash/display/display_change_observer_chromeos.cc +++ b/ash/display/display_change_observer_chromeos.cc @@ -152,7 +152,6 @@ void DisplayChangeObserver::OnDisplayModeChanged( new_info.set_touch_support(state.touch_device_id == 0 ? gfx::Display::TOUCH_SUPPORT_UNAVAILABLE : gfx::Display::TOUCH_SUPPORT_AVAILABLE); - new_info.set_touch_device_id(state.touch_device_id); new_info.set_available_color_profiles( Shell::GetInstance() ->display_configurator() diff --git a/ash/display/display_controller.cc b/ash/display/display_controller.cc index 69e36b7..c8cad9e 100644 --- a/ash/display/display_controller.cc +++ b/ash/display/display_controller.cc @@ -247,6 +247,8 @@ void DisplayController::Start() { new VirtualKeyboardWindowController); Shell::GetScreen()->AddObserver(this); Shell::GetInstance()->display_manager()->set_delegate(this); + + FOR_EACH_OBSERVER(Observer, observers_, OnDisplaysInitialized()); } void DisplayController::Shutdown() { @@ -292,7 +294,6 @@ void DisplayController::InitDisplays() { } } UpdateHostWindowNames(); - FOR_EACH_OBSERVER(Observer, observers_, OnDisplaysInitialized()); } void DisplayController::AddObserver(Observer* observer) { diff --git a/ash/display/display_info.cc b/ash/display/display_info.cc index 9682efa..3159853 100644 --- a/ash/display/display_info.cc +++ b/ash/display/display_info.cc @@ -179,7 +179,6 @@ DisplayInfo::DisplayInfo() has_overscan_(false), rotation_(gfx::Display::ROTATE_0), touch_support_(gfx::Display::TOUCH_SUPPORT_UNKNOWN), - touch_device_id_(0), device_scale_factor_(1.0f), overscan_insets_in_dip_(0, 0, 0, 0), configured_ui_scale_(1.0f), @@ -195,7 +194,6 @@ DisplayInfo::DisplayInfo(int64 id, has_overscan_(has_overscan), rotation_(gfx::Display::ROTATE_0), touch_support_(gfx::Display::TOUCH_SUPPORT_UNKNOWN), - touch_device_id_(0), device_scale_factor_(1.0f), overscan_insets_in_dip_(0, 0, 0, 0), configured_ui_scale_(1.0f), @@ -217,7 +215,6 @@ void DisplayInfo::Copy(const DisplayInfo& native_info) { device_scale_factor_ = native_info.device_scale_factor_; display_modes_ = native_info.display_modes_; touch_support_ = native_info.touch_support_; - touch_device_id_ = native_info.touch_device_id_; // Copy overscan_insets_in_dip_ if it's not empty. This is for test // cases which use "/o" annotation which sets the overscan inset @@ -298,8 +295,7 @@ std::string DisplayInfo::ToString() const { int rotation_degree = static_cast<int>(rotation_) * 90; return base::StringPrintf( "DisplayInfo[%lld] native bounds=%s, size=%s, scale=%f, " - "overscan=%s, rotation=%d, ui-scale=%f, touchscreen=%s, " - "touch-device-id=%d", + "overscan=%s, rotation=%d, ui-scale=%f, touchscreen=%s", static_cast<long long int>(id_), bounds_in_native_.ToString().c_str(), size_in_pixel_.ToString().c_str(), @@ -311,8 +307,7 @@ std::string DisplayInfo::ToString() const { ? "yes" : touch_support_ == gfx::Display::TOUCH_SUPPORT_UNAVAILABLE ? "no" - : "unknown", - touch_device_id_); + : "unknown"); } std::string DisplayInfo::ToFullString() const { diff --git a/ash/display/display_info.h b/ash/display/display_info.h index 62f9210..38e16d8 100644 --- a/ash/display/display_info.h +++ b/ash/display/display_info.h @@ -103,9 +103,6 @@ class ASH_EXPORT DisplayInfo { } gfx::Display::TouchSupport touch_support() const { return touch_support_; } - void set_touch_device_id(int id) { touch_device_id_ = id; } - int touch_device_id() const { return touch_device_id_; } - // Gets/Sets the device scale factor of the display. float device_scale_factor() const { return device_scale_factor_; } void set_device_scale_factor(float scale) { device_scale_factor_ = scale; } @@ -204,10 +201,6 @@ class ASH_EXPORT DisplayInfo { gfx::Display::Rotation rotation_; gfx::Display::TouchSupport touch_support_; - // If the display is also a touch device, it will have a positive - // |touch_device_id_|. Otherwise |touch_device_id_| is 0. - int touch_device_id_; - // This specifies the device's pixel density. (For example, a // display whose DPI is higher than the threshold is considered to have // device_scale_factor = 2.0 on Chrome OS). This is used by the diff --git a/ash/host/ash_window_tree_host.h b/ash/host/ash_window_tree_host.h index 7e791fe..9962b89 100644 --- a/ash/host/ash_window_tree_host.h +++ b/ash/host/ash_window_tree_host.h @@ -42,13 +42,6 @@ class ASH_EXPORT AshWindowTreeHost { scoped_ptr<RootWindowTransformer> transformer) = 0; virtual aura::WindowTreeHost* AsWindowTreeHost() = 0; - - // Updates the display IDs associated with this root window. - // A root window can be associated with up to 2 display IDs (e.g. in mirror - // mode dual monitors case). If the root window is only associated with one - // display id, then the other id should be set to - // gfx::Display::kInvalidDisplayID. - virtual void UpdateDisplayID(int64 id1, int64 id2) {}; }; } // namespace ash diff --git a/ash/host/ash_window_tree_host_x11.cc b/ash/host/ash_window_tree_host_x11.cc index 370eacf..e49e961 100644 --- a/ash/host/ash_window_tree_host_x11.cc +++ b/ash/host/ash_window_tree_host_x11.cc @@ -14,26 +14,162 @@ #include "ash/host/root_window_transformer.h" #include "base/basictypes.h" +#include "base/command_line.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" #include "base/sys_info.h" #include "ui/aura/client/screen_position_client.h" #include "ui/aura/env.h" #include "ui/aura/window.h" #include "ui/base/x/x11_util.h" #include "ui/events/event.h" +#include "ui/events/event_switches.h" #include "ui/events/event_utils.h" +#include "ui/events/platform/platform_event_observer.h" +#include "ui/events/platform/x11/x11_event_source.h" #include "ui/events/x/device_data_manager.h" #include "ui/events/x/device_list_cache_x.h" #include "ui/events/x/touch_factory_x11.h" + #include "ui/gfx/rect.h" #include "ui/gfx/screen.h" namespace ash { +// Accomplishes 2 tasks concerning touch event calibration: +// 1. Being a message-pump observer, +// routes all the touch events to the X root window, +// where they can be calibrated later. +// 2. Has the Calibrate method that does the actual bezel calibration, +// when invoked from X root window's event dispatcher. +class AshWindowTreeHostX11::TouchEventCalibrate + : public ui::PlatformEventObserver { + public: + TouchEventCalibrate() : left_(0), right_(0), top_(0), bottom_(0) { + if (ui::PlatformEventSource::GetInstance()) + ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this); +#if defined(USE_XI2_MT) + std::vector<std::string> parts; + if (Tokenize(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kTouchCalibration), + ",", + &parts) >= 4) { + if (!base::StringToInt(parts[0], &left_)) + DLOG(ERROR) << "Incorrect left border calibration value passed."; + if (!base::StringToInt(parts[1], &right_)) + DLOG(ERROR) << "Incorrect right border calibration value passed."; + if (!base::StringToInt(parts[2], &top_)) + DLOG(ERROR) << "Incorrect top border calibration value passed."; + if (!base::StringToInt(parts[3], &bottom_)) + DLOG(ERROR) << "Incorrect bottom border calibration value passed."; + } +#endif // defined(USE_XI2_MT) + } + + virtual ~TouchEventCalibrate() { + if (ui::PlatformEventSource::GetInstance()) + ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this); + } + + // Modify the location of the |event|, + // expanding it from |bounds| to (|bounds| + bezels). + // Required when touchscreen is bigger than screen (i.e. has bezels), + // because we receive events in touchscreen coordinates, + // which need to be expanded when converting to screen coordinates, + // so that location on bezels will be outside of screen area. + void Calibrate(ui::TouchEvent* event, const gfx::Rect& bounds) { +#if defined(USE_XI2_MT) + int x = event->x(); + int y = event->y(); + + if (!left_ && !right_ && !top_ && !bottom_) + return; + + const int resolution_x = bounds.width(); + const int resolution_y = bounds.height(); + // The "grace area" (10% in this case) is to make it easier for the user to + // navigate to the corner. + const double kGraceAreaFraction = 0.1; + if (left_ || right_) { + // Offset the x position to the real + x -= left_; + // Check if we are in the grace area of the left side. + // Note: We might not want to do this when the gesture is locked? + if (x < 0 && x > -left_ * kGraceAreaFraction) + x = 0; + // Check if we are in the grace area of the right side. + // Note: We might not want to do this when the gesture is locked? + if (x > resolution_x - left_ && + x < resolution_x - left_ + right_ * kGraceAreaFraction) + x = resolution_x - left_; + // Scale the screen area back to the full resolution of the screen. + x = (x * resolution_x) / (resolution_x - (right_ + left_)); + } + if (top_ || bottom_) { + // When there is a top bezel we add our border, + y -= top_; + + // Check if we are in the grace area of the top side. + // Note: We might not want to do this when the gesture is locked? + if (y < 0 && y > -top_ * kGraceAreaFraction) + y = 0; + + // Check if we are in the grace area of the bottom side. + // Note: We might not want to do this when the gesture is locked? + if (y > resolution_y - top_ && + y < resolution_y - top_ + bottom_ * kGraceAreaFraction) + y = resolution_y - top_; + // Scale the screen area back to the full resolution of the screen. + y = (y * resolution_y) / (resolution_y - (bottom_ + top_)); + } + + // Set the modified coordinate back to the event. + if (event->root_location() == event->location()) { + // Usually those will be equal, + // if not, I am not sure what the correct value should be. + event->set_root_location(gfx::Point(x, y)); + } + event->set_location(gfx::Point(x, y)); +#endif // defined(USE_XI2_MT) + } + + private: + // ui::PlatformEventObserver: + virtual void WillProcessEvent(const ui::PlatformEvent& event) OVERRIDE { +#if defined(USE_XI2_MT) + if (event->type == GenericEvent && + (event->xgeneric.evtype == XI_TouchBegin || + event->xgeneric.evtype == XI_TouchUpdate || + event->xgeneric.evtype == XI_TouchEnd)) { + XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(event->xcookie.data); + xievent->event = xievent->root; + xievent->event_x = xievent->root_x; + xievent->event_y = xievent->root_y; + } +#endif // defined(USE_XI2_MT) + } + + virtual void DidProcessEvent(const ui::PlatformEvent& event) OVERRIDE {} + + // The difference in screen's native resolution pixels between + // the border of the touchscreen and the border of the screen, + // aka bezel sizes. + int left_; + int right_; + int top_; + int bottom_; + + DISALLOW_COPY_AND_ASSIGN(TouchEventCalibrate); +}; + +//////////////////////////////////////////////////////////////////////////////// +// AshWindowTreeHostX11 + AshWindowTreeHostX11::AshWindowTreeHostX11(const gfx::Rect& initial_bounds) : WindowTreeHostX11(initial_bounds), - transformer_helper_(this), - display_ids_(std::make_pair(gfx::Display::kInvalidDisplayID, - gfx::Display::kInvalidDisplayID)) { + is_internal_display_(false), + touch_calibrate_(new TouchEventCalibrate), + transformer_helper_(this) { aura::Env::GetInstance()->AddObserver(this); } @@ -111,6 +247,7 @@ void AshWindowTreeHostX11::UnConfineCursor() { void AshWindowTreeHostX11::SetRootWindowTransformer( scoped_ptr<RootWindowTransformer> transformer) { transformer_helper_.SetRootWindowTransformer(transformer.Pass()); + UpdateIsInternalDisplay(); if (pointer_barriers_) { UnConfineCursor(); ConfineCursorToRootWindow(); @@ -119,13 +256,9 @@ void AshWindowTreeHostX11::SetRootWindowTransformer( aura::WindowTreeHost* AshWindowTreeHostX11::AsWindowTreeHost() { return this; } -void AshWindowTreeHostX11::UpdateDisplayID(int64 id1, int64 id2) { - display_ids_.first = id1; - display_ids_.second = id2; -} - void AshWindowTreeHostX11::SetBounds(const gfx::Rect& bounds) { WindowTreeHostX11::SetBounds(bounds); + UpdateIsInternalDisplay(); if (pointer_barriers_) { UnConfineCursor(); ConfineCursorToRootWindow(); @@ -155,8 +288,13 @@ void AshWindowTreeHostX11::OnCursorVisibilityChangedNative(bool show) { void AshWindowTreeHostX11::OnWindowInitialized(aura::Window* window) {} void AshWindowTreeHostX11::OnHostInitialized(aura::WindowTreeHost* host) { + // UpdateIsInternalDisplay relies on RootWindowSettings' display_id being set + // available by the time WED::Init is called. (set in + // DisplayManager::CreateRootWindowForDisplay) + // Ready when NotifyHostInitialized is called from WED::Init. if (host != AsWindowTreeHost()) return; + UpdateIsInternalDisplay(); // We have to enable Tap-to-click by default because the cursor is set to // visible in Shell::InitRootWindowController. @@ -164,6 +302,8 @@ void AshWindowTreeHostX11::OnHostInitialized(aura::WindowTreeHost* host) { } void AshWindowTreeHostX11::OnConfigureNotify() { + UpdateIsInternalDisplay(); + // Always update barrier and mouse location because |bounds_| might // have already been updated in |SetBounds|. if (pointer_barriers_) { @@ -172,68 +312,62 @@ void AshWindowTreeHostX11::OnConfigureNotify() { } } -bool AshWindowTreeHostX11::CanDispatchEvent(const ui::PlatformEvent& event) { - if(!WindowTreeHostX11::CanDispatchEvent(event)) - return false; - XEvent* xev = event; - XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev->xcookie.data); - ui::EventType type = ui::EventTypeFromNative(xev); - // For touch event, check if the root window is residing on the according - // touch display. - switch (type) { +void AshWindowTreeHostX11::TranslateAndDispatchLocatedEvent( + ui::LocatedEvent* event) { + switch (event->type()) { case ui::ET_TOUCH_MOVED: case ui::ET_TOUCH_PRESSED: case ui::ET_TOUCH_CANCELLED: case ui::ET_TOUCH_RELEASED: { -#if defined(OS_CHROMEOS) - int64 touch_display_id = - ui::DeviceDataManager::GetInstance()->GetDisplayForTouchDevice( - xiev->deviceid); - // If we don't have record of display id for this touch device, check - // that if the event is within the bound of the root window. Note - // that in multi-monitor case, the event position is in framebuffer - // space so the bounds check will not work so well. - if (touch_display_id == gfx::Display::kInvalidDisplayID) { - if (base::SysInfo::IsRunningOnChromeOS() && - !bounds().Contains(ui::EventLocationFromNative(xev))) - return false; - } else if (touch_display_id != display_ids_.first && - touch_display_id != display_ids_.second) { - return false; + ui::TouchEvent* touchev = static_cast<ui::TouchEvent*>(event); + if (base::SysInfo::IsRunningOnChromeOS()) { + // X maps the touch-surface to the size of the X root-window. + // In multi-monitor setup, Coordinate Transformation Matrix + // repositions the touch-surface onto part of X root-window + // containing aura root-window corresponding to the touchscreen. + // However, if aura root-window has non-zero origin, + // we need to relocate the event into aura root-window coordinates. + touchev->Relocate(bounds().origin()); +#if defined(USE_XI2_MT) + if (is_internal_display_) + touch_calibrate_->Calibrate(touchev, bounds()); +#endif // defined(USE_XI2_MT) } -#endif // defined(OS_CHROMEOS) - return true; + break; } - default: - return true; - } -} + default: { + aura::Window* root_window = window(); + aura::client::ScreenPositionClient* screen_position_client = + aura::client::GetScreenPositionClient(root_window); + gfx::Rect local(bounds().size()); -void AshWindowTreeHostX11::TranslateAndDispatchLocatedEvent( - ui::LocatedEvent* event) { - if (!event->IsTouchEvent()) { - aura::Window* root_window = window(); - aura::client::ScreenPositionClient* screen_position_client = - aura::client::GetScreenPositionClient(root_window); - gfx::Rect local(bounds().size()); - - if (screen_position_client && !local.Contains(event->location())) { - gfx::Point location(event->location()); - // In order to get the correct point in screen coordinates - // during passive grab, we first need to find on which host window - // the mouse is on, and find out the screen coordinates on that - // host window, then convert it back to this host window's coordinate. - screen_position_client->ConvertHostPointToScreen(root_window, - &location); - screen_position_client->ConvertPointFromScreen(root_window, &location); - ConvertPointToHost(&location); - event->set_location(location); - event->set_root_location(location); + if (screen_position_client && !local.Contains(event->location())) { + gfx::Point location(event->location()); + // In order to get the correct point in screen coordinates + // during passive grab, we first need to find on which host window + // the mouse is on, and find out the screen coordinates on that + // host window, then convert it back to this host window's coordinate. + screen_position_client->ConvertHostPointToScreen(root_window, + &location); + screen_position_client->ConvertPointFromScreen(root_window, &location); + ConvertPointToHost(&location); + event->set_location(location); + event->set_root_location(location); + } + break; } } SendEventToProcessor(event); } +void AshWindowTreeHostX11::UpdateIsInternalDisplay() { + aura::Window* root_window = window(); + gfx::Screen* screen = gfx::Screen::GetScreenFor(root_window); + gfx::Display display = screen->GetDisplayNearestWindow(root_window); + DCHECK(display.is_valid()); + is_internal_display_ = display.IsInternal(); +} + void AshWindowTreeHostX11::SetCrOSTapPaused(bool state) { if (!ui::IsXInput2Available()) return; diff --git a/ash/host/ash_window_tree_host_x11.h b/ash/host/ash_window_tree_host_x11.h index 4e340b2..f690ea8 100644 --- a/ash/host/ash_window_tree_host_x11.h +++ b/ash/host/ash_window_tree_host_x11.h @@ -30,7 +30,6 @@ class ASH_EXPORT AshWindowTreeHostX11 : public AshWindowTreeHost, virtual void SetRootWindowTransformer( scoped_ptr<RootWindowTransformer> transformer) OVERRIDE; virtual aura::WindowTreeHost* AsWindowTreeHost() OVERRIDE; - virtual void UpdateDisplayID(int64 id1, int64 id2) OVERRIDE; // aura::WindowTreehost: virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE; @@ -42,7 +41,6 @@ class ASH_EXPORT AshWindowTreeHostX11 : public AshWindowTreeHost, // aura::WindowTreeHostX11: virtual void OnConfigureNotify() OVERRIDE; - virtual bool CanDispatchEvent(const ui::PlatformEvent& event) OVERRIDE; virtual void TranslateAndDispatchLocatedEvent(ui::LocatedEvent* event) OVERRIDE; @@ -50,20 +48,23 @@ class ASH_EXPORT AshWindowTreeHostX11 : public AshWindowTreeHost, virtual void OnWindowInitialized(aura::Window* window) OVERRIDE; virtual void OnHostInitialized(aura::WindowTreeHost* host) OVERRIDE; + class TouchEventCalibrate; + + // Update is_internal_display_ based on the current state. + void UpdateIsInternalDisplay(); + // Set the CrOS touchpad "tap paused" property. It is used to temporarily // turn off the Tap-to-click feature when the mouse pointer is invisible. void SetCrOSTapPaused(bool state); + // True if the root host resides on the internal display + bool is_internal_display_; + scoped_ptr<XID[]> pointer_barriers_; - TransformerHelper transformer_helper_; + scoped_ptr<TouchEventCalibrate> touch_calibrate_; - // The display IDs associated with this root window. - // In single monitor or extended mode dual monitor case, the root window - // is associated with one display. - // In mirror mode dual monitors case, the root window is associated with - // both displays. - std::pair<int64, int64> display_ids_; + TransformerHelper transformer_helper_; DISALLOW_COPY_AND_ASSIGN(AshWindowTreeHostX11); }; diff --git a/ash/host/ash_window_tree_host_x11_unittest.cc b/ash/host/ash_window_tree_host_x11_unittest.cc index 12aa7bb..efd25c0 100644 --- a/ash/host/ash_window_tree_host_x11_unittest.cc +++ b/ash/host/ash_window_tree_host_x11_unittest.cc @@ -12,7 +12,6 @@ #include "ui/aura/test/aura_test_base.h" #include "ui/aura/window.h" #include "ui/aura/window_event_dispatcher.h" -#include "ui/aura/window_tree_host_x11.h" #include "ui/events/event_processor.h" #include "ui/events/event_target.h" #include "ui/events/event_target_iterator.h" @@ -57,17 +56,17 @@ class RootWindowEventHandler : public ui::EventHandler { namespace ash { -typedef aura::test::AuraTestBase AshWindowTreeHostX11Test; +typedef aura::test::AuraTestBase WindowTreeHostX11Test; // Send X touch events to one WindowTreeHost. The WindowTreeHost's // delegate will get corresponding ui::TouchEvent if the touch events -// are targeting this WindowTreeHost. -TEST_F(AshWindowTreeHostX11Test, DispatchTouchEventToOneRootWindow) { +// are winthin the bound of the WindowTreeHost. +TEST_F(WindowTreeHostX11Test, DispatchTouchEventToOneRootWindow) { // Fake a ChromeOS running env. const char* kLsbRelease = "CHROMEOS_RELEASE_NAME=Chromium OS\n"; base::SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease, base::Time()); - scoped_ptr<aura::WindowTreeHostX11> window_tree_host( + scoped_ptr<AshWindowTreeHostX11> window_tree_host( new AshWindowTreeHostX11(gfx::Rect(0, 0, 2560, 1700))); window_tree_host->InitHost(); scoped_ptr<RootWindowEventHandler> handler( @@ -85,8 +84,7 @@ TEST_F(AshWindowTreeHostX11Test, DispatchTouchEventToOneRootWindow) { // This touch is out of bounds. scoped_xevent.InitTouchEvent( 0, XI_TouchBegin, 5, gfx::Point(1500, 2500), valuators); - if (window_tree_host->CanDispatchEvent(scoped_xevent)) - window_tree_host->DispatchEvent(scoped_xevent); + window_tree_host->DispatchEvent(scoped_xevent); EXPECT_EQ(ui::ET_UNKNOWN, handler->last_touch_type()); EXPECT_EQ(-1, handler->last_touch_id()); EXPECT_EQ(gfx::Point(0, 0), handler->last_touch_location()); @@ -94,24 +92,21 @@ TEST_F(AshWindowTreeHostX11Test, DispatchTouchEventToOneRootWindow) { // Following touchs are within bounds and are passed to delegate. scoped_xevent.InitTouchEvent( 0, XI_TouchBegin, 5, gfx::Point(1500, 1500), valuators); - if (window_tree_host->CanDispatchEvent(scoped_xevent)) - window_tree_host->DispatchEvent(scoped_xevent); + window_tree_host->DispatchEvent(scoped_xevent); EXPECT_EQ(ui::ET_TOUCH_PRESSED, handler->last_touch_type()); EXPECT_EQ(0, handler->last_touch_id()); EXPECT_EQ(gfx::Point(1500, 1500), handler->last_touch_location()); scoped_xevent.InitTouchEvent( 0, XI_TouchUpdate, 5, gfx::Point(1500, 1600), valuators); - if (window_tree_host->CanDispatchEvent(scoped_xevent)) - window_tree_host->DispatchEvent(scoped_xevent); + window_tree_host->DispatchEvent(scoped_xevent); EXPECT_EQ(ui::ET_TOUCH_MOVED, handler->last_touch_type()); EXPECT_EQ(0, handler->last_touch_id()); EXPECT_EQ(gfx::Point(1500, 1600), handler->last_touch_location()); scoped_xevent.InitTouchEvent( 0, XI_TouchEnd, 5, gfx::Point(1500, 1600), valuators); - if (window_tree_host->CanDispatchEvent(scoped_xevent)) - window_tree_host->DispatchEvent(scoped_xevent); + window_tree_host->DispatchEvent(scoped_xevent); EXPECT_EQ(ui::ET_TOUCH_RELEASED, handler->last_touch_type()); EXPECT_EQ(0, handler->last_touch_id()); EXPECT_EQ(gfx::Point(1500, 1600), handler->last_touch_location()); @@ -128,19 +123,19 @@ TEST_F(AshWindowTreeHostX11Test, DispatchTouchEventToOneRootWindow) { // Send X touch events to two WindowTreeHost. The WindowTreeHost which is // the event target of the X touch events should generate the corresponding // ui::TouchEvent for its delegate. -TEST_F(AshWindowTreeHostX11Test, DispatchTouchEventToTwoRootWindow) { +TEST_F(WindowTreeHostX11Test, DispatchTouchEventToTwoRootWindow) { // Fake a ChromeOS running env. const char* kLsbRelease = "CHROMEOS_RELEASE_NAME=Chromium OS\n"; base::SysInfo::SetChromeOSVersionInfoForTest(kLsbRelease, base::Time()); - scoped_ptr<aura::WindowTreeHostX11> window_tree_host1( + scoped_ptr<AshWindowTreeHostX11> window_tree_host1( new AshWindowTreeHostX11(gfx::Rect(0, 0, 2560, 1700))); window_tree_host1->InitHost(); scoped_ptr<RootWindowEventHandler> handler1( new RootWindowEventHandler(window_tree_host1.get())); int host2_y_offset = 1700; - scoped_ptr<aura::WindowTreeHostX11> window_tree_host2( + scoped_ptr<AshWindowTreeHostX11> window_tree_host2( new AshWindowTreeHostX11(gfx::Rect(0, host2_y_offset, 1920, 1080))); window_tree_host2->InitHost(); scoped_ptr<RootWindowEventHandler> handler2( @@ -160,81 +155,74 @@ TEST_F(AshWindowTreeHostX11Test, DispatchTouchEventToTwoRootWindow) { ui::ScopedXI2Event scoped_xevent; scoped_xevent.InitTouchEvent( 0, XI_TouchBegin, 5, gfx::Point(1500, 2500), valuators); - if (window_tree_host1->CanDispatchEvent(scoped_xevent)) - window_tree_host1->DispatchEvent(scoped_xevent); - if (window_tree_host2->CanDispatchEvent(scoped_xevent)) - window_tree_host2->DispatchEvent(scoped_xevent); + window_tree_host1->DispatchEvent(scoped_xevent); + window_tree_host2->DispatchEvent(scoped_xevent); EXPECT_EQ(ui::ET_UNKNOWN, handler1->last_touch_type()); EXPECT_EQ(-1, handler1->last_touch_id()); EXPECT_EQ(gfx::Point(0, 0), handler1->last_touch_location()); EXPECT_EQ(ui::ET_TOUCH_PRESSED, handler2->last_touch_type()); EXPECT_EQ(0, handler2->last_touch_id()); - EXPECT_EQ(gfx::Point(1500, 2500), handler2->last_touch_location()); + EXPECT_EQ(gfx::Point(1500, 2500 - host2_y_offset), + handler2->last_touch_location()); scoped_xevent.InitTouchEvent( 0, XI_TouchBegin, 6, gfx::Point(1600, 2600), valuators); - if (window_tree_host1->CanDispatchEvent(scoped_xevent)) - window_tree_host1->DispatchEvent(scoped_xevent); - if (window_tree_host2->CanDispatchEvent(scoped_xevent)) - window_tree_host2->DispatchEvent(scoped_xevent); + window_tree_host1->DispatchEvent(scoped_xevent); + window_tree_host2->DispatchEvent(scoped_xevent); EXPECT_EQ(ui::ET_UNKNOWN, handler1->last_touch_type()); EXPECT_EQ(-1, handler1->last_touch_id()); EXPECT_EQ(gfx::Point(0, 0), handler1->last_touch_location()); EXPECT_EQ(ui::ET_TOUCH_PRESSED, handler2->last_touch_type()); EXPECT_EQ(1, handler2->last_touch_id()); - EXPECT_EQ(gfx::Point(1600, 2600), handler2->last_touch_location()); + EXPECT_EQ(gfx::Point(1600, 2600 - host2_y_offset), + handler2->last_touch_location()); scoped_xevent.InitTouchEvent( 0, XI_TouchUpdate, 5, gfx::Point(1500, 2550), valuators); - if (window_tree_host1->CanDispatchEvent(scoped_xevent)) - window_tree_host1->DispatchEvent(scoped_xevent); - if (window_tree_host2->CanDispatchEvent(scoped_xevent)) - window_tree_host2->DispatchEvent(scoped_xevent); + window_tree_host1->DispatchEvent(scoped_xevent); + window_tree_host2->DispatchEvent(scoped_xevent); EXPECT_EQ(ui::ET_UNKNOWN, handler1->last_touch_type()); EXPECT_EQ(-1, handler1->last_touch_id()); EXPECT_EQ(gfx::Point(0, 0), handler1->last_touch_location()); EXPECT_EQ(ui::ET_TOUCH_MOVED, handler2->last_touch_type()); EXPECT_EQ(0, handler2->last_touch_id()); - EXPECT_EQ(gfx::Point(1500, 2550), handler2->last_touch_location()); + EXPECT_EQ(gfx::Point(1500, 2550 - host2_y_offset), + handler2->last_touch_location()); scoped_xevent.InitTouchEvent( 0, XI_TouchUpdate, 6, gfx::Point(1600, 2650), valuators); - if (window_tree_host1->CanDispatchEvent(scoped_xevent)) - window_tree_host1->DispatchEvent(scoped_xevent); - if (window_tree_host2->CanDispatchEvent(scoped_xevent)) - window_tree_host2->DispatchEvent(scoped_xevent); + window_tree_host1->DispatchEvent(scoped_xevent); + window_tree_host2->DispatchEvent(scoped_xevent); EXPECT_EQ(ui::ET_UNKNOWN, handler1->last_touch_type()); EXPECT_EQ(-1, handler1->last_touch_id()); EXPECT_EQ(gfx::Point(0, 0), handler1->last_touch_location()); EXPECT_EQ(ui::ET_TOUCH_MOVED, handler2->last_touch_type()); EXPECT_EQ(1, handler2->last_touch_id()); - EXPECT_EQ(gfx::Point(1600, 2650), handler2->last_touch_location()); + EXPECT_EQ(gfx::Point(1600, 2650 - host2_y_offset), + handler2->last_touch_location()); scoped_xevent.InitTouchEvent( 0, XI_TouchEnd, 5, gfx::Point(1500, 2550), valuators); - if (window_tree_host1->CanDispatchEvent(scoped_xevent)) - window_tree_host1->DispatchEvent(scoped_xevent); - if (window_tree_host2->CanDispatchEvent(scoped_xevent)) - window_tree_host2->DispatchEvent(scoped_xevent); + window_tree_host1->DispatchEvent(scoped_xevent); + window_tree_host2->DispatchEvent(scoped_xevent); EXPECT_EQ(ui::ET_UNKNOWN, handler1->last_touch_type()); EXPECT_EQ(-1, handler1->last_touch_id()); EXPECT_EQ(gfx::Point(0, 0), handler1->last_touch_location()); EXPECT_EQ(ui::ET_TOUCH_RELEASED, handler2->last_touch_type()); EXPECT_EQ(0, handler2->last_touch_id()); - EXPECT_EQ(gfx::Point(1500, 2550), handler2->last_touch_location()); - + EXPECT_EQ(gfx::Point(1500, 2550 - host2_y_offset), + handler2->last_touch_location()); scoped_xevent.InitTouchEvent( 0, XI_TouchEnd, 6, gfx::Point(1600, 2650), valuators); - if (window_tree_host1->CanDispatchEvent(scoped_xevent)) - window_tree_host1->DispatchEvent(scoped_xevent); - if (window_tree_host2->CanDispatchEvent(scoped_xevent)) - window_tree_host2->DispatchEvent(scoped_xevent); + window_tree_host1->DispatchEvent(scoped_xevent); + window_tree_host2->DispatchEvent(scoped_xevent); EXPECT_EQ(ui::ET_UNKNOWN, handler1->last_touch_type()); EXPECT_EQ(-1, handler1->last_touch_id()); EXPECT_EQ(gfx::Point(0, 0), handler1->last_touch_location()); EXPECT_EQ(ui::ET_TOUCH_RELEASED, handler2->last_touch_type()); EXPECT_EQ(1, handler2->last_touch_id()); - EXPECT_EQ(gfx::Point(1600, 2650), handler2->last_touch_location()); + EXPECT_EQ(gfx::Point(1600, 2650 - host2_y_offset), + handler2->last_touch_location()); handler1.reset(); handler2.reset(); diff --git a/ash/shell.cc b/ash/shell.cc index c8f65bd..8bd4460 100644 --- a/ash/shell.cc +++ b/ash/shell.cc @@ -114,7 +114,6 @@ #if defined(USE_X11) #include "ash/accelerators/magnifier_key_scroller.h" #include "ash/accelerators/spoken_feedback_toggler.h" -#include "ash/touch/touch_transformer_controller.h" #include "ui/gfx/x/x11_types.h" #endif // defined(USE_X11) #include "ash/ash_constants.h" @@ -757,10 +756,6 @@ Shell::~Shell() { #endif desktop_background_controller_.reset(); -#if defined(OS_CHROMEOS) && defined(USE_X11) - touch_transformer_controller_.reset(); -#endif // defined(OS_CHROMEOS) && defined(USE_X11) - // This also deletes all RootWindows. Note that we invoke Shutdown() on // DisplayController before resetting |display_controller_|, since destruction // of its owned RootWindowControllers relies on the value. @@ -992,13 +987,6 @@ void Shell::Init() { base::Unretained(system_tray_delegate_.get())))); #endif -#if defined(OS_CHROMEOS) && defined(USE_X11) - // Create TouchTransformerController before DisplayController::InitDisplays() - // since TouchTransformerController listens on - // DisplayController::Observer::OnDisplaysInitialized(). - touch_transformer_controller_.reset(new TouchTransformerController()); -#endif // defined(OS_CHROMEOS) && defined(USE_X11) - display_controller_->InitDisplays(); // It needs to be created after RootWindowController has been created diff --git a/ash/shell.h b/ash/shell.h index 6b987606..718a6c6 100644 --- a/ash/shell.h +++ b/ash/shell.h @@ -136,7 +136,6 @@ class SystemTray; class SystemTrayDelegate; class SystemTrayNotifier; class ToplevelWindowEventHandler; -class TouchTransformerController; class TouchObserverHUD; class UserActivityDetector; class UserWallpaperDelegate; @@ -371,11 +370,6 @@ class ASH_EXPORT Shell : public SystemModalContainerEventFilterDelegate, DisplayController* display_controller() { return display_controller_.get(); } -#if defined(OS_CHROMEOS) && defined(USE_X11) - TouchTransformerController* touch_transformer_controller() { - return touch_transformer_controller_.get(); - } -#endif // defined(OS_CHROMEOS) && defined(USE_X11) MouseCursorEventFilter* mouse_cursor_filter() { return mouse_cursor_filter_.get(); } @@ -720,7 +714,6 @@ class ASH_EXPORT Shell : public SystemModalContainerEventFilterDelegate, #if defined(USE_X11) scoped_ptr<ui::EventHandler> magnifier_key_scroll_handler_; scoped_ptr<ui::EventHandler> speech_feedback_handler_; - scoped_ptr<TouchTransformerController> touch_transformer_controller_; #endif // defined(USE_X11) #endif // defined(OS_CHROMEOS) diff --git a/ash/touch/touch_transformer_controller.cc b/ash/touch/touch_transformer_controller.cc deleted file mode 100644 index 87954a3..0000000 --- a/ash/touch/touch_transformer_controller.cc +++ /dev/null @@ -1,225 +0,0 @@ -// 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 "ash/touch/touch_transformer_controller.h" - -#include "ash/display/display_controller.h" -#include "ash/display/display_manager.h" -#include "ash/host/ash_window_tree_host.h" -#include "ash/root_window_controller.h" -#include "ash/shell.h" -#include "ui/aura/window_tree_host.h" -#include "ui/display/chromeos/display_configurator.h" -#include "ui/display/types/chromeos/display_snapshot.h" -#include "ui/events/x/device_data_manager.h" - -namespace ash { - -namespace { - -DisplayManager* GetDisplayManager() { - return Shell::GetInstance()->display_manager(); -} - -} // namespace - -// This function computes the extended mode TouchTransformer for -// |touch_display|. The TouchTransformer maps the touch event position -// from framebuffer size to the display size. -gfx::Transform -TouchTransformerController::GetExtendedModeTouchTransformer( - const DisplayInfo& touch_display, const gfx::Size& fb_size) const { - gfx::Transform ctm; - if (touch_display.touch_device_id() == 0 || - fb_size.width() == 0.0 || - fb_size.height() == 0.0) - return ctm; - float width = touch_display.bounds_in_native().width(); - float height = touch_display.bounds_in_native().height(); - ctm.Scale(width / fb_size.width(), height / fb_size.height()); - return ctm; -} - -bool TouchTransformerController::ShouldComputeMirrorModeTouchTransformer( - const DisplayInfo& touch_display) const { - if (force_compute_mirror_mode_touch_transformer_) - return true; - - if (touch_display.touch_device_id() == 0) - return false; - - const ui::DisplayConfigurator::DisplayState* state = NULL; - const std::vector<ui::DisplayConfigurator::DisplayState>& cached_displays = - Shell::GetInstance()->display_configurator()->cached_displays(); - for (size_t i = 0; i < cached_displays.size(); i++) { - if (cached_displays[i].touch_device_id == touch_display.touch_device_id()) { - state = &cached_displays[i]; - break; - } - } - - if (!state || state->mirror_mode == state->display->native_mode() || - !state->display->is_aspect_preserving_scaling()) { - return false; - } - return true; -} - -// This function computes the mirror mode TouchTransformer for |touch_display|. -// When internal monitor is applied a resolution that does not have -// the same aspect ratio as its native resolution, there would be -// blank regions in the letterboxing/pillarboxing mode. -// The TouchTransformer will make sure the touch events on the blank region -// have negative coordinates and touch events within the chrome region -// have the correct positive coordinates. -gfx::Transform TouchTransformerController::GetMirrorModeTouchTransformer( - const DisplayInfo& touch_display) const { - gfx::Transform ctm; - if (!ShouldComputeMirrorModeTouchTransformer(touch_display)) - return ctm; - - float mirror_width = touch_display.bounds_in_native().width(); - float mirror_height = touch_display.bounds_in_native().height(); - float native_width = 0; - float native_height = 0; - - std::vector<DisplayMode> modes = touch_display.display_modes(); - for (size_t i = 0; i < modes.size(); i++) { - if (modes[i].native) { - native_width = modes[i].size.width(); - native_height = modes[i].size.height(); - break; - } - } - - if (native_height == 0.0 || mirror_height == 0.0 || - native_width == 0.0 || mirror_width == 0.0) - return ctm; - - float native_ar = static_cast<float>(native_width) / - static_cast<float>(native_height); - float mirror_ar = static_cast<float>(mirror_width) / - static_cast<float>(mirror_height); - - if (mirror_ar > native_ar) { // Letterboxing - // Translate before scale. - ctm.Translate(0.0, (1.0 - mirror_ar / native_ar) * 0.5 * mirror_height); - ctm.Scale(1.0, mirror_ar / native_ar); - return ctm; - } - - if (native_ar > mirror_ar) { // Pillarboxing - // Translate before scale. - ctm.Translate((1.0 - native_ar / mirror_ar) * 0.5 * mirror_width, 0.0); - ctm.Scale(native_ar / mirror_ar, 1.0); - return ctm; - } - - return ctm; // Same aspect ratio - return identity -} - -TouchTransformerController::TouchTransformerController() : - force_compute_mirror_mode_touch_transformer_ (false) { - Shell::GetInstance()->display_controller()->AddObserver(this); -} - -TouchTransformerController::~TouchTransformerController() { - Shell::GetInstance()->display_controller()->RemoveObserver(this); -} - -void TouchTransformerController::UpdateTouchTransformer() const { - ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); - device_manager->ClearTouchTransformerRecord(); - - // Display IDs and DisplayInfo for mirror or extended mode. - int64 display1_id = gfx::Display::kInvalidDisplayID; - int64 display2_id = gfx::Display::kInvalidDisplayID; - DisplayInfo display1; - DisplayInfo display2; - // Display ID and DisplayInfo for single display mode. - int64 single_display_id = gfx::Display::kInvalidDisplayID; - DisplayInfo single_display; - - DisplayController* display_controller = - Shell::GetInstance()->display_controller(); - ui::MultipleDisplayState display_state = - Shell::GetInstance()->display_configurator()->display_state(); - if (display_state == ui::MULTIPLE_DISPLAY_STATE_INVALID || - display_state == ui::MULTIPLE_DISPLAY_STATE_HEADLESS) { - return; - } else if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR || - display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED) { - // TODO(miletus) : Handle DUAL_EXTENDED with software mirroring. - DisplayIdPair id_pair = GetDisplayManager()->GetCurrentDisplayIdPair(); - display1_id = id_pair.first; - display2_id = id_pair.second; - DCHECK(display1_id != gfx::Display::kInvalidDisplayID && - display2_id != gfx::Display::kInvalidDisplayID); - display1 = GetDisplayManager()->GetDisplayInfo(display1_id); - display2 = GetDisplayManager()->GetDisplayInfo(display2_id); - } else { - single_display_id = GetDisplayManager()->first_display_id(); - DCHECK(single_display_id != gfx::Display::kInvalidDisplayID); - single_display = GetDisplayManager()->GetDisplayInfo(single_display_id); - } - - if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR) { - // In mirror mode, both displays share the same root window so - // both display ids are associated with the root window. - aura::Window* root = display_controller->GetPrimaryRootWindow(); - RootWindowController::ForWindow(root)->ash_host()->UpdateDisplayID( - display1_id, display2_id); - device_manager->UpdateTouchInfoForDisplay( - display1_id, - display1.touch_device_id(), - GetMirrorModeTouchTransformer(display1)); - device_manager->UpdateTouchInfoForDisplay( - display2_id, - display2.touch_device_id(), - GetMirrorModeTouchTransformer(display2)); - return; - } - - if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED) { - // In extended mode, each display is associated with one root window. - aura::Window* root1 = - display_controller->GetRootWindowForDisplayId(display1_id); - aura::Window* root2 = - display_controller->GetRootWindowForDisplayId(display2_id); - RootWindowController::ForWindow(root1)->ash_host()->UpdateDisplayID( - display1_id, gfx::Display::kInvalidDisplayID); - RootWindowController::ForWindow(root2)->ash_host()->UpdateDisplayID( - display2_id, gfx::Display::kInvalidDisplayID); - gfx::Size fb_size = - Shell::GetInstance()->display_configurator()->framebuffer_size(); - device_manager->UpdateTouchInfoForDisplay( - display1_id, - display1.touch_device_id(), - GetExtendedModeTouchTransformer(display1, fb_size)); - device_manager->UpdateTouchInfoForDisplay( - display2_id, - display2.touch_device_id(), - GetExtendedModeTouchTransformer(display2, fb_size)); - return; - } - - // Single display mode. The root window has one associated display id. - aura::Window* root = - display_controller->GetRootWindowForDisplayId(single_display.id()); - RootWindowController::ForWindow(root)->ash_host()->UpdateDisplayID( - single_display.id(), gfx::Display::kInvalidDisplayID); - device_manager->UpdateTouchInfoForDisplay(single_display_id, - single_display.touch_device_id(), - gfx::Transform()); -} - -void TouchTransformerController::OnDisplaysInitialized() { - UpdateTouchTransformer(); -} - -void TouchTransformerController::OnDisplayConfigurationChanged() { - UpdateTouchTransformer(); -} - -} // namespace ash diff --git a/ash/touch/touch_transformer_controller.h b/ash/touch/touch_transformer_controller.h deleted file mode 100644 index f06be29..0000000 --- a/ash/touch/touch_transformer_controller.h +++ /dev/null @@ -1,55 +0,0 @@ -// 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. - -#ifndef ASH_TOUCH_TOUCH_TRANSFORMER_CONTROLLER_H_ -#define ASH_TOUCH_TOUCH_TRANSFORMER_CONTROLLER_H_ - -#include "ash/ash_export.h" -#include "ash/display/display_controller.h" -#include "ui/gfx/transform.h" - -namespace ash { - -// TouchTransformerController listens to display configuration change -// and updates the touch transformation for touch displays. -class ASH_EXPORT TouchTransformerController - : public DisplayController::Observer { - public: - TouchTransformerController(); - virtual ~TouchTransformerController(); - - // Updates the TouchTransformer for touch device and pushes the new - // TouchTransformer into device manager. - void UpdateTouchTransformer() const; - - // DisplayController::Observer: - virtual void OnDisplaysInitialized() OVERRIDE; - virtual void OnDisplayConfigurationChanged() OVERRIDE; - - private: - FRIEND_TEST_ALL_PREFIXES(TouchTransformerControllerTest, - TouchTransformerMirrorModeLetterboxing); - FRIEND_TEST_ALL_PREFIXES(TouchTransformerControllerTest, - TouchTransformerMirrorModePillarboxing); - FRIEND_TEST_ALL_PREFIXES(TouchTransformerControllerTest, - TouchTransformerExtendedMode); - - bool ShouldComputeMirrorModeTouchTransformer( - const DisplayInfo& touch_display) const ; - - gfx::Transform GetMirrorModeTouchTransformer( - const DisplayInfo& touch_display) const; - - gfx::Transform GetExtendedModeTouchTransformer( - const DisplayInfo& touch_display, const gfx::Size& fb_size) const; - - // For unittests only. - bool force_compute_mirror_mode_touch_transformer_; - - DISALLOW_COPY_AND_ASSIGN(TouchTransformerController); -}; - -} // namespace ash - -#endif // ASH_TOUCH_TOUCH_TRANSFORMER_CONTROLLER_H_ diff --git a/ash/touch/touch_transformer_controller_unittest.cc b/ash/touch/touch_transformer_controller_unittest.cc deleted file mode 100644 index 1b8fa1f..0000000 --- a/ash/touch/touch_transformer_controller_unittest.cc +++ /dev/null @@ -1,206 +0,0 @@ -// 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 "ash/touch/touch_transformer_controller.h" - -#include "ash/shell.h" -#include "ash/test/ash_test_base.h" -#include "ui/aura/window_tree_host.h" -#include "ui/events/x/device_data_manager.h" -#include "ui/gfx/display.h" - -namespace ash { - -namespace { -DisplayInfo CreateDisplayInfo(int64 id, - int touch_device_id, - const gfx::Rect& bounds) { - DisplayInfo info(id, std::string(), false); - info.SetBounds(bounds); - info.set_touch_device_id(touch_device_id); - return info; -} -} // namespace - -typedef test::AshTestBase TouchTransformerControllerTest; - -TEST_F(TouchTransformerControllerTest, TouchTransformerMirrorModeLetterboxing) { - // The internal display has native resolution of 2560x1700, and in - // mirror mode it is configured as 1920x1200. This is in letterboxing - // mode. - DisplayInfo internal_display_info = - CreateDisplayInfo(1, 10, gfx::Rect(0, 0, 1920, 1200)); - std::vector<DisplayMode> internal_modes; - internal_modes.push_back( - DisplayMode(gfx::Size(2560, 1700), 60, false, true)); - internal_modes.push_back( - DisplayMode(gfx::Size(1920, 1200), 60, false, false)); - internal_display_info.set_display_modes(internal_modes); - - DisplayInfo external_display_info = - CreateDisplayInfo(2, 11, gfx::Rect(0, 0, 1920, 1200)); - - TouchTransformerController* tt_controller = - Shell::GetInstance()->touch_transformer_controller(); - ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); - - tt_controller->force_compute_mirror_mode_touch_transformer_ = true; - device_manager->UpdateTouchInfoForDisplay( - internal_display_info.id(), - internal_display_info.touch_device_id(), - tt_controller->GetMirrorModeTouchTransformer(internal_display_info)); - - tt_controller->force_compute_mirror_mode_touch_transformer_ = false; - device_manager->UpdateTouchInfoForDisplay( - external_display_info.id(), - external_display_info.touch_device_id(), - tt_controller->GetMirrorModeTouchTransformer(external_display_info)); - - EXPECT_EQ(1, device_manager->GetDisplayForTouchDevice(10)); - EXPECT_EQ(2, device_manager->GetDisplayForTouchDevice(11)); - - // External touch display has the default TouchTransformer. - float x = 100.0; - float y = 100.0; - device_manager->ApplyTouchTransformer(11, &x, &y); - EXPECT_EQ(100, x); - EXPECT_EQ(100, y); - - // In letterboxing, there is (1-2560*(1200/1920)/1700)/2 = 2.95% of the - // height on both the top & bottom region of the screen is blank. - // When touch events coming at Y range [0, 1200), the mapping should be - // [0, ~35] ---> < 0 - // [~35, ~1165] ---> [0, 1200) - // [~1165, 1200] ---> >= 1200 - x = 100.0; - y = 35.0; - device_manager->ApplyTouchTransformer(10, &x, &y); - EXPECT_EQ(100, static_cast<int>(x)); - EXPECT_EQ(0, static_cast<int>(y)); - - x = 100.0; - y = 1165.0; - device_manager->ApplyTouchTransformer(10, &x, &y); - EXPECT_EQ(100, static_cast<int>(x)); - EXPECT_EQ(1200, static_cast<int>(y)); -} - -TEST_F(TouchTransformerControllerTest, TouchTransformerMirrorModePillarboxing) { - // The internal display has native resolution of 1366x768, and in - // mirror mode it is configured as 1024x768. This is in pillarboxing - // mode. - DisplayInfo internal_display_info = - CreateDisplayInfo(1, 10, gfx::Rect(0, 0, 1024, 768)); - std::vector<DisplayMode> internal_modes; - internal_modes.push_back( - DisplayMode(gfx::Size(1366, 768), 60, false, true)); - internal_modes.push_back( - DisplayMode(gfx::Size(1024, 768), 60, false, false)); - internal_display_info.set_display_modes(internal_modes); - - DisplayInfo external_display_info = - CreateDisplayInfo(2, 11, gfx::Rect(0, 0, 1024, 768)); - - TouchTransformerController* tt_controller = - Shell::GetInstance()->touch_transformer_controller(); - ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); - - tt_controller->force_compute_mirror_mode_touch_transformer_ = true; - device_manager->UpdateTouchInfoForDisplay( - internal_display_info.id(), - internal_display_info.touch_device_id(), - tt_controller->GetMirrorModeTouchTransformer(internal_display_info)); - - tt_controller->force_compute_mirror_mode_touch_transformer_ = false; - device_manager->UpdateTouchInfoForDisplay( - external_display_info.id(), - external_display_info.touch_device_id(), - tt_controller->GetMirrorModeTouchTransformer(external_display_info)); - - EXPECT_EQ(1, device_manager->GetDisplayForTouchDevice(10)); - EXPECT_EQ(2, device_manager->GetDisplayForTouchDevice(11)); - - // External touch display has the default TouchTransformer. - float x = 100.0; - float y = 100.0; - device_manager->ApplyTouchTransformer(11, &x, &y); - EXPECT_EQ(100, x); - EXPECT_EQ(100, y); - - // In pillarboxing, there is (1-768*(1024/768)/1366)/2 = 12.5% of the - // width on both the left & rigth region of the screen is blank. - // When touch events coming at X range [0, 1024), the mapping should be - // [0, ~128] ---> < 0 - // [~128, ~896] ---> [0, 1024) - // [~896, 1024] ---> >= 1024 - x = 128.0; - y = 100.0; - device_manager->ApplyTouchTransformer(10, &x, &y); - EXPECT_EQ(0, static_cast<int>(x)); - EXPECT_EQ(100, static_cast<int>(y)); - - x = 896.0; - y = 100.0; - device_manager->ApplyTouchTransformer(10, &x, &y); - EXPECT_EQ(1024, static_cast<int>(x)); - EXPECT_EQ(100, static_cast<int>(y)); -} - -TEST_F(TouchTransformerControllerTest, TouchTransformerExtendedMode) { - // The internal display has size 1366 x 768. The external display has - // size 2560x1600. The total frame buffer is 2560x2428, - // where 2428 = 768 + 60 (hidden gap) + 1600 - // and the sceond monitor is translated to Point (0, 828) in the - // framebuffer. - DisplayInfo display1 = CreateDisplayInfo(1, 5, gfx::Rect(0, 0, 1366, 768)); - DisplayInfo display2 = CreateDisplayInfo(2, 6, gfx::Rect(0, 828, 2560, 1600)); - gfx::Size fb_size(2560, 2428); - - TouchTransformerController* tt_controller = - Shell::GetInstance()->touch_transformer_controller(); - ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); - - device_manager->UpdateTouchInfoForDisplay( - display1.id(), - display1.touch_device_id(), - tt_controller->GetExtendedModeTouchTransformer(display1, fb_size)); - - device_manager->UpdateTouchInfoForDisplay( - display2.id(), - display2.touch_device_id(), - tt_controller->GetExtendedModeTouchTransformer(display2, fb_size)); - - EXPECT_EQ(1, device_manager->GetDisplayForTouchDevice(5)); - EXPECT_EQ(2, device_manager->GetDisplayForTouchDevice(6)); - - // Mapping for touch events from internal touch display: - // [0, 2560) x [0, 2428) -> [0, 1366) x [0, 768) - float x = 0.0; - float y = 0.0; - device_manager->ApplyTouchTransformer(5, &x, &y); - EXPECT_EQ(0, static_cast<int>(x)); - EXPECT_EQ(0, static_cast<int>(y)); - - x = 2559.0; - y = 2427.0; - device_manager->ApplyTouchTransformer(5, &x, &y); - EXPECT_EQ(1365, static_cast<int>(x)); - EXPECT_EQ(767, static_cast<int>(y)); - - // Mapping for touch events from external touch display: - // [0, 2560) x [0, 2428) -> [0, 2560) x [0, 1600) - x = 0.0; - y = 0.0; - device_manager->ApplyTouchTransformer(6, &x, &y); - EXPECT_EQ(0, static_cast<int>(x)); - EXPECT_EQ(0, static_cast<int>(y)); - - x = 2559.0; - y = 2427.0; - device_manager->ApplyTouchTransformer(6, &x, &y); - EXPECT_EQ(2559, static_cast<int>(x)); - EXPECT_EQ(1599, static_cast<int>(y)); -} - -} // namespace ash |