Chromium Code Reviews| Index: ash/touch/touchscreen_util.cc |
| diff --git a/ash/touch/touchscreen_util.cc b/ash/touch/touchscreen_util.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..574265e99ecacbaa64f570a9f3455c9fe67d1a59 |
| --- /dev/null |
| +++ b/ash/touch/touchscreen_util.cc |
| @@ -0,0 +1,106 @@ |
| +// 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 "ui/events/device_data_manager.h" |
| +#include "ui/events/touchscreen_device.h" |
| + |
| +namespace ash { |
| + |
| +void AssociateTouchscreens(std::vector<DisplayInfo>* displays) { |
| + std::set<int> no_match_touchscreen; |
| + std::vector<ui::TouchscreenDevice> devices = |
|
Daniel Erat
2014/09/11 20:34:00
this function would probably be easier to test if
dnicoara
2014/09/11 21:08:54
Done.
You're right, DisplayChangeObserverChromeos
|
| + ui::DeviceDataManager::GetInstance()->touchscreen_devices(); |
| + |
| + 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 |