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. GetTouchscreenIds()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