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 12namespace ui { 13 14namespace { 15 16bool 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 26bool 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 35bool BitIsSet(const unsigned long* bits, unsigned int bit) { 36 return (bits[bit / EVDEV_LONG_BITS] & (1UL << (bit % EVDEV_LONG_BITS))); 37} 38 39bool 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 49EventDeviceInfo::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 61EventDeviceInfo::~EventDeviceInfo() {} 62 63bool 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 96bool EventDeviceInfo::HasEventType(unsigned int type) const { 97 if (type > EV_MAX) 98 return false; 99 return BitIsSet(ev_bits_, type); 100} 101 102bool EventDeviceInfo::HasKeyEvent(unsigned int code) const { 103 if (code > KEY_MAX) 104 return false; 105 return BitIsSet(key_bits_, code); 106} 107 108bool EventDeviceInfo::HasRelEvent(unsigned int code) const { 109 if (code > REL_MAX) 110 return false; 111 return BitIsSet(rel_bits_, code); 112} 113 114bool EventDeviceInfo::HasAbsEvent(unsigned int code) const { 115 if (code > ABS_MAX) 116 return false; 117 return BitIsSet(abs_bits_, code); 118} 119 120bool EventDeviceInfo::HasMscEvent(unsigned int code) const { 121 if (code > MSC_MAX) 122 return false; 123 return BitIsSet(msc_bits_, code); 124} 125 126bool EventDeviceInfo::HasSwEvent(unsigned int code) const { 127 if (code > SW_MAX) 128 return false; 129 return BitIsSet(sw_bits_, code); 130} 131 132bool EventDeviceInfo::HasLedEvent(unsigned int code) const { 133 if (code > LED_MAX) 134 return false; 135 return BitIsSet(led_bits_, code); 136} 137 138bool EventDeviceInfo::HasProp(unsigned int code) const { 139 if (code > INPUT_PROP_MAX) 140 return false; 141 return BitIsSet(prop_bits_, code); 142} 143 144int32 EventDeviceInfo::GetAbsMinimum(unsigned int code) const { 145 return abs_info_[code].minimum; 146} 147 148int32 EventDeviceInfo::GetAbsMaximum(unsigned int code) const { 149 return abs_info_[code].maximum; 150} 151 152bool 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 162bool EventDeviceInfo::HasRelXY() const { 163 return HasRelEvent(REL_X) && HasRelEvent(REL_Y); 164} 165 166bool 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