diff options
author | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-20 21:10:51 +0000 |
---|---|---|
committer | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-20 21:10:51 +0000 |
commit | e9f575064ea212023b82ec27e36905a066cfc76d (patch) | |
tree | d6f06303ee091acbe74fc31126067c20c2de1d44 /views | |
parent | d9b5b3e38455a1ae06c02df6ebeace9dc9b79f42 (diff) | |
download | chromium_src-e9f575064ea212023b82ec27e36905a066cfc76d.zip chromium_src-e9f575064ea212023b82ec27e36905a066cfc76d.tar.gz chromium_src-e9f575064ea212023b82ec27e36905a066cfc76d.tar.bz2 |
touch: Allow grabbing/ungrabbing touch devices for XInput2.
This allows touch devices to be grabbed when events from the mouse/keyboard are
grabbed. This also exposes TouchFactory, which will eventually be used in more
places.
BUG=none
TEST=none
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=71879
Review URL: http://codereview.chromium.org/6300007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@72002 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r-- | views/controls/menu/menu_host_gtk.cc | 21 | ||||
-rw-r--r-- | views/focus/accelerator_handler_touch.cc | 35 | ||||
-rw-r--r-- | views/touchui/touch_factory.cc | 79 | ||||
-rw-r--r-- | views/touchui/touch_factory.h | 65 | ||||
-rw-r--r-- | views/views.gyp | 27 |
5 files changed, 195 insertions, 32 deletions
diff --git a/views/controls/menu/menu_host_gtk.cc b/views/controls/menu/menu_host_gtk.cc index 917ded3..6b29ce1 100644 --- a/views/controls/menu/menu_host_gtk.cc +++ b/views/controls/menu/menu_host_gtk.cc @@ -6,11 +6,20 @@ #include <gdk/gdk.h> +#if defined(HAVE_XINPUT2) && defined(TOUCH_UI) +#include <gdk/gdkx.h> +#include <X11/extensions/XInput2.h> +#endif + #include "views/controls/menu/menu_controller.h" #include "views/controls/menu/menu_host_root_view.h" #include "views/controls/menu/menu_item_view.h" #include "views/controls/menu/submenu_view.h" +#if defined(HAVE_XINPUT2) && defined(TOUCH_UI) +#include "views/touchui/touch_factory.h" +#endif + namespace views { // static @@ -104,6 +113,10 @@ void MenuHostGtk::ReleaseGrab() { did_input_grab_ = false; gdk_pointer_ungrab(GDK_CURRENT_TIME); gdk_keyboard_ungrab(GDK_CURRENT_TIME); +#if defined(HAVE_XINPUT2) && defined(TOUCH_UI) + TouchFactory::GetInstance()->UngrabTouchDevices( + GDK_WINDOW_XDISPLAY(window_contents()->window)); +#endif } } @@ -151,6 +164,14 @@ void MenuHostGtk::DoCapture() { did_input_grab_ = pointer_grab_status == GDK_GRAB_SUCCESS && keyboard_grab_status == GDK_GRAB_SUCCESS; + +#if defined(HAVE_XINPUT2) && defined(TOUCH_UI) + ::Window window = GDK_WINDOW_XID(window_contents()->window); + Display* display = GDK_WINDOW_XDISPLAY(window_contents()->window); + bool xi2grab = TouchFactory::GetInstance()->GrabTouchDevices(display, window); + did_input_grab_ = did_input_grab_ && xi2grab; +#endif + DCHECK(did_input_grab_); // need keyboard grab. } diff --git a/views/focus/accelerator_handler_touch.cc b/views/focus/accelerator_handler_touch.cc index 84c042d..b24d8f0 100644 --- a/views/focus/accelerator_handler_touch.cc +++ b/views/focus/accelerator_handler_touch.cc @@ -15,41 +15,12 @@ #include "views/accelerator.h" #include "views/event.h" #include "views/focus/focus_manager.h" +#include "views/touchui/touch_factory.h" #include "views/widget/root_view.h" #include "views/widget/widget_gtk.h" 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) { @@ -78,7 +49,7 @@ bool X2EventIsTouchEvent(XEvent* xev) { case XI_ButtonRelease: case XI_Motion: { // Is the event coming from a touch device? - return TouchFactory::IsTouchDevice( + return TouchFactory::GetInstance()->IsTouchDevice( static_cast<XIDeviceEvent*>(cookie->data)->sourceid); } default: @@ -200,7 +171,7 @@ bool DispatchXEvent(XEvent* xev) { #if defined(HAVE_XINPUT2) void SetTouchDeviceList(std::vector<unsigned int>& devices) { - TouchFactory::SetTouchDeviceListInternal(devices); + TouchFactory::GetInstance()->SetTouchDeviceList(devices); } #endif diff --git a/views/touchui/touch_factory.cc b/views/touchui/touch_factory.cc new file mode 100644 index 0000000..8608782 --- /dev/null +++ b/views/touchui/touch_factory.cc @@ -0,0 +1,79 @@ +// 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" + +#include <gdk/gdkx.h> +#include <X11/extensions/XInput2.h> + +#include "base/logging.h" + +namespace views { + +// static +TouchFactory* TouchFactory::GetInstance() { + return Singleton<TouchFactory>::get(); +} + +TouchFactory::TouchFactory() + : touch_device_lookup_(), + touch_device_list_() { +} + +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); + } +} + +bool TouchFactory::IsTouchDevice(unsigned deviceid) { + return deviceid < touch_device_lookup_.size() ? + touch_device_lookup_[deviceid] : false; +} + +bool TouchFactory::GrabTouchDevices(Display* display, ::Window window) { + if (touch_device_list_.empty()) + return true; + + unsigned char mask[(XI_LASTEVENT + 7) / 8]; + bool success = true; + + memset(mask, 0, sizeof(mask)); + 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) { + 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; +} + +} // namespace views diff --git a/views/touchui/touch_factory.h b/views/touchui/touch_factory.h new file mode 100644 index 0000000..04114be --- /dev/null +++ b/views/touchui/touch_factory.h @@ -0,0 +1,65 @@ +// 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/singleton.h" + +typedef unsigned long Window; +typedef struct _XDisplay Display; + +namespace views { + +// Functions related to determining touch devices. +class TouchFactory { + public: + // Returns the TouchFactory singleton. + static TouchFactory* GetInstance(); + + // 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. 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); + + // Grab 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); + + // Ungrab the touch devices. Returns if ungrab was successful for all touch + // devices. + bool UngrabTouchDevices(Display* display); + + private: + TouchFactory(); + + // Requirement for Signleton + friend struct DefaultSingletonTraits<TouchFactory>; + + // 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. + + // A quick lookup table for determining if a device is a touch device. + std::bitset<128> touch_device_lookup_; + + // The list of touch devices. + std::vector<int> touch_device_list_; + + DISALLOW_COPY_AND_ASSIGN(TouchFactory); +}; + +} // namespace views + +#endif // VIEWS_TOUCHUI_TOUCH_FACTORY_H_ diff --git a/views/views.gyp b/views/views.gyp index 7cbcfe0..e9fb72b 100644 --- a/views/views.gyp +++ b/views/views.gyp @@ -6,6 +6,22 @@ 'variables': { 'chromium_code': 1, }, + + 'conditions': [ + [ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', { + 'conditions': [ + ['sysroot!=""', { + 'variables': { + 'pkg-config': './pkg-config-wrapper "<(sysroot)"', + }, + }, { + 'variables': { + 'pkg-config': 'pkg-config' + }, + }],] + }], + ], + 'target_defaults': { 'sources/': [ ['exclude', '/(cocoa|gtk|win)/'], @@ -281,6 +297,8 @@ 'standard_layout.h', 'touchui/gesture_manager.cc', 'touchui/gesture_manager.h', + 'touchui/touch_factory.cc', + 'touchui/touch_factory.h', 'view.cc', 'view.h', 'view_constants.cc', @@ -392,6 +410,15 @@ ['exclude', 'focus/accelerator_handler_gtk.cc'], ['exclude', 'controls/menu/native_menu_gtk.cc'], ], + 'conditions': [ + ['"<!@(<(pkg-config) --atleast-version=2.0 inputproto || echo $?)"!=""', { + # Exclude TouchFactory if XInput2 is not available. + 'sources/': [ + ['exclude', 'touchui/touch_factory.cc'], + ['exclude', 'touchui/touch_factory.h'], + ], + }], + ], }], ['OS=="win"', { 'sources!': [ |