OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/base/touch/touch_factory.h" | 5 #include "ui/base/touch/touch_factory.h" |
6 | 6 |
| 7 #include <string> |
| 8 |
| 9 #include "ui/base/touch/multi_touch_device.h" |
| 10 #include "ui/base/touch/multi_touch_device_x11.h" |
| 11 |
7 #include <X11/cursorfont.h> | 12 #include <X11/cursorfont.h> |
8 #include <X11/extensions/XInput.h> | 13 #include <X11/extensions/XInput.h> |
9 #include <X11/extensions/XInput2.h> | 14 #include <X11/extensions/XInput2.h> |
10 #include <X11/extensions/XIproto.h> | 15 #include <X11/extensions/XIproto.h> |
11 | 16 |
12 #include "base/basictypes.h" | 17 #include "base/basictypes.h" |
13 #include "base/compiler_specific.h" | 18 #include "base/compiler_specific.h" |
14 #include "base/logging.h" | 19 #include "base/logging.h" |
15 #include "base/message_loop.h" | 20 #include "base/message_loop.h" |
16 #include "ui/base/x/x11_util.h" | 21 #include "ui/base/x/x11_util.h" |
17 | 22 |
18 namespace { | 23 namespace { |
19 | 24 |
20 // The X cursor is hidden if it is idle for kCursorIdleSeconds seconds. | 25 // The X cursor is hidden if it is idle for kCursorIdleSeconds seconds. |
21 int kCursorIdleSeconds = 5; | 26 int kCursorIdleSeconds = 5; |
22 | 27 |
| 28 ui::Axis::Type TouchParamToAxisType(ui::TouchFactory::TouchParam tp) { |
| 29 ui::Axis::Type type = ui::Axis::AXIS_TYPE_UNKNOWN; |
| 30 switch (tp) { |
| 31 case ui::TouchFactory::TP_TOUCH_MAJOR: |
| 32 // Length of the touch area. |
| 33 type = ui::Axis::AXIS_TYPE_TOUCH_MAJOR; |
| 34 break; |
| 35 case ui::TouchFactory::TP_TOUCH_MINOR: |
| 36 // Width of the touch area. |
| 37 type = ui::Axis::AXIS_TYPE_TOUCH_MINOR; |
| 38 break; |
| 39 case ui::TouchFactory::TP_ORIENTATION: |
| 40 // Angle between the X-axis and the major axis of the |
| 41 // touch area. |
| 42 type = ui::Axis::AXIS_TYPE_ORIENTATION; |
| 43 break; |
| 44 case ui::TouchFactory::TP_PRESSURE: |
| 45 // Pressure of the touch contact. |
| 46 type = ui::Axis::AXIS_TYPE_PRESSURE; |
| 47 case ui::TouchFactory::TP_TRACKING_ID: |
| 48 // ID of the touch point. |
| 49 type = ui::Axis::AXIS_TYPE_TRACKING_ID; |
| 50 default: |
| 51 break; |
| 52 } |
| 53 |
| 54 return type; |
| 55 } |
| 56 |
23 // Given the TouchParam, return the correspoding XIValuatorClassInfo using | 57 // Given the TouchParam, return the correspoding XIValuatorClassInfo using |
24 // the X device information through Atom name matching. | 58 // the X device information through Atom name matching. |
25 XIValuatorClassInfo* FindTPValuator(Display* display, | 59 XIValuatorClassInfo* FindTPValuator(Display* display, |
26 XIDeviceInfo* info, | 60 XIDeviceInfo* info, |
27 ui::TouchFactory::TouchParam tp) { | 61 ui::TouchFactory::TouchParam tp) { |
28 // Lookup table for mapping TouchParam to Atom string used in X. | 62 // Lookup table for mapping TouchParam to Atom string used in X. |
29 // A full set of Atom strings can be found at xserver-properties.h. | 63 // A full set of Atom strings can be found at xserver-properties.h. |
30 static struct { | 64 static struct { |
31 ui::TouchFactory::TouchParam tp; | 65 ui::TouchFactory::TouchParam tp; |
32 const char* atom; | 66 const char* atom; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 | 99 |
66 if (v->label) { | 100 if (v->label) { |
67 ui::XScopedString atom(XGetAtomName(display, v->label)); | 101 ui::XScopedString atom(XGetAtomName(display, v->label)); |
68 if (atom.string() && strcmp(atom.string(), atom_tp) == 0) | 102 if (atom.string() && strcmp(atom.string(), atom_tp) == 0) |
69 return v; | 103 return v; |
70 } | 104 } |
71 } | 105 } |
72 | 106 |
73 return NULL; | 107 return NULL; |
74 } | 108 } |
75 | |
76 } // namespace | 109 } // namespace |
77 | 110 |
78 namespace ui { | 111 namespace ui { |
79 | 112 |
80 // static | 113 // static |
81 TouchFactory* TouchFactory::GetInstance() { | 114 TouchFactory* TouchFactory::GetInstance() { |
82 return Singleton<TouchFactory>::get(); | 115 return Singleton<TouchFactory>::get(); |
83 } | 116 } |
84 | 117 |
85 TouchFactory::TouchFactory() | 118 TouchFactory::TouchFactory() |
86 : is_cursor_visible_(true), | 119 : device_observer_list_( |
| 120 new ObserverListThreadSafe<TouchFactory::DeviceObserver>()), |
| 121 is_cursor_visible_(true), |
87 cursor_timer_(), | 122 cursor_timer_(), |
88 pointer_device_lookup_(), | 123 pointer_device_lookup_(), |
89 touch_device_available_(false), | 124 touch_device_available_(false), |
90 touch_device_list_(), | 125 touch_device_list_(), |
91 #if defined(USE_XI2_MT) | 126 #if defined(USE_XI2_MT) |
| 127 #if defined(USE_AURA) |
| 128 native_root_window_aura_(ui::GetX11RootWindow()), |
| 129 #endif |
| 130 utouch_frame_handle_(NULL), |
92 min_available_slot_(0), | 131 min_available_slot_(0), |
93 #endif | 132 #endif |
94 slots_used_() { | 133 slots_used_() { |
95 #if defined(USE_AURA) | 134 #if defined(USE_AURA) |
96 if (!base::MessagePumpForUI::HasXInput2()) | 135 if (!base::MessagePumpForUI::HasXInput2()) |
97 return; | 136 return; |
98 #endif | 137 #endif |
99 | 138 |
100 char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | 139 char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
101 XColor black; | 140 XColor black; |
102 black.red = black.green = black.blue = 0; | 141 black.red = black.green = black.blue = 0; |
103 Display* display = ui::GetXDisplay(); | 142 Display* display = ui::GetXDisplay(); |
| 143 |
| 144 if (UFStatusSuccess != frame_x11_new(display, &utouch_frame_handle_)) { |
| 145 LOG(ERROR) << "Failed to create utouch frame instance"; |
| 146 } else { |
| 147 fd_set set; |
| 148 FD_ZERO(&set); |
| 149 FD_SET(frame_get_fd(utouch_frame_handle_), &set); |
| 150 } |
| 151 |
104 Pixmap blank = XCreateBitmapFromData(display, ui::GetX11RootWindow(), | 152 Pixmap blank = XCreateBitmapFromData(display, ui::GetX11RootWindow(), |
105 nodata, 8, 8); | 153 nodata, 8, 8); |
106 invisible_cursor_ = XCreatePixmapCursor(display, blank, blank, | 154 invisible_cursor_ = XCreatePixmapCursor(display, blank, blank, |
107 &black, &black, 0, 0); | 155 &black, &black, 0, 0); |
108 arrow_cursor_ = XCreateFontCursor(display, XC_arrow); | 156 arrow_cursor_ = XCreateFontCursor(display, XC_arrow); |
109 | 157 |
110 SetCursorVisible(false, false); | 158 // TODO(tvoss): Selectively enable visibility for indirect touch devs. |
| 159 // SetCursorVisible(false, false); |
111 UpdateDeviceList(display); | 160 UpdateDeviceList(display); |
112 | 161 |
113 // Make sure the list of devices is kept up-to-date by listening for | 162 // Make sure the list of devices is kept up-to-date by listening for |
114 // XI_HierarchyChanged event on the root window. | 163 // XI_HierarchyChanged event on the root window. |
115 unsigned char mask[XIMaskLen(XI_LASTEVENT)]; | 164 unsigned char mask[XIMaskLen(XI_LASTEVENT)]; |
116 memset(mask, 0, sizeof(mask)); | 165 memset(mask, 0, sizeof(mask)); |
117 | 166 |
118 XISetMask(mask, XI_HierarchyChanged); | 167 XISetMask(mask, XI_HierarchyChanged); |
119 | 168 |
120 XIEventMask evmask; | 169 XIEventMask evmask; |
121 evmask.deviceid = XIAllDevices; | 170 evmask.deviceid = XIAllDevices; |
122 evmask.mask_len = sizeof(mask); | 171 evmask.mask_len = sizeof(mask); |
123 evmask.mask = mask; | 172 evmask.mask = mask; |
124 XISelectEvents(display, ui::GetX11RootWindow(), &evmask, 1); | 173 XISelectEvents(display, ui::GetX11RootWindow(), &evmask, 1); |
125 } | 174 } |
126 | 175 |
127 TouchFactory::~TouchFactory() { | 176 TouchFactory::~TouchFactory() { |
| 177 device_observer_list_->Release(); |
| 178 ObserverListThreadSafeTraits<DeviceObserver>::Destruct( |
| 179 device_observer_list_); |
| 180 |
128 #if defined(USE_AURA) | 181 #if defined(USE_AURA) |
129 if (!base::MessagePumpForUI::HasXInput2()) | 182 if (!base::MessagePumpForUI::HasXInput2()) |
130 return; | 183 return; |
131 #endif | 184 #endif |
132 | 185 |
133 // The XDisplay may be lost by the time we get destroyed. | 186 // The XDisplay may be lost by the time we get destroyed. |
134 if (ui::XDisplayExists()) { | 187 if (ui::XDisplayExists()) { |
135 SetCursorVisible(true, false); | 188 SetCursorVisible(true, false); |
136 Display* display = ui::GetXDisplay(); | 189 Display* display = ui::GetXDisplay(); |
137 XFreeCursor(display, invisible_cursor_); | 190 XFreeCursor(display, invisible_cursor_); |
138 XFreeCursor(display, arrow_cursor_); | 191 XFreeCursor(display, arrow_cursor_); |
139 } | 192 } |
140 } | 193 } |
141 | 194 |
| 195 void TouchFactory::AddDeviceObserver(TouchFactory::DeviceObserver * observer) { |
| 196 device_observer_list_->AddObserver(observer); |
| 197 |
| 198 base::AutoLock al(touch_device_list_lock_); |
| 199 // Make sure that every new observer is provided with an |
| 200 // initial list of devices. |
| 201 device_observer_list_->Notify( |
| 202 &DeviceObserver::OnDevicesUpdated, |
| 203 touch_device_list_); |
| 204 } |
| 205 |
| 206 void TouchFactory::RemoveDeviceObserver( |
| 207 TouchFactory::DeviceObserver * observer) { |
| 208 device_observer_list_->RemoveObserver(observer); |
| 209 } |
| 210 |
142 void TouchFactory::UpdateDeviceList(Display* display) { | 211 void TouchFactory::UpdateDeviceList(Display* display) { |
| 212 base::AutoLock al(touch_device_list_lock_); |
| 213 |
143 // Detect touch devices. | 214 // Detect touch devices. |
144 // NOTE: The new API for retrieving the list of devices (XIQueryDevice) does | 215 // NOTE: The new API for retrieving the list of devices (XIQueryDevice) does |
145 // not provide enough information to detect a touch device. As a result, the | 216 // not provide enough information to detect a touch device. As a result, the |
146 // old version of query function (XListInputDevices) is used instead. | 217 // old version of query function (XListInputDevices) is used instead. |
147 // If XInput2 is not supported, this will return null (with count of -1) so | 218 // If XInput2 is not supported, this will return null (with count of -1) so |
148 // we assume there cannot be any touch devices. | 219 // we assume there cannot be any touch devices. |
149 int count = 0; | 220 int count = 0; |
150 touch_device_available_ = false; | 221 touch_device_available_ = false; |
151 touch_device_lookup_.reset(); | 222 touch_device_lookup_.reset(); |
152 touch_device_list_.clear(); | 223 touch_device_list_.clear(); |
(...skipping 23 matching lines...) Expand all Loading... |
176 // not delivered to the client. So we select for slave devices instead. | 247 // not delivered to the client. So we select for slave devices instead. |
177 // If the touch device has 'GrabDevice' set and 'SendCoreEvents' unset (which | 248 // If the touch device has 'GrabDevice' set and 'SendCoreEvents' unset (which |
178 // is possible), then the device is detected as a floating device, and a | 249 // is possible), then the device is detected as a floating device, and a |
179 // floating device is not connected to a master device. So it is necessary to | 250 // floating device is not connected to a master device. So it is necessary to |
180 // also select on the floating devices. | 251 // also select on the floating devices. |
181 pointer_device_lookup_.reset(); | 252 pointer_device_lookup_.reset(); |
182 XIDeviceInfo* devices = XIQueryDevice(display, XIAllDevices, &count); | 253 XIDeviceInfo* devices = XIQueryDevice(display, XIAllDevices, &count); |
183 for (int i = 0; i < count; i++) { | 254 for (int i = 0; i < count; i++) { |
184 XIDeviceInfo* devinfo = devices + i; | 255 XIDeviceInfo* devinfo = devices + i; |
185 #if defined(USE_XI2_MT) | 256 #if defined(USE_XI2_MT) |
| 257 MultiTouchDevice mtDevice; |
| 258 if (ui::xi_device_info_to_mt_device(devinfo, mtDevice)) |
| 259 touch_device_list_[devinfo->deviceid] = mtDevice; |
| 260 |
186 for (int k = 0; k < devinfo->num_classes; ++k) { | 261 for (int k = 0; k < devinfo->num_classes; ++k) { |
187 XIAnyClassInfo* xiclassinfo = devinfo->classes[k]; | 262 XIAnyClassInfo* xiclassinfo = devinfo->classes[k]; |
188 if (xiclassinfo->type == XITouchClass) { | 263 if (xiclassinfo->type == XITouchClass) { |
189 XITouchClassInfo* tci = | 264 XITouchClassInfo* tci = |
190 reinterpret_cast<XITouchClassInfo *>(xiclassinfo); | 265 reinterpret_cast<XITouchClassInfo *>(xiclassinfo); |
191 // Only care direct touch device (such as touch screen) right now | 266 switch (tci->mode) { |
192 if (tci->mode == XIDirectTouch) { | 267 case XIDirectTouch: |
193 touch_device_lookup_[devinfo->deviceid] = true; | 268 touch_device_lookup_[devinfo->deviceid] = true; |
194 touch_device_list_[devinfo->deviceid] = true; | 269 touch_device_available_ = true; |
195 touch_device_available_ = true; | 270 break; |
| 271 case XIDependentTouch: |
| 272 touch_device_lookup_[devinfo->deviceid] = true; |
| 273 touch_device_available_ = true; |
| 274 break; |
196 } | 275 } |
197 } | 276 } |
198 } | 277 } |
199 #endif | 278 #endif |
200 if (devinfo->use == XIFloatingSlave || devinfo->use == XISlavePointer) | 279 if (devinfo->use == XIFloatingSlave || devinfo->use == XISlavePointer) |
201 pointer_device_lookup_[devinfo->deviceid] = true; | 280 pointer_device_lookup_[devinfo->deviceid] = true; |
202 } | 281 } |
203 if (devices) | 282 if (devices) |
204 XIFreeDeviceInfo(devices); | 283 XIFreeDeviceInfo(devices); |
205 | 284 |
206 SetupValuator(); | 285 SetupValuator(); |
| 286 |
| 287 device_observer_list_->Notify( |
| 288 &DeviceObserver::OnDevicesUpdated, touch_device_list_); |
207 } | 289 } |
208 | 290 |
209 bool TouchFactory::ShouldProcessXI2Event(XEvent* xev) { | 291 bool TouchFactory::ShouldProcessXI2Event(XEvent* xev) { |
210 DCHECK_EQ(GenericEvent, xev->type); | 292 DCHECK_EQ(GenericEvent, xev->type); |
211 XIEvent* event = static_cast<XIEvent*>(xev->xcookie.data); | 293 XIEvent* event = static_cast<XIEvent*>(xev->xcookie.data); |
212 XIDeviceEvent* xiev = reinterpret_cast<XIDeviceEvent*>(event); | 294 XIDeviceEvent* xiev = reinterpret_cast<XIDeviceEvent*>(event); |
213 | 295 |
214 #if defined(USE_XI2_MT) | 296 #if defined(USE_XI2_MT) |
| 297 if (event->evtype == XI_HierarchyChanged) |
| 298 return true; |
215 if (event->evtype == XI_TouchBegin || | 299 if (event->evtype == XI_TouchBegin || |
216 event->evtype == XI_TouchUpdate || | 300 event->evtype == XI_TouchUpdate || |
217 event->evtype == XI_TouchEnd) { | 301 event->evtype == XI_TouchEnd) { |
218 return touch_device_lookup_[xiev->sourceid]; | 302 return touch_device_lookup_[xiev->sourceid]; |
219 } | 303 } |
220 #endif | 304 #endif |
221 if (event->evtype != XI_ButtonPress && | 305 if (event->evtype != XI_ButtonPress && |
222 event->evtype != XI_ButtonRelease && | 306 event->evtype != XI_ButtonRelease && |
223 event->evtype != XI_Motion) | 307 event->evtype != XI_Motion) |
224 return true; | 308 return true; |
225 | 309 |
226 return pointer_device_lookup_[xiev->deviceid]; | 310 return pointer_device_lookup_[xiev->deviceid]; |
227 } | 311 } |
228 | 312 |
| 313 void TouchFactory::ProcessXI2Event(XEvent* event) { |
| 314 // Commented out under the assumption that the window host |
| 315 // already loaded all event data. |
| 316 /* XGenericEventCookie *xcookie = &event->xcookie; |
| 317 if(!XGetEventData(ui::GetXDisplay(), xcookie)) { |
| 318 LOG(ERROR) << "Failed to get X generic event data"; |
| 319 return; |
| 320 }else |
| 321 printf( "Successfully retrieved X generic event data\n" ); |
| 322 */ |
| 323 if (UFStatusSuccess != |
| 324 frame_x11_process_event(utouch_frame_handle_, &event->xcookie)) { |
| 325 LOG(ERROR) << "Failed to inject X event"; |
| 326 } |
| 327 } |
| 328 |
229 void TouchFactory::SetupXI2ForXWindow(Window window) { | 329 void TouchFactory::SetupXI2ForXWindow(Window window) { |
230 // Setup mask for mouse events. It is possible that a device is loaded/plugged | 330 // Setup mask for mouse events. It is possible that a device is loaded/plugged |
231 // in after we have setup XInput2 on a window. In such cases, we need to | 331 // in after we have setup XInput2 on a window. In such cases, we need to |
232 // either resetup XInput2 for the window, so that we get events from the new | 332 // either resetup XInput2 for the window, so that we get events from the new |
233 // device, or we need to listen to events from all devices, and then filter | 333 // device, or we need to listen to events from all devices, and then filter |
234 // the events from uninteresting devices. We do the latter because that's | 334 // the events from uninteresting devices. We do the latter because that's |
235 // simpler. | 335 // simpler. |
236 | 336 |
237 Display* display = ui::GetXDisplay(); | 337 Display* display = ui::GetXDisplay(); |
238 | 338 |
239 unsigned char mask[XIMaskLen(XI_LASTEVENT)]; | 339 unsigned char mask[XIMaskLen(XI_LASTEVENT)]; |
240 memset(mask, 0, sizeof(mask)); | 340 memset(mask, 0, sizeof(mask)); |
241 | 341 |
242 #if defined(USE_XI2_MT) | 342 #if defined(USE_XI2_MT) |
243 XISetMask(mask, XI_TouchBegin); | 343 XISetMask(mask, XI_TouchBegin); |
244 XISetMask(mask, XI_TouchUpdate); | 344 XISetMask(mask, XI_TouchUpdate); |
245 XISetMask(mask, XI_TouchEnd); | 345 XISetMask(mask, XI_TouchEnd); |
246 #endif | 346 XISetMask(mask, XI_TouchOwnership); |
| 347 XISetMask(mask, XI_HierarchyChanged); |
| 348 #else |
247 XISetMask(mask, XI_ButtonPress); | 349 XISetMask(mask, XI_ButtonPress); |
248 XISetMask(mask, XI_ButtonRelease); | 350 XISetMask(mask, XI_ButtonRelease); |
249 XISetMask(mask, XI_Motion); | 351 XISetMask(mask, XI_Motion); |
250 | 352 #endif |
251 XIEventMask evmask; | 353 XIEventMask evmask; |
252 evmask.deviceid = XIAllDevices; | 354 evmask.deviceid = XIAllDevices; |
253 evmask.mask_len = sizeof(mask); | 355 evmask.mask_len = sizeof(mask); |
254 evmask.mask = mask; | 356 evmask.mask = mask; |
255 XISelectEvents(display, window, &evmask, 1); | 357 XISelectEvents(display, window, &evmask, 1); |
256 XFlush(display); | 358 XFlush(display); |
| 359 |
| 360 #if defined(USE_XI2_MT) |
| 361 #if defined(USE_AURA) |
| 362 native_root_window_aura_ = window; |
| 363 #endif |
| 364 #endif |
257 } | 365 } |
258 | 366 |
259 void TouchFactory::SetTouchDeviceList( | 367 void TouchFactory::SetTouchDeviceList( |
260 const std::vector<unsigned int>& devices) { | 368 const std::vector<unsigned int>& devices) { |
261 touch_device_lookup_.reset(); | 369 touch_device_lookup_.reset(); |
262 touch_device_list_.clear(); | 370 touch_device_list_.clear(); |
263 for (std::vector<unsigned int>::const_iterator iter = devices.begin(); | 371 for (std::vector<unsigned int>::const_iterator iter = devices.begin(); |
264 iter != devices.end(); ++iter) { | 372 iter != devices.end(); ++iter) { |
265 DCHECK(*iter < touch_device_lookup_.size()); | 373 DCHECK(*iter < touch_device_lookup_.size()); |
266 touch_device_lookup_[*iter] = true; | 374 touch_device_lookup_[*iter] = true; |
267 touch_device_list_[*iter] = false; | |
268 } | 375 } |
269 | 376 |
270 SetupValuator(); | 377 SetupValuator(); |
271 } | 378 } |
272 | 379 |
273 bool TouchFactory::IsTouchDevice(unsigned deviceid) const { | 380 bool TouchFactory::IsTouchDevice(unsigned deviceid) const { |
274 return deviceid < touch_device_lookup_.size() ? | 381 return deviceid < touch_device_lookup_.size() ? |
275 touch_device_lookup_[deviceid] : false; | 382 touch_device_lookup_[deviceid] : false; |
276 } | 383 } |
277 | 384 |
278 bool TouchFactory::IsMultiTouchDevice(unsigned int deviceid) const { | 385 bool TouchFactory::IsMultiTouchDevice(unsigned int deviceid) const { |
279 return (deviceid < touch_device_lookup_.size() && | 386 return (deviceid < touch_device_lookup_.size() && |
280 touch_device_lookup_[deviceid]) ? | 387 touch_device_lookup_[deviceid]) ? |
281 touch_device_list_.find(deviceid)->second : | 388 touch_device_list_.find(deviceid) != touch_device_list_.end() : |
282 false; | 389 false; |
283 } | 390 } |
284 | 391 |
285 #if defined(USE_XI2_MT) | 392 #if defined(USE_XI2_MT) |
286 int TouchFactory::GetSlotForTrackingID(uint32 tracking_id) { | 393 int TouchFactory::GetSlotForTrackingID(uint32 tracking_id) { |
287 TrackingIdMap::iterator itr = tracking_id_map_.find(tracking_id); | 394 TrackingIdMap::iterator itr = tracking_id_map_.find(tracking_id); |
288 if (itr != tracking_id_map_.end()) | 395 if (itr != tracking_id_map_.end()) |
289 return itr->second; | 396 return itr->second; |
290 | 397 |
291 int slot = min_available_slot_; | 398 int slot = min_available_slot_; |
292 if (slot == kMaxTouchPoints) { | 399 if (slot == kMaxTouchPoints) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 #endif | 443 #endif |
337 | 444 |
338 unsigned char mask[XIMaskLen(XI_LASTEVENT)]; | 445 unsigned char mask[XIMaskLen(XI_LASTEVENT)]; |
339 bool success = true; | 446 bool success = true; |
340 | 447 |
341 memset(mask, 0, sizeof(mask)); | 448 memset(mask, 0, sizeof(mask)); |
342 #if defined(USE_XI2_MT) | 449 #if defined(USE_XI2_MT) |
343 XISetMask(mask, XI_TouchBegin); | 450 XISetMask(mask, XI_TouchBegin); |
344 XISetMask(mask, XI_TouchUpdate); | 451 XISetMask(mask, XI_TouchUpdate); |
345 XISetMask(mask, XI_TouchEnd); | 452 XISetMask(mask, XI_TouchEnd); |
346 #endif | 453 XISetMask(mask, XI_TouchOwnership); |
| 454 XISetMask(mask, XI_HierarchyChanged); |
| 455 #else |
347 XISetMask(mask, XI_ButtonPress); | 456 XISetMask(mask, XI_ButtonPress); |
348 XISetMask(mask, XI_ButtonRelease); | 457 XISetMask(mask, XI_ButtonRelease); |
349 XISetMask(mask, XI_Motion); | 458 XISetMask(mask, XI_Motion); |
| 459 #endif |
350 | 460 |
351 XIEventMask evmask; | 461 XIEventMask evmask; |
352 evmask.mask_len = sizeof(mask); | 462 evmask.mask_len = sizeof(mask); |
353 evmask.mask = mask; | 463 evmask.mask = mask; |
354 for (std::map<int, bool>::const_iterator iter = | 464 for (TouchDeviceList::const_iterator iter = |
355 touch_device_list_.begin(); | 465 touch_device_list_.begin(); |
356 iter != touch_device_list_.end(); ++iter) { | 466 iter != touch_device_list_.end(); ++iter) { |
357 evmask.deviceid = iter->first; | 467 evmask.deviceid = iter->first; |
358 Status status = XIGrabDevice(display, iter->first, window, CurrentTime, | 468 Status status = XIGrabDevice(display, iter->first, window, CurrentTime, |
359 None, GrabModeAsync, GrabModeAsync, False, &evmask); | 469 None, GrabModeAsync, GrabModeAsync, False, &evmask); |
360 success = success && status == GrabSuccess; | 470 success = success && status == GrabSuccess; |
361 } | 471 } |
362 | 472 |
363 return success; | 473 return success; |
364 } | 474 } |
365 | 475 |
366 bool TouchFactory::UngrabTouchDevices(Display* display) { | 476 bool TouchFactory::UngrabTouchDevices(Display* display) { |
367 #if defined(USE_AURA) | 477 #if defined(USE_AURA) |
368 if (!base::MessagePumpForUI::HasXInput2()) | 478 if (!base::MessagePumpForUI::HasXInput2()) |
369 return true; | 479 return true; |
370 #endif | 480 #endif |
371 | 481 |
372 bool success = true; | 482 bool success = true; |
373 for (std::map<int, bool>::const_iterator iter = | 483 for (TouchDeviceList::const_iterator iter = |
374 touch_device_list_.begin(); | 484 touch_device_list_.begin(); |
375 iter != touch_device_list_.end(); ++iter) { | 485 iter != touch_device_list_.end(); ++iter) { |
376 Status status = XIUngrabDevice(display, iter->first, CurrentTime); | 486 Status status = XIUngrabDevice(display, iter->first, CurrentTime); |
377 success = success && status == GrabSuccess; | 487 success = success && status == GrabSuccess; |
378 } | 488 } |
379 return success; | 489 return success; |
380 } | 490 } |
381 | 491 |
382 void TouchFactory::SetCursorVisible(bool show, bool start_timer) { | 492 void TouchFactory::SetCursorVisible(bool show, bool start_timer) { |
383 // This function may get called after the display is terminated. | 493 // This function may get called after the display is terminated. |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 touch_param_min_[info->deviceid][j] = valuator->min; | 548 touch_param_min_[info->deviceid][j] = valuator->min; |
439 touch_param_max_[info->deviceid][j] = valuator->max; | 549 touch_param_max_[info->deviceid][j] = valuator->max; |
440 } | 550 } |
441 } | 551 } |
442 | 552 |
443 #if !defined(USE_XI2_MT) | 553 #if !defined(USE_XI2_MT) |
444 // In order to support multi-touch with XI2.0, we need both a slot_id and | 554 // In order to support multi-touch with XI2.0, we need both a slot_id and |
445 // tracking_id valuator. Without these we'll treat the device as a | 555 // tracking_id valuator. Without these we'll treat the device as a |
446 // single-touch device (like a mouse). | 556 // single-touch device (like a mouse). |
447 // TODO(rbyers): Multi-touch is disabled: http://crbug.com/112329 | 557 // TODO(rbyers): Multi-touch is disabled: http://crbug.com/112329 |
448 //if (valuator_lookup_[info->deviceid][TP_SLOT_ID] == -1 || | 558 // if (valuator_lookup_[info->deviceid][TP_SLOT_ID] == -1 || |
449 // valuator_lookup_[info->deviceid][TP_TRACKING_ID] == -1) { | 559 // valuator_lookup_[info->deviceid][TP_TRACKING_ID] == -1) { |
450 DVLOG(1) << "Touch device " << info->deviceid << | 560 DVLOG(1) << "Touch device " << info->deviceid << |
451 " does not provide enough information for multi-touch, treating as " | 561 " does not provide enough information for multi-touch, treating as " |
452 "a single-touch device."; | 562 "a single-touch device."; |
453 touch_device_list_[info->deviceid] = false; | 563 touch_device_list_[info->deviceid] = false; |
454 //} | 564 // } |
455 #endif | 565 #endif |
456 } | 566 } |
457 | 567 |
458 if (info_list) | 568 if (info_list) |
459 XIFreeDeviceInfo(info_list); | 569 XIFreeDeviceInfo(info_list); |
460 } | 570 } |
461 | 571 |
462 bool TouchFactory::ExtractTouchParam(const XEvent& xev, | 572 bool TouchFactory::ExtractTouchParam(const XEvent& xev, |
463 TouchParam tp, | 573 TouchParam tp, |
464 float* value) { | 574 float* value) { |
(...skipping 27 matching lines...) Expand all Loading... |
492 DCHECK(*value >= 0.0 && *value <= 1.0); | 602 DCHECK(*value >= 0.0 && *value <= 1.0); |
493 return true; | 603 return true; |
494 } | 604 } |
495 return false; | 605 return false; |
496 } | 606 } |
497 | 607 |
498 bool TouchFactory::GetTouchParamRange(unsigned int deviceid, | 608 bool TouchFactory::GetTouchParamRange(unsigned int deviceid, |
499 TouchParam tp, | 609 TouchParam tp, |
500 float* min, | 610 float* min, |
501 float* max) { | 611 float* max) { |
| 612 #if defined(USE_XI2_MT) |
| 613 TouchDeviceList::const_iterator it = touch_device_list_.find(deviceid); |
| 614 if (it == touch_device_list_.end()) |
| 615 return false; |
| 616 |
| 617 MultiTouchDevice::Axes::const_iterator ita = |
| 618 it->second.axes().find(TouchParamToAxisType(tp)); |
| 619 |
| 620 if (ita == it->second.axes().end()) |
| 621 return false; |
| 622 |
| 623 *min = ita->second.min(); |
| 624 *max = ita->second.max(); |
| 625 |
| 626 return true; |
| 627 #else |
502 if (valuator_lookup_[deviceid][tp] >= 0) { | 628 if (valuator_lookup_[deviceid][tp] >= 0) { |
503 *min = touch_param_min_[deviceid][tp]; | 629 *min = touch_param_min_[deviceid][tp]; |
504 *max = touch_param_max_[deviceid][tp]; | 630 *max = touch_param_max_[deviceid][tp]; |
505 return true; | 631 return true; |
506 } | 632 } |
507 return false; | 633 return false; |
| 634 #endif |
508 } | 635 } |
509 | 636 |
510 } // namespace ui | 637 } // namespace ui |
OLD | NEW |