OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/events/ozone/evdev/event_device_info.h" | 5 #include "ui/events/ozone/evdev/event_device_info.h" |
6 | 6 |
7 #include <linux/input.h> | 7 #include <linux/input.h> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/threading/thread_restrictions.h" | 10 #include "base/threading/thread_restrictions.h" |
11 | 11 |
| 12 #if !defined(EVIOCGMTSLOTS) |
| 13 #define EVIOCGMTSLOTS(len) _IOC(_IOC_READ, 'E', 0x0a, len) |
| 14 #endif |
| 15 |
12 namespace ui { | 16 namespace ui { |
13 | 17 |
14 namespace { | 18 namespace { |
15 | 19 |
16 bool GetEventBits(int fd, unsigned int type, void* buf, unsigned int size) { | 20 bool GetEventBits(int fd, unsigned int type, void* buf, unsigned int size) { |
17 if (ioctl(fd, EVIOCGBIT(type, size), buf) < 0) { | 21 if (ioctl(fd, EVIOCGBIT(type, size), buf) < 0) { |
18 DLOG(ERROR) << "failed EVIOCGBIT(" << type << ", " << size << ") on fd " | 22 DLOG(ERROR) << "failed EVIOCGBIT(" << type << ", " << size << ") on fd " |
19 << fd; | 23 << fd; |
20 return false; | 24 return false; |
21 } | 25 } |
(...skipping 11 matching lines...) Expand all Loading... |
33 } | 37 } |
34 | 38 |
35 bool GetAbsInfo(int fd, int code, struct input_absinfo* absinfo) { | 39 bool GetAbsInfo(int fd, int code, struct input_absinfo* absinfo) { |
36 if (ioctl(fd, EVIOCGABS(code), absinfo)) { | 40 if (ioctl(fd, EVIOCGABS(code), absinfo)) { |
37 DLOG(ERROR) << "failed EVIOCGABS(" << code << ") on fd " << fd; | 41 DLOG(ERROR) << "failed EVIOCGABS(" << code << ") on fd " << fd; |
38 return false; | 42 return false; |
39 } | 43 } |
40 return true; | 44 return true; |
41 } | 45 } |
42 | 46 |
| 47 // |request| needs to be the equivalent to: |
| 48 // struct input_mt_request_layout { |
| 49 // uint32_t code; |
| 50 // int32_t values[num_slots]; |
| 51 // }; |
| 52 // |
| 53 // |size| is num_slots + 1 (for code). |
| 54 bool GetSlotValues(int fd, int32_t* request, unsigned int size) { |
| 55 if (ioctl(fd, |
| 56 EVIOCGMTSLOTS(sizeof(int32_t) * size), |
| 57 request) < 0) { |
| 58 DLOG(ERROR) << "failed EVIOCGMTSLOTS(" << request[0] << ") on fd " << fd; |
| 59 return false; |
| 60 } |
| 61 |
| 62 return true; |
| 63 } |
| 64 |
43 } // namespace | 65 } // namespace |
44 | 66 |
45 EventDeviceInfo::EventDeviceInfo() { | 67 EventDeviceInfo::EventDeviceInfo() { |
46 memset(ev_bits_, 0, sizeof(ev_bits_)); | 68 memset(ev_bits_, 0, sizeof(ev_bits_)); |
47 memset(key_bits_, 0, sizeof(key_bits_)); | 69 memset(key_bits_, 0, sizeof(key_bits_)); |
48 memset(rel_bits_, 0, sizeof(rel_bits_)); | 70 memset(rel_bits_, 0, sizeof(rel_bits_)); |
49 memset(abs_bits_, 0, sizeof(abs_bits_)); | 71 memset(abs_bits_, 0, sizeof(abs_bits_)); |
50 memset(msc_bits_, 0, sizeof(msc_bits_)); | 72 memset(msc_bits_, 0, sizeof(msc_bits_)); |
51 memset(sw_bits_, 0, sizeof(sw_bits_)); | 73 memset(sw_bits_, 0, sizeof(sw_bits_)); |
52 memset(led_bits_, 0, sizeof(led_bits_)); | 74 memset(led_bits_, 0, sizeof(led_bits_)); |
(...skipping 26 matching lines...) Expand all Loading... |
79 return false; | 101 return false; |
80 | 102 |
81 if (!GetPropBits(fd, prop_bits_, sizeof(prop_bits_))) | 103 if (!GetPropBits(fd, prop_bits_, sizeof(prop_bits_))) |
82 return false; | 104 return false; |
83 | 105 |
84 for (unsigned int i = 0; i < ABS_CNT; ++i) | 106 for (unsigned int i = 0; i < ABS_CNT; ++i) |
85 if (HasAbsEvent(i)) | 107 if (HasAbsEvent(i)) |
86 if (!GetAbsInfo(fd, i, &abs_info_[i])) | 108 if (!GetAbsInfo(fd, i, &abs_info_[i])) |
87 return false; | 109 return false; |
88 | 110 |
| 111 int max_num_slots = abs_info_[ABS_MT_SLOT].maximum + 1; |
| 112 // |request| is MT code + slots. |
| 113 int32_t request[max_num_slots + 1]; |
| 114 for (unsigned int i = ABS_MT_SLOT + 1; i < ABS_MAX; ++i) { |
| 115 memset(request, 0, sizeof(request)); |
| 116 request[0] = i; |
| 117 if (HasAbsEvent(i)) |
| 118 if (!GetSlotValues(fd, request, max_num_slots + 1)) |
| 119 LOG(WARNING) << "Failed to get multitouch values for code " << i; |
| 120 |
| 121 slot_values_[i - ABS_MT_SLOT - 1].assign( |
| 122 request + 1, request + max_num_slots + 1); |
| 123 } |
| 124 |
89 return true; | 125 return true; |
90 } | 126 } |
91 | 127 |
92 bool EventDeviceInfo::HasEventType(unsigned int type) const { | 128 bool EventDeviceInfo::HasEventType(unsigned int type) const { |
93 if (type > EV_MAX) | 129 if (type > EV_MAX) |
94 return false; | 130 return false; |
95 return EvdevBitIsSet(ev_bits_, type); | 131 return EvdevBitIsSet(ev_bits_, type); |
96 } | 132 } |
97 | 133 |
98 bool EventDeviceInfo::HasKeyEvent(unsigned int code) const { | 134 bool EventDeviceInfo::HasKeyEvent(unsigned int code) const { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 } | 174 } |
139 | 175 |
140 int32 EventDeviceInfo::GetAbsMinimum(unsigned int code) const { | 176 int32 EventDeviceInfo::GetAbsMinimum(unsigned int code) const { |
141 return abs_info_[code].minimum; | 177 return abs_info_[code].minimum; |
142 } | 178 } |
143 | 179 |
144 int32 EventDeviceInfo::GetAbsMaximum(unsigned int code) const { | 180 int32 EventDeviceInfo::GetAbsMaximum(unsigned int code) const { |
145 return abs_info_[code].maximum; | 181 return abs_info_[code].maximum; |
146 } | 182 } |
147 | 183 |
| 184 int32 EventDeviceInfo::GetSlotValue(unsigned int code, |
| 185 unsigned int slot) const { |
| 186 const std::vector<int32_t>& slots = GetMtSlotsForCode(code); |
| 187 DCHECK_LE(0u, slot) << slot << " is an invalid slot"; |
| 188 DCHECK_LT(slot, slots.size()) << slot << " is an invalid slot"; |
| 189 return slots[slot]; |
| 190 } |
| 191 |
148 bool EventDeviceInfo::HasAbsXY() const { | 192 bool EventDeviceInfo::HasAbsXY() const { |
149 if (HasAbsEvent(ABS_X) && HasAbsEvent(ABS_Y)) | 193 if (HasAbsEvent(ABS_X) && HasAbsEvent(ABS_Y)) |
150 return true; | 194 return true; |
151 | 195 |
152 if (HasAbsEvent(ABS_MT_POSITION_X) && HasAbsEvent(ABS_MT_POSITION_Y)) | 196 if (HasAbsEvent(ABS_MT_POSITION_X) && HasAbsEvent(ABS_MT_POSITION_Y)) |
153 return true; | 197 return true; |
154 | 198 |
155 return false; | 199 return false; |
156 } | 200 } |
157 | 201 |
(...skipping 17 matching lines...) Expand all Loading... |
175 | 219 |
176 // Touchpads are not mapped to the screen. | 220 // Touchpads are not mapped to the screen. |
177 if (HasKeyEvent(BTN_LEFT) || HasKeyEvent(BTN_MIDDLE) || | 221 if (HasKeyEvent(BTN_LEFT) || HasKeyEvent(BTN_MIDDLE) || |
178 HasKeyEvent(BTN_RIGHT) || HasKeyEvent(BTN_TOOL_FINGER)) | 222 HasKeyEvent(BTN_RIGHT) || HasKeyEvent(BTN_TOOL_FINGER)) |
179 return false; | 223 return false; |
180 | 224 |
181 // Touchscreens are mapped to the screen. | 225 // Touchscreens are mapped to the screen. |
182 return true; | 226 return true; |
183 } | 227 } |
184 | 228 |
| 229 const std::vector<int32_t>& EventDeviceInfo::GetMtSlotsForCode(int code) const { |
| 230 int index = code - ABS_MT_SLOT - 1; |
| 231 DCHECK_LE(0, index) << code << " is not a valid multi-touch code"; |
| 232 DCHECK_LT(index, EVDEV_ABS_MT_COUNT) |
| 233 << code << " is not a valid multi-touch code"; |
| 234 return slot_values_[index]; |
| 235 } |
| 236 |
185 } // namespace ui | 237 } // namespace ui |
OLD | NEW |