Home | History | Annotate | Download | only in touch
      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