Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: ui/events/x/events_x.cc

Issue 336403005: Use XInput2 events for keyboard events. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add TODO regarding XI2-to-core rewriting. Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/events/event_constants.h" 5 #include "ui/events/event_constants.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <string.h> 8 #include <string.h>
9 #include <X11/extensions/XInput.h> 9 #include <X11/extensions/XInput.h>
10 #include <X11/extensions/XInput2.h> 10 #include <X11/extensions/XInput2.h>
11 #include <X11/Xlib.h> 11 #include <X11/Xlib.h>
12 #include <X11/Xutil.h> 12 #include <X11/Xutil.h>
13 #include <X11/XKBlib.h>
13 14
14 #include "base/logging.h" 15 #include "base/logging.h"
15 #include "base/memory/singleton.h" 16 #include "base/memory/singleton.h"
16 #include "ui/events/event_utils.h" 17 #include "ui/events/event_utils.h"
17 #include "ui/events/keycodes/keyboard_code_conversion_x.h" 18 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
18 #include "ui/events/x/device_data_manager.h" 19 #include "ui/events/x/device_data_manager.h"
19 #include "ui/events/x/device_list_cache_x.h" 20 #include "ui/events/x/device_list_cache_x.h"
20 #include "ui/events/x/touch_factory_x11.h" 21 #include "ui/events/x/touch_factory_x11.h"
21 #include "ui/gfx/display.h" 22 #include "ui/gfx/display.h"
22 #include "ui/gfx/point.h" 23 #include "ui/gfx/point.h"
(...skipping 12 matching lines...) Expand all
35 36
36 // A class to track current modifier state on master device. Only track ctrl, 37 // A class to track current modifier state on master device. Only track ctrl,
37 // alt, shift and caps lock keys currently. The tracked state can then be used 38 // alt, shift and caps lock keys currently. The tracked state can then be used
38 // by floating device. 39 // by floating device.
39 class XModifierStateWatcher{ 40 class XModifierStateWatcher{
40 public: 41 public:
41 static XModifierStateWatcher* GetInstance() { 42 static XModifierStateWatcher* GetInstance() {
42 return Singleton<XModifierStateWatcher>::get(); 43 return Singleton<XModifierStateWatcher>::get();
43 } 44 }
44 45
45 void UpdateStateFromEvent(const base::NativeEvent& native_event) { 46 int StateFromKeyboardCode(ui::KeyboardCode keyboard_code) {
47 switch (keyboard_code) {
48 case ui::VKEY_CONTROL:
49 return ControlMask;
50 case ui::VKEY_SHIFT:
51 return ShiftMask;
52 case ui::VKEY_MENU:
53 return Mod1Mask;
54 case ui::VKEY_CAPITAL:
55 return LockMask;
56 default:
57 return 0;
58 }
59 NOTREACHED();
Daniel Erat 2014/06/25 17:13:25 nit: probably don't need this, right? there's a de
kpschoedel 2014/06/25 19:59:49 Done.
60 }
61
62 void UpdateStateFromXKeyEvent(const base::NativeEvent& native_event) {
63 DCHECK((native_event->type == KeyPress) ||
64 (native_event->type == KeyRelease));
46 // Floating device can't access the modifer state from master device. 65 // Floating device can't access the modifer state from master device.
47 // We need to track the states of modifier keys in a singleton for 66 // We need to track the states of modifier keys in a singleton for
48 // floating devices such as touch screen. Issue 106426 is one example 67 // floating devices such as touch screen. Issue 106426 is one example
49 // of why we need the modifier states for floating device. 68 // of why we need the modifier states for floating device.
50 state_ = native_event->xkey.state; 69 state_ = native_event->xkey.state;
51 // master_state is the state before key press. We need to track the 70 // master_state is the state before key press. We need to track the
52 // state after key press for floating device. Currently only ctrl, 71 // state after key press for floating device. Currently only ctrl,
53 // shift, alt and caps lock keys are tracked. 72 // shift, alt and caps lock keys are tracked.
54 ui::KeyboardCode keyboard_code = ui::KeyboardCodeFromNative(native_event); 73 ui::KeyboardCode keyboard_code = ui::KeyboardCodeFromNative(native_event);
55 unsigned int mask = 0; 74 unsigned int mask = StateFromKeyboardCode(keyboard_code);
75 if (native_event->type == KeyPress)
76 state_ |= mask;
77 else
78 state_ &= ~mask;
79 }
56 80
57 switch (keyboard_code) { 81 void UpdateStateFromXGenericEvent(const base::NativeEvent& native_event) {
58 case ui::VKEY_CONTROL: { 82 DCHECK(native_event->type == GenericEvent);
59 mask = ControlMask; 83 XIDeviceEvent* xievent =
60 break; 84 static_cast<XIDeviceEvent*>(native_event->xcookie.data);
61 } 85 DCHECK((xievent->evtype == XI_KeyPress) ||
62 case ui::VKEY_SHIFT: { 86 (xievent->evtype == XI_KeyRelease));
63 mask = ShiftMask; 87 // Floating device can't access the modifer state from master device.
64 break; 88 // We need to track the states of modifier keys in a singleton for
65 } 89 // floating devices such as touch screen. Issue 106426 is one example
66 case ui::VKEY_MENU: { 90 // of why we need the modifier states for floating device.
67 mask = Mod1Mask; 91 state_ = xievent->mods.effective;
68 break; 92 // master_state is the state before key press. We need to track the
69 } 93 // state after key press for floating device. Currently only ctrl,
70 case ui::VKEY_CAPITAL: { 94 // shift, alt and caps lock keys are tracked.
71 mask = LockMask; 95 ui::KeyboardCode keyboard_code = ui::KeyboardCodeFromNative(native_event);
72 break; 96 unsigned int mask = StateFromKeyboardCode(keyboard_code);
73 } 97 if (native_event->type == XI_KeyPress)
74 default:
75 break;
76 }
77
78 if (native_event->type == KeyPress)
79 state_ |= mask; 98 state_ |= mask;
80 else 99 else
81 state_ &= ~mask; 100 state_ &= ~mask;
82 } 101 }
83 102
84 // Returns the current modifer state in master device. It only contains the 103 // Returns the current modifer state in master device. It only contains the
85 // state of ctrl, shift, alt and caps lock keys. 104 // state of ctrl, shift, alt and caps lock keys.
86 unsigned int state() { return state_; } 105 unsigned int state() { return state_; }
87 106
88 private: 107 private:
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 fabricated_by_xim ? ui::EF_IME_FABRICATED_KEY : 0; 194 fabricated_by_xim ? ui::EF_IME_FABRICATED_KEY : 0;
176 #endif 195 #endif
177 196
178 return GetEventFlagsFromXState(xevent->xkey.state) | 197 return GetEventFlagsFromXState(xevent->xkey.state) |
179 (IsKeypadKey(XLookupKeysym(&xevent->xkey, 0)) ? ui::EF_NUMPAD_KEY : 0) | 198 (IsKeypadKey(XLookupKeysym(&xevent->xkey, 0)) ? ui::EF_NUMPAD_KEY : 0) |
180 (IsFunctionKey(XLookupKeysym(&xevent->xkey, 0)) ? 199 (IsFunctionKey(XLookupKeysym(&xevent->xkey, 0)) ?
181 ui::EF_FUNCTION_KEY : 0) | 200 ui::EF_FUNCTION_KEY : 0) |
182 ime_fabricated_flag; 201 ime_fabricated_flag;
183 } 202 }
184 203
204 int GetEventFlagsFromXGenericEvent(XEvent* xevent) {
205 DCHECK(xevent->type == GenericEvent);
206 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data);
207 DCHECK((xievent->evtype == XI_KeyPress) ||
208 (xievent->evtype == XI_KeyRelease));
209 return GetEventFlagsFromXState(xievent->mods.effective) |
210 (IsKeypadKey(
211 XkbKeycodeToKeysym(xievent->display, xievent->detail, 0, 0))
212 ? ui::EF_NUMPAD_KEY
213 : 0);
214 }
215
185 // Get the event flag for the button in XButtonEvent. During a ButtonPress 216 // Get the event flag for the button in XButtonEvent. During a ButtonPress
186 // event, |state| in XButtonEvent does not include the button that has just been 217 // event, |state| in XButtonEvent does not include the button that has just been
187 // pressed. Instead |state| contains flags for the buttons (if any) that had 218 // pressed. Instead |state| contains flags for the buttons (if any) that had
188 // already been pressed before the current button, and |button| stores the most 219 // already been pressed before the current button, and |button| stores the most
189 // current pressed button. So, if you press down left mouse button, and while 220 // current pressed button. So, if you press down left mouse button, and while
190 // pressing it down, press down the right mouse button, then for the latter 221 // pressing it down, press down the right mouse button, then for the latter
191 // event, |state| would have Button1Mask set but not Button3Mask, and |button| 222 // event, |state| would have Button1Mask set but not Button3Mask, and |button|
192 // would be 3. 223 // would be 3.
193 int GetEventFlagsForButton(int button) { 224 int GetEventFlagsForButton(int button) {
194 switch (button) { 225 switch (button) {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 return IsTouchpadEvent(native_event) ? ET_SCROLL : ET_MOUSEWHEEL; 373 return IsTouchpadEvent(native_event) ? ET_SCROLL : ET_MOUSEWHEEL;
343 } else if (DeviceDataManager::GetInstance()->IsCMTMetricsEvent( 374 } else if (DeviceDataManager::GetInstance()->IsCMTMetricsEvent(
344 native_event)) { 375 native_event)) {
345 return ET_UMA_DATA; 376 return ET_UMA_DATA;
346 } else if (GetButtonMaskForX2Event(xievent)) { 377 } else if (GetButtonMaskForX2Event(xievent)) {
347 return ET_MOUSE_DRAGGED; 378 return ET_MOUSE_DRAGGED;
348 } else { 379 } else {
349 return ET_MOUSE_MOVED; 380 return ET_MOUSE_MOVED;
350 } 381 }
351 } 382 }
383 case XI_KeyPress:
384 return ET_KEY_PRESSED;
385 case XI_KeyRelease:
386 return ET_KEY_RELEASED;
352 } 387 }
353 } 388 }
354 default: 389 default:
355 break; 390 break;
356 } 391 }
357 return ET_UNKNOWN; 392 return ET_UNKNOWN;
358 } 393 }
359 394
360 int EventFlagsFromNative(const base::NativeEvent& native_event) { 395 int EventFlagsFromNative(const base::NativeEvent& native_event) {
361 switch (native_event->type) { 396 switch (native_event->type) {
362 case KeyPress: 397 case KeyPress:
363 case KeyRelease: { 398 case KeyRelease: {
364 XModifierStateWatcher::GetInstance()->UpdateStateFromEvent(native_event); 399 XModifierStateWatcher::GetInstance()->UpdateStateFromXKeyEvent(
400 native_event);
365 return GetEventFlagsFromXKeyEvent(native_event); 401 return GetEventFlagsFromXKeyEvent(native_event);
366 } 402 }
367 case ButtonPress: 403 case ButtonPress:
368 case ButtonRelease: { 404 case ButtonRelease: {
369 int flags = GetEventFlagsFromXState(native_event->xbutton.state); 405 int flags = GetEventFlagsFromXState(native_event->xbutton.state);
370 const EventType type = EventTypeFromNative(native_event); 406 const EventType type = EventTypeFromNative(native_event);
371 if (type == ET_MOUSE_PRESSED || type == ET_MOUSE_RELEASED) 407 if (type == ET_MOUSE_PRESSED || type == ET_MOUSE_RELEASED)
372 flags |= GetEventFlagsForButton(native_event->xbutton.button); 408 flags |= GetEventFlagsForButton(native_event->xbutton.button);
373 return flags; 409 return flags;
374 } 410 }
(...skipping 15 matching lines...) Expand all
390 GetEventFlagsFromXState(xievent->mods.effective) | 426 GetEventFlagsFromXState(xievent->mods.effective) |
391 GetEventFlagsFromXState( 427 GetEventFlagsFromXState(
392 XModifierStateWatcher::GetInstance()->state()); 428 XModifierStateWatcher::GetInstance()->state());
393 break; 429 break;
394 #endif 430 #endif
395 case XI_ButtonPress: 431 case XI_ButtonPress:
396 case XI_ButtonRelease: { 432 case XI_ButtonRelease: {
397 const bool touch = 433 const bool touch =
398 TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid); 434 TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid);
399 int flags = GetButtonMaskForX2Event(xievent) | 435 int flags = GetButtonMaskForX2Event(xievent) |
400 GetEventFlagsFromXState(xievent->mods.effective); 436 GetEventFlagsFromXState(xievent->mods.effective);
401 if (touch) { 437 if (touch) {
402 flags |= GetEventFlagsFromXState( 438 flags |= GetEventFlagsFromXState(
403 XModifierStateWatcher::GetInstance()->state()); 439 XModifierStateWatcher::GetInstance()->state());
404 } 440 }
405 441
406 const EventType type = EventTypeFromNative(native_event); 442 const EventType type = EventTypeFromNative(native_event);
407 int button = EventButtonFromNative(native_event); 443 int button = EventButtonFromNative(native_event);
408 if ((type == ET_MOUSE_PRESSED || type == ET_MOUSE_RELEASED) && !touch) 444 if ((type == ET_MOUSE_PRESSED || type == ET_MOUSE_RELEASED) && !touch)
409 flags |= GetEventFlagsForButton(button); 445 flags |= GetEventFlagsForButton(button);
410 return flags; 446 return flags;
411 } 447 }
412 case XI_Motion: 448 case XI_Motion:
413 return GetButtonMaskForX2Event(xievent) | 449 return GetButtonMaskForX2Event(xievent) |
414 GetEventFlagsFromXState(xievent->mods.effective); 450 GetEventFlagsFromXState(xievent->mods.effective);
451 case XI_KeyPress:
452 case XI_KeyRelease: {
453 XModifierStateWatcher::GetInstance()->UpdateStateFromXGenericEvent(
454 native_event);
455 return GetEventFlagsFromXGenericEvent(native_event);
456 }
415 } 457 }
416 } 458 }
417 } 459 }
418 return 0; 460 return 0;
419 } 461 }
420 462
421 base::TimeDelta EventTimeFromNative(const base::NativeEvent& native_event) { 463 base::TimeDelta EventTimeFromNative(const base::NativeEvent& native_event) {
422 switch(native_event->type) { 464 switch(native_event->type) {
423 case KeyPress: 465 case KeyPress:
424 case KeyRelease: 466 case KeyRelease:
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 case 6: 623 case 6:
582 return gfx::Vector2d(kWheelScrollAmount, 0); 624 return gfx::Vector2d(kWheelScrollAmount, 0);
583 case 7: 625 case 7:
584 return gfx::Vector2d(-kWheelScrollAmount, 0); 626 return gfx::Vector2d(-kWheelScrollAmount, 0);
585 default: 627 default:
586 return gfx::Vector2d(); 628 return gfx::Vector2d();
587 } 629 }
588 } 630 }
589 631
590 base::NativeEvent CopyNativeEvent(const base::NativeEvent& event) { 632 base::NativeEvent CopyNativeEvent(const base::NativeEvent& event) {
591 if (!event || event->type == GenericEvent) 633 if (!event)
592 return NULL; 634 return NULL;
593 XEvent* copy = new XEvent; 635 XEvent* copy = new XEvent;
594 *copy = *event; 636 *copy = *event;
637 if (event->type == GenericEvent) {
638 XIDeviceEvent* xievent_copy = new XIDeviceEvent;
639 *xievent_copy = *static_cast<XIDeviceEvent*>(event->xcookie.data);
640 copy->xcookie.data = xievent_copy;
641 }
595 return copy; 642 return copy;
596 } 643 }
597 644
598 void ReleaseCopiedNativeEvent(const base::NativeEvent& event) { 645 void ReleaseCopiedNativeEvent(const base::NativeEvent& event) {
646 if (event && event->type == GenericEvent)
647 delete static_cast<XIDeviceEvent*>(event->xcookie.data);
599 delete event; 648 delete event;
600 } 649 }
601 650
602 void ClearTouchIdIfReleased(const base::NativeEvent& xev) { 651 void ClearTouchIdIfReleased(const base::NativeEvent& xev) {
603 ui::EventType type = ui::EventTypeFromNative(xev); 652 ui::EventType type = ui::EventTypeFromNative(xev);
604 if (type == ui::ET_TOUCH_CANCELLED || 653 if (type == ui::ET_TOUCH_CANCELLED ||
605 type == ui::ET_TOUCH_RELEASED) { 654 type == ui::ET_TOUCH_RELEASED) {
606 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); 655 ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
607 ui::DeviceDataManager* manager = ui::DeviceDataManager::GetInstance(); 656 ui::DeviceDataManager* manager = ui::DeviceDataManager::GetInstance();
608 double tracking_id; 657 double tracking_id;
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 DeviceDataManager::GetInstance()->GetGestureTimes( 779 DeviceDataManager::GetInstance()->GetGestureTimes(
731 native_event, start_time, end_time); 780 native_event, start_time, end_time);
732 return true; 781 return true;
733 } 782 }
734 783
735 bool IsTouchpadEvent(const base::NativeEvent& event) { 784 bool IsTouchpadEvent(const base::NativeEvent& event) {
736 return DeviceDataManager::GetInstance()->IsTouchpadXInputEvent(event); 785 return DeviceDataManager::GetInstance()->IsTouchpadXInputEvent(event);
737 } 786 }
738 787
739 } // namespace ui 788 } // namespace ui
OLDNEW
« ui/events/keycodes/keyboard_code_conversion_x.cc ('K') | « ui/events/test/events_test_utils_x11.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698