Index: ui/events/x/touch_factory_x11.cc |
diff --git a/ui/events/x/touch_factory_x11.cc b/ui/events/x/touch_factory_x11.cc |
deleted file mode 100644 |
index 10cb890e236f88ba1c3c6f180ec2aa0856c481cb..0000000000000000000000000000000000000000 |
--- a/ui/events/x/touch_factory_x11.cc |
+++ /dev/null |
@@ -1,355 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "ui/events/x/touch_factory_x11.h" |
- |
-#include <X11/Xatom.h> |
-#include <X11/cursorfont.h> |
-#include <X11/extensions/XInput.h> |
-#include <X11/extensions/XInput2.h> |
-#include <X11/extensions/XIproto.h> |
- |
-#include "base/basictypes.h" |
-#include "base/command_line.h" |
-#include "base/compiler_specific.h" |
-#include "base/logging.h" |
-#include "base/memory/singleton.h" |
-#include "base/message_loop/message_loop.h" |
-#include "base/strings/string_number_conversions.h" |
-#include "base/strings/string_split.h" |
-#include "base/sys_info.h" |
-#include "ui/events/event_switches.h" |
-#include "ui/events/x/device_data_manager_x11.h" |
-#include "ui/events/x/device_list_cache_x.h" |
-#include "ui/gfx/x/x11_types.h" |
- |
-namespace ui { |
- |
-TouchFactory::TouchFactory() |
- : pointer_device_lookup_(), |
- touch_events_disabled_(false), |
- touch_device_list_(), |
- max_touch_points_(-1), |
- virtual_core_keyboard_device_(-1), |
- id_generator_(0) { |
- if (!DeviceDataManagerX11::GetInstance()->IsXInput2Available()) |
- return; |
- |
- XDisplay* display = gfx::GetXDisplay(); |
- UpdateDeviceList(display); |
- |
- CommandLine* cmdline = CommandLine::ForCurrentProcess(); |
- touch_events_disabled_ = cmdline->HasSwitch(switches::kTouchEvents) && |
- cmdline->GetSwitchValueASCII(switches::kTouchEvents) == |
- switches::kTouchEventsDisabled; |
-} |
- |
-TouchFactory::~TouchFactory() { |
-} |
- |
-// static |
-TouchFactory* TouchFactory::GetInstance() { |
- return Singleton<TouchFactory>::get(); |
-} |
- |
-// static |
-void TouchFactory::SetTouchDeviceListFromCommandLine() { |
- // Get a list of pointer-devices that should be treated as touch-devices. |
- // This is primarily used for testing/debugging touch-event processing when a |
- // touch-device isn't available. |
- std::string touch_devices = |
- CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
- switches::kTouchDevices); |
- |
- if (!touch_devices.empty()) { |
- std::vector<std::string> devs; |
- std::vector<unsigned int> device_ids; |
- unsigned int devid; |
- base::SplitString(touch_devices, ',', &devs); |
- for (std::vector<std::string>::iterator iter = devs.begin(); |
- iter != devs.end(); ++iter) { |
- if (base::StringToInt(*iter, reinterpret_cast<int*>(&devid))) |
- device_ids.push_back(devid); |
- else |
- DLOG(WARNING) << "Invalid touch-device id: " << *iter; |
- } |
- ui::TouchFactory::GetInstance()->SetTouchDeviceList(device_ids); |
- } |
-} |
- |
-void TouchFactory::UpdateDeviceList(Display* display) { |
- // Detect touch devices. |
- touch_device_lookup_.reset(); |
- touch_device_list_.clear(); |
- touchscreen_ids_.clear(); |
- max_touch_points_ = -1; |
- |
-#if !defined(USE_XI2_MT) |
- // NOTE: The new API for retrieving the list of devices (XIQueryDevice) does |
- // not provide enough information to detect a touch device. As a result, the |
- // old version of query function (XListInputDevices) is used instead. |
- // If XInput2 is not supported, this will return null (with count of -1) so |
- // we assume there cannot be any touch devices. |
- // With XI2.1 or older, we allow only single touch devices. |
- XDeviceList dev_list = |
- DeviceListCacheX::GetInstance()->GetXDeviceList(display); |
- Atom xi_touchscreen = XInternAtom(display, XI_TOUCHSCREEN, false); |
- for (int i = 0; i < dev_list.count; i++) { |
- if (dev_list[i].type == xi_touchscreen) { |
- touch_device_lookup_[dev_list[i].id] = true; |
- touch_device_list_[dev_list[i].id] = false; |
- } |
- } |
-#endif |
- |
- if (!DeviceDataManagerX11::GetInstance()->IsXInput2Available()) |
- return; |
- |
- // Instead of asking X for the list of devices all the time, let's maintain a |
- // list of pointer devices we care about. |
- // It should not be necessary to select for slave devices. XInput2 provides |
- // enough information to the event callback to decide which slave device |
- // triggered the event, thus decide whether the 'pointer event' is a |
- // 'mouse event' or a 'touch event'. |
- // However, on some desktops, some events from a master pointer are |
- // not delivered to the client. So we select for slave devices instead. |
- // If the touch device has 'GrabDevice' set and 'SendCoreEvents' unset (which |
- // is possible), then the device is detected as a floating device, and a |
- // floating device is not connected to a master device. So it is necessary to |
- // also select on the floating devices. |
- pointer_device_lookup_.reset(); |
- XIDeviceList xi_dev_list = |
- DeviceListCacheX::GetInstance()->GetXI2DeviceList(display); |
- for (int i = 0; i < xi_dev_list.count; i++) { |
- XIDeviceInfo* devinfo = xi_dev_list.devices + i; |
- if (devinfo->use == XIFloatingSlave || devinfo->use == XIMasterPointer) { |
-#if defined(USE_XI2_MT) |
- for (int k = 0; k < devinfo->num_classes; ++k) { |
- XIAnyClassInfo* xiclassinfo = devinfo->classes[k]; |
- if (xiclassinfo->type == XITouchClass) { |
- XITouchClassInfo* tci = |
- reinterpret_cast<XITouchClassInfo*>(xiclassinfo); |
- // Only care direct touch device (such as touch screen) right now |
- if (tci->mode == XIDirectTouch) { |
- touch_device_lookup_[devinfo->deviceid] = true; |
- touch_device_list_[devinfo->deviceid] = true; |
- if (tci->num_touches > 0 && tci->num_touches > max_touch_points_) |
- max_touch_points_ = tci->num_touches; |
- } |
- } |
- } |
-#endif |
- pointer_device_lookup_[devinfo->deviceid] = true; |
- } else if (devinfo->use == XIMasterKeyboard) { |
- virtual_core_keyboard_device_ = devinfo->deviceid; |
- } |
- |
-#if defined(USE_XI2_MT) |
- if (devinfo->use == XIFloatingSlave || devinfo->use == XISlavePointer) { |
- for (int k = 0; k < devinfo->num_classes; ++k) { |
- XIAnyClassInfo* xiclassinfo = devinfo->classes[k]; |
- if (xiclassinfo->type == XITouchClass) { |
- XITouchClassInfo* tci = |
- reinterpret_cast<XITouchClassInfo*>(xiclassinfo); |
- // Only care direct touch device (such as touch screen) right now |
- if (tci->mode == XIDirectTouch) |
- CacheTouchscreenIds(display, devinfo->deviceid); |
- } |
- } |
- } |
-#endif |
- } |
-} |
- |
-bool TouchFactory::ShouldProcessXI2Event(XEvent* xev) { |
- DCHECK_EQ(GenericEvent, xev->type); |
- XIEvent* event = static_cast<XIEvent*>(xev->xcookie.data); |
- XIDeviceEvent* xiev = reinterpret_cast<XIDeviceEvent*>(event); |
- |
-#if defined(USE_XI2_MT) |
- if (event->evtype == XI_TouchBegin || |
- event->evtype == XI_TouchUpdate || |
- event->evtype == XI_TouchEnd) { |
- return !touch_events_disabled_ && IsTouchDevice(xiev->deviceid); |
- } |
-#endif |
- // Make sure only key-events from the virtual core keyboard are processed. |
- if (event->evtype == XI_KeyPress || event->evtype == XI_KeyRelease) { |
- return (virtual_core_keyboard_device_ < 0) || |
- (virtual_core_keyboard_device_ == xiev->deviceid); |
- } |
- |
- if (event->evtype != XI_ButtonPress && |
- event->evtype != XI_ButtonRelease && |
- event->evtype != XI_Motion) |
- return true; |
- |
- if (!pointer_device_lookup_[xiev->deviceid]) |
- return false; |
- |
- return IsTouchDevice(xiev->deviceid) ? !touch_events_disabled_ : true; |
-} |
- |
-void TouchFactory::SetupXI2ForXWindow(Window window) { |
- // Setup mask for mouse events. It is possible that a device is loaded/plugged |
- // in after we have setup XInput2 on a window. In such cases, we need to |
- // either resetup XInput2 for the window, so that we get events from the new |
- // device, or we need to listen to events from all devices, and then filter |
- // the events from uninteresting devices. We do the latter because that's |
- // simpler. |
- |
- XDisplay* display = gfx::GetXDisplay(); |
- |
- unsigned char mask[XIMaskLen(XI_LASTEVENT)]; |
- memset(mask, 0, sizeof(mask)); |
- |
-#if defined(USE_XI2_MT) |
- XISetMask(mask, XI_TouchBegin); |
- XISetMask(mask, XI_TouchUpdate); |
- XISetMask(mask, XI_TouchEnd); |
-#endif |
- XISetMask(mask, XI_ButtonPress); |
- XISetMask(mask, XI_ButtonRelease); |
- XISetMask(mask, XI_Motion); |
-#if defined(OS_CHROMEOS) |
- if (base::SysInfo::IsRunningOnChromeOS()) { |
- XISetMask(mask, XI_KeyPress); |
- XISetMask(mask, XI_KeyRelease); |
- } |
-#endif |
- |
- XIEventMask evmask; |
- evmask.deviceid = XIAllDevices; |
- evmask.mask_len = sizeof(mask); |
- evmask.mask = mask; |
- XISelectEvents(display, window, &evmask, 1); |
- XFlush(display); |
-} |
- |
-void TouchFactory::SetTouchDeviceList( |
- const std::vector<unsigned int>& devices) { |
- touch_device_lookup_.reset(); |
- touch_device_list_.clear(); |
- for (std::vector<unsigned int>::const_iterator iter = devices.begin(); |
- iter != devices.end(); ++iter) { |
- DCHECK(*iter < touch_device_lookup_.size()); |
- touch_device_lookup_[*iter] = true; |
- touch_device_list_[*iter] = false; |
- } |
-} |
- |
-bool TouchFactory::IsTouchDevice(unsigned deviceid) const { |
- return deviceid < touch_device_lookup_.size() ? |
- touch_device_lookup_[deviceid] : false; |
-} |
- |
-bool TouchFactory::IsMultiTouchDevice(unsigned int deviceid) const { |
- return (deviceid < touch_device_lookup_.size() && |
- touch_device_lookup_[deviceid]) ? |
- touch_device_list_.find(deviceid)->second : |
- false; |
-} |
- |
-bool TouchFactory::QuerySlotForTrackingID(uint32 tracking_id, int* slot) { |
- if (!id_generator_.HasGeneratedIDFor(tracking_id)) |
- return false; |
- *slot = static_cast<int>(id_generator_.GetGeneratedID(tracking_id)); |
- return true; |
-} |
- |
-int TouchFactory::GetSlotForTrackingID(uint32 tracking_id) { |
- return id_generator_.GetGeneratedID(tracking_id); |
-} |
- |
-void TouchFactory::AcquireSlotForTrackingID(uint32 tracking_id) { |
- tracking_id_refcounts_[tracking_id]++; |
-} |
- |
-void TouchFactory::ReleaseSlotForTrackingID(uint32 tracking_id) { |
- tracking_id_refcounts_[tracking_id]--; |
- if (tracking_id_refcounts_[tracking_id] == 0) |
- id_generator_.ReleaseNumber(tracking_id); |
-} |
- |
-bool TouchFactory::IsTouchDevicePresent() { |
- return !touch_events_disabled_ && touch_device_lookup_.any(); |
-} |
- |
-int TouchFactory::GetMaxTouchPoints() const { |
- return max_touch_points_; |
-} |
- |
-void TouchFactory::ResetForTest() { |
- pointer_device_lookup_.reset(); |
- touch_device_lookup_.reset(); |
- touch_events_disabled_ = false; |
- touch_device_list_.clear(); |
- touchscreen_ids_.clear(); |
- tracking_id_refcounts_.clear(); |
- max_touch_points_ = -1; |
- id_generator_.ResetForTest(); |
-} |
- |
-void TouchFactory::SetTouchDeviceForTest( |
- const std::vector<unsigned int>& devices) { |
- touch_device_lookup_.reset(); |
- touch_device_list_.clear(); |
- for (std::vector<unsigned int>::const_iterator iter = devices.begin(); |
- iter != devices.end(); ++iter) { |
- DCHECK(*iter < touch_device_lookup_.size()); |
- touch_device_lookup_[*iter] = true; |
- touch_device_list_[*iter] = true; |
- } |
- touch_events_disabled_ = false; |
-} |
- |
-void TouchFactory::SetPointerDeviceForTest( |
- const std::vector<unsigned int>& devices) { |
- pointer_device_lookup_.reset(); |
- for (std::vector<unsigned int>::const_iterator iter = devices.begin(); |
- iter != devices.end(); ++iter) { |
- pointer_device_lookup_[*iter] = true; |
- } |
-} |
- |
-void TouchFactory::CacheTouchscreenIds(Display* display, int device_id) { |
- XDevice* device = XOpenDevice(display, device_id); |
- if (!device) |
- return; |
- |
- Atom actual_type_return; |
- int actual_format_return; |
- unsigned long nitems_return; |
- unsigned long bytes_after_return; |
- unsigned char *prop_return; |
- |
- const char kDeviceProductIdString[] = "Device Product ID"; |
- Atom device_product_id_atom = |
- XInternAtom(display, kDeviceProductIdString, false); |
- |
- if (device_product_id_atom != None && |
- XGetDeviceProperty(display, device, device_product_id_atom, 0, 2, |
- False, XA_INTEGER, &actual_type_return, |
- &actual_format_return, &nitems_return, |
- &bytes_after_return, &prop_return) == Success) { |
- if (actual_type_return == XA_INTEGER && |
- actual_format_return == 32 && |
- nitems_return == 2) { |
- // An actual_format_return of 32 implies that the returned data is an |
- // array of longs. See the description of |prop_return| in `man |
- // XGetDeviceProperty` for details. |
- long* ptr = reinterpret_cast<long*>(prop_return); |
- |
- // Internal displays will have a vid and pid of 0. Ignore them. |
- // ptr[0] is the vid, and ptr[1] is the pid. |
- if (ptr[0] || ptr[1]) |
- touchscreen_ids_.insert(std::make_pair(ptr[0], ptr[1])); |
- } |
- XFree(prop_return); |
- } |
- |
- XCloseDevice(display, device); |
-} |
- |
-} // namespace ui |