| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/devices/x11/touch_factory_x11.h" | 5 #include "ui/events/devices/x11/touch_factory_x11.h" |
| 6 | 6 |
| 7 #include <X11/Xatom.h> | 7 #include <X11/Xatom.h> |
| 8 #include <X11/cursorfont.h> | 8 #include <X11/cursorfont.h> |
| 9 #include <X11/extensions/XInput.h> | 9 #include <X11/extensions/XInput.h> |
| 10 #include <X11/extensions/XInput2.h> | 10 #include <X11/extensions/XInput2.h> |
| 11 #include <X11/extensions/XIproto.h> | 11 #include <X11/extensions/XIproto.h> |
| 12 | 12 |
| 13 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
| 14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 15 #include "base/compiler_specific.h" | 15 #include "base/compiler_specific.h" |
| 16 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/memory/singleton.h" | 17 #include "base/memory/singleton.h" |
| 18 #include "base/message_loop/message_loop.h" | 18 #include "base/message_loop/message_loop.h" |
| 19 #include "base/strings/string_number_conversions.h" | 19 #include "base/strings/string_number_conversions.h" |
| 20 #include "base/strings/string_split.h" | 20 #include "base/strings/string_split.h" |
| 21 #include "base/sys_info.h" | 21 #include "base/sys_info.h" |
| 22 #include "ui/events/base_event_utils.h" | 22 #include "ui/events/base_event_utils.h" |
| 23 #include "ui/events/devices/x11/device_data_manager_x11.h" | 23 #include "ui/events/devices/x11/device_data_manager_x11.h" |
| 24 #include "ui/events/devices/x11/device_list_cache_x11.h" | 24 #include "ui/events/devices/x11/device_list_cache_x11.h" |
| 25 #include "ui/events/event_switches.h" | 25 #include "ui/events/event_switches.h" |
| 26 #include "ui/gfx/x/x11_types.h" | 26 #include "ui/gfx/x/x11_types.h" |
| 27 | 27 |
| 28 namespace ui { | 28 namespace ui { |
| 29 | 29 |
| 30 namespace { |
| 31 |
| 32 bool IsTouchEventsFlagDisabled() { |
| 33 auto* command_line = base::CommandLine::ForCurrentProcess(); |
| 34 bool touch_flag_status = command_line->HasSwitch(switches::kTouchEvents) && |
| 35 command_line->GetSwitchValueASCII(switches::kTouchEvents) == |
| 36 switches::kTouchEventsDisabled; |
| 37 #if defined(OS_CHROMEOS) |
| 38 return !GetTouchEventsCrOsMasterSwitch() && touch_flag_status; |
| 39 #else |
| 40 return touch_flag_status; |
| 41 #endif // defined(OS_CHROMEOS) |
| 42 |
| 43 } |
| 44 |
| 45 } // namespace |
| 46 |
| 47 |
| 30 TouchFactory::TouchFactory() | 48 TouchFactory::TouchFactory() |
| 31 : pointer_device_lookup_(), | 49 : pointer_device_lookup_(), |
| 32 touch_device_list_(), | 50 touch_device_list_(), |
| 33 virtual_core_keyboard_device_(-1), | 51 virtual_core_keyboard_device_(-1), |
| 34 id_generator_(0) { | 52 id_generator_(0), |
| 53 touch_events_disabled_(IsTouchEventsFlagDisabled()) { |
| 35 if (!DeviceDataManagerX11::GetInstance()->IsXInput2Available()) | 54 if (!DeviceDataManagerX11::GetInstance()->IsXInput2Available()) |
| 36 return; | 55 return; |
| 37 | 56 |
| 38 XDisplay* display = gfx::GetXDisplay(); | 57 XDisplay* display = gfx::GetXDisplay(); |
| 39 UpdateDeviceList(display); | 58 UpdateDeviceList(display); |
| 40 } | 59 } |
| 41 | 60 |
| 42 TouchFactory::~TouchFactory() { | 61 TouchFactory::~TouchFactory() { |
| 43 } | 62 } |
| 44 | 63 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 // the touchscreen device), and one from the master (deviceid == the | 171 // the touchscreen device), and one from the master (deviceid == the |
| 153 // id of the master pointer device). Instead of processing both | 172 // id of the master pointer device). Instead of processing both |
| 154 // events, discard the event that comes from the slave, and only | 173 // events, discard the event that comes from the slave, and only |
| 155 // allow processing the event coming from the master. | 174 // allow processing the event coming from the master. |
| 156 // For a 'floating' touchscreen device, X11 sends only one event for | 175 // For a 'floating' touchscreen device, X11 sends only one event for |
| 157 // each touch, with both deviceid and sourceid set to the id of the | 176 // each touch, with both deviceid and sourceid set to the id of the |
| 158 // touchscreen device. | 177 // touchscreen device. |
| 159 bool is_from_master_or_float = touch_device_list_[xiev->deviceid]; | 178 bool is_from_master_or_float = touch_device_list_[xiev->deviceid]; |
| 160 bool is_from_slave_device = !is_from_master_or_float | 179 bool is_from_slave_device = !is_from_master_or_float |
| 161 && xiev->sourceid == xiev->deviceid; | 180 && xiev->sourceid == xiev->deviceid; |
| 162 return ui::AreTouchEventsEnabled() && | 181 return !touch_events_disabled_ && |
| 163 IsTouchDevice(xiev->deviceid) && | 182 IsTouchDevice(xiev->deviceid) && |
| 164 !is_from_slave_device; | 183 !is_from_slave_device; |
| 165 } | 184 } |
| 166 | 185 |
| 167 // Make sure only key-events from the virtual core keyboard are processed. | 186 // Make sure only key-events from the virtual core keyboard are processed. |
| 168 if (event->evtype == XI_KeyPress || event->evtype == XI_KeyRelease) { | 187 if (event->evtype == XI_KeyPress || event->evtype == XI_KeyRelease) { |
| 169 return (virtual_core_keyboard_device_ < 0) || | 188 return (virtual_core_keyboard_device_ < 0) || |
| 170 (virtual_core_keyboard_device_ == xiev->deviceid); | 189 (virtual_core_keyboard_device_ == xiev->deviceid); |
| 171 } | 190 } |
| 172 | 191 |
| 173 if (event->evtype != XI_ButtonPress && | 192 if (event->evtype != XI_ButtonPress && |
| 174 event->evtype != XI_ButtonRelease && | 193 event->evtype != XI_ButtonRelease && |
| 175 event->evtype != XI_Motion) { | 194 event->evtype != XI_Motion) { |
| 176 return true; | 195 return true; |
| 177 } | 196 } |
| 178 | 197 |
| 179 if (!pointer_device_lookup_[xiev->deviceid]) | 198 if (!pointer_device_lookup_[xiev->deviceid]) |
| 180 return false; | 199 return false; |
| 181 | 200 |
| 182 return IsTouchDevice(xiev->deviceid) ? ui::AreTouchEventsEnabled() : true; | 201 return IsTouchDevice(xiev->deviceid) ? !touch_events_disabled_ : true; |
| 183 } | 202 } |
| 184 | 203 |
| 185 void TouchFactory::SetupXI2ForXWindow(Window window) { | 204 void TouchFactory::SetupXI2ForXWindow(Window window) { |
| 186 // Setup mask for mouse events. It is possible that a device is loaded/plugged | 205 // Setup mask for mouse events. It is possible that a device is loaded/plugged |
| 187 // in after we have setup XInput2 on a window. In such cases, we need to | 206 // in after we have setup XInput2 on a window. In such cases, we need to |
| 188 // either resetup XInput2 for the window, so that we get events from the new | 207 // either resetup XInput2 for the window, so that we get events from the new |
| 189 // device, or we need to listen to events from all devices, and then filter | 208 // device, or we need to listen to events from all devices, and then filter |
| 190 // the events from uninteresting devices. We do the latter because that's | 209 // the events from uninteresting devices. We do the latter because that's |
| 191 // simpler. | 210 // simpler. |
| 192 | 211 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 | 278 |
| 260 int TouchFactory::GetSlotForTrackingID(uint32 tracking_id) { | 279 int TouchFactory::GetSlotForTrackingID(uint32 tracking_id) { |
| 261 return id_generator_.GetGeneratedID(tracking_id); | 280 return id_generator_.GetGeneratedID(tracking_id); |
| 262 } | 281 } |
| 263 | 282 |
| 264 void TouchFactory::ReleaseSlotForTrackingID(uint32 tracking_id) { | 283 void TouchFactory::ReleaseSlotForTrackingID(uint32 tracking_id) { |
| 265 id_generator_.ReleaseNumber(tracking_id); | 284 id_generator_.ReleaseNumber(tracking_id); |
| 266 } | 285 } |
| 267 | 286 |
| 268 bool TouchFactory::IsTouchDevicePresent() { | 287 bool TouchFactory::IsTouchDevicePresent() { |
| 269 return ui::AreTouchEventsEnabled() && touch_device_lookup_.any(); | 288 return !touch_events_disabled_ && touch_device_lookup_.any(); |
| 270 } | 289 } |
| 271 | 290 |
| 272 void TouchFactory::ResetForTest() { | 291 void TouchFactory::ResetForTest() { |
| 273 pointer_device_lookup_.reset(); | 292 pointer_device_lookup_.reset(); |
| 274 touch_device_lookup_.reset(); | 293 touch_device_lookup_.reset(); |
| 275 touch_device_list_.clear(); | 294 touch_device_list_.clear(); |
| 276 touchscreen_ids_.clear(); | 295 touchscreen_ids_.clear(); |
| 277 id_generator_.ResetForTest(); | 296 id_generator_.ResetForTest(); |
| 297 touch_events_disabled_ = false; |
| 278 } | 298 } |
| 279 | 299 |
| 280 void TouchFactory::SetTouchDeviceForTest( | 300 void TouchFactory::SetTouchDeviceForTest( |
| 281 const std::vector<int>& devices) { | 301 const std::vector<int>& devices) { |
| 282 touch_device_lookup_.reset(); | 302 touch_device_lookup_.reset(); |
| 283 touch_device_list_.clear(); | 303 touch_device_list_.clear(); |
| 284 for (std::vector<int>::const_iterator iter = devices.begin(); | 304 for (std::vector<int>::const_iterator iter = devices.begin(); |
| 285 iter != devices.end(); ++iter) { | 305 iter != devices.end(); ++iter) { |
| 286 DCHECK(IsValidDevice(*iter)); | 306 DCHECK(IsValidDevice(*iter)); |
| 287 touch_device_lookup_[*iter] = true; | 307 touch_device_lookup_[*iter] = true; |
| 288 touch_device_list_[*iter] = true; | 308 touch_device_list_[*iter] = true; |
| 289 } | 309 } |
| 310 touch_events_disabled_ = false; |
| 290 } | 311 } |
| 291 | 312 |
| 292 void TouchFactory::SetPointerDeviceForTest( | 313 void TouchFactory::SetPointerDeviceForTest( |
| 293 const std::vector<int>& devices) { | 314 const std::vector<int>& devices) { |
| 294 pointer_device_lookup_.reset(); | 315 pointer_device_lookup_.reset(); |
| 295 for (std::vector<int>::const_iterator iter = devices.begin(); | 316 for (std::vector<int>::const_iterator iter = devices.begin(); |
| 296 iter != devices.end(); ++iter) { | 317 iter != devices.end(); ++iter) { |
| 297 pointer_device_lookup_[*iter] = true; | 318 pointer_device_lookup_[*iter] = true; |
| 298 } | 319 } |
| 299 } | 320 } |
| 300 | 321 |
| 301 void TouchFactory::CacheTouchscreenIds(int device_id) { | 322 void TouchFactory::CacheTouchscreenIds(int device_id) { |
| 302 if (!DeviceDataManager::HasInstance()) | 323 if (!DeviceDataManager::HasInstance()) |
| 303 return; | 324 return; |
| 304 std::vector<TouchscreenDevice> touchscreens = | 325 std::vector<TouchscreenDevice> touchscreens = |
| 305 DeviceDataManager::GetInstance()->touchscreen_devices(); | 326 DeviceDataManager::GetInstance()->touchscreen_devices(); |
| 306 const auto it = | 327 const auto it = |
| 307 std::find_if(touchscreens.begin(), touchscreens.end(), | 328 std::find_if(touchscreens.begin(), touchscreens.end(), |
| 308 [device_id](const TouchscreenDevice& touchscreen) { | 329 [device_id](const TouchscreenDevice& touchscreen) { |
| 309 return touchscreen.id == device_id; | 330 return touchscreen.id == device_id; |
| 310 }); | 331 }); |
| 311 // Internal displays will have a vid and pid of 0. Ignore them. | 332 // Internal displays will have a vid and pid of 0. Ignore them. |
| 312 if (it != touchscreens.end() && it->vendor_id && it->product_id) | 333 if (it != touchscreens.end() && it->vendor_id && it->product_id) |
| 313 touchscreen_ids_.insert(std::make_pair(it->vendor_id, it->product_id)); | 334 touchscreen_ids_.insert(std::make_pair(it->vendor_id, it->product_id)); |
| 314 } | 335 } |
| 315 | 336 |
| 316 } // namespace ui | 337 } // namespace ui |
| OLD | NEW |