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