summaryrefslogtreecommitdiffstats
path: root/views/touchui
diff options
context:
space:
mode:
authormiletus@chromium.org <miletus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-18 17:42:52 +0000
committermiletus@chromium.org <miletus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-18 17:42:52 +0000
commitf9740e86231f2ed7eef6bb782e028b708833e243 (patch)
treefc50d4b56dfff78faaff92b11f823ae0f04baa21 /views/touchui
parentbf2ecb42b2821b9609ce5736d8218c730011d7db (diff)
downloadchromium_src-f9740e86231f2ed7eef6bb782e028b708833e243.zip
chromium_src-f9740e86231f2ed7eef6bb782e028b708833e243.tar.gz
chromium_src-f9740e86231f2ed7eef6bb782e028b708833e243.tar.bz2
Add extra touch information and related API to views::TouchEvent.
Some touch devices provide, other than (x,y) location, extra touch information. views::TouchEvent is changed to keep track of touch radius, touch angle and ratio between major and minor touch axis. To be able to query what extra touch data is supported by the device, bookkeeping of the device supported TouchParams is added to views::TouchFactory. Next step will be routing these touch information to WebKit. BUG= TEST= Review URL: http://codereview.chromium.org/6820004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81963 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/touchui')
-rw-r--r--views/touchui/touch_factory.cc91
-rw-r--r--views/touchui/touch_factory.h29
2 files changed, 119 insertions, 1 deletions
diff --git a/views/touchui/touch_factory.cc b/views/touchui/touch_factory.cc
index c363492..d9a65a1 100644
--- a/views/touchui/touch_factory.cc
+++ b/views/touchui/touch_factory.cc
@@ -9,6 +9,7 @@
#include <X11/extensions/XInput2.h>
#include <X11/extensions/XIproto.h>
+#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "ui/base/x/x11_util.h"
@@ -18,6 +19,54 @@ static int kCursorIdleSeconds = 5;
namespace views {
+namespace {
+
+// Given the TouchParam, return the correspoding valuator index using
+// the X device information through Atom name matching.
+char FindTPValuator(Display* display,
+ XIDeviceInfo* info,
+ TouchFactory::TouchParam touch_param) {
+ // Lookup table for mapping TouchParam to Atom string used in X.
+ // A full set of Atom strings can be found at xserver-properties.h.
+ static struct {
+ TouchFactory::TouchParam tp;
+ const char* atom;
+ } kTouchParamAtom[] = {
+ { TouchFactory::TP_TOUCH_MAJOR, "Abs MT Touch Major" },
+ { TouchFactory::TP_TOUCH_MINOR, "Abs MT Touch Minor" },
+ { TouchFactory::TP_ORIENTATION, "Abs MT Orientation" },
+ { TouchFactory::TP_LAST_ENTRY, NULL },
+ };
+
+ const char* atom_tp = NULL;
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTouchParamAtom); i++) {
+ if (touch_param == kTouchParamAtom[i].tp) {
+ atom_tp = kTouchParamAtom[i].atom;
+ break;
+ }
+ }
+
+ if (!atom_tp)
+ return -1;
+
+ for (int i = 0; i < info->num_classes; i++) {
+ if (info->classes[i]->type != XIValuatorClass)
+ continue;
+ XIValuatorClassInfo* v =
+ reinterpret_cast<XIValuatorClassInfo*>(info->classes[i]);
+
+ const char* atom = XGetAtomName(display, v->label);
+
+ if (atom && strcmp(atom, atom_tp) == 0)
+ return v->number;
+ }
+
+ return -1;
+}
+
+} // namespace
+
// static
TouchFactory* TouchFactory::GetInstance() {
return Singleton<TouchFactory>::get();
@@ -56,6 +105,8 @@ TouchFactory::TouchFactory()
}
if (devlist)
XFreeDeviceList(devlist);
+
+ SetupValuator();
}
TouchFactory::~TouchFactory() {
@@ -75,6 +126,8 @@ void TouchFactory::SetTouchDeviceList(
touch_device_lookup_[*iter] = true;
touch_device_list_.push_back(*iter);
}
+
+ SetupValuator();
}
bool TouchFactory::IsTouchDevice(unsigned deviceid) const {
@@ -145,4 +198,42 @@ void TouchFactory::SetCursorVisible(bool show, bool start_timer) {
}
}
+void TouchFactory::SetupValuator() {
+ memset(valuator_lookup_, -1, sizeof(valuator_lookup_));
+
+ Display* display = ui::GetXDisplay();
+ int ndevice;
+ XIDeviceInfo* info_list = XIQueryDevice(display, XIAllDevices, &ndevice);
+
+ for (int i = 0; i < ndevice; i++) {
+ XIDeviceInfo* info = info_list + i;
+
+ if (!IsTouchDevice(info->deviceid))
+ continue;
+
+ for (int i = 0; i < TP_LAST_ENTRY; i++) {
+ TouchParam tp = static_cast<TouchParam>(i);
+ valuator_lookup_[info->deviceid][i] = FindTPValuator(display, info, tp);
+ }
+ }
+
+ if (info_list)
+ XIFreeDeviceInfo(info_list);
+}
+
+bool TouchFactory::ExtractTouchParam(const XEvent& xev,
+ TouchParam tp,
+ float* value) {
+ XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev.xcookie.data);
+ if (xiev->sourceid >= kMaxDeviceNum)
+ return false;
+ int v = valuator_lookup_[xiev->sourceid][tp];
+ if (v >= 0 && XIMaskIsSet(xiev->valuators.mask, v)) {
+ *value = xiev->valuators.values[v];
+ return true;
+ }
+
+ return false;
+}
+
} // namespace views
diff --git a/views/touchui/touch_factory.h b/views/touchui/touch_factory.h
index 143a932..f4c6f05 100644
--- a/views/touchui/touch_factory.h
+++ b/views/touchui/touch_factory.h
@@ -15,12 +15,21 @@
typedef unsigned long Cursor;
typedef unsigned long Window;
typedef struct _XDisplay Display;
+typedef union _XEvent XEvent;
namespace views {
// Functions related to determining touch devices.
class TouchFactory {
public:
+ // Define the touch params following the Multi-touch Protocol.
+ enum TouchParam {
+ TP_TOUCH_MAJOR = 0,
+ TP_TOUCH_MINOR,
+ TP_ORIENTATION,
+ TP_LAST_ENTRY
+ };
+
// Returns the TouchFactory singleton.
static TouchFactory* GetInstance();
@@ -50,6 +59,11 @@ class TouchFactory {
return is_cursor_visible_;
}
+ // Extract the TouchParam from the XEvent. Return true and the value is set
+ // if the TouchParam is found, false and value unchanged if the TouchParam
+ // is not found.
+ bool ExtractTouchParam(const XEvent& xev, TouchParam tp, float* value);
+
private:
TouchFactory();
@@ -59,6 +73,10 @@ class TouchFactory {
SetCursorVisible(false, false);
}
+ // Setup the internal bookkeeping of the touch params valuator information for
+ // touch devices
+ void SetupValuator();
+
// Requirement for Signleton
friend struct DefaultSingletonTraits<TouchFactory>;
@@ -84,12 +102,21 @@ class TouchFactory {
// identifier for the touch device. This can be completed after enough testing
// on real touch devices.
+ static const int kMaxDeviceNum = 128;
+
// A quick lookup table for determining if a device is a touch device.
- std::bitset<128> touch_device_lookup_;
+ std::bitset<kMaxDeviceNum> touch_device_lookup_;
// The list of touch devices.
std::vector<int> touch_device_list_;
+ // Index table to find the valuator for the TouchParam on the specific device
+ // by valuator_lookup_[device_id][touch_params]. Use 2-D array to get fast
+ // index at the expense of space. If the kMaxDeviceNum grows larger that the
+ // space waste becomes a concern, the 2D lookup table can be replaced by a
+ // hash map.
+ char valuator_lookup_[kMaxDeviceNum][TP_LAST_ENTRY];
+
DISALLOW_COPY_AND_ASSIGN(TouchFactory);
};