| 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 |