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