diff options
author | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-26 22:04:44 +0000 |
---|---|---|
committer | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-26 22:04:44 +0000 |
commit | a3e2de75e309b527cd694b16d23100bbec1710d9 (patch) | |
tree | 30f49027fbf74758595ee30b0b301206a4c2becf /views/touchui | |
parent | e30e4d816f7e32f2be39f32159e020d3b037de04 (diff) | |
download | chromium_src-a3e2de75e309b527cd694b16d23100bbec1710d9.zip chromium_src-a3e2de75e309b527cd694b16d23100bbec1710d9.tar.gz chromium_src-a3e2de75e309b527cd694b16d23100bbec1710d9.tar.bz2 |
Consolidate/cleanup event cracking code; single out GdkEvents; saves ~850 lines.
Move ui::NativeEvent typdefs and common functions to ui/base/events.h.
Remove NativeEvent2 typedef, single out GdkEvent* uses that should be removed.
Implement platform specific ui/base/[platform]/events_[platform].cc.
Revise views::NativeEvent definitions (to support Aura abstraction).
Consolidate Event[Type/Flags/Location]FromNative(), GetMouseWheelOffset(), etc.
Remove GetRepeatCount(), GetWindowsFlags(), IsExtendedKey(), etc.
Add IsMouseEvent(), KeyboardCodeFromNative(), EF_EXTENDED flag, etc.
Localize GetFlagsFromGdkEvent(), move some file locals to new helpers files.
Move views/touchui/touch_factory.h|cc to ui/base/touch.
Stop mixing Windows mouse events' MK_*BUTTON into their wParams.
BUG=93945
TEST=No build breaks (many configs...), no mouse/key behavior changes.
Review URL: http://codereview.chromium.org/7942004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@102815 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/touchui')
-rw-r--r-- | views/touchui/gesture_manager.cc | 3 | ||||
-rw-r--r-- | views/touchui/touch_factory.cc | 502 | ||||
-rw-r--r-- | views/touchui/touch_factory.h | 206 |
3 files changed, 1 insertions, 710 deletions
diff --git a/views/touchui/gesture_manager.cc b/views/touchui/gesture_manager.cc index cf966ae..723db77 100644 --- a/views/touchui/gesture_manager.cc +++ b/views/touchui/gesture_manager.cc @@ -36,8 +36,7 @@ bool GestureManager::ProcessTouchEventForGesture(const TouchEvent& event, // Conver the touch-event into a mouse-event. This mouse-event gets its // location information from the native-event, so it needs to convert the // coordinate to the target widget. - Event::FromNativeEvent2 from_native; - MouseEvent mouseev(event, from_native); + MouseEvent mouseev(event); if (ViewsDelegate::views_delegate->GetDefaultParentView()) { // TODO(oshima): We may need to send the event back through // window manager to handle mouse capture correctly. diff --git a/views/touchui/touch_factory.cc b/views/touchui/touch_factory.cc deleted file mode 100644 index e644bca..0000000 --- a/views/touchui/touch_factory.cc +++ /dev/null @@ -1,502 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "views/touchui/touch_factory.h" - -#if defined(TOOLKIT_USES_GTK) -// TODO(sad) Remove all TOOLKIT_USES_GTK uses once we move to aura only. -#include <gtk/gtk.h> -#include <gdk/gdkx.h> -#endif -#include <X11/cursorfont.h> -#include <X11/extensions/XInput.h> -#include <X11/extensions/XInput2.h> -#include <X11/extensions/XIproto.h> - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "base/logging.h" -#include "base/message_loop.h" -#include "ui/base/x/x11_util.h" - -namespace { - -// The X cursor is hidden if it is idle for kCursorIdleSeconds seconds. -int kCursorIdleSeconds = 5; - -// Given the TouchParam, return the correspoding XIValuatorClassInfo using -// the X device information through Atom name matching. -XIValuatorClassInfo* FindTPValuator(Display* display, - XIDeviceInfo* info, - views::TouchFactory::TouchParam tp) { - // 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 { - views::TouchFactory::TouchParam tp; - const char* atom; - } kTouchParamAtom[] = { - { views::TouchFactory::TP_TOUCH_MAJOR, "Abs MT Touch Major" }, - { views::TouchFactory::TP_TOUCH_MINOR, "Abs MT Touch Minor" }, - { views::TouchFactory::TP_ORIENTATION, "Abs MT Orientation" }, - { views::TouchFactory::TP_PRESSURE, "Abs MT Pressure" }, -#if !defined(USE_XI2_MT) - // For Slot ID, See this chromeos revision: http://git.chromium.org/gitweb/? - // p=chromiumos/overlays/chromiumos-overlay.git; - // a=commit;h=9164d0a75e48c4867e4ef4ab51f743ae231c059a - { views::TouchFactory::TP_SLOT_ID, "Abs MT Slot ID" }, -#endif - { views::TouchFactory::TP_TRACKING_ID, "Abs MT Tracking ID" }, - { views::TouchFactory::TP_LAST_ENTRY, NULL }, - }; - - const char* atom_tp = NULL; - - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTouchParamAtom); i++) { - if (tp == kTouchParamAtom[i].tp) { - atom_tp = kTouchParamAtom[i].atom; - break; - } - } - - if (!atom_tp) - return NULL; - - 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; - } - - return NULL; -} - -#if defined(TOOLKIT_USES_GTK) -// Setup XInput2 select for the GtkWidget. -gboolean GtkWidgetRealizeCallback(GSignalInvocationHint* hint, guint nparams, - const GValue* pvalues, gpointer data) { - GtkWidget* widget = GTK_WIDGET(g_value_get_object(pvalues)); - GdkWindow* window = widget->window; - views::TouchFactory* factory = static_cast<views::TouchFactory*>(data); - - if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_TOPLEVEL && - GDK_WINDOW_TYPE(window) != GDK_WINDOW_CHILD && - GDK_WINDOW_TYPE(window) != GDK_WINDOW_DIALOG) - return true; - - factory->SetupXI2ForXWindow(GDK_WINDOW_XID(window)); - return true; -} - -// We need to capture all the GDK windows that get created, and start -// listening for XInput2 events. So we setup a callback to the 'realize' -// signal for GTK+ widgets, so that whenever the signal triggers for any -// GtkWidget, which means the GtkWidget should now have a GdkWindow, we can -// setup XInput2 events for the GdkWindow. -guint realize_signal_id = 0; -guint realize_hook_id = 0; - -void SetupGtkWidgetRealizeNotifier(views::TouchFactory* factory) { - gpointer klass = g_type_class_ref(GTK_TYPE_WIDGET); - - g_signal_parse_name("realize", GTK_TYPE_WIDGET, - &realize_signal_id, NULL, FALSE); - realize_hook_id = g_signal_add_emission_hook(realize_signal_id, 0, - GtkWidgetRealizeCallback, static_cast<gpointer>(factory), NULL); - - g_type_class_unref(klass); -} - -void RemoveGtkWidgetRealizeNotifier() { - if (realize_signal_id != 0) - g_signal_remove_emission_hook(realize_signal_id, realize_hook_id); - realize_signal_id = 0; - realize_hook_id = 0; -} -#endif - -} // namespace - -namespace views { - -// static -TouchFactory* TouchFactory::GetInstance() { - return Singleton<TouchFactory>::get(); -} - -TouchFactory::TouchFactory() - : is_cursor_visible_(true), - keep_mouse_cursor_(false), - cursor_timer_(), - pointer_device_lookup_(), -#if defined(USE_XI2_MT) - touch_device_list_() { -#else - touch_device_list_(), - slots_used_() { -#endif -#if defined(TOUCH_UI) - if (!base::MessagePumpForUI::HasXInput2()) - return; -#endif - - char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - XColor black; - black.red = black.green = black.blue = 0; - Display* display = ui::GetXDisplay(); - 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); - UpdateDeviceList(display); - -#if defined(TOOLKIT_USES_GTK) - // TODO(sad): Here, we only setup so that the X windows created by GTK+ are - // setup for XInput2 events. We need a way to listen for XInput2 events for X - // windows created by other means (e.g. for context menus). - SetupGtkWidgetRealizeNotifier(this); -#endif - // Make sure the list of devices is kept up-to-date by listening for - // XI_HierarchyChanged event on the root window. - unsigned char mask[XIMaskLen(XI_LASTEVENT)]; - memset(mask, 0, sizeof(mask)); - - XISetMask(mask, XI_HierarchyChanged); - - XIEventMask evmask; - evmask.deviceid = XIAllDevices; - evmask.mask_len = sizeof(mask); - evmask.mask = mask; - XISelectEvents(display, ui::GetX11RootWindow(), &evmask, 1); -} - -TouchFactory::~TouchFactory() { -#if defined(TOUCH_UI) - if (!base::MessagePumpForUI::HasXInput2()) - return; -#endif - - SetCursorVisible(true, false); - Display* display = ui::GetXDisplay(); - XFreeCursor(display, invisible_cursor_); - XFreeCursor(display, arrow_cursor_); - -#if defined(TOOLKIT_USES_GTK) - RemoveGtkWidgetRealizeNotifier(); -#endif -} - -void TouchFactory::UpdateDeviceList(Display* display) { - // Detect touch devices. - // NOTE: The new API for retrieving the list of devices (XIQueryDevice) does - // not provide enough information to detect a touch device. As a result, the - // old version of query function (XListInputDevices) is used instead. - // If XInput2 is not supported, this will return null (with count of -1) so - // we assume there cannot be any touch devices. - int count = 0; - touch_device_lookup_.reset(); - touch_device_list_.clear(); -#if !defined(USE_XI2_MT) - XDeviceInfo* devlist = XListInputDevices(display, &count); - for (int i = 0; i < count; i++) { - if (devlist[i].type) { - const char* devtype = XGetAtomName(display, devlist[i].type); - if (devtype && !strcmp(devtype, XI_TOUCHSCREEN)) { - touch_device_lookup_[devlist[i].id] = true; - touch_device_list_.push_back(devlist[i].id); - } - } - } - if (devlist) - XFreeDeviceList(devlist); -#endif - - // Instead of asking X for the list of devices all the time, let's maintain a - // list of pointer devices we care about. - // It should not be necessary to select for slave devices. XInput2 provides - // enough information to the event callback to decide which slave device - // triggered the event, thus decide whether the 'pointer event' is a - // 'mouse event' or a 'touch event'. - // However, on some desktops, some events from a master pointer are - // not delivered to the client. So we select for slave devices instead. - // If the touch device has 'GrabDevice' set and 'SendCoreEvents' unset (which - // is possible), then the device is detected as a floating device, and a - // floating device is not connected to a master device. So it is necessary to - // also select on the floating devices. - pointer_device_lookup_.reset(); - XIDeviceInfo* devices = XIQueryDevice(display, XIAllDevices, &count); - for (int i = 0; i < count; i++) { - XIDeviceInfo* devinfo = devices + i; -#if defined(USE_XI2_MT) - 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_.push_back(devinfo->deviceid); - } - } - } -#endif - if (devinfo->use == XIFloatingSlave || devinfo->use == XISlavePointer) - pointer_device_lookup_[devinfo->deviceid] = true; - } - if (devices) - XIFreeDeviceInfo(devices); - - SetupValuator(); -} - -bool TouchFactory::ShouldProcessXI2Event(XEvent* xev) { - DCHECK_EQ(GenericEvent, xev->type); - XIEvent* event = static_cast<XIEvent*>(xev->xcookie.data); - XIDeviceEvent* xiev = reinterpret_cast<XIDeviceEvent*>(event); - -#if defined(USE_XI2_MT) - if (event->evtype == XI_TouchBegin || - event->evtype == XI_TouchUpdate || - event->evtype == XI_TouchEnd) { - return touch_device_lookup_[xiev->sourceid]; - } -#endif - if (event->evtype != XI_ButtonPress && - event->evtype != XI_ButtonRelease && - event->evtype != XI_Motion) - return true; - - return pointer_device_lookup_[xiev->deviceid]; -} - -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 - // either resetup XInput2 for the window, so that we get events from the new - // device, or we need to listen to events from all devices, and then filter - // the events from uninteresting devices. We do the latter because that's - // simpler. - - Display* display = ui::GetXDisplay(); - - unsigned char mask[XIMaskLen(XI_LASTEVENT)]; - memset(mask, 0, sizeof(mask)); - -#if defined(USE_XI2_MT) - XISetMask(mask, XI_TouchBegin); - XISetMask(mask, XI_TouchUpdate); - XISetMask(mask, XI_TouchEnd); -#endif - XISetMask(mask, XI_ButtonPress); - XISetMask(mask, XI_ButtonRelease); - XISetMask(mask, XI_Motion); - - XIEventMask evmask; - evmask.deviceid = XIAllDevices; - evmask.mask_len = sizeof(mask); - evmask.mask = mask; - XISelectEvents(display, window, &evmask, 1); - XFlush(display); -} - -void TouchFactory::SetTouchDeviceList( - const std::vector<unsigned int>& devices) { - touch_device_lookup_.reset(); - touch_device_list_.clear(); - for (std::vector<unsigned int>::const_iterator iter = devices.begin(); - iter != devices.end(); ++iter) { - DCHECK(*iter < touch_device_lookup_.size()); - touch_device_lookup_[*iter] = true; - touch_device_list_.push_back(*iter); - } - - SetupValuator(); -} - -bool TouchFactory::IsTouchDevice(unsigned deviceid) const { - return deviceid < touch_device_lookup_.size() ? - touch_device_lookup_[deviceid] : false; -} - -#if !defined(USE_XI2_MT) -bool TouchFactory::IsSlotUsed(int slot) const { - CHECK_LT(slot, kMaxTouchPoints); - return slots_used_[slot]; -} - -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) - if (!base::MessagePumpForUI::HasXInput2() || - touch_device_list_.empty()) - return true; -#endif - - unsigned char mask[XIMaskLen(XI_LASTEVENT)]; - bool success = true; - - memset(mask, 0, sizeof(mask)); -#if defined(USE_XI2_MT) - XISetMask(mask, XI_TouchBegin); - XISetMask(mask, XI_TouchUpdate); - XISetMask(mask, XI_TouchEnd); -#endif - XISetMask(mask, XI_ButtonPress); - XISetMask(mask, XI_ButtonRelease); - XISetMask(mask, XI_Motion); - - XIEventMask evmask; - evmask.mask_len = sizeof(mask); - evmask.mask = mask; - for (std::vector<int>::const_iterator iter = - touch_device_list_.begin(); - iter != touch_device_list_.end(); ++iter) { - evmask.deviceid = *iter; - Status status = XIGrabDevice(display, *iter, window, CurrentTime, None, - GrabModeAsync, GrabModeAsync, False, &evmask); - success = success && status == GrabSuccess; - } - - return success; -} - -bool TouchFactory::UngrabTouchDevices(Display* display) { -#if defined(TOUCH_UI) - if (!base::MessagePumpForUI::HasXInput2()) - return true; -#endif - - bool success = true; - for (std::vector<int>::const_iterator iter = - touch_device_list_.begin(); - iter != touch_device_list_.end(); ++iter) { - Status status = XIUngrabDevice(display, *iter, CurrentTime); - success = success && status == GrabSuccess; - } - return success; -} - -void TouchFactory::SetCursorVisible(bool show, bool start_timer) { -#if defined(TOUCH_UI) - if (!base::MessagePumpForUI::HasXInput2()) - return; -#endif - - // The cursor is going to be shown. Reset the timer for hiding it. - if (show && start_timer) { - cursor_timer_.Stop(); - cursor_timer_.Start( - FROM_HERE, base::TimeDelta::FromSeconds(kCursorIdleSeconds), - this, &TouchFactory::HideCursorForInactivity); - } else { - cursor_timer_.Stop(); - } - - if (show == is_cursor_visible_) - return; - - is_cursor_visible_ = show; - - Display* display = ui::GetXDisplay(); - Window window = DefaultRootWindow(display); - - if (is_cursor_visible_) { - XDefineCursor(display, window, arrow_cursor_); - } else { - XDefineCursor(display, window, invisible_cursor_); - } -} - -void TouchFactory::SetupValuator() { - memset(valuator_lookup_, -1, sizeof(valuator_lookup_)); - memset(touch_param_min_, 0, sizeof(touch_param_min_)); - memset(touch_param_max_, 0, sizeof(touch_param_max_)); - - 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 j = 0; j < TP_LAST_ENTRY; j++) { - TouchParam tp = static_cast<TouchParam>(j); - XIValuatorClassInfo* valuator = FindTPValuator(display, info, tp); - if (valuator) { - valuator_lookup_[info->deviceid][j] = valuator->number; - touch_param_min_[info->deviceid][j] = valuator->min; - touch_param_max_[info->deviceid][j] = valuator->max; - } - } - } - - 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; - } - -#if defined(USE_XI2_MT) - // With XInput2 MT, Tracking ID is provided in the detail field. - if (tp == TP_TRACKING_ID) { - *value = xiev->detail; - return true; - } -#endif - - return false; -} - -bool TouchFactory::NormalizeTouchParam(unsigned int deviceid, - TouchParam tp, - float* value) { - float max_value; - float min_value; - if (GetTouchParamRange(deviceid, tp, &min_value, &max_value)) { - *value = (*value - min_value) / (max_value - min_value); - DCHECK(*value >= 0.0 && *value <= 1.0); - return true; - } - return false; -} - -bool TouchFactory::GetTouchParamRange(unsigned int deviceid, - TouchParam tp, - float* min, - float* max) { - if (valuator_lookup_[deviceid][tp] >= 0) { - *min = touch_param_min_[deviceid][tp]; - *max = touch_param_max_[deviceid][tp]; - return true; - } - return false; -} - -} // namespace views diff --git a/views/touchui/touch_factory.h b/views/touchui/touch_factory.h deleted file mode 100644 index ca281e4..0000000 --- a/views/touchui/touch_factory.h +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef VIEWS_TOUCHUI_TOUCH_FACTORY_H_ -#define VIEWS_TOUCHUI_TOUCH_FACTORY_H_ -#pragma once - -#include <bitset> -#include <vector> - -#include "base/memory/singleton.h" -#include "base/timer.h" -#include "views/views_export.h" - -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 VIEWS_EXPORT TouchFactory { - public: - // Define the touch params following the Multi-touch Protocol. - enum TouchParam { - TP_TOUCH_MAJOR = 0, // Length of the touch area. - TP_TOUCH_MINOR, // Width of the touch area. - TP_ORIENTATION, // Angle between the X-axis and the major axis of the - // touch area. - TP_PRESSURE, // Pressure of the touch contact. - - // NOTE: A touch event can have multiple touch points. So when we receive a - // touch event, we need to determine which point triggered the event. - // A touch point can have both a 'Slot ID' and a 'Tracking ID', and they can - // be (in fact, usually are) different. The 'Slot ID' ranges between 0 and - // (X - 1), where X is the maximum touch points supported by the device. The - // 'Tracking ID' can be any 16-bit value. With XInput 2.0, an XI_Motion - // event that comes from a currently-unused 'Slot ID' indicates the creation - // of a new touch point, and any event that comes with a 0 value for - // 'Tracking ID' marks the removal of a touch point. During the lifetime of - // a touchpoint, we use the 'Slot ID' as its identifier. The XI_ButtonPress - // and XI_ButtonRelease events are ignored. -#if !defined(USE_XI2_MT) - TP_SLOT_ID, // ID of the finger that triggered a touch event - // (useful when tracking multiple simultaneous - // touches) -#endif - // NOTE for XInput MT: 'Tracking ID' is provided in every touch event to - // track individual touch. 'Tracking ID' is an unsigned 32-bit value and - // is increased for each new touch. It will wrap back to 0 when reaching - // the numerical limit. - TP_TRACKING_ID, // ID of the touch point. - - TP_LAST_ENTRY - }; - - // Returns the TouchFactory singleton. - static TouchFactory* GetInstance(); - - // Updates the list of devices. - void UpdateDeviceList(Display* display); - - // Checks whether an XI2 event should be processed or not (i.e. if the event - // originated from a device we are interested in). - bool ShouldProcessXI2Event(XEvent* xevent); - - // Setup an X Window for XInput2 events. - void SetupXI2ForXWindow(::Window xid); - - // Keeps a list of touch devices so that it is possible to determine if a - // pointer event is a touch-event or a mouse-event. The list is reset each - // time this is called. - void SetTouchDeviceList(const std::vector<unsigned int>& devices); - - // Is the device a touch-device? - bool IsTouchDevice(unsigned int deviceid) const; - -#if !defined(USE_XI2_MT) - // 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. - bool GrabTouchDevices(Display* display, ::Window window); - - // Ungrabs the touch devices. Returns if ungrab was successful for all touch - // devices. - bool UngrabTouchDevices(Display* display); - - // Updates the root window to show (or hide) the cursor. Also indicate whether - // the timer should be started to automatically hide the cursor after a - // certain duration of inactivity (i.e. it is ignored if |show| is false). - void SetCursorVisible(bool show, bool start_timer); - - // Whether the cursor is currently visible or not. - bool is_cursor_visible() const { - 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); - - // Normalize the TouchParam with value on deviceid to fall into [0, 1]. - // *value = (*value - min_value_of_tp) / (max_value_of_tp - min_value_of_tp) - // Returns true and sets the normalized value in|value| if normalization is - // successful. Returns false and |value| is unchanged otherwise. - bool NormalizeTouchParam(unsigned int deviceid, TouchParam tp, float* value); - - // Extract the range of the TouchParam. Return true if the range is available - // and written into min & max, false if the range is not available. - bool GetTouchParamRange(unsigned int deviceid, - TouchParam tp, - float* min, - float* max); - - void set_keep_mouse_cursor(bool keep) { keep_mouse_cursor_ = keep; } - bool keep_mouse_cursor() const { return keep_mouse_cursor_; } - - private: - TouchFactory(); - - ~TouchFactory(); - - void HideCursorForInactivity() { - 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>; - - // The default cursor is hidden after startup, and when the mouse pointer is - // idle for a while. Once there is some event from a mouse device, the cursor - // is immediately displayed. - bool is_cursor_visible_; - - // Whether to turn off automatic hiding of mouse cursor. This is useful for - // debugging touch build on the desktop. - bool keep_mouse_cursor_; - - // The cursor is hidden if it is idle for a certain amount time. This timer - // is used to keep track of the idleness. - base::OneShotTimer<TouchFactory> cursor_timer_; - - // The default cursor. - Cursor arrow_cursor_; - - // The invisible cursor. - Cursor invisible_cursor_; - - // NOTE: To keep track of touch devices, we currently maintain a lookup table - // to quickly decide if a device is a touch device or not. We also maintain a - // list of the touch devices. Ideally, there will be only one touch device, - // and instead of having the lookup table and the list, there will be a single - // 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 events from the pointer device - // should be processed. - std::bitset<kMaxDeviceNum> pointer_device_lookup_; - - // A quick lookup table for determining if a device is a touch device. - 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. - signed char valuator_lookup_[kMaxDeviceNum][TP_LAST_ENTRY]; - - // Index table to find the min & max value of the TouchParam on a specific - // device. - 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; - - // A lookup table for slots in use for a touch event. - std::bitset<kMaxTouchPoints> slots_used_; -#endif - - DISALLOW_COPY_AND_ASSIGN(TouchFactory); -}; - -} // namespace views - -#endif // VIEWS_TOUCHUI_TOUCH_FACTORY_H_ |