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