summaryrefslogtreecommitdiffstats
path: root/ui/base/ozone/event_factory_ozone.cc
blob: 1076f75885b65ade94ef12dbee3e15e8afa14c0b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Copyright (c) 2013 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/base/ozone/event_factory_ozone.h"

#include <fcntl.h>
#include <linux/input.h>
#include <poll.h>
#include <unistd.h>

#include "base/message_pump_ozone.h"
#include "base/strings/stringprintf.h"
#include "ui/base/ozone/key_event_converter_ozone.h"
#include "ui/base/ozone/touch_event_converter_ozone.h"

namespace ui {

EventFactoryOzone::EventFactoryOzone() {}

EventFactoryOzone::~EventFactoryOzone() {
  for (unsigned i = 0; i < fd_controllers_.size(); i++) {
    fd_controllers_[i]->StopWatchingFileDescriptor();
  }
}

void EventFactoryOzone::CreateEvdevWatchers() {
  // The number of devices in the directory is unknown without reading
  // the contents of the directory. Further, with hot-plugging,  the entries
  // might decrease during the execution of this loop. So exciting from the
  // loop on the first failure of open below is both cheaper and more
  // reliable.
  for (int id = 0; true; id++) {
    std::string path = base::StringPrintf("/dev/input/event%d", id);
    int fd = open(path.c_str(), O_RDONLY | O_NONBLOCK);
    if (fd < 0)
      break;
    size_t evtype = 0;
    COMPILE_ASSERT(sizeof(evtype) * 8 >= EV_MAX, evtype_wide_enough);
    if (ioctl(fd, EVIOCGBIT(0, sizeof(evtype)), &evtype) == -1) {
      DLOG(ERROR) << "failed ioctl EVIOCGBIT 0" << path;
      close(fd);
      continue;
    }

    EventConverterOzone* watcher = NULL;
    // TODO(rjkroege) Add more device types. Support hot-plugging.
    if (evtype & (1 << EV_ABS))
      watcher = new TouchEventConverterOzone(fd, id);
    else if (evtype & (1 << EV_KEY))
      watcher = new KeyEventConverterOzone();

    if (watcher) {
      base::MessagePumpLibevent::FileDescriptorWatcher* controller =
          new base::MessagePumpLibevent::FileDescriptorWatcher();
      base::MessagePumpOzone::Current()->WatchFileDescriptor(
          fd, true, base::MessagePumpLibevent::WATCH_READ, controller, watcher);
      evdev_watchers_.push_back(watcher);
      fd_controllers_.push_back(controller);
    } else {
      close(fd);
    }
  }
}

}  // namespace ui