• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ui/events/ozone/evdev/event_factory.h"
6 
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <linux/input.h>
10 #include <poll.h>
11 #include <unistd.h>
12 
13 #include "base/strings/stringprintf.h"
14 #include "ui/events/ozone/evdev/event_device_info.h"
15 #include "ui/events/ozone/evdev/key_event_converter.h"
16 #include "ui/events/ozone/evdev/touch_event_converter.h"
17 #include "ui/events/ozone/event_factory_ozone.h"
18 
19 namespace ui {
20 
21 namespace {
22 
IsTouchPad(const EventDeviceInfo & devinfo)23 bool IsTouchPad(const EventDeviceInfo& devinfo) {
24   if (!devinfo.HasEventType(EV_ABS))
25     return false;
26 
27   return devinfo.HasKeyEvent(BTN_LEFT) || devinfo.HasKeyEvent(BTN_MIDDLE) ||
28          devinfo.HasKeyEvent(BTN_RIGHT) || devinfo.HasKeyEvent(BTN_TOOL_FINGER);
29 }
30 
IsTouchScreen(const EventDeviceInfo & devinfo)31 bool IsTouchScreen(const EventDeviceInfo& devinfo) {
32   return devinfo.HasEventType(EV_ABS) && !IsTouchPad(devinfo);
33 }
34 
35 }  // namespace
36 
EventFactoryEvdev()37 EventFactoryEvdev::EventFactoryEvdev() {}
38 
~EventFactoryEvdev()39 EventFactoryEvdev::~EventFactoryEvdev() {}
40 
StartProcessingEvents()41 void EventFactoryEvdev::StartProcessingEvents() {
42   // The number of devices in the directory is unknown without reading
43   // the contents of the directory. Further, with hot-plugging,  the entries
44   // might decrease during the execution of this loop. So exciting from the
45   // loop on the first failure of open below is both cheaper and more
46   // reliable.
47   for (int id = 0; true; id++) {
48     std::string path = base::StringPrintf("/dev/input/event%d", id);
49     int fd = open(path.c_str(), O_RDONLY | O_NONBLOCK);
50     if (fd < 0) {
51       DLOG(ERROR) << "Cannot open '" << path << "': " << strerror(errno);
52       break;
53     }
54 
55     EventDeviceInfo devinfo;
56     if (!devinfo.Initialize(fd)) {
57       DLOG(ERROR) << "failed to get device information for " << path;
58       close(fd);
59       continue;
60     }
61 
62     if (IsTouchPad(devinfo)) {
63       LOG(WARNING) << "touchpad device not supported: " << path;
64       close(fd);
65       continue;
66     }
67 
68     scoped_ptr<EventConverterOzone> converter;
69     // TODO(rjkroege) Add more device types. Support hot-plugging.
70     if (IsTouchScreen(devinfo))
71       converter.reset(new TouchEventConverterEvdev(fd, id));
72     else if (devinfo.HasEventType(EV_KEY))
73       converter.reset(new KeyEventConverterEvdev(fd, id, &modifiers_));
74 
75     if (converter) {
76       AddEventConverter(fd, converter.Pass());
77     } else {
78       close(fd);
79     }
80   }
81 }
82 
83 }  // namespace ui
84