diff options
author | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-28 16:18:02 +0000 |
---|---|---|
committer | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-28 16:18:02 +0000 |
commit | 03ed0251f417df026b23de8685be145c893d7e2d (patch) | |
tree | e9f2f173a16a0076c7805b8a44b79d42036907df | |
parent | 8a0b9ca58bb4a04b4a3c0bba97687a0dc0c8c056 (diff) | |
download | chromium_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.cc | 45 | ||||
-rw-r--r-- | ui/base/touch/touch_factory.h | 25 | ||||
-rw-r--r-- | views/events/event_x.cc | 45 |
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; |