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. 4 5#include "ui/display/chromeos/touchscreen_delegate_impl.h" 6 7#include <cmath> 8#include <set> 9 10#include "ui/display/types/chromeos/display_mode.h" 11#include "ui/display/types/chromeos/display_snapshot.h" 12#include "ui/display/types/chromeos/touchscreen_device_manager.h" 13 14namespace ui { 15 16TouchscreenDelegateImpl::TouchscreenDelegateImpl( 17 scoped_ptr<TouchscreenDeviceManager> touch_device_manager) 18 : touch_device_manager_(touch_device_manager.Pass()) {} 19 20TouchscreenDelegateImpl::~TouchscreenDelegateImpl() {} 21 22void TouchscreenDelegateImpl::AssociateTouchscreens( 23 std::vector<DisplayConfigurator::DisplayState>* displays) { 24 std::set<int> no_match_touchscreen; 25 std::vector<TouchscreenDevice> devices = touch_device_manager_->GetDevices(); 26 27 int internal_touchscreen = -1; 28 for (size_t i = 0; i < devices.size(); ++i) { 29 if (devices[i].is_internal) { 30 internal_touchscreen = i; 31 break; 32 } 33 } 34 35 DisplayConfigurator::DisplayState* internal_state = NULL; 36 for (size_t i = 0; i < displays->size(); ++i) { 37 DisplayConfigurator::DisplayState* state = &(*displays)[i]; 38 if (state->display->type() == DISPLAY_CONNECTION_TYPE_INTERNAL && 39 state->display->native_mode() && 40 state->touch_device_id == 0) { 41 internal_state = state; 42 break; 43 } 44 } 45 46 if (internal_state && internal_touchscreen >= 0) { 47 internal_state->touch_device_id = devices[internal_touchscreen].id; 48 VLOG(2) << "Found internal touchscreen for internal display " 49 << internal_state->display->display_id() << " touch_device_id " 50 << internal_state->touch_device_id << " size " 51 << devices[internal_touchscreen].size.ToString(); 52 } 53 54 for (size_t i = 0; i < devices.size(); ++i) { 55 if (internal_state && 56 internal_state->touch_device_id == devices[i].id) 57 continue; 58 bool found_mapping = false; 59 for (size_t j = 0; j < displays->size(); ++j) { 60 DisplayConfigurator::DisplayState* state = &(*displays)[j]; 61 const DisplayMode* mode = state->display->native_mode(); 62 if (state->touch_device_id != 0 || !mode) 63 continue; 64 65 // Allow 1 pixel difference between screen and touchscreen 66 // resolutions. Because in some cases for monitor resolution 67 // 1024x768 touchscreen's resolution would be 1024x768, but for 68 // some 1023x767. It really depends on touchscreen's firmware 69 // configuration. 70 if (std::abs(mode->size().width() - devices[i].size.width()) <= 1 && 71 std::abs(mode->size().height() - devices[i].size.height()) <= 1) { 72 state->touch_device_id = devices[i].id; 73 74 VLOG(2) << "Found touchscreen for display " 75 << state->display->display_id() << " touch_device_id " 76 << state->touch_device_id << " size " 77 << devices[i].size.ToString(); 78 found_mapping = true; 79 break; 80 } 81 } 82 83 if (!found_mapping) { 84 no_match_touchscreen.insert(devices[i].id); 85 VLOG(2) << "No matching display for touch_device_id " 86 << devices[i].id << " size " << devices[i].size.ToString(); 87 } 88 } 89 90 // Sometimes we can't find a matching screen for the touchscreen, e.g. 91 // due to the touchscreen's reporting range having no correlation with the 92 // screen's resolution. In this case, we arbitrarily assign unmatched 93 // touchscreens to unmatched screens. 94 for (std::set<int>::iterator it = no_match_touchscreen.begin(); 95 it != no_match_touchscreen.end(); 96 ++it) { 97 for (size_t i = 0; i < displays->size(); ++i) { 98 DisplayConfigurator::DisplayState* state = &(*displays)[i]; 99 if (state->display->type() != DISPLAY_CONNECTION_TYPE_INTERNAL && 100 state->display->native_mode() != NULL && 101 state->touch_device_id == 0) { 102 state->touch_device_id = *it; 103 VLOG(2) << "Arbitrarily matching touchscreen " 104 << state->touch_device_id << " to display " 105 << state->display->display_id(); 106 break; 107 } 108 } 109 } 110} 111 112} // namespace ui 113