blob: 5311a828369183a2c9cf8dfebafffb89cd67ac7f [file] [log] [blame]
// 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 "ui/display/chromeos/touchscreen_delegate_impl.h"
#include <cmath>
#include <set>
#include "ui/display/types/chromeos/display_mode.h"
#include "ui/display/types/chromeos/display_snapshot.h"
#include "ui/display/types/chromeos/touchscreen_device_manager.h"
namespace ui {
TouchscreenDelegateImpl::TouchscreenDelegateImpl(
scoped_ptr<TouchscreenDeviceManager> touch_device_manager)
: touch_device_manager_(touch_device_manager.Pass()) {}
TouchscreenDelegateImpl::~TouchscreenDelegateImpl() {}
void TouchscreenDelegateImpl::AssociateTouchscreens(
std::vector<DisplayConfigurator::DisplayState>* displays) {
std::set<int> no_match_touchscreen;
std::vector<TouchscreenDevice> devices = touch_device_manager_->GetDevices();
for (size_t i = 0; i < devices.size(); ++i) {
bool found_mapping = false;
for (size_t j = 0; j < displays->size(); ++j) {
DisplayConfigurator::DisplayState* state = &(*displays)[j];
const DisplayMode* mode = state->display->native_mode();
if (state->touch_device_id != 0 || !mode)
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(mode->size().width() - devices[i].size.width()) <= 1 &&
std::abs(mode->size().height() - devices[i].size.height()) <= 1) {
state->touch_device_id = devices[i].id;
VLOG(2) << "Found touchscreen for display "
<< state->display->display_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) {
DisplayConfigurator::DisplayState* state = &(*displays)[i];
if (state->display->type() != DISPLAY_CONNECTION_TYPE_INTERNAL &&
state->display->native_mode() != NULL &&
state->touch_device_id == 0) {
state->touch_device_id = *it;
VLOG(2) << "Arbitrarily matching touchscreen "
<< state->touch_device_id << " to display "
<< state->display->display_id();
break;
}
}
}
}
} // namespace ui