From f1e99b1b03848eb939fd3f51b56de1b23dfab057 Mon Sep 17 00:00:00 2001 From: "sadrul@chromium.org" Date: Thu, 20 Jan 2011 00:11:23 +0000 Subject: 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 Review URL: http://codereview.chromium.org/6300007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@71879 0039d316-1c4b-4281-b951-d872f2087c98 --- views/touchui/touch_factory.cc | 79 ++++++++++++++++++++++++++++++++++++++++++ views/touchui/touch_factory.h | 65 ++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 views/touchui/touch_factory.cc create mode 100644 views/touchui/touch_factory.h (limited to 'views/touchui') 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 +#include + +#include "base/logging.h" + +namespace views { + +// static +TouchFactory* TouchFactory::GetInstance() { + return Singleton::get(); +} + +TouchFactory::TouchFactory() + : touch_device_lookup_(), + touch_device_list_() { +} + +void TouchFactory::SetTouchDeviceList( + const std::vector& devices) { + touch_device_lookup_.reset(); + touch_device_list_.clear(); + for (std::vector::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::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::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 +#include + +#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& 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; + + // 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 touch_device_list_; + + DISALLOW_COPY_AND_ASSIGN(TouchFactory); +}; + +} // namespace views + +#endif // VIEWS_TOUCHUI_TOUCH_FACTORY_H_ -- cgit v1.1