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_device_info.h"
      6 
      7 #include <linux/input.h>
      8 
      9 #include "base/logging.h"
     10 #include "base/threading/thread_restrictions.h"
     11 
     12 namespace ui {
     13 
     14 namespace {
     15 
     16 bool GetEventBits(int fd, unsigned int type, void* buf, unsigned int size) {
     17   if (ioctl(fd, EVIOCGBIT(type, size), buf) < 0) {
     18     DLOG(ERROR) << "failed EVIOCGBIT(" << type << ", " << size << ") on fd "
     19                 << fd;
     20     return false;
     21   }
     22 
     23   return true;
     24 }
     25 
     26 bool GetPropBits(int fd, void* buf, unsigned int size) {
     27   if (ioctl(fd, EVIOCGPROP(size), buf) < 0) {
     28     DLOG(ERROR) << "failed EVIOCGPROP(" << size << ") on fd " << fd;
     29     return false;
     30   }
     31 
     32   return true;
     33 }
     34 
     35 bool BitIsSet(const unsigned long* bits, unsigned int bit) {
     36   return (bits[bit / EVDEV_LONG_BITS] & (1UL << (bit % EVDEV_LONG_BITS)));
     37 }
     38 
     39 bool GetAbsInfo(int fd, int code, struct input_absinfo* absinfo) {
     40   if (ioctl(fd, EVIOCGABS(code), absinfo)) {
     41     DLOG(ERROR) << "failed EVIOCGABS(" << code << ") on fd " << fd;
     42     return false;
     43   }
     44   return true;
     45 }
     46 
     47 }  // namespace
     48 
     49 EventDeviceInfo::EventDeviceInfo() {
     50   memset(ev_bits_, 0, sizeof(ev_bits_));
     51   memset(key_bits_, 0, sizeof(key_bits_));
     52   memset(rel_bits_, 0, sizeof(rel_bits_));
     53   memset(abs_bits_, 0, sizeof(abs_bits_));
     54   memset(msc_bits_, 0, sizeof(msc_bits_));
     55   memset(sw_bits_, 0, sizeof(sw_bits_));
     56   memset(led_bits_, 0, sizeof(led_bits_));
     57   memset(prop_bits_, 0, sizeof(prop_bits_));
     58   memset(abs_info_, 0, sizeof(abs_info_));
     59 }
     60 
     61 EventDeviceInfo::~EventDeviceInfo() {}
     62 
     63 bool EventDeviceInfo::Initialize(int fd) {
     64   if (!GetEventBits(fd, 0, ev_bits_, sizeof(ev_bits_)))
     65     return false;
     66 
     67   if (!GetEventBits(fd, EV_KEY, key_bits_, sizeof(key_bits_)))
     68     return false;
     69 
     70   if (!GetEventBits(fd, EV_REL, rel_bits_, sizeof(rel_bits_)))
     71     return false;
     72 
     73   if (!GetEventBits(fd, EV_ABS, abs_bits_, sizeof(abs_bits_)))
     74     return false;
     75 
     76   if (!GetEventBits(fd, EV_MSC, msc_bits_, sizeof(msc_bits_)))
     77     return false;
     78 
     79   if (!GetEventBits(fd, EV_SW, sw_bits_, sizeof(sw_bits_)))
     80     return false;
     81 
     82   if (!GetEventBits(fd, EV_LED, led_bits_, sizeof(led_bits_)))
     83     return false;
     84 
     85   if (!GetPropBits(fd, prop_bits_, sizeof(prop_bits_)))
     86     return false;
     87 
     88   for (unsigned int i = 0; i < ABS_CNT; ++i)
     89     if (HasAbsEvent(i))
     90       if (!GetAbsInfo(fd, i, &abs_info_[i]))
     91         return false;
     92 
     93   return true;
     94 }
     95 
     96 bool EventDeviceInfo::HasEventType(unsigned int type) const {
     97   if (type > EV_MAX)
     98     return false;
     99   return BitIsSet(ev_bits_, type);
    100 }
    101 
    102 bool EventDeviceInfo::HasKeyEvent(unsigned int code) const {
    103   if (code > KEY_MAX)
    104     return false;
    105   return BitIsSet(key_bits_, code);
    106 }
    107 
    108 bool EventDeviceInfo::HasRelEvent(unsigned int code) const {
    109   if (code > REL_MAX)
    110     return false;
    111   return BitIsSet(rel_bits_, code);
    112 }
    113 
    114 bool EventDeviceInfo::HasAbsEvent(unsigned int code) const {
    115   if (code > ABS_MAX)
    116     return false;
    117   return BitIsSet(abs_bits_, code);
    118 }
    119 
    120 bool EventDeviceInfo::HasMscEvent(unsigned int code) const {
    121   if (code > MSC_MAX)
    122     return false;
    123   return BitIsSet(msc_bits_, code);
    124 }
    125 
    126 bool EventDeviceInfo::HasSwEvent(unsigned int code) const {
    127   if (code > SW_MAX)
    128     return false;
    129   return BitIsSet(sw_bits_, code);
    130 }
    131 
    132 bool EventDeviceInfo::HasLedEvent(unsigned int code) const {
    133   if (code > LED_MAX)
    134     return false;
    135   return BitIsSet(led_bits_, code);
    136 }
    137 
    138 bool EventDeviceInfo::HasProp(unsigned int code) const {
    139   if (code > INPUT_PROP_MAX)
    140     return false;
    141   return BitIsSet(prop_bits_, code);
    142 }
    143 
    144 int32 EventDeviceInfo::GetAbsMinimum(unsigned int code) const {
    145   return abs_info_[code].minimum;
    146 }
    147 
    148 int32 EventDeviceInfo::GetAbsMaximum(unsigned int code) const {
    149   return abs_info_[code].maximum;
    150 }
    151 
    152 bool EventDeviceInfo::HasAbsXY() const {
    153   if (HasAbsEvent(ABS_X) && HasAbsEvent(ABS_Y))
    154     return true;
    155 
    156   if (HasAbsEvent(ABS_MT_POSITION_X) && HasAbsEvent(ABS_MT_POSITION_Y))
    157     return true;
    158 
    159   return false;
    160 }
    161 
    162 bool EventDeviceInfo::HasRelXY() const {
    163   return HasRelEvent(REL_X) && HasRelEvent(REL_Y);
    164 }
    165 
    166 bool EventDeviceInfo::IsMappedToScreen() const {
    167   // Device position is mapped directly to the screen.
    168   if (HasProp(INPUT_PROP_DIRECT))
    169     return true;
    170 
    171   // Device position moves the cursor.
    172   if (HasProp(INPUT_PROP_POINTER))
    173     return false;
    174 
    175   // Tablets are mapped to the screen.
    176   if (HasKeyEvent(BTN_TOOL_PEN) || HasKeyEvent(BTN_STYLUS) ||
    177       HasKeyEvent(BTN_STYLUS2))
    178     return true;
    179 
    180   // Touchpads are not mapped to the screen.
    181   if (HasKeyEvent(BTN_LEFT) || HasKeyEvent(BTN_MIDDLE) ||
    182       HasKeyEvent(BTN_RIGHT) || HasKeyEvent(BTN_TOOL_FINGER))
    183     return false;
    184 
    185   // Touchscreens are mapped to the screen.
    186   return true;
    187 }
    188 
    189 }  // namespace ui
    190