OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "aura/event.h" | |
6 | |
7 #include <X11/Xlib.h> | |
8 #include <X11/extensions/XInput2.h> | |
9 | |
10 #include "base/logging.h" | |
11 #include "ui/base/keycodes/keyboard_code_conversion_x.h" | |
12 | |
13 namespace aura { | |
14 | |
15 namespace { | |
16 | |
17 int GetEventFlagsFromXState(unsigned int state) { | |
18 int flags = 0; | |
19 if (state & ControlMask) | |
20 flags |= ui::EF_CONTROL_DOWN; | |
21 if (state & ShiftMask) | |
22 flags |= ui::EF_SHIFT_DOWN; | |
23 if (state & Mod1Mask) | |
24 flags |= ui::EF_ALT_DOWN; | |
25 if (state & LockMask) | |
26 flags |= ui::EF_CAPS_LOCK_DOWN; | |
27 if (state & Button1Mask) | |
28 flags |= ui::EF_LEFT_BUTTON_DOWN; | |
29 if (state & Button2Mask) | |
30 flags |= ui::EF_MIDDLE_BUTTON_DOWN; | |
31 if (state & Button3Mask) | |
32 flags |= ui::EF_RIGHT_BUTTON_DOWN; | |
33 | |
34 return flags; | |
35 } | |
36 | |
37 // Get the event flag for the button in XButtonEvent. During a ButtonPress | |
38 // event, |state| in XButtonEvent does not include the button that has just been | |
39 // pressed. Instead |state| contains flags for the buttons (if any) that had | |
40 // already been pressed before the current button, and |button| stores the most | |
41 // current pressed button. So, if you press down left mouse button, and while | |
42 // pressing it down, press down the right mouse button, then for the latter | |
43 // event, |state| would have Button1Mask set but not Button3Mask, and |button| | |
44 // would be 3. | |
45 int GetEventFlagsForButton(int button) { | |
46 switch (button) { | |
47 case 1: | |
48 return ui::EF_LEFT_BUTTON_DOWN; | |
49 case 2: | |
50 return ui::EF_MIDDLE_BUTTON_DOWN; | |
51 case 3: | |
52 return ui::EF_RIGHT_BUTTON_DOWN; | |
53 } | |
54 | |
55 DLOG(WARNING) << "Unexpected button (" << button << ") received."; | |
56 return 0; | |
57 } | |
58 | |
59 int GetButtonMaskForX2Event(XIDeviceEvent* xievent) { | |
60 int buttonflags = 0; | |
61 | |
62 for (int i = 0; i < 8 * xievent->buttons.mask_len; i++) { | |
63 if (XIMaskIsSet(xievent->buttons.mask, i)) { | |
64 buttonflags |= GetEventFlagsForButton(i); | |
65 } | |
66 } | |
67 | |
68 return buttonflags; | |
69 } | |
70 | |
71 ui::EventType EventTypeFromNative(NativeEvent native_event) { | |
72 switch (native_event->type) { | |
73 case KeyPress: | |
74 return ui::ET_KEY_PRESSED; | |
75 case KeyRelease: | |
76 return ui::ET_KEY_RELEASED; | |
77 case ButtonPress: | |
78 if (native_event->xbutton.button == 4 || | |
79 native_event->xbutton.button == 5) | |
80 return ui::ET_MOUSEWHEEL; | |
81 return ui::ET_MOUSE_PRESSED; | |
82 case ButtonRelease: | |
83 if (native_event->xbutton.button == 4 || | |
84 native_event->xbutton.button == 5) | |
85 return ui::ET_MOUSEWHEEL; | |
86 return ui::ET_MOUSE_RELEASED; | |
87 case MotionNotify: | |
88 if (native_event->xmotion.state & | |
89 (Button1Mask | Button2Mask | Button3Mask)) | |
90 return ui::ET_MOUSE_DRAGGED; | |
91 return ui::ET_MOUSE_MOVED; | |
92 case GenericEvent: { | |
93 XIDeviceEvent* xievent = | |
94 static_cast<XIDeviceEvent*>(native_event->xcookie.data); | |
95 // TODO(sad): Determine if sourceid is a touch device. | |
96 switch (xievent->evtype) { | |
97 case XI_ButtonPress: | |
98 return (xievent->detail == 4 || xievent->detail == 5) ? | |
99 ui::ET_MOUSEWHEEL : ui::ET_MOUSE_PRESSED; | |
100 case XI_ButtonRelease: | |
101 return (xievent->detail == 4 || xievent->detail == 5) ? | |
102 ui::ET_MOUSEWHEEL : ui::ET_MOUSE_RELEASED; | |
103 case XI_Motion: | |
104 return GetButtonMaskForX2Event(xievent) ? ui::ET_MOUSE_DRAGGED : | |
105 ui::ET_MOUSE_MOVED; | |
106 } | |
107 } | |
108 default: | |
109 NOTREACHED(); | |
110 break; | |
111 } | |
112 return ui::ET_UNKNOWN; | |
113 } | |
114 | |
115 gfx::Point GetEventLocation(XEvent* xev) { | |
116 switch (xev->type) { | |
117 case ButtonPress: | |
118 case ButtonRelease: | |
119 return gfx::Point(xev->xbutton.x, xev->xbutton.y); | |
120 | |
121 case MotionNotify: | |
122 return gfx::Point(xev->xmotion.x, xev->xmotion.y); | |
123 | |
124 case GenericEvent: { | |
125 XIDeviceEvent* xievent = | |
126 static_cast<XIDeviceEvent*>(xev->xcookie.data); | |
127 return gfx::Point(static_cast<int>(xievent->event_x), | |
128 static_cast<int>(xievent->event_y)); | |
129 } | |
130 } | |
131 | |
132 return gfx::Point(); | |
133 } | |
134 | |
135 int GetLocatedEventFlags(XEvent* xev) { | |
136 switch (xev->type) { | |
137 case ButtonPress: | |
138 case ButtonRelease: | |
139 return GetEventFlagsFromXState(xev->xbutton.state) | | |
140 GetEventFlagsForButton(xev->xbutton.button); | |
141 | |
142 case MotionNotify: | |
143 return GetEventFlagsFromXState(xev->xmotion.state); | |
144 | |
145 case GenericEvent: { | |
146 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); | |
147 bool touch = false; // TODO(sad): Determine if xievent->sourceid is a | |
148 // touch device. | |
149 switch (xievent->evtype) { | |
150 case XI_ButtonPress: | |
151 case XI_ButtonRelease: | |
152 return GetButtonMaskForX2Event(xievent) | | |
153 GetEventFlagsFromXState(xievent->mods.effective) | | |
154 (touch ? 0 : GetEventFlagsForButton(xievent->detail)); | |
155 | |
156 case XI_Motion: | |
157 return GetButtonMaskForX2Event(xievent) | | |
158 GetEventFlagsFromXState(xievent->mods.effective); | |
159 } | |
160 } | |
161 } | |
162 | |
163 return 0; | |
164 } | |
165 | |
166 } // namespace | |
167 | |
168 void Event::Init() { | |
169 memset(&native_event_, 0, sizeof(native_event_)); | |
170 } | |
171 | |
172 void Event::InitWithNativeEvent(NativeEvent native_event) { | |
173 native_event_ = native_event; | |
174 } | |
175 | |
176 LocatedEvent::LocatedEvent(NativeEvent native_event) | |
177 : Event(native_event, EventTypeFromNative(native_event), | |
178 GetLocatedEventFlags(native_event)), | |
179 location_(GetEventLocation(native_event)) { | |
180 } | |
181 | |
182 MouseEvent::MouseEvent(NativeEvent native_event) | |
183 : LocatedEvent(native_event) { | |
184 } | |
185 | |
186 KeyEvent::KeyEvent(NativeEvent native_event) | |
187 : Event(native_event, | |
188 EventTypeFromNative(native_event), | |
189 GetEventFlagsFromXState(native_event->xbutton.state)), | |
190 key_code_(ui::KeyboardCodeFromXKeyEvent(native_event)) { | |
191 } | |
192 | |
193 } // namespace aura | |
OLD | NEW |