OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/event.h" | 5 #include "views/event.h" |
6 | 6 |
7 #include <gdk/gdkx.h> | 7 #include <gdk/gdkx.h> |
| 8 #if defined(HAVE_XINPUT2) |
| 9 #include <X11/extensions/XInput2.h> |
| 10 #endif |
8 | 11 |
9 #include "app/keyboard_code_conversion_x.h" | 12 #include "app/keyboard_code_conversion_x.h" |
10 #include "views/widget/root_view.h" | 13 #include "views/widget/root_view.h" |
11 #include "views/widget/widget_gtk.h" | 14 #include "views/widget/widget_gtk.h" |
12 | 15 |
13 namespace views { | 16 namespace views { |
14 | 17 |
15 namespace { | 18 namespace { |
16 | 19 |
17 int GetEventFlagsFromXState(unsigned int state) { | 20 int GetEventFlagsFromXState(unsigned int state) { |
18 int flags = 0; | 21 int flags = 0; |
19 if (state & ControlMask) | 22 if (state & ControlMask) |
20 flags |= Event::EF_CONTROL_DOWN; | 23 flags |= Event::EF_CONTROL_DOWN; |
21 if (state & ShiftMask) | 24 if (state & ShiftMask) |
22 flags |= Event::EF_SHIFT_DOWN; | 25 flags |= Event::EF_SHIFT_DOWN; |
23 if (state & Mod1Mask) | 26 if (state & Mod1Mask) |
24 flags |= Event::EF_ALT_DOWN; | 27 flags |= Event::EF_ALT_DOWN; |
25 if (state & Button1Mask) | 28 if (state & Button1Mask) |
26 flags |= Event::EF_LEFT_BUTTON_DOWN; | 29 flags |= Event::EF_LEFT_BUTTON_DOWN; |
27 if (state & Button2Mask) | 30 if (state & Button2Mask) |
28 flags |= Event::EF_MIDDLE_BUTTON_DOWN; | 31 flags |= Event::EF_MIDDLE_BUTTON_DOWN; |
29 if (state & Button3Mask) | 32 if (state & Button3Mask) |
30 flags |= Event::EF_RIGHT_BUTTON_DOWN; | 33 flags |= Event::EF_RIGHT_BUTTON_DOWN; |
31 | 34 |
32 return flags; | 35 return flags; |
33 } | 36 } |
34 | 37 |
35 // Get the event flag for the button in XButtonEvent. During a KeyPress event, | 38 // Get the event flag for the button in XButtonEvent. During a ButtonPress |
36 // |state| in XButtonEvent does not include the button that has just been | 39 // event, |state| in XButtonEvent does not include the button that has just been |
37 // pressed. Instead |state| contains flags for the buttons (if any) that had | 40 // pressed. Instead |state| contains flags for the buttons (if any) that had |
38 // already been pressed before the current button, and |button| stores the most | 41 // already been pressed before the current button, and |button| stores the most |
39 // current pressed button. So, if you press down left mouse button, and while | 42 // current pressed button. So, if you press down left mouse button, and while |
40 // pressing it down, press down the right mouse button, then for the latter | 43 // pressing it down, press down the right mouse button, then for the latter |
41 // event, |state| would have Button1Mask set but not Button3Mask, and |button| | 44 // event, |state| would have Button1Mask set but not Button3Mask, and |button| |
42 // would be 3. | 45 // would be 3. |
43 int GetEventFlagsForButton(int button) { | 46 int GetEventFlagsForButton(int button) { |
44 switch (button) { | 47 switch (button) { |
45 case 1: | 48 case 1: |
46 return Event::EF_LEFT_BUTTON_DOWN; | 49 return Event::EF_LEFT_BUTTON_DOWN; |
47 case 2: | 50 case 2: |
48 return Event::EF_MIDDLE_BUTTON_DOWN; | 51 return Event::EF_MIDDLE_BUTTON_DOWN; |
49 case 3: | 52 case 3: |
50 return Event::EF_RIGHT_BUTTON_DOWN; | 53 return Event::EF_RIGHT_BUTTON_DOWN; |
51 } | 54 } |
52 | 55 |
53 DLOG(WARNING) << "Unexpected button (" << button << ") received."; | 56 DLOG(WARNING) << "Unexpected button (" << button << ") received."; |
54 return 0; | 57 return 0; |
55 } | 58 } |
56 | 59 |
| 60 #if defined(HAVE_XINPUT2) |
| 61 int GetButtonMaskForX2Event(XIDeviceEvent* xievent) { |
| 62 int buttonflags = 0; |
| 63 |
| 64 for (int i = 0; i < 8 * xievent->buttons.mask_len; i++) { |
| 65 if (XIMaskIsSet(xievent->buttons.mask, i)) { |
| 66 buttonflags |= GetEventFlagsForButton(i); |
| 67 } |
| 68 } |
| 69 |
| 70 return buttonflags; |
| 71 } |
| 72 #endif // HAVE_XINPUT2 |
| 73 |
57 Event::EventType GetMouseEventType(XEvent* xev) { | 74 Event::EventType GetMouseEventType(XEvent* xev) { |
58 switch (xev->type) { | 75 switch (xev->type) { |
59 case ButtonPress: | 76 case ButtonPress: |
60 return Event::ET_MOUSE_PRESSED; | 77 return Event::ET_MOUSE_PRESSED; |
61 case ButtonRelease: | 78 case ButtonRelease: |
62 return Event::ET_MOUSE_RELEASED; | 79 return Event::ET_MOUSE_RELEASED; |
63 case MotionNotify: | 80 case MotionNotify: |
64 if (xev->xmotion.state & (Button1Mask | Button2Mask | Button3Mask)) { | 81 if (xev->xmotion.state & (Button1Mask | Button2Mask | Button3Mask)) { |
65 return Event::ET_MOUSE_DRAGGED; | 82 return Event::ET_MOUSE_DRAGGED; |
66 } | 83 } |
67 return Event::ET_MOUSE_MOVED; | 84 return Event::ET_MOUSE_MOVED; |
| 85 #if defined(HAVE_XINPUT2) |
| 86 case GenericEvent: { |
| 87 XIDeviceEvent* xievent = |
| 88 static_cast<XIDeviceEvent*>(xev->xcookie.data); |
| 89 switch (xievent->evtype) { |
| 90 case XI_ButtonPress: |
| 91 return Event::ET_MOUSE_PRESSED; |
| 92 case XI_ButtonRelease: |
| 93 return Event::ET_MOUSE_RELEASED; |
| 94 case XI_Motion: |
| 95 return GetButtonMaskForX2Event(xievent) ? Event::ET_MOUSE_DRAGGED : |
| 96 Event::ET_MOUSE_MOVED; |
| 97 } |
| 98 } |
| 99 #endif |
68 } | 100 } |
69 | 101 |
70 return Event::ET_UNKNOWN; | 102 return Event::ET_UNKNOWN; |
71 } | 103 } |
72 | 104 |
73 gfx::Point GetMouseEventLocation(XEvent* xev) { | 105 gfx::Point GetMouseEventLocation(XEvent* xev) { |
74 switch (xev->type) { | 106 switch (xev->type) { |
75 case ButtonPress: | 107 case ButtonPress: |
76 case ButtonRelease: | 108 case ButtonRelease: |
77 return gfx::Point(xev->xbutton.x, xev->xbutton.y); | 109 return gfx::Point(xev->xbutton.x, xev->xbutton.y); |
78 | 110 |
79 case MotionNotify: | 111 case MotionNotify: |
80 return gfx::Point(xev->xmotion.x, xev->xmotion.y); | 112 return gfx::Point(xev->xmotion.x, xev->xmotion.y); |
| 113 |
| 114 #if defined(HAVE_XINPUT2) |
| 115 case GenericEvent: { |
| 116 XIDeviceEvent* xievent = |
| 117 static_cast<XIDeviceEvent*>(xev->xcookie.data); |
| 118 return gfx::Point(static_cast<int>(xievent->event_x), |
| 119 static_cast<int>(xievent->event_y)); |
| 120 } |
| 121 #endif |
81 } | 122 } |
82 | 123 |
83 return gfx::Point(); | 124 return gfx::Point(); |
84 } | 125 } |
85 | 126 |
86 int GetMouseEventFlags(XEvent* xev) { | 127 int GetMouseEventFlags(XEvent* xev) { |
87 switch (xev->type) { | 128 switch (xev->type) { |
88 case ButtonPress: | 129 case ButtonPress: |
89 case ButtonRelease: | 130 case ButtonRelease: |
90 return GetEventFlagsFromXState(xev->xbutton.state) | | 131 return GetEventFlagsFromXState(xev->xbutton.state) | |
91 GetEventFlagsForButton(xev->xbutton.button); | 132 GetEventFlagsForButton(xev->xbutton.button); |
92 | 133 |
93 case MotionNotify: | 134 case MotionNotify: |
94 return GetEventFlagsFromXState(xev->xmotion.state); | 135 return GetEventFlagsFromXState(xev->xmotion.state); |
| 136 |
| 137 #if defined(HAVE_XINPUT2) |
| 138 case GenericEvent: { |
| 139 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); |
| 140 switch (xievent->evtype) { |
| 141 case XI_ButtonPress: |
| 142 case XI_ButtonRelease: |
| 143 return GetButtonMaskForX2Event(xievent) | |
| 144 GetEventFlagsFromXState(xievent->mods.effective) | |
| 145 GetEventFlagsForButton(xievent->detail); |
| 146 |
| 147 case XI_Motion: |
| 148 return GetButtonMaskForX2Event(xievent) | |
| 149 GetEventFlagsFromXState(xievent->mods.effective); |
| 150 } |
| 151 } |
| 152 #endif |
95 } | 153 } |
96 | 154 |
97 return 0; | 155 return 0; |
98 } | 156 } |
99 | 157 |
100 } // namespace | 158 } // namespace |
101 | 159 |
102 KeyEvent::KeyEvent(XEvent* xev) | 160 KeyEvent::KeyEvent(XEvent* xev) |
103 : Event(xev->type == KeyPress ? | 161 : Event(xev->type == KeyPress ? |
104 Event::ET_KEY_PRESSED : Event::ET_KEY_RELEASED, | 162 Event::ET_KEY_PRESSED : Event::ET_KEY_RELEASED, |
105 GetEventFlagsFromXState(xev->xkey.state)), | 163 GetEventFlagsFromXState(xev->xkey.state)), |
106 key_code_(app::KeyboardCodeFromXKeyEvent(xev)), | 164 key_code_(app::KeyboardCodeFromXKeyEvent(xev)), |
107 repeat_count_(0), | 165 repeat_count_(0), |
108 message_flags_(0) { | 166 message_flags_(0) { |
109 } | 167 } |
110 | 168 |
111 MouseEvent::MouseEvent(XEvent* xev) | 169 MouseEvent::MouseEvent(XEvent* xev) |
112 : LocatedEvent(GetMouseEventType(xev), | 170 : LocatedEvent(GetMouseEventType(xev), |
113 GetMouseEventLocation(xev), | 171 GetMouseEventLocation(xev), |
114 GetMouseEventFlags(xev)) { | 172 GetMouseEventFlags(xev)) { |
115 } | 173 } |
116 | 174 |
117 } // namespace views | 175 } // namespace views |
OLD | NEW |