Home | History | Annotate | Download | only in x
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef UI_EVENTS_X_TOUCH_FACTORY_X11_H_
      6 #define UI_EVENTS_X_TOUCH_FACTORY_X11_H_
      7 
      8 #include <bitset>
      9 #include <map>
     10 #include <set>
     11 #include <utility>
     12 #include <vector>
     13 
     14 #include "base/timer/timer.h"
     15 #include "ui/events/events_base_export.h"
     16 #include "ui/gfx/sequential_id_generator.h"
     17 
     18 template <typename T> struct DefaultSingletonTraits;
     19 
     20 typedef unsigned long Cursor;
     21 typedef unsigned long Window;
     22 typedef struct _XDisplay Display;
     23 typedef union _XEvent XEvent;
     24 
     25 namespace ui {
     26 
     27 // Functions related to determining touch devices.
     28 class EVENTS_BASE_EXPORT TouchFactory {
     29  private:
     30   TouchFactory();
     31   ~TouchFactory();
     32 
     33  public:
     34   // Returns the TouchFactory singleton.
     35   static TouchFactory* GetInstance();
     36 
     37   // Sets the touch devices from the command line.
     38   static void SetTouchDeviceListFromCommandLine();
     39 
     40   // Updates the list of devices.
     41   void UpdateDeviceList(Display* display);
     42 
     43   // Checks whether an XI2 event should be processed or not (i.e. if the event
     44   // originated from a device we are interested in).
     45   bool ShouldProcessXI2Event(XEvent* xevent);
     46 
     47   // Setup an X Window for XInput2 events.
     48   void SetupXI2ForXWindow(::Window xid);
     49 
     50   // Keeps a list of touch devices so that it is possible to determine if a
     51   // pointer event is a touch-event or a mouse-event. The list is reset each
     52   // time this is called.
     53   void SetTouchDeviceList(const std::vector<unsigned int>& devices);
     54 
     55   // Is the device a touch-device?
     56   bool IsTouchDevice(unsigned int deviceid) const;
     57 
     58   // Is the device a real multi-touch-device? (see doc. for |touch_device_list_|
     59   // below for more explanation.)
     60   bool IsMultiTouchDevice(unsigned int deviceid) const;
     61 
     62   // Tries to find an existing slot ID mapping to tracking ID. Returns true
     63   // if the slot is found and it is saved in |slot|, false if no such slot
     64   // can be found.
     65   bool QuerySlotForTrackingID(uint32 tracking_id, int* slot);
     66 
     67   // Tries to find an existing slot ID mapping to tracking ID. If there
     68   // isn't one already, allocates a new slot ID and sets up the mapping.
     69   int GetSlotForTrackingID(uint32 tracking_id);
     70 
     71   // Increases the number of times |ReleaseSlotForTrackingID| needs to be called
     72   // on a given tracking id before it will actually be released.
     73   void AcquireSlotForTrackingID(uint32 tracking_id);
     74 
     75   // Releases the slot ID mapping to tracking ID.
     76   void ReleaseSlotForTrackingID(uint32 tracking_id);
     77 
     78   // Whether any touch device is currently present and enabled.
     79   bool IsTouchDevicePresent();
     80 
     81   // Pairs of <vendor id, product id> of external touch screens.
     82   const std::set<std::pair<int, int> >& GetTouchscreenIds() const {
     83     return touchscreen_ids_;
     84   }
     85 
     86   // Return maximum simultaneous touch points supported by device.
     87   int GetMaxTouchPoints() const;
     88 
     89   // Resets the TouchFactory singleton.
     90   void ResetForTest();
     91 
     92   // Sets up the device id in the list |devices| as multi-touch capable
     93   // devices and enables touch events processing. This function is only
     94   // for test purpose, and it does not query from X server.
     95   void SetTouchDeviceForTest(const std::vector<unsigned int>& devices);
     96 
     97   // Sets up the device id in the list |devices| as pointer devices.
     98   // This function is only for test purpose, and it does not query from
     99   // X server.
    100   void SetPointerDeviceForTest(const std::vector<unsigned int>& devices);
    101 
    102  private:
    103   // Requirement for Singleton
    104   friend struct DefaultSingletonTraits<TouchFactory>;
    105 
    106   void CacheTouchscreenIds(Display* display, int id);
    107 
    108   // NOTE: To keep track of touch devices, we currently maintain a lookup table
    109   // to quickly decide if a device is a touch device or not. We also maintain a
    110   // list of the touch devices. Ideally, there will be only one touch device,
    111   // and instead of having the lookup table and the list, there will be a single
    112   // identifier for the touch device. This can be completed after enough testing
    113   // on real touch devices.
    114 
    115   static const int kMaxDeviceNum = 128;
    116 
    117   // A quick lookup table for determining if events from the pointer device
    118   // should be processed.
    119   std::bitset<kMaxDeviceNum> pointer_device_lookup_;
    120 
    121   // A quick lookup table for determining if a device is a touch device.
    122   std::bitset<kMaxDeviceNum> touch_device_lookup_;
    123 
    124   // Indicates whether a touch device is currently available or not.
    125   bool touch_device_available_;
    126 
    127   // Indicates whether touch events are explicitly disabled.
    128   bool touch_events_disabled_;
    129 
    130   // The list of touch devices. For testing/debugging purposes, a single-pointer
    131   // device (mouse or touch screen without sufficient X/driver support for MT)
    132   // can sometimes be treated as a touch device. The key in the map represents
    133   // the device id, and the value represents if the device is multi-touch
    134   // capable.
    135   std::map<int, bool> touch_device_list_;
    136 
    137   // Touch screen <vid, pid>s.
    138   std::set<std::pair<int, int> > touchscreen_ids_;
    139 
    140   // Maps from a tracking id to the number of times |ReleaseSlotForTrackingID|
    141   // must be called before the tracking id is released.
    142   std::map<uint32, int> tracking_id_refcounts_;
    143 
    144   // Maximum simultaneous touch points supported by device. In the case of
    145   // devices with multiple digitizers (e.g. multiple touchscreens), the value
    146   // is the maximum of the set of maximum supported contacts by each individual
    147   // digitizer.
    148   int max_touch_points_;
    149 
    150   // Device ID of the virtual core keyboard.
    151   int virtual_core_keyboard_device_;
    152 
    153   SequentialIDGenerator id_generator_;
    154 
    155   DISALLOW_COPY_AND_ASSIGN(TouchFactory);
    156 };
    157 
    158 }  // namespace ui
    159 
    160 #endif  // UI_EVENTS_X_TOUCH_FACTORY_X11_H_
    161