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