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 #ifndef UI_EVENTS_OZONE_EVDEV_EVENT_DEVICE_INFO_H_
6 #define UI_EVENTS_OZONE_EVDEV_EVENT_DEVICE_INFO_H_
7 
8 #include <limits.h>
9 #include <linux/input.h>
10 #include <stddef.h>
11 #include <stdint.h>
12 
13 #include <string>
14 #include <vector>
15 
16 #include "base/component_export.h"
17 #include "base/macros.h"
18 #include "ui/events/devices/input_device.h"
19 #include "ui/events/ozone/evdev/event_device_util.h"
20 
21 #if !defined(ABS_MT_TOOL_Y)
22 #define ABS_MT_TOOL_Y 0x3d
23 #endif
24 
25 // ABS_MT_SLOT isn't valid options for EVIOCGMTSLOTS ioctl.
26 #define EVDEV_ABS_MT_FIRST ABS_MT_TOUCH_MAJOR
27 #define EVDEV_ABS_MT_LAST ABS_MT_TOOL_Y
28 #define EVDEV_ABS_MT_COUNT (EVDEV_ABS_MT_LAST - EVDEV_ABS_MT_FIRST + 1)
29 
30 namespace base {
31 class FilePath;
32 }
33 
34 namespace ui {
35 
36 // Input device types.
COMPONENT_EXPORT(EVDEV)37 enum COMPONENT_EXPORT(EVDEV) EventDeviceType {
38   DT_KEYBOARD,
39   DT_MOUSE,
40   DT_POINTING_STICK,
41   DT_TOUCHPAD,
42   DT_TOUCHSCREEN,
43   DT_MULTITOUCH,
44   DT_MULTITOUCH_MOUSE,
45   DT_ALL,
46 };
47 
48 // Device information for Linux input devices
49 //
50 // This stores and queries information about input devices; in
51 // particular it knows which events the device can generate.
COMPONENT_EXPORT(EVDEV)52 class COMPONENT_EXPORT(EVDEV) EventDeviceInfo {
53  public:
54   EventDeviceInfo();
55   ~EventDeviceInfo();
56 
57   // Initialize device information from an open device.
58   bool Initialize(int fd, const base::FilePath& path);
59 
60   // Manual initialization.
61   void SetEventTypes(const unsigned long* ev_bits, size_t len);
62   void SetKeyEvents(const unsigned long* key_bits, size_t len);
63   void SetRelEvents(const unsigned long* rel_bits, size_t len);
64   void SetAbsEvents(const unsigned long* abs_bits, size_t len);
65   void SetMscEvents(const unsigned long* msc_bits, size_t len);
66   void SetSwEvents(const unsigned long* sw_bits, size_t len);
67   void SetLedEvents(const unsigned long* led_bits, size_t len);
68   void SetFfEvents(const unsigned long* ff_bits, size_t len);
69   void SetProps(const unsigned long* prop_bits, size_t len);
70   void SetAbsInfo(unsigned int code, const input_absinfo& absinfo);
71   void SetAbsMtSlots(unsigned int code, const std::vector<int32_t>& values);
72   void SetAbsMtSlot(unsigned int code, unsigned int slot, uint32_t value);
73   void SetDeviceType(InputDeviceType type);
74   void SetId(input_id id);
75   void SetName(const std::string& name);
76 
77   // Check events this device can generate.
78   bool HasEventType(unsigned int type) const;
79   bool HasKeyEvent(unsigned int code) const;
80   bool HasRelEvent(unsigned int code) const;
81   bool HasAbsEvent(unsigned int code) const;
82   bool HasMscEvent(unsigned int code) const;
83   bool HasSwEvent(unsigned int code) const;
84   bool HasLedEvent(unsigned int code) const;
85   bool HasFfEvent(unsigned int code) const;
86 
87   // Properties of absolute axes.
88   int32_t GetAbsMinimum(unsigned int code) const;
89   int32_t GetAbsMaximum(unsigned int code) const;
90   int32_t GetAbsResolution(unsigned int code) const;
91   int32_t GetAbsValue(unsigned int code) const;
92   input_absinfo GetAbsInfoByCode(unsigned int code) const;
93   uint32_t GetAbsMtSlotCount() const;
94   int32_t GetAbsMtSlotValue(unsigned int code, unsigned int slot) const;
95   int32_t GetAbsMtSlotValueWithDefault(unsigned int code,
96                                        unsigned int slot,
97                                        int32_t default_value) const;
98 
99   // Device identification.
100   const std::string& name() const { return name_; }
101   const std::string& phys() const { return phys_; }
102   uint16_t bustype() const { return input_id_.bustype; }
103   uint16_t vendor_id() const { return input_id_.vendor; }
104   uint16_t product_id() const { return input_id_.product; }
105   uint16_t version() const { return input_id_.version; }
106 
107   // Check input device properties.
108   bool HasProp(unsigned int code) const;
109 
110   // Has absolute X & Y axes (excludes MT)
111   bool HasAbsXY() const;
112 
113   // Has MT absolute X & Y events.
114   bool HasMTAbsXY() const;
115 
116   // Has relative X & Y axes.
117   bool HasRelXY() const;
118 
119   // Has multitouch protocol "B".
120   bool HasMultitouch() const;
121 
122   // Determine whether this is a "Direct Touch" device e.g. touchscreen.
123   // Corresponds to INPUT_PROP_DIRECT but may be inferred.
124   // NB: The Linux documentation says tablets would be direct, but they are
125   //     not (and drivers do not actually set INPUT_PROP_DIRECT for them).
126   bool HasDirect() const;
127 
128   // Determine whether device moves the cursor. This is the case for touchpads
129   // and tablets but not touchscreens.
130   // Corresponds to INPUT_PROP_POINTER but may be inferred.
131   bool HasPointer() const;
132 
133   // Has stylus EV_KEY events.
134   bool HasStylus() const;
135 
136   // Determine whether there's a keyboard on this device.
137   bool HasKeyboard() const;
138 
139   // Determine whether there's a mouse on this device. Excludes pointing sticks.
140   bool HasMouse() const;
141 
142   // Determine whether there's a pointing stick (such as a TrackPoint) on this
143   // device.
144   bool HasPointingStick() const;
145 
146   // Determine whether there's a touchpad on this device.
147   bool HasTouchpad() const;
148 
149   // Determine whether there's a tablet on this device.
150   bool HasTablet() const;
151 
152   // Determine whether there's a touchscreen on this device.
153   bool HasTouchscreen() const;
154 
155   // Determine whether there's a gamepad on this device.
156   bool HasGamepad() const;
157 
158   // Determine whether the device supports rumble.
159   bool SupportsRumble() const;
160 
161   // Determine if this is a dedicated device for a stylus button.
162   bool IsStylusButtonDevice() const;
163 
164   // The device type (internal or external.)
165   InputDeviceType device_type() const { return device_type_; }
166 
167   // Determines InputDeviceType from device identification.
168   static InputDeviceType GetInputDeviceTypeFromId(input_id id);
169 
170  private:
171   enum class LegacyAbsoluteDeviceType {
172     TOUCHPAD,
173     TOUCHSCREEN,
174     TABLET,
175     NONE,
176   };
177 
178   // Probe absolute X & Y axis behavior. This is for legacy drivers that
179   // do not tell us what the axes mean.
180   LegacyAbsoluteDeviceType ProbeLegacyAbsoluteDevice() const;
181 
182   unsigned long ev_bits_[EVDEV_BITS_TO_LONGS(EV_CNT)];
183   unsigned long key_bits_[EVDEV_BITS_TO_LONGS(KEY_CNT)];
184   unsigned long rel_bits_[EVDEV_BITS_TO_LONGS(REL_CNT)];
185   unsigned long abs_bits_[EVDEV_BITS_TO_LONGS(ABS_CNT)];
186   unsigned long msc_bits_[EVDEV_BITS_TO_LONGS(MSC_CNT)];
187   unsigned long sw_bits_[EVDEV_BITS_TO_LONGS(SW_CNT)];
188   unsigned long led_bits_[EVDEV_BITS_TO_LONGS(LED_CNT)];
189   unsigned long prop_bits_[EVDEV_BITS_TO_LONGS(INPUT_PROP_CNT)];
190   unsigned long ff_bits_[EVDEV_BITS_TO_LONGS(FF_CNT)];
191 
192   struct input_absinfo abs_info_[ABS_CNT];
193 
194   // Store the values for the multi-touch properties for each slot.
195   std::vector<int32_t> slot_values_[EVDEV_ABS_MT_COUNT];
196 
197   // Device identification.
198   std::string name_;
199   input_id input_id_ = {};
200 
201   // Device evdev physical property containing the output for EVIOCGPHYS that is
202   // (supposed to be) stable between reboots and hotplugs.
203   std::string phys_;
204 
205   // Whether this is an internal or external device.
206   InputDeviceType device_type_ = InputDeviceType::INPUT_DEVICE_UNKNOWN;
207 
208   DISALLOW_COPY_AND_ASSIGN(EventDeviceInfo);
209 };
210 
211 }  // namspace ui
212 
213 #endif  // UI_EVENTS_OZONE_EVDEV_EVENT_DEVICE_INFO_H_
214