| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "views/events/event.h" | 5 #include "views/events/event.h" |
| 6 | 6 |
| 7 #include <gdk/gdk.h> | 7 #include <gdk/gdk.h> |
| 8 #include <gdk/gdkx.h> | 8 #include <gdk/gdkx.h> |
| 9 #if defined(HAVE_XINPUT2) | |
| 10 #include <X11/extensions/XInput2.h> | 9 #include <X11/extensions/XInput2.h> |
| 11 #endif | |
| 12 #include <X11/Xlib.h> | |
| 13 | 10 |
| 14 #include "base/logging.h" | 11 #include "base/logging.h" |
| 15 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
| 16 #include "ui/base/keycodes/keyboard_code_conversion_x.h" | 13 #include "ui/base/keycodes/keyboard_code_conversion_x.h" |
| 14 #include "views/touchui/touch_factory.h" |
| 17 #include "views/widget/root_view.h" | 15 #include "views/widget/root_view.h" |
| 18 | 16 |
| 19 #if defined(HAVE_XINPUT2) | |
| 20 #include "views/touchui/touch_factory.h" | |
| 21 #endif | |
| 22 | |
| 23 namespace views { | 17 namespace views { |
| 24 | 18 |
| 25 namespace { | 19 namespace { |
| 26 | 20 |
| 27 // Scroll amount for each wheelscroll event. 53 is also the value used for GTK+. | 21 // Scroll amount for each wheelscroll event. 53 is also the value used for GTK+. |
| 28 static int kWheelScrollAmount = 53; | 22 static int kWheelScrollAmount = 53; |
| 29 | 23 |
| 30 int GetEventFlagsFromXState(unsigned int state) { | 24 int GetEventFlagsFromXState(unsigned int state) { |
| 31 int flags = 0; | 25 int flags = 0; |
| 32 if (state & ControlMask) | 26 if (state & ControlMask) |
| (...skipping 29 matching lines...) Expand all Loading... |
| 62 case 2: | 56 case 2: |
| 63 return ui::EF_MIDDLE_BUTTON_DOWN; | 57 return ui::EF_MIDDLE_BUTTON_DOWN; |
| 64 case 3: | 58 case 3: |
| 65 return ui::EF_RIGHT_BUTTON_DOWN; | 59 return ui::EF_RIGHT_BUTTON_DOWN; |
| 66 } | 60 } |
| 67 | 61 |
| 68 DLOG(WARNING) << "Unexpected button (" << button << ") received."; | 62 DLOG(WARNING) << "Unexpected button (" << button << ") received."; |
| 69 return 0; | 63 return 0; |
| 70 } | 64 } |
| 71 | 65 |
| 72 #if defined(HAVE_XINPUT2) | |
| 73 int GetButtonMaskForX2Event(XIDeviceEvent* xievent) { | 66 int GetButtonMaskForX2Event(XIDeviceEvent* xievent) { |
| 74 int buttonflags = 0; | 67 int buttonflags = 0; |
| 75 | 68 |
| 76 for (int i = 0; i < 8 * xievent->buttons.mask_len; i++) { | 69 for (int i = 0; i < 8 * xievent->buttons.mask_len; i++) { |
| 77 if (XIMaskIsSet(xievent->buttons.mask, i)) { | 70 if (XIMaskIsSet(xievent->buttons.mask, i)) { |
| 78 buttonflags |= GetEventFlagsForButton(i); | 71 buttonflags |= GetEventFlagsForButton(i); |
| 79 } | 72 } |
| 80 } | 73 } |
| 81 | 74 |
| 82 return buttonflags; | 75 return buttonflags; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 } | 107 } |
| 115 | 108 |
| 116 int GetTouchIDFromXEvent(XEvent* xev) { | 109 int GetTouchIDFromXEvent(XEvent* xev) { |
| 117 float slot = 0; | 110 float slot = 0; |
| 118 if (!TouchFactory::GetInstance()->ExtractTouchParam( | 111 if (!TouchFactory::GetInstance()->ExtractTouchParam( |
| 119 *xev, TouchFactory::TP_SLOT_ID, &slot)) | 112 *xev, TouchFactory::TP_SLOT_ID, &slot)) |
| 120 LOG(ERROR) << "Could not get the slot ID for the event. Using 0."; | 113 LOG(ERROR) << "Could not get the slot ID for the event. Using 0."; |
| 121 return slot; | 114 return slot; |
| 122 } | 115 } |
| 123 | 116 |
| 124 #endif // HAVE_XINPUT2 | |
| 125 | |
| 126 ui::EventType EventTypeFromNative(NativeEvent2 native_event) { | 117 ui::EventType EventTypeFromNative(NativeEvent2 native_event) { |
| 127 switch (native_event->type) { | 118 switch (native_event->type) { |
| 128 case KeyPress: | 119 case KeyPress: |
| 129 return ui::ET_KEY_PRESSED; | 120 return ui::ET_KEY_PRESSED; |
| 130 case KeyRelease: | 121 case KeyRelease: |
| 131 return ui::ET_KEY_RELEASED; | 122 return ui::ET_KEY_RELEASED; |
| 132 case ButtonPress: | 123 case ButtonPress: |
| 133 if (native_event->xbutton.button == 4 || | 124 if (native_event->xbutton.button == 4 || |
| 134 native_event->xbutton.button == 5) | 125 native_event->xbutton.button == 5) |
| 135 return ui::ET_MOUSEWHEEL; | 126 return ui::ET_MOUSEWHEEL; |
| 136 return ui::ET_MOUSE_PRESSED; | 127 return ui::ET_MOUSE_PRESSED; |
| 137 case ButtonRelease: | 128 case ButtonRelease: |
| 138 if (native_event->xbutton.button == 4 || | 129 if (native_event->xbutton.button == 4 || |
| 139 native_event->xbutton.button == 5) | 130 native_event->xbutton.button == 5) |
| 140 return ui::ET_MOUSEWHEEL; | 131 return ui::ET_MOUSEWHEEL; |
| 141 return ui::ET_MOUSE_RELEASED; | 132 return ui::ET_MOUSE_RELEASED; |
| 142 case MotionNotify: | 133 case MotionNotify: |
| 143 if (native_event->xmotion.state & | 134 if (native_event->xmotion.state & |
| 144 (Button1Mask | Button2Mask | Button3Mask)) | 135 (Button1Mask | Button2Mask | Button3Mask)) |
| 145 return ui::ET_MOUSE_DRAGGED; | 136 return ui::ET_MOUSE_DRAGGED; |
| 146 return ui::ET_MOUSE_MOVED; | 137 return ui::ET_MOUSE_MOVED; |
| 147 #if defined(HAVE_XINPUT2) | |
| 148 case GenericEvent: { | 138 case GenericEvent: { |
| 149 XIDeviceEvent* xievent = | 139 XIDeviceEvent* xievent = |
| 150 static_cast<XIDeviceEvent*>(native_event->xcookie.data); | 140 static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
| 151 if (TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid)) | 141 if (TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid)) |
| 152 return GetTouchEventType(native_event); | 142 return GetTouchEventType(native_event); |
| 153 switch (xievent->evtype) { | 143 switch (xievent->evtype) { |
| 154 case XI_ButtonPress: | 144 case XI_ButtonPress: |
| 155 return (xievent->detail == 4 || xievent->detail == 5) ? | 145 return (xievent->detail == 4 || xievent->detail == 5) ? |
| 156 ui::ET_MOUSEWHEEL : ui::ET_MOUSE_PRESSED; | 146 ui::ET_MOUSEWHEEL : ui::ET_MOUSE_PRESSED; |
| 157 case XI_ButtonRelease: | 147 case XI_ButtonRelease: |
| 158 return (xievent->detail == 4 || xievent->detail == 5) ? | 148 return (xievent->detail == 4 || xievent->detail == 5) ? |
| 159 ui::ET_MOUSEWHEEL : ui::ET_MOUSE_RELEASED; | 149 ui::ET_MOUSEWHEEL : ui::ET_MOUSE_RELEASED; |
| 160 case XI_Motion: | 150 case XI_Motion: |
| 161 return GetButtonMaskForX2Event(xievent) ? ui::ET_MOUSE_DRAGGED : | 151 return GetButtonMaskForX2Event(xievent) ? ui::ET_MOUSE_DRAGGED : |
| 162 ui::ET_MOUSE_MOVED; | 152 ui::ET_MOUSE_MOVED; |
| 163 } | 153 } |
| 164 } | 154 } |
| 165 #endif | |
| 166 default: | 155 default: |
| 167 NOTREACHED(); | 156 NOTREACHED(); |
| 168 break; | 157 break; |
| 169 } | 158 } |
| 170 return ui::ET_UNKNOWN; | 159 return ui::ET_UNKNOWN; |
| 171 } | 160 } |
| 172 | 161 |
| 173 int GetMouseWheelOffset(XEvent* xev) { | 162 int GetMouseWheelOffset(XEvent* xev) { |
| 174 #if defined(HAVE_XINPUT2) | |
| 175 if (xev->type == GenericEvent) { | 163 if (xev->type == GenericEvent) { |
| 176 XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev->xcookie.data); | 164 XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev->xcookie.data); |
| 177 return xiev->detail == 4 ? kWheelScrollAmount : -kWheelScrollAmount; | 165 return xiev->detail == 4 ? kWheelScrollAmount : -kWheelScrollAmount; |
| 178 } | 166 } |
| 179 #endif | |
| 180 return xev->xbutton.button == 4 ? kWheelScrollAmount : -kWheelScrollAmount; | 167 return xev->xbutton.button == 4 ? kWheelScrollAmount : -kWheelScrollAmount; |
| 181 } | 168 } |
| 182 | 169 |
| 183 gfx::Point GetEventLocation(XEvent* xev) { | 170 gfx::Point GetEventLocation(XEvent* xev) { |
| 184 switch (xev->type) { | 171 switch (xev->type) { |
| 185 case ButtonPress: | 172 case ButtonPress: |
| 186 case ButtonRelease: | 173 case ButtonRelease: |
| 187 return gfx::Point(xev->xbutton.x, xev->xbutton.y); | 174 return gfx::Point(xev->xbutton.x, xev->xbutton.y); |
| 188 | 175 |
| 189 case MotionNotify: | 176 case MotionNotify: |
| 190 return gfx::Point(xev->xmotion.x, xev->xmotion.y); | 177 return gfx::Point(xev->xmotion.x, xev->xmotion.y); |
| 191 | 178 |
| 192 #if defined(HAVE_XINPUT2) | |
| 193 case GenericEvent: { | 179 case GenericEvent: { |
| 194 XIDeviceEvent* xievent = | 180 XIDeviceEvent* xievent = |
| 195 static_cast<XIDeviceEvent*>(xev->xcookie.data); | 181 static_cast<XIDeviceEvent*>(xev->xcookie.data); |
| 196 return gfx::Point(static_cast<int>(xievent->event_x), | 182 return gfx::Point(static_cast<int>(xievent->event_x), |
| 197 static_cast<int>(xievent->event_y)); | 183 static_cast<int>(xievent->event_y)); |
| 198 } | 184 } |
| 199 #endif | |
| 200 } | 185 } |
| 201 | 186 |
| 202 return gfx::Point(); | 187 return gfx::Point(); |
| 203 } | 188 } |
| 204 | 189 |
| 205 int GetLocatedEventFlags(XEvent* xev) { | 190 int GetLocatedEventFlags(XEvent* xev) { |
| 206 switch (xev->type) { | 191 switch (xev->type) { |
| 207 case ButtonPress: | 192 case ButtonPress: |
| 208 case ButtonRelease: | 193 case ButtonRelease: |
| 209 return GetEventFlagsFromXState(xev->xbutton.state) | | 194 return GetEventFlagsFromXState(xev->xbutton.state) | |
| 210 GetEventFlagsForButton(xev->xbutton.button); | 195 GetEventFlagsForButton(xev->xbutton.button); |
| 211 | 196 |
| 212 case MotionNotify: | 197 case MotionNotify: |
| 213 return GetEventFlagsFromXState(xev->xmotion.state); | 198 return GetEventFlagsFromXState(xev->xmotion.state); |
| 214 | 199 |
| 215 #if defined(HAVE_XINPUT2) | |
| 216 case GenericEvent: { | 200 case GenericEvent: { |
| 217 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); | 201 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); |
| 218 bool touch = | 202 bool touch = |
| 219 TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid); | 203 TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid); |
| 220 switch (xievent->evtype) { | 204 switch (xievent->evtype) { |
| 221 case XI_ButtonPress: | 205 case XI_ButtonPress: |
| 222 case XI_ButtonRelease: | 206 case XI_ButtonRelease: |
| 223 return GetButtonMaskForX2Event(xievent) | | 207 return GetButtonMaskForX2Event(xievent) | |
| 224 GetEventFlagsFromXState(xievent->mods.effective) | | 208 GetEventFlagsFromXState(xievent->mods.effective) | |
| 225 (touch ? 0 : GetEventFlagsForButton(xievent->detail)); | 209 (touch ? 0 : GetEventFlagsForButton(xievent->detail)); |
| 226 | 210 |
| 227 case XI_Motion: | 211 case XI_Motion: |
| 228 return GetButtonMaskForX2Event(xievent) | | 212 return GetButtonMaskForX2Event(xievent) | |
| 229 GetEventFlagsFromXState(xievent->mods.effective); | 213 GetEventFlagsFromXState(xievent->mods.effective); |
| 230 } | 214 } |
| 231 } | 215 } |
| 232 #endif | |
| 233 } | 216 } |
| 234 | 217 |
| 235 return 0; | 218 return 0; |
| 236 } | 219 } |
| 237 | 220 |
| 238 uint16 GetCharacterFromXKeyEvent(XKeyEvent* key) { | 221 uint16 GetCharacterFromXKeyEvent(XKeyEvent* key) { |
| 239 char buf[6]; | 222 char buf[6]; |
| 240 int bytes_written = XLookupString(key, buf, 6, NULL, NULL); | 223 int bytes_written = XLookupString(key, buf, 6, NULL, NULL); |
| 241 DCHECK_LE(bytes_written, 6); | 224 DCHECK_LE(bytes_written, 6); |
| 242 | 225 |
| 243 string16 result; | 226 string16 result; |
| 244 return (bytes_written > 0 && UTF8ToUTF16(buf, bytes_written, &result) && | 227 return (bytes_written > 0 && UTF8ToUTF16(buf, bytes_written, &result) && |
| 245 result.length() == 1) ? result[0] : 0; | 228 result.length() == 1) ? result[0] : 0; |
| 246 } | 229 } |
| 247 | 230 |
| 248 float GetTouchRadiusFromXEvent(XEvent* xev) { | 231 float GetTouchRadiusFromXEvent(XEvent* xev) { |
| 249 float diameter = 0.0; | 232 float diameter = 0.0; |
| 250 | |
| 251 #if defined(HAVE_XINPUT2) | |
| 252 TouchFactory* touch_factory = TouchFactory::GetInstance(); | 233 TouchFactory* touch_factory = TouchFactory::GetInstance(); |
| 253 touch_factory->ExtractTouchParam(*xev, TouchFactory::TP_TOUCH_MAJOR, | 234 touch_factory->ExtractTouchParam(*xev, TouchFactory::TP_TOUCH_MAJOR, |
| 254 &diameter); | 235 &diameter); |
| 255 #endif | |
| 256 | |
| 257 return diameter / 2.0; | 236 return diameter / 2.0; |
| 258 } | 237 } |
| 259 | 238 |
| 260 float GetTouchAngleFromXEvent(XEvent* xev) { | 239 float GetTouchAngleFromXEvent(XEvent* xev) { |
| 261 float angle = 0.0; | 240 float angle = 0.0; |
| 262 | |
| 263 #if defined(HAVE_XINPUT2) | |
| 264 TouchFactory* touch_factory = TouchFactory::GetInstance(); | 241 TouchFactory* touch_factory = TouchFactory::GetInstance(); |
| 265 touch_factory->ExtractTouchParam(*xev, TouchFactory::TP_ORIENTATION, | 242 touch_factory->ExtractTouchParam(*xev, TouchFactory::TP_ORIENTATION, |
| 266 &angle); | 243 &angle); |
| 267 #endif | |
| 268 | |
| 269 return angle; | 244 return angle; |
| 270 } | 245 } |
| 271 | 246 |
| 272 | 247 |
| 273 float GetTouchRatioFromXEvent(XEvent* xev) { | 248 float GetTouchRatioFromXEvent(XEvent* xev) { |
| 274 float ratio = 1.0; | 249 float ratio = 1.0; |
| 275 | |
| 276 #if defined(HAVE_XINPUT2) | |
| 277 TouchFactory* touch_factory = TouchFactory::GetInstance(); | 250 TouchFactory* touch_factory = TouchFactory::GetInstance(); |
| 278 float major_v = -1.0; | 251 float major_v = -1.0; |
| 279 float minor_v = -1.0; | 252 float minor_v = -1.0; |
| 280 | 253 |
| 281 if (!touch_factory->ExtractTouchParam(*xev, | 254 if (!touch_factory->ExtractTouchParam(*xev, |
| 282 TouchFactory::TP_TOUCH_MAJOR, | 255 TouchFactory::TP_TOUCH_MAJOR, |
| 283 &major_v) || | 256 &major_v) || |
| 284 !touch_factory->ExtractTouchParam(*xev, | 257 !touch_factory->ExtractTouchParam(*xev, |
| 285 TouchFactory::TP_TOUCH_MINOR, | 258 TouchFactory::TP_TOUCH_MINOR, |
| 286 &minor_v)) | 259 &minor_v)) |
| 287 return ratio; | 260 return ratio; |
| 288 | 261 |
| 289 // In case minor axis exists but is zero. | 262 // In case minor axis exists but is zero. |
| 290 if (minor_v > 0.0) | 263 if (minor_v > 0.0) |
| 291 ratio = major_v / minor_v; | 264 ratio = major_v / minor_v; |
| 292 #endif | |
| 293 | 265 |
| 294 return ratio; | 266 return ratio; |
| 295 } | 267 } |
| 296 | 268 |
| 297 } // namespace | 269 } // namespace |
| 298 | 270 |
| 299 //////////////////////////////////////////////////////////////////////////////// | 271 //////////////////////////////////////////////////////////////////////////////// |
| 300 // Event, private: | 272 // Event, private: |
| 301 | 273 |
| 302 void Event::InitWithNativeEvent2(NativeEvent2 native_event_2, | 274 void Event::InitWithNativeEvent2(NativeEvent2 native_event_2, |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 | 381 |
| 410 MouseWheelEvent::MouseWheelEvent(NativeEvent2 native_event_2, | 382 MouseWheelEvent::MouseWheelEvent(NativeEvent2 native_event_2, |
| 411 FromNativeEvent2 from_native) | 383 FromNativeEvent2 from_native) |
| 412 : MouseEvent(native_event_2, from_native), | 384 : MouseEvent(native_event_2, from_native), |
| 413 offset_(GetMouseWheelOffset(native_event_2)) { | 385 offset_(GetMouseWheelOffset(native_event_2)) { |
| 414 } | 386 } |
| 415 | 387 |
| 416 //////////////////////////////////////////////////////////////////////////////// | 388 //////////////////////////////////////////////////////////////////////////////// |
| 417 // TouchEvent, public: | 389 // TouchEvent, public: |
| 418 | 390 |
| 419 #if defined(HAVE_XINPUT2) | |
| 420 TouchEvent::TouchEvent(NativeEvent2 native_event_2, | 391 TouchEvent::TouchEvent(NativeEvent2 native_event_2, |
| 421 FromNativeEvent2 from_native) | 392 FromNativeEvent2 from_native) |
| 422 : LocatedEvent(native_event_2, from_native), | 393 : LocatedEvent(native_event_2, from_native), |
| 423 touch_id_(GetTouchIDFromXEvent(native_event_2)), | 394 touch_id_(GetTouchIDFromXEvent(native_event_2)), |
| 424 radius_(GetTouchRadiusFromXEvent(native_event_2)), | 395 radius_(GetTouchRadiusFromXEvent(native_event_2)), |
| 425 angle_(GetTouchAngleFromXEvent(native_event_2)), | 396 angle_(GetTouchAngleFromXEvent(native_event_2)), |
| 426 ratio_(GetTouchRatioFromXEvent(native_event_2)) { | 397 ratio_(GetTouchRatioFromXEvent(native_event_2)) { |
| 427 if (type() == ui::ET_TOUCH_PRESSED || type() == ui::ET_TOUCH_RELEASED) { | 398 if (type() == ui::ET_TOUCH_PRESSED || type() == ui::ET_TOUCH_RELEASED) { |
| 428 TouchFactory* factory = TouchFactory::GetInstance(); | 399 TouchFactory* factory = TouchFactory::GetInstance(); |
| 429 float slot; | 400 float slot; |
| 430 if (factory->ExtractTouchParam(*native_event_2, | 401 if (factory->ExtractTouchParam(*native_event_2, |
| 431 TouchFactory::TP_SLOT_ID, &slot)) { | 402 TouchFactory::TP_SLOT_ID, &slot)) { |
| 432 factory->SetSlotUsed(slot, type() == ui::ET_TOUCH_PRESSED); | 403 factory->SetSlotUsed(slot, type() == ui::ET_TOUCH_PRESSED); |
| 433 } | 404 } |
| 434 } | 405 } |
| 435 } | 406 } |
| 436 #endif | |
| 437 | 407 |
| 438 } // namespace views | 408 } // namespace views |
| OLD | NEW |