| 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" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 } | 45 } |
| 46 | 46 |
| 47 // |request| needs to be the equivalent to: | 47 // |request| needs to be the equivalent to: |
| 48 // struct input_mt_request_layout { | 48 // struct input_mt_request_layout { |
| 49 // uint32_t code; | 49 // uint32_t code; |
| 50 // int32_t values[num_slots]; | 50 // int32_t values[num_slots]; |
| 51 // }; | 51 // }; |
| 52 // | 52 // |
| 53 // |size| is num_slots + 1 (for code). | 53 // |size| is num_slots + 1 (for code). |
| 54 bool GetSlotValues(int fd, int32_t* request, unsigned int size) { | 54 bool GetSlotValues(int fd, int32_t* request, unsigned int size) { |
| 55 if (ioctl(fd, | 55 size_t data_size = size * sizeof(*request); |
| 56 EVIOCGMTSLOTS(sizeof(int32_t) * size), | 56 |
| 57 request) < 0) { | 57 if (ioctl(fd, EVIOCGMTSLOTS(data_size), request) < 0) { |
| 58 DLOG(ERROR) << "failed EVIOCGMTSLOTS(" << request[0] << ") on fd " << fd; | 58 DLOG(ERROR) << "failed EVIOCGMTSLOTS(" << request[0] << ") on fd " << fd; |
| 59 return false; | 59 return false; |
| 60 } | 60 } |
| 61 | 61 |
| 62 return true; | 62 return true; |
| 63 } | 63 } |
| 64 | 64 |
| 65 void AssignBitset(const unsigned long* src, | 65 void AssignBitset(const unsigned long* src, |
| 66 size_t src_len, | 66 size_t src_len, |
| 67 unsigned long* dst, | 67 unsigned long* dst, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 return false; | 110 return false; |
| 111 | 111 |
| 112 if (!GetPropBits(fd, prop_bits_, sizeof(prop_bits_))) | 112 if (!GetPropBits(fd, prop_bits_, sizeof(prop_bits_))) |
| 113 return false; | 113 return false; |
| 114 | 114 |
| 115 for (unsigned int i = 0; i < ABS_CNT; ++i) | 115 for (unsigned int i = 0; i < ABS_CNT; ++i) |
| 116 if (HasAbsEvent(i)) | 116 if (HasAbsEvent(i)) |
| 117 if (!GetAbsInfo(fd, i, &abs_info_[i])) | 117 if (!GetAbsInfo(fd, i, &abs_info_[i])) |
| 118 return false; | 118 return false; |
| 119 | 119 |
| 120 int max_num_slots = abs_info_[ABS_MT_SLOT].maximum + 1; | 120 int max_num_slots = GetAbsMtSlotCount(); |
| 121 |
| 121 // |request| is MT code + slots. | 122 // |request| is MT code + slots. |
| 122 int32_t request[max_num_slots + 1]; | 123 int32_t request[max_num_slots + 1]; |
| 123 for (unsigned int i = ABS_MT_SLOT + 1; i < ABS_MAX; ++i) { | 124 int32_t* request_code = &request[0]; |
| 125 int32_t* request_slots = &request[1]; |
| 126 for (unsigned int i = EVDEV_ABS_MT_FIRST; i <= EVDEV_ABS_MT_LAST; ++i) { |
| 127 if (!HasAbsEvent(i)) |
| 128 continue; |
| 129 |
| 124 memset(request, 0, sizeof(request)); | 130 memset(request, 0, sizeof(request)); |
| 125 request[0] = i; | 131 *request_code = i; |
| 126 if (HasAbsEvent(i)) | 132 if (!GetSlotValues(fd, request, max_num_slots + 1)) |
| 127 if (!GetSlotValues(fd, request, max_num_slots + 1)) | 133 LOG(WARNING) << "Failed to get multitouch values for code " << i; |
| 128 LOG(WARNING) << "Failed to get multitouch values for code " << i; | |
| 129 | 134 |
| 130 slot_values_[i - ABS_MT_SLOT - 1].assign( | 135 std::vector<int32_t>* slots = &slot_values_[i - EVDEV_ABS_MT_FIRST]; |
| 131 request + 1, request + max_num_slots + 1); | 136 slots->assign(request_slots, request_slots + max_num_slots); |
| 132 } | 137 } |
| 133 | 138 |
| 134 return true; | 139 return true; |
| 135 } | 140 } |
| 136 | 141 |
| 137 void EventDeviceInfo::SetEventTypes(const unsigned long* ev_bits, size_t len) { | 142 void EventDeviceInfo::SetEventTypes(const unsigned long* ev_bits, size_t len) { |
| 138 AssignBitset(ev_bits, len, ev_bits_, arraysize(ev_bits_)); | 143 AssignBitset(ev_bits, len, ev_bits_, arraysize(ev_bits_)); |
| 139 } | 144 } |
| 140 | 145 |
| 141 void EventDeviceInfo::SetKeyEvents(const unsigned long* key_bits, size_t len) { | 146 void EventDeviceInfo::SetKeyEvents(const unsigned long* key_bits, size_t len) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 167 } | 172 } |
| 168 | 173 |
| 169 void EventDeviceInfo::SetAbsInfo(unsigned int code, | 174 void EventDeviceInfo::SetAbsInfo(unsigned int code, |
| 170 const input_absinfo& abs_info) { | 175 const input_absinfo& abs_info) { |
| 171 if (code > ABS_MAX) | 176 if (code > ABS_MAX) |
| 172 return; | 177 return; |
| 173 | 178 |
| 174 memcpy(&abs_info_[code], &abs_info, sizeof(abs_info)); | 179 memcpy(&abs_info_[code], &abs_info, sizeof(abs_info)); |
| 175 } | 180 } |
| 176 | 181 |
| 182 void EventDeviceInfo::SetAbsMtSlots(int code, |
| 183 const std::vector<int32_t>& values) { |
| 184 DCHECK_EQ(GetAbsMtSlotCount(), values.size()); |
| 185 int index = code - EVDEV_ABS_MT_FIRST; |
| 186 if (index < 0 || index >= EVDEV_ABS_MT_COUNT) |
| 187 return; |
| 188 slot_values_[index] = values; |
| 189 } |
| 190 |
| 177 bool EventDeviceInfo::HasEventType(unsigned int type) const { | 191 bool EventDeviceInfo::HasEventType(unsigned int type) const { |
| 178 if (type > EV_MAX) | 192 if (type > EV_MAX) |
| 179 return false; | 193 return false; |
| 180 return EvdevBitIsSet(ev_bits_, type); | 194 return EvdevBitIsSet(ev_bits_, type); |
| 181 } | 195 } |
| 182 | 196 |
| 183 bool EventDeviceInfo::HasKeyEvent(unsigned int code) const { | 197 bool EventDeviceInfo::HasKeyEvent(unsigned int code) const { |
| 184 if (code > KEY_MAX) | 198 if (code > KEY_MAX) |
| 185 return false; | 199 return false; |
| 186 return EvdevBitIsSet(key_bits_, code); | 200 return EvdevBitIsSet(key_bits_, code); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 215 return false; | 229 return false; |
| 216 return EvdevBitIsSet(led_bits_, code); | 230 return EvdevBitIsSet(led_bits_, code); |
| 217 } | 231 } |
| 218 | 232 |
| 219 bool EventDeviceInfo::HasProp(unsigned int code) const { | 233 bool EventDeviceInfo::HasProp(unsigned int code) const { |
| 220 if (code > INPUT_PROP_MAX) | 234 if (code > INPUT_PROP_MAX) |
| 221 return false; | 235 return false; |
| 222 return EvdevBitIsSet(prop_bits_, code); | 236 return EvdevBitIsSet(prop_bits_, code); |
| 223 } | 237 } |
| 224 | 238 |
| 225 int32 EventDeviceInfo::GetAbsMinimum(unsigned int code) const { | 239 int32_t EventDeviceInfo::GetAbsMinimum(unsigned int code) const { |
| 226 return abs_info_[code].minimum; | 240 return abs_info_[code].minimum; |
| 227 } | 241 } |
| 228 | 242 |
| 229 int32 EventDeviceInfo::GetAbsMaximum(unsigned int code) const { | 243 int32_t EventDeviceInfo::GetAbsMaximum(unsigned int code) const { |
| 230 return abs_info_[code].maximum; | 244 return abs_info_[code].maximum; |
| 231 } | 245 } |
| 232 | 246 |
| 233 int32 EventDeviceInfo::GetSlotValue(unsigned int code, | 247 uint32_t EventDeviceInfo::GetAbsMtSlotCount() const { |
| 234 unsigned int slot) const { | 248 if (!HasAbsEvent(ABS_MT_SLOT)) |
| 235 const std::vector<int32_t>& slots = GetMtSlotsForCode(code); | 249 return 0; |
| 236 DCHECK_LE(0u, slot) << slot << " is an invalid slot"; | 250 return GetAbsMaximum(ABS_MT_SLOT) + 1; |
| 237 DCHECK_LT(slot, slots.size()) << slot << " is an invalid slot"; | 251 } |
| 238 return slots[slot]; | 252 |
| 253 int32_t EventDeviceInfo::GetAbsMtSlotValue(unsigned int code, |
| 254 unsigned int slot) const { |
| 255 unsigned int index = code - EVDEV_ABS_MT_FIRST; |
| 256 DCHECK(index < EVDEV_ABS_MT_COUNT); |
| 257 return slot_values_[index][slot]; |
| 258 } |
| 259 |
| 260 int32_t EventDeviceInfo::GetAbsMtSlotValueWithDefault( |
| 261 unsigned int code, |
| 262 unsigned int slot, |
| 263 int32_t default_value) const { |
| 264 if (!HasAbsEvent(code)) |
| 265 return default_value; |
| 266 return GetAbsMtSlotValue(code, slot); |
| 239 } | 267 } |
| 240 | 268 |
| 241 bool EventDeviceInfo::HasAbsXY() const { | 269 bool EventDeviceInfo::HasAbsXY() const { |
| 242 return HasAbsEvent(ABS_X) && HasAbsEvent(ABS_Y); | 270 return HasAbsEvent(ABS_X) && HasAbsEvent(ABS_Y); |
| 243 } | 271 } |
| 244 | 272 |
| 245 bool EventDeviceInfo::HasMTAbsXY() const { | 273 bool EventDeviceInfo::HasMTAbsXY() const { |
| 246 return HasAbsEvent(ABS_MT_POSITION_X) && HasAbsEvent(ABS_MT_POSITION_Y); | 274 return HasAbsEvent(ABS_MT_POSITION_X) && HasAbsEvent(ABS_MT_POSITION_Y); |
| 247 } | 275 } |
| 248 | 276 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 } | 345 } |
| 318 | 346 |
| 319 bool EventDeviceInfo::HasTablet() const { | 347 bool EventDeviceInfo::HasTablet() const { |
| 320 return HasAbsXY() && HasPointer() && HasStylus(); | 348 return HasAbsXY() && HasPointer() && HasStylus(); |
| 321 } | 349 } |
| 322 | 350 |
| 323 bool EventDeviceInfo::HasTouchscreen() const { | 351 bool EventDeviceInfo::HasTouchscreen() const { |
| 324 return HasAbsXY() && HasDirect(); | 352 return HasAbsXY() && HasDirect(); |
| 325 } | 353 } |
| 326 | 354 |
| 327 const std::vector<int32_t>& EventDeviceInfo::GetMtSlotsForCode(int code) const { | |
| 328 int index = code - ABS_MT_SLOT - 1; | |
| 329 DCHECK_LE(0, index) << code << " is not a valid multi-touch code"; | |
| 330 DCHECK_LT(index, EVDEV_ABS_MT_COUNT) | |
| 331 << code << " is not a valid multi-touch code"; | |
| 332 return slot_values_[index]; | |
| 333 } | |
| 334 | |
| 335 EventDeviceInfo::LegacyAbsoluteDeviceType | 355 EventDeviceInfo::LegacyAbsoluteDeviceType |
| 336 EventDeviceInfo::ProbeLegacyAbsoluteDevice() const { | 356 EventDeviceInfo::ProbeLegacyAbsoluteDevice() const { |
| 337 if (!HasAbsXY()) | 357 if (!HasAbsXY()) |
| 338 return LegacyAbsoluteDeviceType::LADT_NONE; | 358 return LegacyAbsoluteDeviceType::LADT_NONE; |
| 339 | 359 |
| 340 if (HasStylus()) | 360 if (HasStylus()) |
| 341 return LegacyAbsoluteDeviceType::LADT_TABLET; | 361 return LegacyAbsoluteDeviceType::LADT_TABLET; |
| 342 | 362 |
| 343 if (HasKeyEvent(BTN_TOOL_FINGER) && HasKeyEvent(BTN_TOUCH)) | 363 if (HasKeyEvent(BTN_TOOL_FINGER) && HasKeyEvent(BTN_TOUCH)) |
| 344 return LegacyAbsoluteDeviceType::LADT_TOUCHPAD; | 364 return LegacyAbsoluteDeviceType::LADT_TOUCHPAD; |
| 345 | 365 |
| 346 if (HasKeyEvent(BTN_TOUCH)) | 366 if (HasKeyEvent(BTN_TOUCH)) |
| 347 return LegacyAbsoluteDeviceType::LADT_TOUCHSCREEN; | 367 return LegacyAbsoluteDeviceType::LADT_TOUCHSCREEN; |
| 348 | 368 |
| 349 return LegacyAbsoluteDeviceType::LADT_NONE; | 369 return LegacyAbsoluteDeviceType::LADT_NONE; |
| 350 } | 370 } |
| 351 | 371 |
| 352 } // namespace ui | 372 } // namespace ui |
| OLD | NEW |