diff options
author | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-23 17:49:02 +0000 |
---|---|---|
committer | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-23 17:49:02 +0000 |
commit | 60e102b8c352484ab9535d2d4be244ef24ac74d5 (patch) | |
tree | a3d42b8556e874c6a0e6f33be31efe828428938d | |
parent | 474440d78a17a4bad94e36e14078f3640b37fd92 (diff) | |
download | chromium_src-60e102b8c352484ab9535d2d4be244ef24ac74d5.zip chromium_src-60e102b8c352484ab9535d2d4be244ef24ac74d5.tar.gz chromium_src-60e102b8c352484ab9535d2d4be244ef24ac74d5.tar.bz2 |
touch: Detect touch device, and listen for events on floating devices.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/6724025
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79148 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/message_pump_glib_x.cc | 40 | ||||
-rw-r--r-- | base/message_pump_glib_x.h | 5 | ||||
-rw-r--r-- | views/touchui/touch_factory.cc | 17 |
3 files changed, 42 insertions, 20 deletions
diff --git a/base/message_pump_glib_x.cc b/base/message_pump_glib_x.cc index 06a156e..35cfc1a 100644 --- a/base/message_pump_glib_x.cc +++ b/base/message_pump_glib_x.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -80,7 +80,7 @@ MessagePumpGlibX::MessagePumpGlibX() : base::MessagePumpForUI(), #if defined(HAVE_XINPUT2) xiopcode_(-1), masters_(), - slaves_(), + floats_(), #endif gdksource_(NULL), dispatching_event_(false), @@ -112,22 +112,29 @@ void MessagePumpGlibX::SetupXInput2ForXWindow(Window xwindow) { XISetMask(mask, XI_ButtonRelease); XISetMask(mask, XI_Motion); - // It is necessary to select only for the master 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'. So it is not necessary to select for the slave - // devices here. - XIEventMask evmasks[masters_.size()]; + // It is not 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'. + // 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. + std::set<int> devices; + std::set_union(masters_.begin(), masters_.end(), + floats_.begin(), floats_.end(), + std::inserter(devices, devices.begin())); + XIEventMask evmasks[devices.size()]; int count = 0; - for (std::set<int>::const_iterator iter = masters_.begin(); - iter != masters_.end(); + for (std::set<int>::const_iterator iter = devices.begin(); + iter != devices.end(); ++iter, ++count) { evmasks[count].deviceid = *iter; evmasks[count].mask_len = sizeof(mask); evmasks[count].mask = mask; } - XISelectEvents(xdisplay, xwindow, evmasks, masters_.size()); + XISelectEvents(xdisplay, xwindow, evmasks, devices.size()); // TODO(sad): Setup masks for keyboard events. @@ -224,7 +231,8 @@ void MessagePumpGlibX::EventDispatcherX(GdkEvent* event, gpointer data) { if (!pump_x->gdksource_) { pump_x->gdksource_ = g_main_current_source(); - pump_x->gdkdispatcher_ = pump_x->gdksource_->source_funcs->dispatch; + if (pump_x->gdksource_) + pump_x->gdkdispatcher_ = pump_x->gdksource_->source_funcs->dispatch; } else if (!pump_x->IsDispatchingEvent()) { if (event->type != GDK_NOTHING && pump_x->capture_gdk_events_[event->type]) { @@ -294,17 +302,15 @@ void MessagePumpGlibX::InitializeXInput2(void) { XIDeviceInfo* devices = XIQueryDevice(xdisplay, XIAllDevices, &count); for (int i = 0; i < count; i++) { XIDeviceInfo* devinfo = devices + i; - if (devinfo->use == XISlavePointer) { - slaves_.insert(devinfo->deviceid); + if (devinfo->use == XIFloatingSlave) { + floats_.insert(devinfo->deviceid); } else if (devinfo->use == XIMasterPointer) { masters_.insert(devinfo->deviceid); } - // We do not need to care about XIFloatingSlave, because the callback for - // XI_HierarchyChanged event will take care of it. } XIFreeDeviceInfo(devices); - // TODO(sad): Select on root for XI_HierarchyChanged so that slaves_ and + // TODO(sad): Select on root for XI_HierarchyChanged so that floats_ and // masters_ can be kept up-to-date. This is a relatively rare event, so we can // put it off for a later time. // Note: It is not necessary to listen for XI_DeviceChanged events. diff --git a/base/message_pump_glib_x.h b/base/message_pump_glib_x.h index e94b797..2959ef0 100644 --- a/base/message_pump_glib_x.h +++ b/base/message_pump_glib_x.h @@ -52,9 +52,8 @@ class MessagePumpGlibX : public MessagePumpForUI { // necessary to query X for the list of devices for each GdkWindow created. std::set<int> masters_; - // The list of slave (physical) pointer devices. - // TODO(sad): This is currently unused, and may be removed eventually. - std::set<int> slaves_; + // The list of floating pointer devices. + std::set<int> floats_; #endif // The event source for GDK events. diff --git a/views/touchui/touch_factory.cc b/views/touchui/touch_factory.cc index 99c2ec5..66cdf6b 100644 --- a/views/touchui/touch_factory.cc +++ b/views/touchui/touch_factory.cc @@ -5,7 +5,9 @@ #include "views/touchui/touch_factory.h" #include <X11/cursorfont.h> +#include <X11/extensions/XInput.h> #include <X11/extensions/XInput2.h> +#include <X11/extensions/XIproto.h> #include "base/compiler_specific.h" #include "base/logging.h" @@ -36,6 +38,21 @@ TouchFactory::TouchFactory() arrow_cursor_ = XCreateFontCursor(display, XC_arrow); SetCursorVisible(false, false); + + // Detect touch devices. + // 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. + int count = 0; + XDeviceInfo* devlist = XListInputDevices(display, &count); + for (int i = 0; i < count; i++) { + const char* devtype = XGetAtomName(display, devlist[i].type); + if (devtype && !strcmp(devtype, XI_TOUCHSCREEN)) { + touch_device_lookup_[devlist[i].id] = true; + touch_device_list_.push_back(devlist[i].id); + } + } + XFreeDeviceList(devlist); } TouchFactory::~TouchFactory() { |