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..b7f0b994ae7d2678ca93093858522ece54acbe1d |
--- /dev/null |
+++ b/ash/touch/touchscreen_util.cc |
@@ -0,0 +1,103 @@ |
+// 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 |