| // 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/touchscreen_util.h" |
| |
| #include <set> |
| |
| #include "base/logging.h" |
| |
| namespace ash { |
| |
| void AssociateTouchscreens(std::vector<DisplayInfo>* displays, |
| const std::vector<ui::TouchscreenDevice>& devices) { |
| std::set<int> no_match_touchscreen; |
| int internal_touchscreen = -1; |
| for (size_t i = 0; i < devices.size(); ++i) { |
| if (devices[i].is_internal) { |
| internal_touchscreen = i; |
| break; |
| } |
| } |
| |
| DisplayInfo* internal_state = NULL; |
| for (size_t i = 0; i < displays->size(); ++i) { |
| DisplayInfo* state = &(*displays)[i]; |
| if (state->id() == gfx::Display::InternalDisplayId() && |
| !state->GetNativeModeSize().IsEmpty() && |
| state->touch_support() == gfx::Display::TOUCH_SUPPORT_UNKNOWN) { |
| internal_state = state; |
| break; |
| } |
| } |
| |
| if (internal_state && internal_touchscreen >= 0) { |
| internal_state->set_touch_device_id(devices[internal_touchscreen].id); |
| internal_state->set_touch_support(gfx::Display::TOUCH_SUPPORT_AVAILABLE); |
| VLOG(2) << "Found internal touchscreen for internal display " |
| << internal_state->id() << " touch_device_id " |
| << internal_state->touch_device_id() << " size " |
| << devices[internal_touchscreen].size.ToString(); |
| } |
| |
| for (size_t i = 0; i < devices.size(); ++i) { |
| if (internal_state && internal_state->touch_device_id() == devices[i].id) |
| continue; |
| |
| bool found_mapping = false; |
| for (size_t j = 0; j < displays->size(); ++j) { |
| DisplayInfo* state = &(*displays)[j]; |
| const gfx::Size native_size = state->GetNativeModeSize(); |
| if (state->touch_support() == gfx::Display::TOUCH_SUPPORT_AVAILABLE || |
| native_size.IsEmpty()) |
| continue; |
| |
| // Allow 1 pixel difference between screen and touchscreen |
| // resolutions. Because in some cases for monitor resolution |
| // 1024x768 touchscreen's resolution would be 1024x768, but for |
| // some 1023x767. It really depends on touchscreen's firmware |
| // configuration. |
| if (std::abs(native_size.width() - devices[i].size.width()) <= 1 && |
| std::abs(native_size.height() - devices[i].size.height()) <= 1) { |
| state->set_touch_device_id(devices[i].id); |
| state->set_touch_support(gfx::Display::TOUCH_SUPPORT_AVAILABLE); |
| |
| VLOG(2) << "Found touchscreen for display " << state->id() |
| << " touch_device_id " << state->touch_device_id() << " size " |
| << devices[i].size.ToString(); |
| found_mapping = true; |
| break; |
| } |
| } |
| |
| if (!found_mapping) { |
| no_match_touchscreen.insert(devices[i].id); |
| VLOG(2) << "No matching display for touch_device_id " << devices[i].id |
| << " size " << devices[i].size.ToString(); |
| } |
| } |
| |
| // Sometimes we can't find a matching screen for the touchscreen, e.g. |
| // due to the touchscreen's reporting range having no correlation with the |
| // screen's resolution. In this case, we arbitrarily assign unmatched |
| // touchscreens to unmatched screens. |
| for (std::set<int>::iterator it = no_match_touchscreen.begin(); |
| it != no_match_touchscreen.end(); |
| ++it) { |
| for (size_t i = 0; i < displays->size(); ++i) { |
| DisplayInfo* state = &(*displays)[i]; |
| if (state->id() != gfx::Display::InternalDisplayId() && |
| !state->GetNativeModeSize().IsEmpty() && |
| state->touch_support() == gfx::Display::TOUCH_SUPPORT_UNKNOWN) { |
| state->set_touch_device_id(*it); |
| state->set_touch_support(gfx::Display::TOUCH_SUPPORT_AVAILABLE); |
| VLOG(2) << "Arbitrarily matching touchscreen " |
| << state->touch_device_id() << " to display " << state->id(); |
| break; |
| } |
| } |
| } |
| } |
| |
| } // namespace ash |