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) { | |
sadrul
2012/04/03 19:52:01
We have way too many types as it is. Either get ri
| |
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 native_root_window_aura_(ui::GetX11RootWindow()), | |
128 #if defined(USE_UTOUCH) | |
129 utouch_frame_handle_(NULL), | |
130 #endif // USE_UTOUCH | |
131 #endif // USE_AURA | |
92 min_available_slot_(0), | 132 min_available_slot_(0), |
93 #endif | 133 #endif |
94 slots_used_() { | 134 slots_used_() { |
95 #if defined(USE_AURA) | 135 #if defined(USE_AURA) |
96 if (!base::MessagePumpForUI::HasXInput2()) | 136 if (!base::MessagePumpForUI::HasXInput2()) |
97 return; | 137 return; |
98 #endif | 138 #endif |
99 | 139 |
100 char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | 140 char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
101 XColor black; | 141 XColor black; |
102 black.red = black.green = black.blue = 0; | 142 black.red = black.green = black.blue = 0; |
103 Display* display = ui::GetXDisplay(); | 143 Display* display = ui::GetXDisplay(); |
144 | |
145 #if defined(USE_AURA) && defined(USE_UTOUCH) | |
146 if (UFStatusSuccess != frame_x11_new(display, &utouch_frame_handle_)) { | |
147 LOG(ERROR) << "Failed to create utouch frame instance"; | |
148 } else { | |
149 fd_set set; | |
150 FD_ZERO(&set); | |
151 FD_SET(frame_get_fd(utouch_frame_handle_), &set); | |
152 } | |
153 #endif // USE_AURA && USE_UTOUCH | |
154 | |
104 Pixmap blank = XCreateBitmapFromData(display, ui::GetX11RootWindow(), | 155 Pixmap blank = XCreateBitmapFromData(display, ui::GetX11RootWindow(), |
105 nodata, 8, 8); | 156 nodata, 8, 8); |
106 invisible_cursor_ = XCreatePixmapCursor(display, blank, blank, | 157 invisible_cursor_ = XCreatePixmapCursor(display, blank, blank, |
107 &black, &black, 0, 0); | 158 &black, &black, 0, 0); |
108 arrow_cursor_ = XCreateFontCursor(display, XC_arrow); | 159 arrow_cursor_ = XCreateFontCursor(display, XC_arrow); |
109 | 160 |
110 SetCursorVisible(false, false); | 161 // TODO(tvoss): Selectively enable visibility for indirect touch devs. |
162 // SetCursorVisible(false, false); | |
111 UpdateDeviceList(display); | 163 UpdateDeviceList(display); |
112 | 164 |
113 // Make sure the list of devices is kept up-to-date by listening for | 165 // Make sure the list of devices is kept up-to-date by listening for |
114 // XI_HierarchyChanged event on the root window. | 166 // XI_HierarchyChanged event on the root window. |
115 unsigned char mask[XIMaskLen(XI_LASTEVENT)]; | 167 unsigned char mask[XIMaskLen(XI_LASTEVENT)]; |
116 memset(mask, 0, sizeof(mask)); | 168 memset(mask, 0, sizeof(mask)); |
117 | 169 |
118 XISetMask(mask, XI_HierarchyChanged); | 170 XISetMask(mask, XI_HierarchyChanged); |
119 | 171 |
120 XIEventMask evmask; | 172 XIEventMask evmask; |
121 evmask.deviceid = XIAllDevices; | 173 evmask.deviceid = XIAllDevices; |
122 evmask.mask_len = sizeof(mask); | 174 evmask.mask_len = sizeof(mask); |
123 evmask.mask = mask; | 175 evmask.mask = mask; |
124 XISelectEvents(display, ui::GetX11RootWindow(), &evmask, 1); | 176 XISelectEvents(display, ui::GetX11RootWindow(), &evmask, 1); |
125 } | 177 } |
126 | 178 |
127 TouchFactory::~TouchFactory() { | 179 TouchFactory::~TouchFactory() { |
180 device_observer_list_->Release(); | |
181 ObserverListThreadSafeTraits<DeviceObserver>::Destruct( | |
182 device_observer_list_); | |
183 | |
128 #if defined(USE_AURA) | 184 #if defined(USE_AURA) |
129 if (!base::MessagePumpForUI::HasXInput2()) | 185 if (!base::MessagePumpForUI::HasXInput2()) |
130 return; | 186 return; |
131 #endif | 187 |
188 #if defined(USE_UTOUCH) | |
189 frame_x11_delete(utouch_frame_handle_); | |
190 #endif // USE_UTOUCH | |
191 #endif // USE_AURA | |
132 | 192 |
133 // The XDisplay may be lost by the time we get destroyed. | 193 // The XDisplay may be lost by the time we get destroyed. |
134 if (ui::XDisplayExists()) { | 194 if (ui::XDisplayExists()) { |
135 SetCursorVisible(true, false); | 195 SetCursorVisible(true, false); |
136 Display* display = ui::GetXDisplay(); | 196 Display* display = ui::GetXDisplay(); |
137 XFreeCursor(display, invisible_cursor_); | 197 XFreeCursor(display, invisible_cursor_); |
138 XFreeCursor(display, arrow_cursor_); | 198 XFreeCursor(display, arrow_cursor_); |
139 } | 199 } |
140 } | 200 } |
141 | 201 |
202 void TouchFactory::AddDeviceObserver(TouchFactory::DeviceObserver * observer) { | |
203 device_observer_list_->AddObserver(observer); | |
204 | |
205 base::AutoLock al(touch_device_list_lock_); | |
206 // Make sure that every new observer is provided with an | |
207 // initial list of devices. | |
208 device_observer_list_->Notify( | |
209 &DeviceObserver::OnDevicesUpdated, | |
210 touch_device_list_); | |
211 } | |
212 | |
213 void TouchFactory::RemoveDeviceObserver( | |
214 TouchFactory::DeviceObserver * observer) { | |
215 device_observer_list_->RemoveObserver(observer); | |
216 } | |
217 | |
142 void TouchFactory::UpdateDeviceList(Display* display) { | 218 void TouchFactory::UpdateDeviceList(Display* display) { |
219 base::AutoLock al(touch_device_list_lock_); | |
sadrul
2012/04/03 19:52:01
Why?
| |
220 | |
143 // Detect touch devices. | 221 // Detect touch devices. |
144 // NOTE: The new API for retrieving the list of devices (XIQueryDevice) does | 222 // 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 | 223 // not provide enough information to detect a touch device. As a result, the |
146 // old version of query function (XListInputDevices) is used instead. | 224 // old version of query function (XListInputDevices) is used instead. |
147 // If XInput2 is not supported, this will return null (with count of -1) so | 225 // If XInput2 is not supported, this will return null (with count of -1) so |
148 // we assume there cannot be any touch devices. | 226 // we assume there cannot be any touch devices. |
149 int count = 0; | 227 int count = 0; |
150 touch_device_available_ = false; | 228 touch_device_available_ = false; |
151 touch_device_lookup_.reset(); | 229 touch_device_lookup_.reset(); |
152 touch_device_list_.clear(); | 230 touch_device_list_.clear(); |
(...skipping 23 matching lines...) Expand all Loading... | |
176 // not delivered to the client. So we select for slave devices instead. | 254 // not delivered to the client. So we select for slave devices instead. |
177 // If the touch device has 'GrabDevice' set and 'SendCoreEvents' unset (which | 255 // 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 | 256 // 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 | 257 // floating device is not connected to a master device. So it is necessary to |
180 // also select on the floating devices. | 258 // also select on the floating devices. |
181 pointer_device_lookup_.reset(); | 259 pointer_device_lookup_.reset(); |
182 XIDeviceInfo* devices = XIQueryDevice(display, XIAllDevices, &count); | 260 XIDeviceInfo* devices = XIQueryDevice(display, XIAllDevices, &count); |
183 for (int i = 0; i < count; i++) { | 261 for (int i = 0; i < count; i++) { |
184 XIDeviceInfo* devinfo = devices + i; | 262 XIDeviceInfo* devinfo = devices + i; |
185 #if defined(USE_XI2_MT) | 263 #if defined(USE_XI2_MT) |
264 MultiTouchDevice mtDevice; | |
265 if (ui::xi_device_info_to_mt_device(devinfo, mtDevice)) | |
266 touch_device_list_[devinfo->deviceid] = mtDevice; | |
267 | |
186 for (int k = 0; k < devinfo->num_classes; ++k) { | 268 for (int k = 0; k < devinfo->num_classes; ++k) { |
187 XIAnyClassInfo* xiclassinfo = devinfo->classes[k]; | 269 XIAnyClassInfo* xiclassinfo = devinfo->classes[k]; |
188 if (xiclassinfo->type == XITouchClass) { | 270 if (xiclassinfo->type == XITouchClass) { |
189 XITouchClassInfo* tci = | 271 XITouchClassInfo* tci = |
190 reinterpret_cast<XITouchClassInfo *>(xiclassinfo); | 272 reinterpret_cast<XITouchClassInfo *>(xiclassinfo); |
191 // Only care direct touch device (such as touch screen) right now | 273 switch (tci->mode) { |
192 if (tci->mode == XIDirectTouch) { | 274 case XIDirectTouch: |
193 touch_device_lookup_[devinfo->deviceid] = true; | 275 touch_device_lookup_[devinfo->deviceid] = true; |
194 touch_device_list_[devinfo->deviceid] = true; | 276 touch_device_available_ = true; |
195 touch_device_available_ = true; | 277 break; |
278 case XIDependentTouch: | |
279 touch_device_lookup_[devinfo->deviceid] = true; | |
280 touch_device_available_ = true; | |
281 break; | |
196 } | 282 } |
197 } | 283 } |
198 } | 284 } |
199 #endif | 285 #endif |
200 if (devinfo->use == XIFloatingSlave || devinfo->use == XISlavePointer) | 286 if (devinfo->use == XIFloatingSlave || devinfo->use == XISlavePointer) |
201 pointer_device_lookup_[devinfo->deviceid] = true; | 287 pointer_device_lookup_[devinfo->deviceid] = true; |
202 } | 288 } |
203 if (devices) | 289 if (devices) |
204 XIFreeDeviceInfo(devices); | 290 XIFreeDeviceInfo(devices); |
205 | 291 |
206 SetupValuator(); | 292 SetupValuator(); |
293 | |
294 device_observer_list_->Notify( | |
295 &DeviceObserver::OnDevicesUpdated, touch_device_list_); | |
207 } | 296 } |
208 | 297 |
209 bool TouchFactory::ShouldProcessXI2Event(XEvent* xev) { | 298 bool TouchFactory::ShouldProcessXI2Event(XEvent* xev) { |
210 DCHECK_EQ(GenericEvent, xev->type); | 299 DCHECK_EQ(GenericEvent, xev->type); |
211 XIEvent* event = static_cast<XIEvent*>(xev->xcookie.data); | 300 XIEvent* event = static_cast<XIEvent*>(xev->xcookie.data); |
212 XIDeviceEvent* xiev = reinterpret_cast<XIDeviceEvent*>(event); | 301 XIDeviceEvent* xiev = reinterpret_cast<XIDeviceEvent*>(event); |
213 | 302 |
214 #if defined(USE_XI2_MT) | 303 #if defined(USE_XI2_MT) |
304 if (event->evtype == XI_HierarchyChanged) | |
305 return true; | |
215 if (event->evtype == XI_TouchBegin || | 306 if (event->evtype == XI_TouchBegin || |
216 event->evtype == XI_TouchUpdate || | 307 event->evtype == XI_TouchUpdate || |
217 event->evtype == XI_TouchEnd) { | 308 event->evtype == XI_TouchEnd) { |
218 return touch_device_lookup_[xiev->sourceid]; | 309 return touch_device_lookup_[xiev->sourceid]; |
219 } | 310 } |
220 #endif | 311 #endif |
221 if (event->evtype != XI_ButtonPress && | 312 if (event->evtype != XI_ButtonPress && |
222 event->evtype != XI_ButtonRelease && | 313 event->evtype != XI_ButtonRelease && |
223 event->evtype != XI_Motion) | 314 event->evtype != XI_Motion) |
224 return true; | 315 return true; |
225 | 316 |
226 return pointer_device_lookup_[xiev->deviceid]; | 317 return pointer_device_lookup_[xiev->deviceid]; |
227 } | 318 } |
228 | 319 |
320 #if defined(USE_UTOUCH) | |
321 void TouchFactory::ProcessXI2Event(XEvent* event) { | |
322 // Commented out under the assumption that the window host | |
323 // already loaded all event data. | |
324 /* XGenericEventCookie *xcookie = &event->xcookie; | |
325 if(!XGetEventData(ui::GetXDisplay(), xcookie)) { | |
326 LOG(ERROR) << "Failed to get X generic event data"; | |
327 return; | |
328 }else | |
329 printf( "Successfully retrieved X generic event data\n" ); | |
330 */ | |
331 if (UFStatusSuccess != | |
332 frame_x11_process_event(utouch_frame_handle_, &event->xcookie)) { | |
333 LOG(ERROR) << "Failed to inject X event"; | |
334 } | |
335 } | |
336 #endif // USE_UTOUCH | |
337 | |
229 void TouchFactory::SetupXI2ForXWindow(Window window) { | 338 void TouchFactory::SetupXI2ForXWindow(Window window) { |
230 // Setup mask for mouse events. It is possible that a device is loaded/plugged | 339 // 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 | 340 // 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 | 341 // 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 | 342 // 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 | 343 // the events from uninteresting devices. We do the latter because that's |
235 // simpler. | 344 // simpler. |
236 | 345 |
237 Display* display = ui::GetXDisplay(); | 346 Display* display = ui::GetXDisplay(); |
238 | 347 |
239 unsigned char mask[XIMaskLen(XI_LASTEVENT)]; | 348 unsigned char mask[XIMaskLen(XI_LASTEVENT)]; |
240 memset(mask, 0, sizeof(mask)); | 349 memset(mask, 0, sizeof(mask)); |
241 | 350 |
242 #if defined(USE_XI2_MT) | 351 #if defined(USE_XI2_MT) |
243 XISetMask(mask, XI_TouchBegin); | 352 XISetMask(mask, XI_TouchBegin); |
244 XISetMask(mask, XI_TouchUpdate); | 353 XISetMask(mask, XI_TouchUpdate); |
245 XISetMask(mask, XI_TouchEnd); | 354 XISetMask(mask, XI_TouchEnd); |
246 #endif | 355 XISetMask(mask, XI_TouchOwnership); |
356 XISetMask(mask, XI_HierarchyChanged); | |
357 #else | |
247 XISetMask(mask, XI_ButtonPress); | 358 XISetMask(mask, XI_ButtonPress); |
248 XISetMask(mask, XI_ButtonRelease); | 359 XISetMask(mask, XI_ButtonRelease); |
249 XISetMask(mask, XI_Motion); | 360 XISetMask(mask, XI_Motion); |
250 | 361 #endif |
251 XIEventMask evmask; | 362 XIEventMask evmask; |
252 evmask.deviceid = XIAllDevices; | 363 evmask.deviceid = XIAllDevices; |
253 evmask.mask_len = sizeof(mask); | 364 evmask.mask_len = sizeof(mask); |
254 evmask.mask = mask; | 365 evmask.mask = mask; |
255 XISelectEvents(display, window, &evmask, 1); | 366 XISelectEvents(display, window, &evmask, 1); |
256 XFlush(display); | 367 XFlush(display); |
368 | |
369 #if defined(USE_XI2_MT) | |
370 #if defined(USE_AURA) | |
371 native_root_window_aura_ = window; | |
372 #endif | |
373 #endif | |
257 } | 374 } |
258 | 375 |
259 void TouchFactory::SetTouchDeviceList( | 376 void TouchFactory::SetTouchDeviceList( |
260 const std::vector<unsigned int>& devices) { | 377 const std::vector<unsigned int>& devices) { |
261 touch_device_lookup_.reset(); | 378 touch_device_lookup_.reset(); |
262 touch_device_list_.clear(); | 379 touch_device_list_.clear(); |
263 for (std::vector<unsigned int>::const_iterator iter = devices.begin(); | 380 for (std::vector<unsigned int>::const_iterator iter = devices.begin(); |
264 iter != devices.end(); ++iter) { | 381 iter != devices.end(); ++iter) { |
265 DCHECK(*iter < touch_device_lookup_.size()); | 382 DCHECK(*iter < touch_device_lookup_.size()); |
266 touch_device_lookup_[*iter] = true; | 383 touch_device_lookup_[*iter] = true; |
267 touch_device_list_[*iter] = false; | |
268 } | 384 } |
269 | 385 |
270 SetupValuator(); | 386 SetupValuator(); |
271 } | 387 } |
272 | 388 |
273 bool TouchFactory::IsTouchDevice(unsigned deviceid) const { | 389 bool TouchFactory::IsTouchDevice(unsigned deviceid) const { |
274 return deviceid < touch_device_lookup_.size() ? | 390 return deviceid < touch_device_lookup_.size() ? |
275 touch_device_lookup_[deviceid] : false; | 391 touch_device_lookup_[deviceid] : false; |
276 } | 392 } |
277 | 393 |
278 bool TouchFactory::IsMultiTouchDevice(unsigned int deviceid) const { | 394 bool TouchFactory::IsMultiTouchDevice(unsigned int deviceid) const { |
279 return (deviceid < touch_device_lookup_.size() && | 395 return (deviceid < touch_device_lookup_.size() && |
280 touch_device_lookup_[deviceid]) ? | 396 touch_device_lookup_[deviceid]) ? |
281 touch_device_list_.find(deviceid)->second : | 397 touch_device_list_.find(deviceid) != touch_device_list_.end() : |
282 false; | 398 false; |
283 } | 399 } |
284 | 400 |
285 #if defined(USE_XI2_MT) | 401 #if defined(USE_XI2_MT) |
286 int TouchFactory::GetSlotForTrackingID(uint32 tracking_id) { | 402 int TouchFactory::GetSlotForTrackingID(uint32 tracking_id) { |
287 TrackingIdMap::iterator itr = tracking_id_map_.find(tracking_id); | 403 TrackingIdMap::iterator itr = tracking_id_map_.find(tracking_id); |
288 if (itr != tracking_id_map_.end()) | 404 if (itr != tracking_id_map_.end()) |
289 return itr->second; | 405 return itr->second; |
290 | 406 |
291 int slot = min_available_slot_; | 407 int slot = min_available_slot_; |
292 if (slot == kMaxTouchPoints) { | 408 if (slot == kMaxTouchPoints) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
336 #endif | 452 #endif |
337 | 453 |
338 unsigned char mask[XIMaskLen(XI_LASTEVENT)]; | 454 unsigned char mask[XIMaskLen(XI_LASTEVENT)]; |
339 bool success = true; | 455 bool success = true; |
340 | 456 |
341 memset(mask, 0, sizeof(mask)); | 457 memset(mask, 0, sizeof(mask)); |
342 #if defined(USE_XI2_MT) | 458 #if defined(USE_XI2_MT) |
343 XISetMask(mask, XI_TouchBegin); | 459 XISetMask(mask, XI_TouchBegin); |
344 XISetMask(mask, XI_TouchUpdate); | 460 XISetMask(mask, XI_TouchUpdate); |
345 XISetMask(mask, XI_TouchEnd); | 461 XISetMask(mask, XI_TouchEnd); |
346 #endif | 462 XISetMask(mask, XI_TouchOwnership); |
463 XISetMask(mask, XI_HierarchyChanged); | |
464 #else | |
347 XISetMask(mask, XI_ButtonPress); | 465 XISetMask(mask, XI_ButtonPress); |
348 XISetMask(mask, XI_ButtonRelease); | 466 XISetMask(mask, XI_ButtonRelease); |
349 XISetMask(mask, XI_Motion); | 467 XISetMask(mask, XI_Motion); |
468 #endif | |
350 | 469 |
351 XIEventMask evmask; | 470 XIEventMask evmask; |
352 evmask.mask_len = sizeof(mask); | 471 evmask.mask_len = sizeof(mask); |
353 evmask.mask = mask; | 472 evmask.mask = mask; |
354 for (std::map<int, bool>::const_iterator iter = | 473 for (TouchDeviceList::const_iterator iter = |
355 touch_device_list_.begin(); | 474 touch_device_list_.begin(); |
356 iter != touch_device_list_.end(); ++iter) { | 475 iter != touch_device_list_.end(); ++iter) { |
357 evmask.deviceid = iter->first; | 476 evmask.deviceid = iter->first; |
358 Status status = XIGrabDevice(display, iter->first, window, CurrentTime, | 477 Status status = XIGrabDevice(display, iter->first, window, CurrentTime, |
359 None, GrabModeAsync, GrabModeAsync, False, &evmask); | 478 None, GrabModeAsync, GrabModeAsync, False, &evmask); |
360 success = success && status == GrabSuccess; | 479 success = success && status == GrabSuccess; |
361 } | 480 } |
362 | 481 |
363 return success; | 482 return success; |
364 } | 483 } |
365 | 484 |
366 bool TouchFactory::UngrabTouchDevices(Display* display) { | 485 bool TouchFactory::UngrabTouchDevices(Display* display) { |
367 #if defined(USE_AURA) | 486 #if defined(USE_AURA) |
368 if (!base::MessagePumpForUI::HasXInput2()) | 487 if (!base::MessagePumpForUI::HasXInput2()) |
369 return true; | 488 return true; |
370 #endif | 489 #endif |
371 | 490 |
372 bool success = true; | 491 bool success = true; |
373 for (std::map<int, bool>::const_iterator iter = | 492 for (TouchDeviceList::const_iterator iter = |
374 touch_device_list_.begin(); | 493 touch_device_list_.begin(); |
375 iter != touch_device_list_.end(); ++iter) { | 494 iter != touch_device_list_.end(); ++iter) { |
376 Status status = XIUngrabDevice(display, iter->first, CurrentTime); | 495 Status status = XIUngrabDevice(display, iter->first, CurrentTime); |
377 success = success && status == GrabSuccess; | 496 success = success && status == GrabSuccess; |
378 } | 497 } |
379 return success; | 498 return success; |
380 } | 499 } |
381 | 500 |
382 void TouchFactory::SetCursorVisible(bool show, bool start_timer) { | 501 void TouchFactory::SetCursorVisible(bool show, bool start_timer) { |
383 // This function may get called after the display is terminated. | 502 // 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; | 557 touch_param_min_[info->deviceid][j] = valuator->min; |
439 touch_param_max_[info->deviceid][j] = valuator->max; | 558 touch_param_max_[info->deviceid][j] = valuator->max; |
440 } | 559 } |
441 } | 560 } |
442 | 561 |
443 #if !defined(USE_XI2_MT) | 562 #if !defined(USE_XI2_MT) |
444 // In order to support multi-touch with XI2.0, we need both a slot_id and | 563 // 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 | 564 // tracking_id valuator. Without these we'll treat the device as a |
446 // single-touch device (like a mouse). | 565 // single-touch device (like a mouse). |
447 // TODO(rbyers): Multi-touch is disabled: http://crbug.com/112329 | 566 // TODO(rbyers): Multi-touch is disabled: http://crbug.com/112329 |
448 //if (valuator_lookup_[info->deviceid][TP_SLOT_ID] == -1 || | 567 // if (valuator_lookup_[info->deviceid][TP_SLOT_ID] == -1 || |
449 // valuator_lookup_[info->deviceid][TP_TRACKING_ID] == -1) { | 568 // valuator_lookup_[info->deviceid][TP_TRACKING_ID] == -1) { |
450 DVLOG(1) << "Touch device " << info->deviceid << | 569 DVLOG(1) << "Touch device " << info->deviceid << |
451 " does not provide enough information for multi-touch, treating as " | 570 " does not provide enough information for multi-touch, treating as " |
452 "a single-touch device."; | 571 "a single-touch device."; |
453 touch_device_list_[info->deviceid] = false; | 572 touch_device_list_[info->deviceid] = false; |
454 //} | 573 // } |
455 #endif | 574 #endif |
456 } | 575 } |
457 | 576 |
458 if (info_list) | 577 if (info_list) |
459 XIFreeDeviceInfo(info_list); | 578 XIFreeDeviceInfo(info_list); |
460 } | 579 } |
461 | 580 |
462 bool TouchFactory::ExtractTouchParam(const XEvent& xev, | 581 bool TouchFactory::ExtractTouchParam(const XEvent& xev, |
463 TouchParam tp, | 582 TouchParam tp, |
464 float* value) { | 583 float* value) { |
(...skipping 27 matching lines...) Expand all Loading... | |
492 DCHECK(*value >= 0.0 && *value <= 1.0); | 611 DCHECK(*value >= 0.0 && *value <= 1.0); |
493 return true; | 612 return true; |
494 } | 613 } |
495 return false; | 614 return false; |
496 } | 615 } |
497 | 616 |
498 bool TouchFactory::GetTouchParamRange(unsigned int deviceid, | 617 bool TouchFactory::GetTouchParamRange(unsigned int deviceid, |
499 TouchParam tp, | 618 TouchParam tp, |
500 float* min, | 619 float* min, |
501 float* max) { | 620 float* max) { |
621 #if defined(USE_XI2_MT) | |
622 TouchDeviceList::const_iterator it = touch_device_list_.find(deviceid); | |
623 if (it == touch_device_list_.end()) | |
624 return false; | |
625 | |
626 MultiTouchDevice::Axes::const_iterator ita = | |
627 it->second.axes().find(TouchParamToAxisType(tp)); | |
628 | |
629 if (ita == it->second.axes().end()) | |
630 return false; | |
631 | |
632 *min = ita->second.min(); | |
633 *max = ita->second.max(); | |
634 | |
635 return true; | |
636 #else | |
502 if (valuator_lookup_[deviceid][tp] >= 0) { | 637 if (valuator_lookup_[deviceid][tp] >= 0) { |
503 *min = touch_param_min_[deviceid][tp]; | 638 *min = touch_param_min_[deviceid][tp]; |
504 *max = touch_param_max_[deviceid][tp]; | 639 *max = touch_param_max_[deviceid][tp]; |
505 return true; | 640 return true; |
506 } | 641 } |
507 return false; | 642 return false; |
643 #endif | |
508 } | 644 } |
509 | 645 |
510 } // namespace ui | 646 } // namespace ui |
OLD | NEW |