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/x/device_data_manager.h" | 5 #include "ui/events/x/device_data_manager.h" |
6 | 6 |
7 #include <X11/extensions/XInput.h> | 7 #include <X11/extensions/XInput.h> |
8 #include <X11/extensions/XInput2.h> | 8 #include <X11/extensions/XInput2.h> |
9 #include <X11/Xlib.h> | 9 #include <X11/Xlib.h> |
10 | 10 |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/memory/singleton.h" | 12 #include "base/memory/singleton.h" |
13 #include "ui/events/event_constants.h" | 13 #include "ui/events/event_constants.h" |
14 #include "ui/events/event_utils.h" | |
15 #include "ui/events/x/device_list_cache_x.h" | 14 #include "ui/events/x/device_list_cache_x.h" |
16 #include "ui/events/x/touch_factory_x11.h" | 15 #include "ui/events/x/touch_factory_x11.h" |
17 #include "ui/gfx/x/x11_types.h" | 16 #include "ui/gfx/x/x11_types.h" |
18 | 17 |
19 // XIScrollClass was introduced in XI 2.1 so we need to define it here | 18 // XIScrollClass was introduced in XI 2.1 so we need to define it here |
20 // for backward-compatibility with older versions of XInput. | 19 // for backward-compatibility with older versions of XInput. |
21 #if !defined(XIScrollClass) | 20 #if !defined(XIScrollClass) |
22 #define XIScrollClass 3 | 21 #define XIScrollClass 3 |
23 #endif | 22 #endif |
24 | 23 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 bool DeviceDataManager::IsTouchDataType(const int type) { | 104 bool DeviceDataManager::IsTouchDataType(const int type) { |
106 return (type >= kTouchDataTypeStart) && (type <= kTouchDataTypeEnd); | 105 return (type >= kTouchDataTypeStart) && (type <= kTouchDataTypeEnd); |
107 } | 106 } |
108 | 107 |
109 DeviceDataManager* DeviceDataManager::GetInstance() { | 108 DeviceDataManager* DeviceDataManager::GetInstance() { |
110 return Singleton<DeviceDataManager>::get(); | 109 return Singleton<DeviceDataManager>::get(); |
111 } | 110 } |
112 | 111 |
113 DeviceDataManager::DeviceDataManager() | 112 DeviceDataManager::DeviceDataManager() |
114 : natural_scroll_enabled_(false), | 113 : natural_scroll_enabled_(false), |
| 114 xi_opcode_(-1), |
115 atom_cache_(gfx::GetXDisplay(), kCachedAtoms), | 115 atom_cache_(gfx::GetXDisplay(), kCachedAtoms), |
116 button_map_count_(0) { | 116 button_map_count_(0) { |
| 117 CHECK(gfx::GetXDisplay()); |
117 InitializeXInputInternal(); | 118 InitializeXInputInternal(); |
118 | 119 |
119 // Make sure the sizes of enum and kCachedAtoms are aligned. | 120 // Make sure the sizes of enum and kCachedAtoms are aligned. |
120 CHECK(arraysize(kCachedAtoms) == static_cast<size_t>(DT_LAST_ENTRY) + 1); | 121 CHECK(arraysize(kCachedAtoms) == static_cast<size_t>(DT_LAST_ENTRY) + 1); |
121 UpdateDeviceList(gfx::GetXDisplay()); | 122 UpdateDeviceList(gfx::GetXDisplay()); |
122 UpdateButtonMap(); | 123 UpdateButtonMap(); |
123 } | 124 } |
124 | 125 |
125 DeviceDataManager::~DeviceDataManager() { | 126 DeviceDataManager::~DeviceDataManager() { |
126 } | 127 } |
127 | 128 |
128 bool DeviceDataManager::InitializeXInputInternal() { | 129 bool DeviceDataManager::InitializeXInputInternal() { |
129 // Check if XInput is available on the system. | 130 // Check if XInput is available on the system. |
130 xi_opcode_ = -1; | 131 xi_opcode_ = -1; |
131 int opcode, event, error; | 132 int opcode, event, error; |
132 if (!XQueryExtension( | 133 if (!XQueryExtension( |
133 gfx::GetXDisplay(), "XInputExtension", &opcode, &event, &error)) { | 134 gfx::GetXDisplay(), "XInputExtension", &opcode, &event, &error)) { |
134 VLOG(1) << "X Input extension not available: error=" << error; | 135 VLOG(1) << "X Input extension not available: error=" << error; |
135 return false; | 136 return false; |
136 } | 137 } |
137 xi_opcode_ = opcode; | |
138 | 138 |
139 // Check the XInput version. | 139 // Check the XInput version. |
140 #if defined(USE_XI2_MT) | 140 #if defined(USE_XI2_MT) |
141 int major = 2, minor = USE_XI2_MT; | 141 int major = 2, minor = USE_XI2_MT; |
142 #else | 142 #else |
143 int major = 2, minor = 0; | 143 int major = 2, minor = 0; |
144 #endif | 144 #endif |
145 if (XIQueryVersion(gfx::GetXDisplay(), &major, &minor) == BadRequest) { | 145 if (XIQueryVersion(gfx::GetXDisplay(), &major, &minor) == BadRequest) { |
146 VLOG(1) << "XInput2 not supported in the server."; | 146 VLOG(1) << "XInput2 not supported in the server."; |
147 return false; | 147 return false; |
148 } | 148 } |
| 149 #if defined(USE_XI2_MT) |
| 150 if (major < 2 || (major == 2 && minor < USE_XI2_MT)) { |
| 151 DVLOG(1) << "XI version on server is " << major << "." << minor << ". " |
| 152 << "But 2." << USE_XI2_MT << " is required."; |
| 153 return false; |
| 154 } |
| 155 #endif |
| 156 |
| 157 xi_opcode_ = opcode; |
| 158 CHECK_NE(-1, xi_opcode_); |
149 | 159 |
150 // Possible XI event types for XIDeviceEvent. See the XI2 protocol | 160 // Possible XI event types for XIDeviceEvent. See the XI2 protocol |
151 // specification. | 161 // specification. |
152 xi_device_event_types_[XI_KeyPress] = true; | 162 xi_device_event_types_[XI_KeyPress] = true; |
153 xi_device_event_types_[XI_KeyRelease] = true; | 163 xi_device_event_types_[XI_KeyRelease] = true; |
154 xi_device_event_types_[XI_ButtonPress] = true; | 164 xi_device_event_types_[XI_ButtonPress] = true; |
155 xi_device_event_types_[XI_ButtonRelease] = true; | 165 xi_device_event_types_[XI_ButtonRelease] = true; |
156 xi_device_event_types_[XI_Motion] = true; | 166 xi_device_event_types_[XI_Motion] = true; |
157 // Multi-touch support was introduced in XI 2.2. | 167 // Multi-touch support was introduced in XI 2.2. |
158 if (minor >= 2) { | 168 if (minor >= 2) { |
159 xi_device_event_types_[XI_TouchBegin] = true; | 169 xi_device_event_types_[XI_TouchBegin] = true; |
160 xi_device_event_types_[XI_TouchUpdate] = true; | 170 xi_device_event_types_[XI_TouchUpdate] = true; |
161 xi_device_event_types_[XI_TouchEnd] = true; | 171 xi_device_event_types_[XI_TouchEnd] = true; |
162 } | 172 } |
163 return true; | 173 return true; |
164 } | 174 } |
165 | 175 |
| 176 bool DeviceDataManager::IsXInput2Available() const { |
| 177 return xi_opcode_ != -1; |
| 178 } |
| 179 |
166 float DeviceDataManager::GetNaturalScrollFactor(int sourceid) const { | 180 float DeviceDataManager::GetNaturalScrollFactor(int sourceid) const { |
167 // Natural scroll is touchpad-only. | 181 // Natural scroll is touchpad-only. |
168 if (sourceid >= kMaxDeviceNum || !touchpads_[sourceid]) | 182 if (sourceid >= kMaxDeviceNum || !touchpads_[sourceid]) |
169 return -1.0f; | 183 return -1.0f; |
170 | 184 |
171 return natural_scroll_enabled_ ? 1.0f : -1.0f; | 185 return natural_scroll_enabled_ ? 1.0f : -1.0f; |
172 } | 186 } |
173 | 187 |
174 void DeviceDataManager::UpdateDeviceList(Display* display) { | 188 void DeviceDataManager::UpdateDeviceList(Display* display) { |
175 cmt_devices_.reset(); | 189 cmt_devices_.reset(); |
176 touchpads_.reset(); | 190 touchpads_.reset(); |
177 for (int i = 0; i < kMaxDeviceNum; ++i) { | 191 for (int i = 0; i < kMaxDeviceNum; ++i) { |
178 valuator_count_[i] = 0; | 192 valuator_count_[i] = 0; |
179 valuator_lookup_[i].clear(); | 193 valuator_lookup_[i].clear(); |
180 data_type_lookup_[i].clear(); | 194 data_type_lookup_[i].clear(); |
181 valuator_min_[i].clear(); | 195 valuator_min_[i].clear(); |
182 valuator_max_[i].clear(); | 196 valuator_max_[i].clear(); |
183 for (int j = 0; j < kMaxSlotNum; j++) | 197 for (int j = 0; j < kMaxSlotNum; j++) |
184 last_seen_valuator_[i][j].clear(); | 198 last_seen_valuator_[i][j].clear(); |
185 } | 199 } |
186 | 200 |
187 // Find all the touchpad devices. | 201 // Find all the touchpad devices. |
188 XDeviceList dev_list = | 202 XDeviceList dev_list = |
189 ui::DeviceListCacheX::GetInstance()->GetXDeviceList(display); | 203 ui::DeviceListCacheX::GetInstance()->GetXDeviceList(display); |
190 Atom xi_touchpad = XInternAtom(display, XI_TOUCHPAD, false); | 204 Atom xi_touchpad = XInternAtom(display, XI_TOUCHPAD, false); |
191 for (int i = 0; i < dev_list.count; ++i) | 205 for (int i = 0; i < dev_list.count; ++i) |
192 if (dev_list[i].type == xi_touchpad) | 206 if (dev_list[i].type == xi_touchpad) |
193 touchpads_[dev_list[i].id] = true; | 207 touchpads_[dev_list[i].id] = true; |
194 | 208 |
| 209 if (!IsXInput2Available()) |
| 210 return; |
| 211 |
195 // Update the structs with new valuator information | 212 // Update the structs with new valuator information |
196 XIDeviceList info_list = | 213 XIDeviceList info_list = |
197 ui::DeviceListCacheX::GetInstance()->GetXI2DeviceList(display); | 214 ui::DeviceListCacheX::GetInstance()->GetXI2DeviceList(display); |
198 Atom atoms[DT_LAST_ENTRY]; | 215 Atom atoms[DT_LAST_ENTRY]; |
199 for (int data_type = 0; data_type < DT_LAST_ENTRY; ++data_type) | 216 for (int data_type = 0; data_type < DT_LAST_ENTRY; ++data_type) |
200 atoms[data_type] = atom_cache_.GetAtom(kCachedAtoms[data_type]); | 217 atoms[data_type] = atom_cache_.GetAtom(kCachedAtoms[data_type]); |
201 | 218 |
202 for (int i = 0; i < info_list.count; ++i) { | 219 for (int i = 0; i < info_list.count; ++i) { |
203 XIDeviceInfo* info = info_list.devices + i; | 220 XIDeviceInfo* info = info_list.devices + i; |
204 | 221 |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 int val_index, | 608 int val_index, |
592 DataType data_type, | 609 DataType data_type, |
593 double min, | 610 double min, |
594 double max) { | 611 double max) { |
595 valuator_lookup_[deviceid][data_type] = val_index; | 612 valuator_lookup_[deviceid][data_type] = val_index; |
596 data_type_lookup_[deviceid][val_index] = data_type; | 613 data_type_lookup_[deviceid][val_index] = data_type; |
597 valuator_min_[deviceid][data_type] = min; | 614 valuator_min_[deviceid][data_type] = min; |
598 valuator_max_[deviceid][data_type] = max; | 615 valuator_max_[deviceid][data_type] = max; |
599 } | 616 } |
600 } // namespace ui | 617 } // namespace ui |
OLD | NEW |