summaryrefslogtreecommitdiffstats
path: root/views
diff options
context:
space:
mode:
authorsadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-23 19:35:18 +0000
committersadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-23 19:35:18 +0000
commit194bf38fe616b10b0d3c551292db6832567186d9 (patch)
treebacebff474c08a2531c2464024afbb72a90dac22 /views
parent909116fdb8f7eaaf225bdf3314fdf4e46d42f115 (diff)
downloadchromium_src-194bf38fe616b10b0d3c551292db6832567186d9.zip
chromium_src-194bf38fe616b10b0d3c551292db6832567186d9.tar.gz
chromium_src-194bf38fe616b10b0d3c551292db6832567186d9.tar.bz2
touchui: Create touch-events.
Create and process touch-events. The touch-events are created from pointer-events. The way to decide whether a 'pointer event' originated from a touch-device is not yet well-defined. So for now, use the --touch-devices command line parameter to specify which pointer devices should be treated as touch-device. For example, you can run: ./out/Debug/chrome --touch-devices=7,8 to treat the events coming in from devices with id 7 and 8 as touch events. (these are the slave ids you get from 'xinput list') BUG=None TEST=None Review URL: http://codereview.chromium.org/4738001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67133 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r--views/event.h4
-rw-r--r--views/event_x.cc49
-rw-r--r--views/focus/accelerator_handler.h9
-rw-r--r--views/focus/accelerator_handler_touch.cc58
-rw-r--r--views/widget/root_view.cc6
5 files changed, 120 insertions, 6 deletions
diff --git a/views/event.h b/views/event.h
index ab9abf3..1ec666d 100644
--- a/views/event.h
+++ b/views/event.h
@@ -297,6 +297,10 @@ class TouchEvent : public LocatedEvent {
// from 'from' coordinate system to 'to' coordinate system.
TouchEvent(const TouchEvent& model, View* from, View* to);
+#if defined(HAVE_XINPUT2)
+ explicit TouchEvent(XEvent* xev);
+#endif
+
// Return the touch point for this event.
bool identity() const {
return touch_id_;
diff --git a/views/event_x.cc b/views/event_x.cc
index 60b0d2f..774aa7f 100644
--- a/views/event_x.cc
+++ b/views/event_x.cc
@@ -71,6 +71,46 @@ int GetButtonMaskForX2Event(XIDeviceEvent* xievent) {
return buttonflags;
}
+
+Event::EventType GetTouchEventType(XEvent* xev) {
+ XGenericEventCookie* cookie = &xev->xcookie;
+ switch (cookie->evtype) {
+ case XI_ButtonPress:
+ return Event::ET_TOUCH_PRESSED;
+ case XI_ButtonRelease:
+ return Event::ET_TOUCH_RELEASED;
+ case XI_Motion:
+ return Event::ET_TOUCH_MOVED;
+
+ // Note: We will not generate a _STATIONARY event here. It will be created,
+ // when necessary, by a RWHVV.
+
+ // TODO(sad): When do we trigger a _CANCELLED event? Maybe that will also be
+ // done by a RWHVV, e.g. when it gets destroyed in the middle of a
+ // touch-sequence?
+ }
+
+ return Event::ET_UNKNOWN;
+}
+
+gfx::Point GetTouchEventLocation(XEvent* xev) {
+ XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev->xcookie.data);
+ return gfx::Point(xiev->event_x, xiev->event_y);
+}
+
+int GetTouchEventFlags(XEvent* xev) {
+ XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev->xcookie.data);
+ return GetButtonMaskForX2Event(xiev) |
+ GetEventFlagsFromXState(xiev->mods.effective);
+}
+
+int GetTouchIDFromXEvent(XEvent* xev) {
+ // TODO(sad): How we determine the touch-id from the event is as yet
+ // undecided.
+ XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev->xcookie.data);
+ return xiev->sourceid;
+}
+
#endif // HAVE_XINPUT2
Event::EventType GetMouseEventType(XEvent* xev) {
@@ -182,4 +222,13 @@ MouseWheelEvent::MouseWheelEvent(XEvent* xev)
// used for GTK+.
}
+#if defined(HAVE_XINPUT2)
+TouchEvent::TouchEvent(XEvent* xev)
+ : LocatedEvent(GetTouchEventType(xev),
+ GetTouchEventLocation(xev),
+ GetTouchEventFlags(xev)),
+ touch_id_(GetTouchIDFromXEvent(xev)) {
+}
+#endif
+
} // namespace views
diff --git a/views/focus/accelerator_handler.h b/views/focus/accelerator_handler.h
index 088f3f1..2d08e47 100644
--- a/views/focus/accelerator_handler.h
+++ b/views/focus/accelerator_handler.h
@@ -13,6 +13,7 @@
#endif
#include <set>
+#include <vector>
#include "base/message_loop.h"
@@ -22,7 +23,13 @@ namespace views {
// Dispatch an XEvent to the RootView. Return true if the event was dispatched
// and handled, false otherwise.
bool DispatchXEvent(XEvent* xevent);
-#endif
+
+#if defined(HAVE_XINPUT2)
+// Keep a list of touch devices so that it is possible to determine if a pointer
+// event is a touch-event or a mouse-event.
+void SetTouchDeviceList(std::vector<unsigned int>& devices);
+#endif // HAVE_XINPUT2
+#endif // TOUCH_UI
// This class delegates the key messages to the associated FocusManager class
// for the window that is receiving these messages for accelerator processing.
diff --git a/views/focus/accelerator_handler_touch.cc b/views/focus/accelerator_handler_touch.cc
index aa971d5..a35fc45 100644
--- a/views/focus/accelerator_handler_touch.cc
+++ b/views/focus/accelerator_handler_touch.cc
@@ -4,6 +4,7 @@
#include "views/focus/accelerator_handler.h"
+#include <bitset>
#include <gtk/gtk.h>
#if defined(HAVE_XINPUT2)
#include <X11/extensions/XInput2.h>
@@ -19,6 +20,36 @@
namespace views {
+#if defined(HAVE_XINPUT2)
+// Functions related to determining touch devices.
+class TouchFactory {
+ public:
+ // Keep a list of touch devices so that it is possible to determine if a
+ // pointer event is a touch-event or a mouse-event.
+ static void SetTouchDeviceListInternal(
+ const std::vector<unsigned int>& devices) {
+ for (std::vector<unsigned int>::const_iterator iter = devices.begin();
+ iter != devices.end(); ++iter) {
+ DCHECK(*iter < touch_devices.size());
+ touch_devices[*iter] = true;
+ }
+ }
+
+ // Is the device a touch-device?
+ static bool IsTouchDevice(unsigned int deviceid) {
+ return deviceid < touch_devices.size() ? touch_devices[deviceid] : false;
+ }
+
+ private:
+ // A quick lookup table for determining if a device is a touch device.
+ static std::bitset<128> touch_devices;
+
+ DISALLOW_COPY_AND_ASSIGN(TouchFactory);
+};
+
+std::bitset<128> TouchFactory::touch_devices;
+#endif
+
namespace {
RootView* FindRootViewForGdkWindow(GdkWindow* gdk_window) {
@@ -41,7 +72,18 @@ RootView* FindRootViewForGdkWindow(GdkWindow* gdk_window) {
#if defined(HAVE_XINPUT2)
bool X2EventIsTouchEvent(XEvent* xev) {
// TODO(sad): Determine if the captured event is a touch-event.
- return false;
+ XGenericEventCookie* cookie = &xev->xcookie;
+ switch (cookie->evtype) {
+ case XI_ButtonPress:
+ case XI_ButtonRelease:
+ case XI_Motion: {
+ // Is the event coming from a touch device?
+ return TouchFactory::IsTouchDevice(
+ static_cast<XIDeviceEvent*>(cookie->data)->sourceid);
+ }
+ default:
+ return false;
+ }
}
#endif // HAVE_XINPUT2
@@ -50,13 +92,13 @@ bool X2EventIsTouchEvent(XEvent* xev) {
#if defined(HAVE_XINPUT2)
bool DispatchX2Event(RootView* root, XEvent* xev) {
if (X2EventIsTouchEvent(xev)) {
- // TODO(sad): Create a TouchEvent, and send it off to |root|. If the event
+ // Create a TouchEvent, and send it off to |root|. If the event
// is processed by |root|, then return. Otherwise let it fall through so it
// can be used (if desired) as a mouse event.
- // TouchEvent touch(xev);
- // if (root->OnTouchEvent(touch))
- // return true;
+ TouchEvent touch(xev);
+ if (root->OnTouchEvent(touch))
+ return true;
}
XGenericEventCookie* cookie = &xev->xcookie;
@@ -171,6 +213,12 @@ bool DispatchXEvent(XEvent* xev) {
return false;
}
+#if defined(HAVE_XINPUT2)
+void SetTouchDeviceList(std::vector<unsigned int>& devices) {
+ TouchFactory::SetTouchDeviceListInternal(devices);
+}
+#endif
+
AcceleratorHandler::AcceleratorHandler() {}
bool AcceleratorHandler::Dispatch(GdkEvent* event) {
diff --git a/views/widget/root_view.cc b/views/widget/root_view.cc
index 753e9de..92f6cf7 100644
--- a/views/widget/root_view.cc
+++ b/views/widget/root_view.cc
@@ -285,6 +285,12 @@ void RootView::ViewHierarchyChanged(bool is_add, View* parent, View* child) {
default_keyboard_handler_ = NULL;
}
+#if defined(TOUCH_UI)
+ if (touch_pressed_handler_) {
+ touch_pressed_handler_ = NULL;
+ }
+#endif
+
FocusManager* focus_manager = widget_->GetFocusManager();
// An unparanted RootView does not have a FocusManager.
if (focus_manager)