[email protected] | 682990f | 2013-01-10 06:49:11 | [diff] [blame] | 1 | // Copyright (c) 2013 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. | ||||
4 | |||||
5 | #include "ash/display/event_transformation_handler.h" | ||||
6 | |||||
[email protected] | a1c0601d | 2013-04-19 03:39:34 | [diff] [blame] | 7 | #include <cmath> |
8 | |||||
[email protected] | 682990f | 2013-01-10 06:49:11 | [diff] [blame] | 9 | #include "ash/shell.h" |
10 | #include "ash/wm/coordinate_conversion.h" | ||||
11 | #include "ash/wm/window_util.h" | ||||
[email protected] | 682990f | 2013-01-10 06:49:11 | [diff] [blame] | 12 | #include "ui/aura/window.h" |
[email protected] | fcc51c95 | 2014-02-21 21:31:26 | [diff] [blame] | 13 | #include "ui/aura/window_event_dispatcher.h" |
[email protected] | 682990f | 2013-01-10 06:49:11 | [diff] [blame] | 14 | #include "ui/compositor/dip_util.h" |
[email protected] | 86ccbd4 | 2013-09-18 18:11:54 | [diff] [blame] | 15 | #include "ui/events/event.h" |
[email protected] | 682990f | 2013-01-10 06:49:11 | [diff] [blame] | 16 | #include "ui/gfx/display.h" |
17 | #include "ui/gfx/screen.h" | ||||
18 | |||||
[email protected] | a1c0601d | 2013-04-19 03:39:34 | [diff] [blame] | 19 | #if defined(OS_CHROMEOS) |
[email protected] | 29957af | 2014-03-14 21:08:56 | [diff] [blame^] | 20 | #include "ui/display/chromeos/output_configurator.h" |
[email protected] | a1c0601d | 2013-04-19 03:39:34 | [diff] [blame] | 21 | #endif // defined(OS_CHROMEOS) |
22 | |||||
[email protected] | 682990f | 2013-01-10 06:49:11 | [diff] [blame] | 23 | namespace ash { |
24 | namespace internal { | ||||
25 | namespace { | ||||
26 | |||||
27 | // Boost factor for non-integrated displays. | ||||
28 | const float kBoostForNonIntegrated = 1.20f; | ||||
29 | } | ||||
30 | |||||
31 | EventTransformationHandler::EventTransformationHandler() | ||||
32 | : transformation_mode_(TRANSFORM_AUTO) { | ||||
33 | } | ||||
34 | |||||
35 | EventTransformationHandler::~EventTransformationHandler() { | ||||
36 | } | ||||
37 | |||||
38 | void EventTransformationHandler::OnScrollEvent(ui::ScrollEvent* event) { | ||||
39 | if (transformation_mode_ == TRANSFORM_NONE) | ||||
40 | return; | ||||
41 | |||||
[email protected] | 36ba1dc | 2013-09-20 08:58:04 | [diff] [blame] | 42 | // It is unnecessary to scale the event for the device scale factor since |
43 | // the event locations etc. are already in DIP. | ||||
[email protected] | 682990f | 2013-01-10 06:49:11 | [diff] [blame] | 44 | gfx::Point point_in_screen(event->location()); |
45 | aura::Window* target = static_cast<aura::Window*>(event->target()); | ||||
[email protected] | 682990f | 2013-01-10 06:49:11 | [diff] [blame] | 46 | wm::ConvertPointToScreen(target, &point_in_screen); |
47 | const gfx::Display& display = | ||||
48 | Shell::GetScreen()->GetDisplayNearestPoint(point_in_screen); | ||||
[email protected] | 682990f | 2013-01-10 06:49:11 | [diff] [blame] | 49 | |
[email protected] | 36ba1dc | 2013-09-20 08:58:04 | [diff] [blame] | 50 | // Apply some additional scaling if the display is non-integrated. |
51 | if (!display.IsInternal()) | ||||
52 | event->Scale(kBoostForNonIntegrated); | ||||
[email protected] | 682990f | 2013-01-10 06:49:11 | [diff] [blame] | 53 | } |
54 | |||||
[email protected] | a1c0601d | 2013-04-19 03:39:34 | [diff] [blame] | 55 | #if defined(OS_CHROMEOS) |
56 | // This is to scale the TouchEvent's radius when the touch display is in | ||||
57 | // mirror mode. TouchEvent's radius is often reported in the touchscreen's | ||||
58 | // native resolution. In mirror mode, the touch display could be configured | ||||
59 | // at a lower resolution. We scale down the radius using the ratio defined as | ||||
60 | // the sqrt of | ||||
61 | // (mirror_width * mirror_height) / (native_width * native_height) | ||||
62 | void EventTransformationHandler::OnTouchEvent(ui::TouchEvent* event) { | ||||
[email protected] | 29957af | 2014-03-14 21:08:56 | [diff] [blame^] | 63 | using ui::OutputConfigurator; |
[email protected] | a1c0601d | 2013-04-19 03:39:34 | [diff] [blame] | 64 | OutputConfigurator* output_configurator = |
65 | ash::Shell::GetInstance()->output_configurator(); | ||||
66 | |||||
[email protected] | cb62bd74 | 2013-05-16 04:54:36 | [diff] [blame] | 67 | // Check output_configurator's output_state instead of checking |
68 | // DisplayManager::IsMirrored() because the compositor based mirroring | ||||
69 | // won't cause the scaling issue. | ||||
[email protected] | c9750510 | 2014-02-12 14:50:26 | [diff] [blame] | 70 | if (output_configurator->output_state() != ui::OUTPUT_STATE_DUAL_MIRROR) |
[email protected] | a1c0601d | 2013-04-19 03:39:34 | [diff] [blame] | 71 | return; |
72 | |||||
73 | const std::map<int, float>& area_ratio_map = | ||||
74 | output_configurator->GetMirroredDisplayAreaRatioMap(); | ||||
75 | |||||
76 | // TODO(miletus): When there are more than 1 touchscreen (e.g. Link connected | ||||
77 | // to an external touchscreen), the correct way to do is to have a way | ||||
78 | // to find out which touchscreen is the event originating from and use the | ||||
79 | // area ratio of that touchscreen to scale the event's radius. | ||||
80 | // Tracked here crbug.com/233245 | ||||
81 | if (area_ratio_map.size() != 1) { | ||||
82 | LOG(ERROR) << "Mirroring mode with " << area_ratio_map.size() | ||||
83 | << " touch display found"; | ||||
84 | return; | ||||
85 | } | ||||
86 | |||||
87 | float area_ratio_sqrt = std::sqrt(area_ratio_map.begin()->second); | ||||
88 | event->set_radius_x(event->radius_x() * area_ratio_sqrt); | ||||
89 | event->set_radius_y(event->radius_y() * area_ratio_sqrt); | ||||
90 | } | ||||
91 | #endif // defined(OS_CHROMEOS) | ||||
92 | |||||
[email protected] | 682990f | 2013-01-10 06:49:11 | [diff] [blame] | 93 | } // namespace internal |
94 | } // namespace ash |