summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-28 16:18:02 +0000
committersadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-28 16:18:02 +0000
commit03ed0251f417df026b23de8685be145c893d7e2d (patch)
treee9f2f173a16a0076c7805b8a44b79d42036907df
parent8a0b9ca58bb4a04b4a3c0bba97687a0dc0c8c056 (diff)
downloadchromium_src-03ed0251f417df026b23de8685be145c893d7e2d.zip
chromium_src-03ed0251f417df026b23de8685be145c893d7e2d.tar.gz
chromium_src-03ed0251f417df026b23de8685be145c893d7e2d.tar.bz2
touchui: Convert XI2 MT tracking id to slot id.
The slot id mapped from tracking id is used as the touch id, and the gesture recognizer expects touch points to always start from 0. Patch from: Ningxin Hu <ningxin.hu@intel.com> (http://codereview.chromium.org/7927001/) BUG=95150 TEST=manually (touch-drag to scroll webpage, tap to click link) Review URL: http://codereview.chromium.org/8070003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@103122 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ui/base/touch/touch_factory.cc45
-rw-r--r--ui/base/touch/touch_factory.h25
-rw-r--r--views/events/event_x.cc45
3 files changed, 93 insertions, 22 deletions
diff --git a/ui/base/touch/touch_factory.cc b/ui/base/touch/touch_factory.cc
index e528523..fcab846 100644
--- a/ui/base/touch/touch_factory.cc
+++ b/ui/base/touch/touch_factory.cc
@@ -135,12 +135,11 @@ TouchFactory::TouchFactory()
keep_mouse_cursor_(false),
cursor_timer_(),
pointer_device_lookup_(),
-#if defined(USE_XI2_MT)
- touch_device_list_() {
-#else
touch_device_list_(),
- slots_used_() {
+#if defined(USE_XI2_MT)
+ min_available_slot_(0),
#endif
+ slots_used_() {
#if defined(TOUCH_UI)
if (!base::MessagePumpForUI::HasXInput2())
return;
@@ -335,7 +334,42 @@ bool TouchFactory::IsRealTouchDevice(unsigned int deviceid) const {
false;
}
-#if !defined(USE_XI2_MT)
+#if defined(USE_XI2_MT)
+int TouchFactory::GetSlotForTrackingID(uint32 tracking_id) {
+ TrackingIdMap::iterator itr = tracking_id_map_.find(tracking_id);
+ if (itr != tracking_id_map_.end())
+ return itr->second;
+
+ int slot = min_available_slot_;
+ if (slot == kMaxTouchPoints) {
+ LOG(ERROR) << "Could not find available slot for touch point";
+ return 0;
+ }
+ SetSlotUsed(slot, true);
+ tracking_id_map_.insert(std::make_pair(tracking_id, slot));
+
+ // Updates the minium available slot ID
+ while (++min_available_slot_ < kMaxTouchPoints &&
+ IsSlotUsed(min_available_slot_))
+ continue;
+
+ return slot;
+}
+
+void TouchFactory::ReleaseSlotForTrackingID(uint32 tracking_id) {
+ TrackingIdMap::iterator itr = tracking_id_map_.find(tracking_id);
+ if (itr != tracking_id_map_.end()) {
+ int slot = itr->second;
+ SetSlotUsed(slot, false);
+ tracking_id_map_.erase(itr);
+ if (slot < min_available_slot_)
+ min_available_slot_ = slot;
+ } else {
+ NOTREACHED() << "Cannot find slot mapping to tracking ID " << tracking_id;
+ }
+}
+#endif
+
bool TouchFactory::IsSlotUsed(int slot) const {
CHECK_LT(slot, kMaxTouchPoints);
return slots_used_[slot];
@@ -345,7 +379,6 @@ void TouchFactory::SetSlotUsed(int slot, bool used) {
CHECK_LT(slot, kMaxTouchPoints);
slots_used_[slot] = used;
}
-#endif
bool TouchFactory::GrabTouchDevices(Display* display, ::Window window) {
#if defined(TOUCH_UI)
diff --git a/ui/base/touch/touch_factory.h b/ui/base/touch/touch_factory.h
index 9b16113..3b1b5f1 100644
--- a/ui/base/touch/touch_factory.h
+++ b/ui/base/touch/touch_factory.h
@@ -11,6 +11,7 @@
#include <vector>
#include "base/memory/singleton.h"
+#include "base/hash_tables.h"
#include "base/timer.h"
#include "ui/base/ui_export.h"
@@ -82,13 +83,20 @@ class UI_EXPORT TouchFactory {
// for more explanation.)
bool IsRealTouchDevice(unsigned int deviceid) const;
-#if !defined(USE_XI2_MT)
+#if defined(USE_XI2_MT)
+ // Tries to find an existing slot ID mapping to tracking ID. If there
+ // isn't one already, allocates a new slot ID and sets up the mapping.
+ int GetSlotForTrackingID(uint32 tracking_id);
+
+ // Releases the slot ID mapping to tracking ID.
+ void ReleaseSlotForTrackingID(uint32 tracking_id);
+#endif
+
// Is the slot ID currently used?
bool IsSlotUsed(int slot) const;
// Marks a slot as being used/unused.
void SetSlotUsed(int slot, bool used);
-#endif
// Grabs the touch devices for the specified window on the specified display.
// Returns if grab was successful for all touch devices.
@@ -198,13 +206,22 @@ class UI_EXPORT TouchFactory {
int touch_param_min_[kMaxDeviceNum][TP_LAST_ENTRY];
int touch_param_max_[kMaxDeviceNum][TP_LAST_ENTRY];
-#if !defined(USE_XI2_MT)
// Maximum simultaneous touch points.
static const int kMaxTouchPoints = 32;
+#if defined(USE_XI2_MT)
+ // Stores the minimum available slot ID which helps get slot ID from
+ // tracking ID. When it equals to kMaxTouchPoints, there is no available
+ // slot.
+ int min_available_slot_;
+
+ // A hash table to map tracking ID to slot.
+ typedef base::hash_map<uint32, int> TrackingIdMap;
+ TrackingIdMap tracking_id_map_;
+#endif
+
// A lookup table for slots in use for a touch event.
std::bitset<kMaxTouchPoints> slots_used_;
-#endif
DISALLOW_COPY_AND_ASSIGN(TouchFactory);
};
diff --git a/views/events/event_x.cc b/views/events/event_x.cc
index cbbc477..f5cfd43 100644
--- a/views/events/event_x.cc
+++ b/views/events/event_x.cc
@@ -20,20 +20,28 @@ namespace views {
namespace {
int GetTouchIDFromXEvent(XEvent* xev) {
- float id = 0;
+ float slot = 0;
+ ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
+ XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data);
+ if (!factory->IsRealTouchDevice(xievent->sourceid)) {
+ // TODO(sad): Come up with a way to generate touch-ids for multi-touch
+ // events when touch-events are generated from a mouse.
+ return slot;
+ }
+
#if defined(USE_XI2_MT)
- // TODO(ningxin.hu@gmail.com): Make the id always start from 0 for a new
- // touch-sequence when TRACKING_ID is used to extract the touch id.
- ui::TouchFactory::TouchParam tp = ui::TouchFactory::TP_TRACKING_ID;
+ float tracking_id;
+ if (!factory->ExtractTouchParam(
+ *xev, ui::TouchFactory::TP_TRACKING_ID, &tracking_id))
+ LOG(ERROR) << "Could not get the slot ID for the event. Using 0.";
+ else
+ slot = factory->GetSlotForTrackingID(tracking_id);
#else
- ui::TouchFactory::TouchParam tp = ui::TouchFactory::TP_SLOT_ID;
+ if (!factory->ExtractTouchParam(
+ *xev, ui::TouchFactory::TP_SLOT_ID, &slot))
+ LOG(ERROR) << "Could not get the slot ID for the event. Using 0.";
#endif
- ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
- XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data);
- if (factory->IsRealTouchDevice(xievent->sourceid) &&
- !factory->ExtractTouchParam(*xev, tp, &id))
- LOG(ERROR) << "Could not get the touch ID for the event. Using 0.";
- return id;
+ return slot;
}
uint16 GetCharacterFromXKeyEvent(XKeyEvent* key) {
@@ -174,7 +182,20 @@ TouchEvent::TouchEvent(const ui::NativeEvent& native_event)
ui::TouchFactory::TP_ORIENTATION,
0.0)),
force_(GetTouchForceFromXEvent(native_event)) {
-#if !defined(USE_XI2_MT)
+#if defined(USE_XI2_MT)
+ if (type() == ui::ET_TOUCH_RELEASED) {
+ // NOTE: The slot is allocated by TouchFactory for each XI_TouchBegin
+ // event, which carries a new tracking ID to identify a new touch
+ // sequence.
+ ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
+ float tracking_id;
+ if (factory->ExtractTouchParam(*native_event,
+ ui::TouchFactory::TP_TRACKING_ID,
+ &tracking_id)) {
+ factory->ReleaseSlotForTrackingID(tracking_id);
+ }
+ }
+#else
if (type() == ui::ET_TOUCH_PRESSED || type() == ui::ET_TOUCH_RELEASED) {
ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
float slot;