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