summaryrefslogtreecommitdiffstats
path: root/views/touchui
diff options
context:
space:
mode:
authorsadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-20 16:58:11 +0000
committersadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-20 16:58:11 +0000
commit086aa35fb71b1c7801f2b04c9bdd44f7a7ac03b1 (patch)
treeab9460554bfb71ce760fb26fa6b1af209a2d2894 /views/touchui
parentf680c5c3ad1f804fd4b5ed694f565a94f05c8d22 (diff)
downloadchromium_src-086aa35fb71b1c7801f2b04c9bdd44f7a7ac03b1.zip
chromium_src-086aa35fb71b1c7801f2b04c9bdd44f7a7ac03b1.tar.gz
chromium_src-086aa35fb71b1c7801f2b04c9bdd44f7a7ac03b1.tar.bz2
Make sure the device list is kept up-to-date.
A device can be loaded at times after chrome has already started. So make sure the list of devices is kept up-to-date. BUG=none TEST=none Review URL: http://codereview.chromium.org/6877061 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@82316 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/touchui')
-rw-r--r--views/touchui/touch_factory.cc57
-rw-r--r--views/touchui/touch_factory.h7
2 files changed, 45 insertions, 19 deletions
diff --git a/views/touchui/touch_factory.cc b/views/touchui/touch_factory.cc
index 4ac8ddc..dc6fb96 100644
--- a/views/touchui/touch_factory.cc
+++ b/views/touchui/touch_factory.cc
@@ -119,7 +119,7 @@ TouchFactory* TouchFactory::GetInstance() {
TouchFactory::TouchFactory()
: is_cursor_visible_(true),
cursor_timer_(),
- pointer_devices_(),
+ pointer_device_lookup_(),
touch_device_list_() {
char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
XColor black;
@@ -139,10 +139,18 @@ TouchFactory::TouchFactory()
// windows created by other means (e.g. for context menus).
SetupGtkWidgetRealizeNotifier(this);
- // 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.
+ // Make sure the list of devices is kept up-to-date by listening for
+ // XI_HierarchyChanged event on the root window.
+ unsigned char mask[XIMaskLen(XI_LASTEVENT)];
+ memset(mask, 0, sizeof(mask));
+
+ XISetMask(mask, XI_HierarchyChanged);
+
+ XIEventMask evmask;
+ evmask.deviceid = XIAllDevices;
+ evmask.mask_len = sizeof(mask);
+ evmask.mask = mask;
+ XISelectEvents(display, ui::GetX11RootWindow(), &evmask, 1);
}
TouchFactory::~TouchFactory() {
@@ -185,12 +193,12 @@ void TouchFactory::UpdateDeviceList(Display* display) {
// 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_devices_.clear();
+ pointer_device_lookup_.reset();
XIDeviceInfo* devices = XIQueryDevice(display, XIAllDevices, &count);
for (int i = 0; i < count; i++) {
XIDeviceInfo* devinfo = devices + i;
if (devinfo->use == XIFloatingSlave || devinfo->use == XIMasterPointer) {
- pointer_devices_.insert(devinfo->deviceid);
+ pointer_device_lookup_[devinfo->deviceid] = true;
}
}
XIFreeDeviceInfo(devices);
@@ -198,7 +206,27 @@ void TouchFactory::UpdateDeviceList(Display* display) {
SetupValuator();
}
+bool TouchFactory::ShouldProcessXI2Event(XEvent* xev) {
+ DCHECK_EQ(GenericEvent, xev->type);
+
+ XGenericEventCookie* cookie = &xev->xcookie;
+ if (cookie->evtype != XI_ButtonPress &&
+ cookie->evtype != XI_ButtonRelease &&
+ cookie->evtype != XI_Motion)
+ return true;
+
+ XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(cookie->data);
+ return pointer_device_lookup_[xiev->sourceid];
+}
+
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.
+
Display* display = ui::GetXDisplay();
unsigned char mask[XIMaskLen(XI_LASTEVENT)];
@@ -208,16 +236,11 @@ void TouchFactory::SetupXI2ForXWindow(Window window) {
XISetMask(mask, XI_ButtonRelease);
XISetMask(mask, XI_Motion);
- XIEventMask evmask[pointer_devices_.size()];
- int count = 0;
- for (std::set<int>::const_iterator iter = pointer_devices_.begin();
- iter != pointer_devices_.end();
- ++iter, ++count) {
- evmask[count].deviceid = *iter;
- evmask[count].mask_len = sizeof(mask);
- evmask[count].mask = mask;
- }
- XISelectEvents(display, window, evmask, pointer_devices_.size());
+ XIEventMask evmask;
+ evmask.deviceid = XIAllDevices;
+ evmask.mask_len = sizeof(mask);
+ evmask.mask = mask;
+ XISelectEvents(display, window, &evmask, 1);
XFlush(display);
}
diff --git a/views/touchui/touch_factory.h b/views/touchui/touch_factory.h
index 0890d22..e3a8042 100644
--- a/views/touchui/touch_factory.h
+++ b/views/touchui/touch_factory.h
@@ -7,7 +7,6 @@
#pragma once
#include <bitset>
-#include <set>
#include <vector>
#include "base/memory/singleton.h"
@@ -37,6 +36,10 @@ class TouchFactory {
// Updates the list of devices.
void UpdateDeviceList(Display* display);
+ // Checks whether an XI2 event should be processed or not (i.e. if the event
+ // originated from a device we are interested in).
+ bool ShouldProcessXI2Event(XEvent* xevent);
+
// Setup an X Window for XInput2 events.
void SetupXI2ForXWindow(::Window xid);
@@ -113,7 +116,7 @@ class TouchFactory {
// A quick lookup table for determining if events from the pointer device
// should be processed.
- std::set<int> pointer_devices_;
+ std::bitset<kMaxDeviceNum> pointer_device_lookup_;
// A quick lookup table for determining if a device is a touch device.
std::bitset<kMaxDeviceNum> touch_device_lookup_;