15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file. 4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/events/ozone/evdev/touch_event_converter_evdev.h" 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <errno.h> 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <fcntl.h> 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <linux/input.h> 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <poll.h> 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <stdio.h> 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <unistd.h> 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <cmath> 153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <limits> 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/bind.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/callback.h" 190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/command_line.h" 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/logging.h" 21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/memory/scoped_vector.h" 22a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "base/message_loop/message_loop.h" 230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/strings/string_number_conversions.h" 240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/strings/string_util.h" 250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/strings/stringprintf.h" 26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h" 27d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event_constants.h" 280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "ui/events/event_switches.h" 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/screen.h" 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace { 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochstruct TouchCalibration { 340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int bezel_left; 350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int bezel_right; 360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int bezel_top; 370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int bezel_bottom; 380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}; 390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid GetTouchCalibration(TouchCalibration* cal) { 410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch std::vector<std::string> parts; 420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (Tokenize(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch switches::kTouchCalibration), 440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ",", 450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &parts) >= 4) { 460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!base::StringToInt(parts[0], &cal->bezel_left)) 470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DLOG(ERROR) << "Incorrect left border calibration value passed."; 480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!base::StringToInt(parts[1], &cal->bezel_right)) 490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DLOG(ERROR) << "Incorrect right border calibration value passed."; 500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!base::StringToInt(parts[2], &cal->bezel_top)) 510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DLOG(ERROR) << "Incorrect top border calibration value passed."; 520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!base::StringToInt(parts[3], &cal->bezel_bottom)) 530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DLOG(ERROR) << "Incorrect bottom border calibration value passed."; 540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochfloat TuxelsToPixels(float val, 580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch float min_tuxels, 590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch float num_tuxels, 600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch float min_pixels, 610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch float num_pixels) { 620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Map [min_tuxels, min_tuxels + num_tuxels) to 630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // [min_pixels, min_pixels + num_pixels). 640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return min_pixels + (val - min_tuxels) * num_pixels / num_tuxels; 650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccifloat TuxelToPixelSize(float val, float num_tuxels, float num_pixels) { 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return val * num_pixels / num_tuxels; 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace ui { 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 750529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTouchEventConverterEvdev::TouchEventConverterEvdev( 760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int fd, 770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::FilePath path, 780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const EventDeviceInfo& info, 790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const EventDispatchCallback& callback) 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : EventConverterEvdev(fd, path), 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback_(callback), 820de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) syn_dropped_(false), 830de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) is_type_a_(false), 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci current_slot_(0) { 850de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) Init(info); 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TouchEventConverterEvdev::~TouchEventConverterEvdev() { 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Stop(); 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) close(fd_); 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 930de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)void TouchEventConverterEvdev::Init(const EventDeviceInfo& info) { 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Screen *screen = gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE); 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!screen) 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; // No scaling. 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Display display = screen->GetPrimaryDisplay(); 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Size size = display.GetSizeInPixel(); 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1000de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) pressure_min_ = info.GetAbsMinimum(ABS_MT_PRESSURE), 1010de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) pressure_max_ = info.GetAbsMaximum(ABS_MT_PRESSURE), 1020de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) x_min_tuxels_ = info.GetAbsMinimum(ABS_MT_POSITION_X), 1030de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) x_num_tuxels_ = info.GetAbsMaximum(ABS_MT_POSITION_X) - x_min_tuxels_ + 1, 1040de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) y_min_tuxels_ = info.GetAbsMinimum(ABS_MT_POSITION_Y), 1050de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) y_num_tuxels_ = info.GetAbsMaximum(ABS_MT_POSITION_Y) - y_min_tuxels_ + 1, 1060de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) x_min_pixels_ = x_min_tuxels_, 1070de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) x_num_pixels_ = x_num_tuxels_, 1080de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) y_min_pixels_ = y_min_tuxels_, 1090de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) y_num_pixels_ = y_num_tuxels_, 1100de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 1110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Map coordinates onto screen. 1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch x_min_pixels_ = 0; 1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch y_min_pixels_ = 0; 1140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch x_num_pixels_ = size.width(); 1150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch y_num_pixels_ = size.height(); 1160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VLOG(1) << "mapping touch coordinates to screen coordinates: " 1180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch << base::StringPrintf("%dx%d", size.width(), size.height()); 1190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Apply --touch-calibration. 1210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch TouchCalibration cal = {}; 1220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch GetTouchCalibration(&cal); 1230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch x_min_tuxels_ += cal.bezel_left; 1240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch x_num_tuxels_ -= cal.bezel_left + cal.bezel_right; 1250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch y_min_tuxels_ += cal.bezel_top; 1260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch y_num_tuxels_ -= cal.bezel_top + cal.bezel_bottom; 1270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VLOG(1) << "applying touch calibration: " 1290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch << base::StringPrintf("[%d, %d, %d, %d]", 1300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch cal.bezel_left, 1310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch cal.bezel_right, 1320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch cal.bezel_top, 1330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch cal.bezel_bottom); 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1360de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)bool TouchEventConverterEvdev::Reinitialize() { 1370de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) EventDeviceInfo info; 1380de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) if (info.Initialize(fd_)) { 1390de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) Init(info); 1400de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) return true; 1410de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 1420de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) return false; 1430de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)} 1440de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void TouchEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) { 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) input_event inputs[MAX_FINGERS * 6 + 1]; 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ssize_t read_size = read(fd, inputs, sizeof(inputs)); 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (read_size < 0) { 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (errno == EINTR || errno == EAGAIN) 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (errno != ENODEV) 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PLOG(ERROR) << "error reading device " << path_.value(); 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Stop(); 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (unsigned i = 0; i < read_size / sizeof(*inputs); i++) { 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ProcessInputEvent(inputs[i]); 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void TouchEventConverterEvdev::ProcessInputEvent(const input_event& input) { 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (input.type == EV_SYN) { 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ProcessSyn(input); 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if(syn_dropped_) { 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Do nothing. This branch indicates we have lost sync with the driver. 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (input.type == EV_ABS) { 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (current_slot_ >= MAX_FINGERS) { 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG(ERROR) << "too many touch events: " << current_slot_; 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ProcessAbs(input); 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (input.type == EV_KEY) { 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) switch (input.code) { 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case BTN_TOUCH: 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) default: 178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NOTIMPLEMENTED() << "invalid code for EV_KEY: " << input.code; 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NOTIMPLEMENTED() << "invalid type: " << input.type; 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void TouchEventConverterEvdev::ProcessAbs(const input_event& input) { 186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) switch (input.code) { 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case ABS_MT_TOUCH_MAJOR: 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) altered_slots_.set(current_slot_); 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(spang): If we have all of major, minor, and orientation, 1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // we can scale the ellipse correctly. However on the Pixel we get 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // neither minor nor orientation, so this is all we can do. 1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci events_[current_slot_].radius_x_ = 1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TuxelToPixelSize(input.value, x_num_tuxels_, x_num_pixels_) / 2.0f; 1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case ABS_MT_TOUCH_MINOR: 1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci altered_slots_.set(current_slot_); 1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci events_[current_slot_].radius_y_ = 1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TuxelToPixelSize(input.value, y_num_tuxels_, y_num_pixels_) / 2.0f; 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case ABS_MT_POSITION_X: 201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) altered_slots_.set(current_slot_); 202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) events_[current_slot_].x_ = TuxelsToPixels(input.value, 203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) x_min_tuxels_, 204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) x_num_tuxels_, 205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) x_min_pixels_, 206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) x_num_pixels_); 207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case ABS_MT_POSITION_Y: 209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) altered_slots_.set(current_slot_); 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) events_[current_slot_].y_ = TuxelsToPixels(input.value, 211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) y_min_tuxels_, 212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) y_num_tuxels_, 213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) y_min_pixels_, 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) y_num_pixels_); 215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case ABS_MT_TRACKING_ID: 217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) altered_slots_.set(current_slot_); 218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (input.value < 0) { 219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) events_[current_slot_].type_ = ET_TOUCH_RELEASED; 220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) events_[current_slot_].finger_ = input.value; 222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) events_[current_slot_].type_ = ET_TOUCH_PRESSED; 223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case ABS_MT_PRESSURE: 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) altered_slots_.set(current_slot_); 227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) events_[current_slot_].pressure_ = input.value - pressure_min_; 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) events_[current_slot_].pressure_ /= pressure_max_ - pressure_min_; 229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case ABS_MT_SLOT: 231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) current_slot_ = input.value; 232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) altered_slots_.set(current_slot_); 233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) default: 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(5) << "unhandled code for EV_ABS: " << input.code; 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void TouchEventConverterEvdev::ProcessSyn(const input_event& input) { 240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) switch (input.code) { 241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SYN_REPORT: 242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (syn_dropped_) { 243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Have to re-initialize. 244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (Reinitialize()) { 245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) syn_dropped_ = false; 246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) altered_slots_.reset(); 247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG(ERROR) << "failed to re-initialize device info"; 249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ReportEvents(base::TimeDelta::FromMicroseconds( 252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) input.time.tv_sec * 1000000 + input.time.tv_usec)); 253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (is_type_a_) 255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) current_slot_ = 0; 256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SYN_MT_REPORT: 258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // For type A devices, we just get a stream of all current contacts, 259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // in some arbitrary order. 260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) events_[current_slot_++].type_ = ET_TOUCH_PRESSED; 261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) is_type_a_ = true; 262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SYN_DROPPED: 264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Some buffer has overrun. We ignore all events up to and 265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // including the next SYN_REPORT. 266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) syn_dropped_ = true; 267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) default: 269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NOTIMPLEMENTED() << "invalid code for EV_SYN: " << input.code; 270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void TouchEventConverterEvdev::ReportEvents(base::TimeDelta delta) { 274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (int i = 0; i < MAX_FINGERS; i++) { 275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (altered_slots_[i]) { 276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(rikroege): Support elliptical finger regions. 2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TouchEvent evt(events_[i].type_, 2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::PointF(events_[i].x_, events_[i].y_), 2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /* flags */ 0, 2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /* touch_id */ i, 2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delta, 2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /* radius_x */ events_[i].radius_x_, 2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /* radius_y */ events_[i].radius_y_, 2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /* angle */ 0., 2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci events_[i].pressure_); 2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback_.Run(&evt); 287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Subsequent events for this finger will be touch-move until it 289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // is released. 290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) events_[i].type_ = ET_TOUCH_MOVED; 291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 292c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) altered_slots_.reset(); 294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace ui 297