Chromium Code Reviews| 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 "ui/base/events.h" | 5 #include "ui/base/events.h" |
| 6 | 6 |
| 7 #include <X11/Xlib.h> | 7 #include <X11/Xlib.h> |
| 8 #include <X11/extensions/XInput2.h> | 8 #include <X11/extensions/XInput2.h> |
| 9 #include <string.h> | 9 #include <string.h> |
| 10 | 10 |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "ui/base/keycodes/keyboard_code_conversion_x.h" | 12 #include "ui/base/keycodes/keyboard_code_conversion_x.h" |
| 13 #include "ui/base/touch/touch_factory.h" | 13 #include "ui/base/touch/touch_factory.h" |
| 14 #include "ui/base/x/x11_util.h" | |
| 14 #include "ui/gfx/point.h" | 15 #include "ui/gfx/point.h" |
| 15 | 16 |
| 16 #if !defined(TOOLKIT_USES_GTK) | 17 #if !defined(TOOLKIT_USES_GTK) |
| 17 #include "base/message_pump_x.h" | 18 #include "base/message_pump_x.h" |
| 18 #endif | 19 #endif |
| 19 | 20 |
| 20 namespace { | 21 namespace { |
| 21 | 22 |
| 22 // Scroll amount for each wheelscroll event. 53 is also the value used for GTK+. | 23 // Scroll amount for each wheelscroll event. 53 is also the value used for GTK+. |
| 23 static const int kWheelScrollAmount = 53; | 24 static const int kWheelScrollAmount = 53; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 63 return ui::EF_LEFT_BUTTON_DOWN; | 64 return ui::EF_LEFT_BUTTON_DOWN; |
| 64 case 2: | 65 case 2: |
| 65 return ui::EF_MIDDLE_BUTTON_DOWN; | 66 return ui::EF_MIDDLE_BUTTON_DOWN; |
| 66 case 3: | 67 case 3: |
| 67 return ui::EF_RIGHT_BUTTON_DOWN; | 68 return ui::EF_RIGHT_BUTTON_DOWN; |
| 68 default: | 69 default: |
| 69 return 0; | 70 return 0; |
| 70 } | 71 } |
| 71 } | 72 } |
| 72 | 73 |
| 74 int GetMappedButton(int button) { | |
| 75 static unsigned char map[256]; | |
| 76 static int count = 0; | |
| 77 if (!count) | |
| 78 count = XGetPointerMapping(ui::GetXDisplay(), map, arraysize(map)); | |
|
Daniel Erat
2011/12/04 15:51:45
i think that you need to refresh the cached copy o
sadrul
2011/12/07 16:36:12
Indeed. I thought about it, and assumed perhaps th
| |
| 79 return button > 0 && button <= count ? map[button - 1] : button; | |
| 80 } | |
| 81 | |
| 73 int GetButtonMaskForX2Event(XIDeviceEvent* xievent) { | 82 int GetButtonMaskForX2Event(XIDeviceEvent* xievent) { |
| 74 int buttonflags = 0; | 83 int buttonflags = 0; |
| 75 for (int i = 0; i < 8 * xievent->buttons.mask_len; i++) { | 84 for (int i = 0; i < 8 * xievent->buttons.mask_len; i++) { |
| 76 if (XIMaskIsSet(xievent->buttons.mask, i)) { | 85 if (XIMaskIsSet(xievent->buttons.mask, i)) { |
| 77 buttonflags |= GetEventFlagsForButton(i); | 86 int button = (xievent->sourceid == xievent->deviceid) ? |
| 87 GetMappedButton(i) : i; | |
|
Daniel Erat
2011/12/04 15:51:45
nit: indent one less space?
sadrul
2011/12/07 17:06:52
Done.
| |
| 88 buttonflags |= GetEventFlagsForButton(button); | |
| 78 } | 89 } |
| 79 } | 90 } |
| 80 return buttonflags; | 91 return buttonflags; |
| 81 } | 92 } |
| 82 | 93 |
| 83 ui::EventType GetTouchEventType(const base::NativeEvent& native_event) { | 94 ui::EventType GetTouchEventType(const base::NativeEvent& native_event) { |
| 84 XIDeviceEvent* event = | 95 XIDeviceEvent* event = |
| 85 static_cast<XIDeviceEvent*>(native_event->xcookie.data); | 96 static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
| 86 #if defined(USE_XI2_MT) | 97 #if defined(USE_XI2_MT) |
| 87 switch(event->evtype) { | 98 switch(event->evtype) { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 178 return ET_MOUSE_MOVED; | 189 return ET_MOUSE_MOVED; |
| 179 case EnterNotify: | 190 case EnterNotify: |
| 180 return ET_MOUSE_ENTERED; | 191 return ET_MOUSE_ENTERED; |
| 181 case LeaveNotify: | 192 case LeaveNotify: |
| 182 return ET_MOUSE_EXITED; | 193 return ET_MOUSE_EXITED; |
| 183 case GenericEvent: { | 194 case GenericEvent: { |
| 184 XIDeviceEvent* xievent = | 195 XIDeviceEvent* xievent = |
| 185 static_cast<XIDeviceEvent*>(native_event->xcookie.data); | 196 static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
| 186 if (TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid)) | 197 if (TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid)) |
| 187 return GetTouchEventType(native_event); | 198 return GetTouchEventType(native_event); |
| 199 int button = EventButtonFromNative(native_event); | |
| 188 switch (xievent->evtype) { | 200 switch (xievent->evtype) { |
| 189 case XI_ButtonPress: | 201 case XI_ButtonPress: |
| 190 if (xievent->detail >= kMinWheelButton && | 202 if (button >= kMinWheelButton && |
| 191 xievent->detail <= kMaxWheelButton) | 203 button <= kMaxWheelButton) |
| 192 return ET_MOUSEWHEEL; | 204 return ET_MOUSEWHEEL; |
| 193 return ET_MOUSE_PRESSED; | 205 return ET_MOUSE_PRESSED; |
| 194 case XI_ButtonRelease: | 206 case XI_ButtonRelease: |
| 195 if (xievent->detail >= kMinWheelButton && | 207 if (button >= kMinWheelButton && |
| 196 xievent->detail <= kMaxWheelButton) | 208 button <= kMaxWheelButton) |
| 197 return ET_MOUSEWHEEL; | 209 return ET_MOUSEWHEEL; |
| 198 return ET_MOUSE_RELEASED; | 210 return ET_MOUSE_RELEASED; |
| 199 case XI_Motion: | 211 case XI_Motion: |
| 200 return GetButtonMaskForX2Event(xievent) ? | 212 return GetButtonMaskForX2Event(xievent) ? |
| 201 ET_MOUSE_DRAGGED : ET_MOUSE_MOVED; | 213 ET_MOUSE_DRAGGED : ET_MOUSE_MOVED; |
| 202 } | 214 } |
| 203 } | 215 } |
| 204 default: | 216 default: |
| 205 break; | 217 break; |
| 206 } | 218 } |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 226 XIDeviceEvent* xievent = | 238 XIDeviceEvent* xievent = |
| 227 static_cast<XIDeviceEvent*>(native_event->xcookie.data); | 239 static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
| 228 const bool touch = | 240 const bool touch = |
| 229 TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid); | 241 TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid); |
| 230 switch (xievent->evtype) { | 242 switch (xievent->evtype) { |
| 231 case XI_ButtonPress: | 243 case XI_ButtonPress: |
| 232 case XI_ButtonRelease: { | 244 case XI_ButtonRelease: { |
| 233 int flags = GetButtonMaskForX2Event(xievent) | | 245 int flags = GetButtonMaskForX2Event(xievent) | |
| 234 GetEventFlagsFromXState(xievent->mods.effective); | 246 GetEventFlagsFromXState(xievent->mods.effective); |
| 235 const EventType type = EventTypeFromNative(native_event); | 247 const EventType type = EventTypeFromNative(native_event); |
| 248 int button = EventButtonFromNative(native_event); | |
| 236 if ((type == ET_MOUSE_PRESSED || type == ET_MOUSE_RELEASED) && !touch) | 249 if ((type == ET_MOUSE_PRESSED || type == ET_MOUSE_RELEASED) && !touch) |
| 237 flags |= GetEventFlagsForButton(xievent->detail); | 250 flags |= GetEventFlagsForButton(button); |
| 238 return flags; | 251 return flags; |
| 239 } | 252 } |
| 240 case XI_Motion: | 253 case XI_Motion: |
| 241 return GetButtonMaskForX2Event(xievent) | | 254 return GetButtonMaskForX2Event(xievent) | |
| 242 GetEventFlagsFromXState(xievent->mods.effective); | 255 GetEventFlagsFromXState(xievent->mods.effective); |
| 243 } | 256 } |
| 244 } | 257 } |
| 245 } | 258 } |
| 246 return 0; | 259 return 0; |
| 247 } | 260 } |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 274 double y = xievent->event_y; | 287 double y = xievent->event_y; |
| 275 if (XIMaskIsSet(xievent->valuators.mask, 1)) | 288 if (XIMaskIsSet(xievent->valuators.mask, 1)) |
| 276 y = *valuators++ - (xievent->root_y - xievent->event_y); | 289 y = *valuators++ - (xievent->root_y - xievent->event_y); |
| 277 | 290 |
| 278 return gfx::Point(static_cast<int>(x), static_cast<int>(y)); | 291 return gfx::Point(static_cast<int>(x), static_cast<int>(y)); |
| 279 } | 292 } |
| 280 } | 293 } |
| 281 return gfx::Point(); | 294 return gfx::Point(); |
| 282 } | 295 } |
| 283 | 296 |
| 297 int EventButtonFromNative(const base::NativeEvent& native_event) { | |
| 298 CHECK_EQ(GenericEvent, native_event->type); | |
| 299 XIDeviceEvent* xievent = | |
| 300 static_cast<XIDeviceEvent*>(native_event->xcookie.data); | |
| 301 int button = xievent->detail; | |
| 302 | |
| 303 return (xievent->sourceid == xievent->deviceid) ? | |
| 304 GetMappedButton(button) : button; | |
|
Daniel Erat
2011/12/04 15:51:45
nit: indent one less space?
sadrul
2011/12/07 17:06:52
Done.
| |
| 305 } | |
| 306 | |
| 284 KeyboardCode KeyboardCodeFromNative(const base::NativeEvent& native_event) { | 307 KeyboardCode KeyboardCodeFromNative(const base::NativeEvent& native_event) { |
| 285 return KeyboardCodeFromXKeyEvent(native_event); | 308 return KeyboardCodeFromXKeyEvent(native_event); |
| 286 } | 309 } |
| 287 | 310 |
| 288 bool IsMouseEvent(const base::NativeEvent& native_event) { | 311 bool IsMouseEvent(const base::NativeEvent& native_event) { |
| 289 if (native_event->type == ButtonPress || | 312 if (native_event->type == ButtonPress || |
| 290 native_event->type == ButtonRelease || | 313 native_event->type == ButtonRelease || |
| 291 native_event->type == MotionNotify) | 314 native_event->type == MotionNotify) |
| 292 return true; | 315 return true; |
| 293 if (native_event->type == GenericEvent) { | 316 if (native_event->type == GenericEvent) { |
| 294 XIDeviceEvent* xievent = | 317 XIDeviceEvent* xievent = |
| 295 static_cast<XIDeviceEvent*>(native_event->xcookie.data); | 318 static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
| 296 return xievent->evtype == XI_ButtonPress || | 319 return xievent->evtype == XI_ButtonPress || |
| 297 xievent->evtype == XI_ButtonRelease || | 320 xievent->evtype == XI_ButtonRelease || |
| 298 xievent->evtype == XI_Motion; | 321 xievent->evtype == XI_Motion; |
| 299 } | 322 } |
| 300 return false; | 323 return false; |
| 301 } | 324 } |
| 302 | 325 |
| 303 int GetMouseWheelOffset(const base::NativeEvent& native_event) { | 326 int GetMouseWheelOffset(const base::NativeEvent& native_event) { |
| 304 int button; | 327 int button; |
| 305 if (native_event->type == GenericEvent) { | 328 if (native_event->type == GenericEvent) |
| 306 XIDeviceEvent* xiev = | 329 button = EventButtonFromNative(native_event); |
| 307 static_cast<XIDeviceEvent*>(native_event->xcookie.data); | 330 else |
| 308 button = xiev->detail; | |
| 309 } else { | |
| 310 button = native_event->xbutton.button; | 331 button = native_event->xbutton.button; |
| 311 } | |
| 312 switch (button) { | 332 switch (button) { |
| 313 case 4: | 333 case 4: |
| 314 #if defined(OS_CHROMEOS) | 334 #if defined(OS_CHROMEOS) |
| 315 case 8: | 335 case 8: |
| 316 #endif | 336 #endif |
| 317 return kWheelScrollAmount; | 337 return kWheelScrollAmount; |
| 318 | 338 |
| 319 case 5: | 339 case 5: |
| 320 #if defined(OS_CHROMEOS) | 340 #if defined(OS_CHROMEOS) |
| 321 case 9: | 341 case 9: |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 398 // Make sure we use atom from current xdisplay, which may | 418 // Make sure we use atom from current xdisplay, which may |
| 399 // change during the test. | 419 // change during the test. |
| 400 noop->xclient.message_type = XInternAtom( | 420 noop->xclient.message_type = XInternAtom( |
| 401 base::MessagePumpX::GetDefaultXDisplay(), | 421 base::MessagePumpX::GetDefaultXDisplay(), |
| 402 "noop", False); | 422 "noop", False); |
| 403 #endif | 423 #endif |
| 404 return noop; | 424 return noop; |
| 405 } | 425 } |
| 406 | 426 |
| 407 } // namespace ui | 427 } // namespace ui |
| OLD | NEW |