10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
20529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
30529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// found in the LICENSE file.
40529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.h"
60529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include <errno.h>
80529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include <libevdev/libevdev.h>
90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include <linux/input.h>
100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/message_loop/message_loop.h"
120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/strings/string_util.h"
130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/strings/stringprintf.h"
140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace ui {
160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace {
180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochstd::string FormatLog(const char* fmt, va_list args) {
200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string msg = base::StringPrintV(fmt, args);
210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!msg.empty() && msg[msg.size() - 1] == '\n')
220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    msg.erase(msg.end() - 1, msg.end());
230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return msg;
240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}  // namespace
270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
280529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochEventReaderLibevdevCros::EventReaderLibevdevCros(int fd,
290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                                 const base::FilePath& path,
300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                                 scoped_ptr<Delegate> delegate)
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : EventConverterEvdev(fd, path), delegate_(delegate.Pass()) {
320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  memset(&evdev_, 0, sizeof(evdev_));
330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  evdev_.log = OnLogMessage;
340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  evdev_.log_udata = this;
350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  evdev_.syn_report = OnSynReport;
360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  evdev_.syn_report_udata = this;
370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  evdev_.fd = fd;
380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  memset(&evstate_, 0, sizeof(evstate_));
400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  evdev_.evstate = &evstate_;
410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  Event_Init(&evdev_);
420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  Event_Open(&evdev_);
440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  delegate_->OnLibEvdevCrosOpen(&evdev_, &evstate_);
460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
480529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochEventReaderLibevdevCros::~EventReaderLibevdevCros() {
490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  Stop();
500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EvdevClose(&evdev_);
510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
530529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochEventReaderLibevdevCros::Delegate::~Delegate() {}
540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid EventReaderLibevdevCros::OnFileCanReadWithoutBlocking(int fd) {
560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (EvdevRead(&evdev_)) {
570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (errno == EINTR || errno == EAGAIN)
580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return;
590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (errno != ENODEV)
600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      PLOG(ERROR) << "error reading device " << path_.value();
610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    Stop();
620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// static
670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid EventReaderLibevdevCros::OnSynReport(void* data,
680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                          EventStateRec* evstate,
690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                          struct timeval* tv) {
700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EventReaderLibevdevCros* reader = static_cast<EventReaderLibevdevCros*>(data);
710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  reader->delegate_->OnLibEvdevCrosEvent(&reader->evdev_, evstate, *tv);
720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// static
750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid EventReaderLibevdevCros::OnLogMessage(void* data,
760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                           int level,
770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                           const char* fmt,
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                           ...) {
790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  va_list args;
800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  va_start(args, fmt);
810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (level >= LOGLEVEL_ERROR)
820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    LOG(ERROR) << "libevdev: " << FormatLog(fmt, args);
830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  else if (level >= LOGLEVEL_WARNING)
840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    LOG(WARNING) << "libevdev: " << FormatLog(fmt, args);
850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  else
860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    VLOG(3) << "libevdev: " << FormatLog(fmt, args);
870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  va_end(args);
880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}  // namespace ui
91