Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(455)

Unified Diff: ui/base/touch/touch_factory.cc

Issue 9773024: This patch implements Chromium's Aura gesture recognizer in terms of utouch-grail and utouch-frame … (Closed) Base URL: https://src.chromium.org/svn/trunk/src/
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/base/touch/touch_factory.h ('k') | ui/ui.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/base/touch/touch_factory.cc
===================================================================
--- ui/base/touch/touch_factory.cc (revision 126124)
+++ ui/base/touch/touch_factory.cc (working copy)
@@ -9,10 +9,14 @@
#include <X11/extensions/XInput2.h>
#include <X11/extensions/XIproto.h>
+#include <string>
+
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/message_loop.h"
+#include "ui/base/touch/multi_touch_device.h"
+#include "ui/base/touch/multi_touch_device_x11.h"
#include "ui/base/x/x11_util.h"
namespace {
@@ -20,6 +24,35 @@
// The X cursor is hidden if it is idle for kCursorIdleSeconds seconds.
int kCursorIdleSeconds = 5;
+ui::Axis::Type TouchParamToAxisType(ui::TouchFactory::TouchParam tp) {
+ ui::Axis::Type type = ui::Axis::AXIS_TYPE_UNKNOWN;
+ switch (tp) {
+ case ui::TouchFactory::TP_TOUCH_MAJOR:
+ // Length of the touch area.
+ type = ui::Axis::AXIS_TYPE_TOUCH_MAJOR;
+ break;
+ case ui::TouchFactory::TP_TOUCH_MINOR:
+ // Width of the touch area.
+ type = ui::Axis::AXIS_TYPE_TOUCH_MINOR;
+ break;
+ case ui::TouchFactory::TP_ORIENTATION:
+ // Angle between the X-axis and the major axis of the
+ // touch area.
+ type = ui::Axis::AXIS_TYPE_ORIENTATION;
+ break;
+ case ui::TouchFactory::TP_PRESSURE:
+ // Pressure of the touch contact.
+ type = ui::Axis::AXIS_TYPE_PRESSURE;
+ case ui::TouchFactory::TP_TRACKING_ID:
+ // ID of the touch point.
+ type = ui::Axis::AXIS_TYPE_TRACKING_ID;
+ default:
+ break;
+ }
+
+ return type;
+}
+
// Given the TouchParam, return the correspoding XIValuatorClassInfo using
// the X device information through Atom name matching.
XIValuatorClassInfo* FindTPValuator(Display* display,
@@ -72,7 +105,6 @@
return NULL;
}
-
} // namespace
namespace ui {
@@ -83,12 +115,19 @@
}
TouchFactory::TouchFactory()
- : is_cursor_visible_(true),
+ : device_observer_list_(
+ new ObserverListThreadSafe<TouchFactory::DeviceObserver>()),
+ is_cursor_visible_(true),
cursor_timer_(),
pointer_device_lookup_(),
touch_device_available_(false),
touch_device_list_(),
#if defined(USE_XI2_MT)
+#if defined(USE_AURA)
+#if defined(USE_UTOUCH)
+ utouch_frame_handle_(NULL),
+#endif // USE_UTOUCH
+#endif // USE_AURA
min_available_slot_(0),
#endif
slots_used_() {
@@ -101,13 +140,25 @@
XColor black;
black.red = black.green = black.blue = 0;
Display* display = ui::GetXDisplay();
+
+#if defined(USE_AURA) && defined(USE_UTOUCH)
+ if (UFStatusSuccess != frame_x11_new(display, &utouch_frame_handle_)) {
+ LOG(ERROR) << "Failed to create utouch frame instance";
+ } else {
+ fd_set set;
+ FD_ZERO(&set);
+ FD_SET(frame_get_fd(utouch_frame_handle_), &set);
+ }
+#endif // USE_AURA && USE_UTOUCH
+
Pixmap blank = XCreateBitmapFromData(display, ui::GetX11RootWindow(),
nodata, 8, 8);
invisible_cursor_ = XCreatePixmapCursor(display, blank, blank,
&black, &black, 0, 0);
arrow_cursor_ = XCreateFontCursor(display, XC_arrow);
- SetCursorVisible(false, false);
+ // TODO(tvoss): Selectively enable visibility for indirect touch devs.
+ // SetCursorVisible(false, false);
UpdateDeviceList(display);
// Make sure the list of devices is kept up-to-date by listening for
@@ -128,8 +179,12 @@
#if defined(USE_AURA)
if (!base::MessagePumpForUI::HasXInput2())
return;
-#endif
+#if defined(USE_UTOUCH)
+ frame_x11_delete(utouch_frame_handle_);
+#endif // USE_UTOUCH
+#endif // USE_AURA
+
// The XDisplay may be lost by the time we get destroyed.
if (ui::XDisplayExists()) {
SetCursorVisible(true, false);
@@ -139,6 +194,21 @@
}
}
+void TouchFactory::AddDeviceObserver(TouchFactory::DeviceObserver * observer) {
+ device_observer_list_->AddObserver(observer);
+
+ // Make sure that every new observer is provided with an
+ // initial list of devices.
+ device_observer_list_->Notify(
+ &DeviceObserver::OnDevicesUpdated,
+ touch_device_list_);
+}
+
+void TouchFactory::RemoveDeviceObserver(
+ TouchFactory::DeviceObserver * observer) {
+ device_observer_list_->RemoveObserver(observer);
+}
+
void TouchFactory::UpdateDeviceList(Display* display) {
// Detect touch devices.
// NOTE: The new API for retrieving the list of devices (XIQueryDevice) does
@@ -183,16 +253,24 @@
for (int i = 0; i < count; i++) {
XIDeviceInfo* devinfo = devices + i;
#if defined(USE_XI2_MT)
+ MultiTouchDevice mtDevice;
+ if (ui::xi_device_info_to_mt_device(devinfo, mtDevice))
+ touch_device_list_[devinfo->deviceid] = mtDevice;
+
for (int k = 0; k < devinfo->num_classes; ++k) {
XIAnyClassInfo* xiclassinfo = devinfo->classes[k];
if (xiclassinfo->type == XITouchClass) {
XITouchClassInfo* tci =
reinterpret_cast<XITouchClassInfo *>(xiclassinfo);
- // Only care direct touch device (such as touch screen) right now
- if (tci->mode == XIDirectTouch) {
- touch_device_lookup_[devinfo->deviceid] = true;
- touch_device_list_[devinfo->deviceid] = true;
- touch_device_available_ = true;
+ switch (tci->mode) {
+ case XIDirectTouch:
+ touch_device_lookup_[devinfo->deviceid] = true;
+ touch_device_available_ = true;
+ break;
+ case XIDependentTouch:
+ touch_device_lookup_[devinfo->deviceid] = true;
+ touch_device_available_ = true;
+ break;
}
}
}
@@ -204,6 +282,9 @@
XIFreeDeviceInfo(devices);
SetupValuator();
+
+ device_observer_list_->Notify(
+ &DeviceObserver::OnDevicesUpdated, touch_device_list_);
}
bool TouchFactory::ShouldProcessXI2Event(XEvent* xev) {
@@ -212,6 +293,8 @@
XIDeviceEvent* xiev = reinterpret_cast<XIDeviceEvent*>(event);
#if defined(USE_XI2_MT)
+ if (event->evtype == XI_HierarchyChanged)
+ return true;
if (event->evtype == XI_TouchBegin ||
event->evtype == XI_TouchUpdate ||
event->evtype == XI_TouchEnd) {
@@ -226,6 +309,24 @@
return pointer_device_lookup_[xiev->deviceid];
}
+#if defined(USE_UTOUCH)
+void TouchFactory::ProcessXI2Event(XEvent* event) {
+ // Commented out under the assumption that the window host
+ // already loaded all event data.
+ /* XGenericEventCookie *xcookie = &event->xcookie;
+ if(!XGetEventData(ui::GetXDisplay(), xcookie)) {
+ LOG(ERROR) << "Failed to get X generic event data";
+ return;
+ }else
+ printf( "Successfully retrieved X generic event data\n" );
+ */
+ if (UFStatusSuccess !=
+ frame_x11_process_event(utouch_frame_handle_, &event->xcookie)) {
+ LOG(ERROR) << "Failed to inject X event";
+ }
+}
+#endif // USE_UTOUCH
+
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
@@ -243,11 +344,13 @@
XISetMask(mask, XI_TouchBegin);
XISetMask(mask, XI_TouchUpdate);
XISetMask(mask, XI_TouchEnd);
-#endif
+ XISetMask(mask, XI_TouchOwnership);
+ XISetMask(mask, XI_HierarchyChanged);
+#else
XISetMask(mask, XI_ButtonPress);
XISetMask(mask, XI_ButtonRelease);
XISetMask(mask, XI_Motion);
-
+#endif
XIEventMask evmask;
evmask.deviceid = XIAllDevices;
evmask.mask_len = sizeof(mask);
@@ -264,7 +367,6 @@
iter != devices.end(); ++iter) {
DCHECK(*iter < touch_device_lookup_.size());
touch_device_lookup_[*iter] = true;
- touch_device_list_[*iter] = false;
}
SetupValuator();
@@ -278,8 +380,8 @@
bool TouchFactory::IsMultiTouchDevice(unsigned int deviceid) const {
return (deviceid < touch_device_lookup_.size() &&
touch_device_lookup_[deviceid]) ?
- touch_device_list_.find(deviceid)->second :
- false;
+ touch_device_list_.find(deviceid) != touch_device_list_.end() :
+ false;
}
#if defined(USE_XI2_MT)
@@ -343,15 +445,18 @@
XISetMask(mask, XI_TouchBegin);
XISetMask(mask, XI_TouchUpdate);
XISetMask(mask, XI_TouchEnd);
-#endif
+ XISetMask(mask, XI_TouchOwnership);
+ XISetMask(mask, XI_HierarchyChanged);
+#else
XISetMask(mask, XI_ButtonPress);
XISetMask(mask, XI_ButtonRelease);
XISetMask(mask, XI_Motion);
+#endif
XIEventMask evmask;
evmask.mask_len = sizeof(mask);
evmask.mask = mask;
- for (std::map<int, bool>::const_iterator iter =
+ for (TouchDeviceList::const_iterator iter =
touch_device_list_.begin();
iter != touch_device_list_.end(); ++iter) {
evmask.deviceid = iter->first;
@@ -370,7 +475,7 @@
#endif
bool success = true;
- for (std::map<int, bool>::const_iterator iter =
+ for (TouchDeviceList::const_iterator iter =
touch_device_list_.begin();
iter != touch_device_list_.end(); ++iter) {
Status status = XIUngrabDevice(display, iter->first, CurrentTime);
@@ -445,13 +550,13 @@
// tracking_id valuator. Without these we'll treat the device as a
// single-touch device (like a mouse).
// TODO(rbyers): Multi-touch is disabled: http://crbug.com/112329
- //if (valuator_lookup_[info->deviceid][TP_SLOT_ID] == -1 ||
+ // if (valuator_lookup_[info->deviceid][TP_SLOT_ID] == -1 ||
// valuator_lookup_[info->deviceid][TP_TRACKING_ID] == -1) {
DVLOG(1) << "Touch device " << info->deviceid <<
" does not provide enough information for multi-touch, treating as "
"a single-touch device.";
touch_device_list_[info->deviceid] = false;
- //}
+ // }
#endif
}
@@ -499,12 +604,29 @@
TouchParam tp,
float* min,
float* max) {
+#if defined(USE_XI2_MT)
+ TouchDeviceList::const_iterator it = touch_device_list_.find(deviceid);
+ if (it == touch_device_list_.end())
+ return false;
+
+ MultiTouchDevice::Axes::const_iterator ita =
+ it->second.axes().find(TouchParamToAxisType(tp));
+
+ if (ita == it->second.axes().end())
+ return false;
+
+ *min = ita->second.min();
+ *max = ita->second.max();
+
+ return true;
+#else
if (valuator_lookup_[deviceid][tp] >= 0) {
*min = touch_param_min_[deviceid][tp];
*max = touch_param_max_[deviceid][tp];
return true;
}
return false;
+#endif
}
} // namespace ui
« no previous file with comments | « ui/base/touch/touch_factory.h ('k') | ui/ui.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698