Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ui / events / ozone / evdev / event_device_info.cc
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 #if !defined(EVIOCGMTSLOTS)
13 #define EVIOCGMTSLOTS(len) _IOC(_IOC_READ, 'E', 0x0a, len)
14 #endif
15
16 namespace ui {
17
18 namespace {
19
20 bool GetEventBits(int fd, unsigned int type, void* buf, unsigned int size) {
21   if (ioctl(fd, EVIOCGBIT(type, size), buf) < 0) {
22     DLOG(ERROR) << "failed EVIOCGBIT(" << type << ", " << size << ") on fd "
23                 << fd;
24     return false;
25   }
26
27   return true;
28 }
29
30 bool GetPropBits(int fd, void* buf, unsigned int size) {
31   if (ioctl(fd, EVIOCGPROP(size), buf) < 0) {
32     DLOG(ERROR) << "failed EVIOCGPROP(" << size << ") on fd " << fd;
33     return false;
34   }
35
36   return true;
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 // |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
65 }  // namespace
66
67 EventDeviceInfo::EventDeviceInfo() {
68   memset(ev_bits_, 0, sizeof(ev_bits_));
69   memset(key_bits_, 0, sizeof(key_bits_));
70   memset(rel_bits_, 0, sizeof(rel_bits_));
71   memset(abs_bits_, 0, sizeof(abs_bits_));
72   memset(msc_bits_, 0, sizeof(msc_bits_));
73   memset(sw_bits_, 0, sizeof(sw_bits_));
74   memset(led_bits_, 0, sizeof(led_bits_));
75   memset(prop_bits_, 0, sizeof(prop_bits_));
76   memset(abs_info_, 0, sizeof(abs_info_));
77 }
78
79 EventDeviceInfo::~EventDeviceInfo() {}
80
81 bool EventDeviceInfo::Initialize(int fd) {
82   if (!GetEventBits(fd, 0, ev_bits_, sizeof(ev_bits_)))
83     return false;
84
85   if (!GetEventBits(fd, EV_KEY, key_bits_, sizeof(key_bits_)))
86     return false;
87
88   if (!GetEventBits(fd, EV_REL, rel_bits_, sizeof(rel_bits_)))
89     return false;
90
91   if (!GetEventBits(fd, EV_ABS, abs_bits_, sizeof(abs_bits_)))
92     return false;
93
94   if (!GetEventBits(fd, EV_MSC, msc_bits_, sizeof(msc_bits_)))
95     return false;
96
97   if (!GetEventBits(fd, EV_SW, sw_bits_, sizeof(sw_bits_)))
98     return false;
99
100   if (!GetEventBits(fd, EV_LED, led_bits_, sizeof(led_bits_)))
101     return false;
102
103   if (!GetPropBits(fd, prop_bits_, sizeof(prop_bits_)))
104     return false;
105
106   for (unsigned int i = 0; i < ABS_CNT; ++i)
107     if (HasAbsEvent(i))
108       if (!GetAbsInfo(fd, i, &abs_info_[i]))
109         return false;
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
125   return true;
126 }
127
128 bool EventDeviceInfo::HasEventType(unsigned int type) const {
129   if (type > EV_MAX)
130     return false;
131   return EvdevBitIsSet(ev_bits_, type);
132 }
133
134 bool EventDeviceInfo::HasKeyEvent(unsigned int code) const {
135   if (code > KEY_MAX)
136     return false;
137   return EvdevBitIsSet(key_bits_, code);
138 }
139
140 bool EventDeviceInfo::HasRelEvent(unsigned int code) const {
141   if (code > REL_MAX)
142     return false;
143   return EvdevBitIsSet(rel_bits_, code);
144 }
145
146 bool EventDeviceInfo::HasAbsEvent(unsigned int code) const {
147   if (code > ABS_MAX)
148     return false;
149   return EvdevBitIsSet(abs_bits_, code);
150 }
151
152 bool EventDeviceInfo::HasMscEvent(unsigned int code) const {
153   if (code > MSC_MAX)
154     return false;
155   return EvdevBitIsSet(msc_bits_, code);
156 }
157
158 bool EventDeviceInfo::HasSwEvent(unsigned int code) const {
159   if (code > SW_MAX)
160     return false;
161   return EvdevBitIsSet(sw_bits_, code);
162 }
163
164 bool EventDeviceInfo::HasLedEvent(unsigned int code) const {
165   if (code > LED_MAX)
166     return false;
167   return EvdevBitIsSet(led_bits_, code);
168 }
169
170 bool EventDeviceInfo::HasProp(unsigned int code) const {
171   if (code > INPUT_PROP_MAX)
172     return false;
173   return EvdevBitIsSet(prop_bits_, code);
174 }
175
176 int32 EventDeviceInfo::GetAbsMinimum(unsigned int code) const {
177   return abs_info_[code].minimum;
178 }
179
180 int32 EventDeviceInfo::GetAbsMaximum(unsigned int code) const {
181   return abs_info_[code].maximum;
182 }
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
192 bool EventDeviceInfo::HasAbsXY() const {
193   if (HasAbsEvent(ABS_X) && HasAbsEvent(ABS_Y))
194     return true;
195
196   if (HasAbsEvent(ABS_MT_POSITION_X) && HasAbsEvent(ABS_MT_POSITION_Y))
197     return true;
198
199   return false;
200 }
201
202 bool EventDeviceInfo::HasRelXY() const {
203   return HasRelEvent(REL_X) && HasRelEvent(REL_Y);
204 }
205
206 bool EventDeviceInfo::IsMappedToScreen() const {
207   // Device position is mapped directly to the screen.
208   if (HasProp(INPUT_PROP_DIRECT))
209     return true;
210
211   // Device position moves the cursor.
212   if (HasProp(INPUT_PROP_POINTER))
213     return false;
214
215   // Tablets are mapped to the screen.
216   if (HasKeyEvent(BTN_TOOL_PEN) || HasKeyEvent(BTN_STYLUS) ||
217       HasKeyEvent(BTN_STYLUS2))
218     return true;
219
220   // Touchpads are not mapped to the screen.
221   if (HasKeyEvent(BTN_LEFT) || HasKeyEvent(BTN_MIDDLE) ||
222       HasKeyEvent(BTN_RIGHT) || HasKeyEvent(BTN_TOOL_FINGER))
223     return false;
224
225   // Touchscreens are mapped to the screen.
226   return true;
227 }
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
237 }  // namespace ui