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