Home | History | Annotate | Download | only in evdev
      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 
     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 
     31 bool IsTouchScreen(const EventDeviceInfo& devinfo) {
     32   return devinfo.HasEventType(EV_ABS) && !IsTouchPad(devinfo);
     33 }
     34 
     35 }  // namespace
     36 
     37 EventFactoryEvdev::EventFactoryEvdev() {}
     38 
     39 EventFactoryEvdev::~EventFactoryEvdev() {}
     40 
     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