event_transformation_handler.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
1069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project// Use of this source code is governed by a BSD-style license that can be 3069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project// found in the LICENSE file. 4069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 5069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#include "ash/display/event_transformation_handler.h" 6069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 7069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#include <cmath> 8069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 9069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#include "ash/screen_ash.h" 10069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#include "ash/shell.h" 11069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#include "ash/wm/coordinate_conversion.h" 12069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#include "ash/wm/window_util.h" 13069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#include "ui/aura/root_window.h" 14069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#include "ui/aura/window.h" 15069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#include "ui/base/events/event.h" 16069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#include "ui/compositor/dip_util.h" 17069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#include "ui/gfx/display.h" 18069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#include "ui/gfx/screen.h" 19069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 20069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#if defined(OS_CHROMEOS) 21069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#include "chromeos/display/output_configurator.h" 22069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#endif // defined(OS_CHROMEOS) 23069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 24069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectnamespace ash { 25069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectnamespace internal { 26069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectnamespace { 27069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 28069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project// Boost factor for non-integrated displays. 29069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectconst float kBoostForNonIntegrated = 1.20f; 30069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project} 31069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 32069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source ProjectEventTransformationHandler::EventTransformationHandler() 33069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project : transformation_mode_(TRANSFORM_AUTO) { 34069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project} 35069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 36069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source ProjectEventTransformationHandler::~EventTransformationHandler() { 37069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project} 38069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 39069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectvoid EventTransformationHandler::OnScrollEvent(ui::ScrollEvent* event) { 40d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath if (transformation_mode_ == TRANSFORM_NONE) 41d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath return; 42d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath 43d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath // Get the device scale factor and stack it on the final scale factor. 44069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project gfx::Point point_in_screen(event->location()); 45d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath aura::Window* target = static_cast<aura::Window*>(event->target()); 46069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project const float scale_at_target = ui::GetDeviceScaleFactor(target->layer()); 47069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project float scale = scale_at_target; 48069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 49069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Apply some additional scaling if the display is non-integrated. 50069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project wm::ConvertPointToScreen(target, &point_in_screen); 51069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project const gfx::Display& display = 52069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Shell::GetScreen()->GetDisplayNearestPoint(point_in_screen); 53069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (!display.IsInternal()) 54069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project scale *= kBoostForNonIntegrated; 55069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 56069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project event->Scale(scale); 57069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project} 58069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 59069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#if defined(OS_CHROMEOS) 60069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project// This is to scale the TouchEvent's radius when the touch display is in 61069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project// mirror mode. TouchEvent's radius is often reported in the touchscreen's 62069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project// native resolution. In mirror mode, the touch display could be configured 63// at a lower resolution. We scale down the radius using the ratio defined as 64// the sqrt of 65// (mirror_width * mirror_height) / (native_width * native_height) 66void EventTransformationHandler::OnTouchEvent(ui::TouchEvent* event) { 67 using chromeos::OutputConfigurator; 68 OutputConfigurator* output_configurator = 69 ash::Shell::GetInstance()->output_configurator(); 70 71 if (output_configurator->output_state() != chromeos::STATE_DUAL_MIRROR) 72 return; 73 74 const std::map<int, float>& area_ratio_map = 75 output_configurator->GetMirroredDisplayAreaRatioMap(); 76 77 // TODO(miletus): When there are more than 1 touchscreen (e.g. Link connected 78 // to an external touchscreen), the correct way to do is to have a way 79 // to find out which touchscreen is the event originating from and use the 80 // area ratio of that touchscreen to scale the event's radius. 81 // Tracked here crbug.com/233245 82 if (area_ratio_map.size() != 1) { 83 LOG(ERROR) << "Mirroring mode with " << area_ratio_map.size() 84 << " touch display found"; 85 return; 86 } 87 88 float area_ratio_sqrt = std::sqrt(area_ratio_map.begin()->second); 89 event->set_radius_x(event->radius_x() * area_ratio_sqrt); 90 event->set_radius_y(event->radius_y() * area_ratio_sqrt); 91} 92#endif // defined(OS_CHROMEOS) 93 94} // namespace internal 95} // namespace ash 96