| 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 |