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 "views/events/event.h" | 5 #include "views/events/event.h" |
6 | 6 |
7 #include <gdk/gdk.h> | 7 #include <gdk/gdk.h> |
8 #include <gdk/gdkx.h> | 8 #include <gdk/gdkx.h> |
9 #if defined(HAVE_XINPUT2) | |
10 #include <X11/extensions/XInput2.h> | 9 #include <X11/extensions/XInput2.h> |
11 #endif | |
12 #include <X11/Xlib.h> | |
13 | 10 |
14 #include "base/logging.h" | 11 #include "base/logging.h" |
15 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
16 #include "ui/base/keycodes/keyboard_code_conversion_x.h" | 13 #include "ui/base/keycodes/keyboard_code_conversion_x.h" |
| 14 #include "views/touchui/touch_factory.h" |
17 #include "views/widget/root_view.h" | 15 #include "views/widget/root_view.h" |
18 | 16 |
19 #if defined(HAVE_XINPUT2) | |
20 #include "views/touchui/touch_factory.h" | |
21 #endif | |
22 | |
23 namespace views { | 17 namespace views { |
24 | 18 |
25 namespace { | 19 namespace { |
26 | 20 |
27 // Scroll amount for each wheelscroll event. 53 is also the value used for GTK+. | 21 // Scroll amount for each wheelscroll event. 53 is also the value used for GTK+. |
28 static int kWheelScrollAmount = 53; | 22 static int kWheelScrollAmount = 53; |
29 | 23 |
30 int GetEventFlagsFromXState(unsigned int state) { | 24 int GetEventFlagsFromXState(unsigned int state) { |
31 int flags = 0; | 25 int flags = 0; |
32 if (state & ControlMask) | 26 if (state & ControlMask) |
(...skipping 29 matching lines...) Expand all Loading... |
62 case 2: | 56 case 2: |
63 return ui::EF_MIDDLE_BUTTON_DOWN; | 57 return ui::EF_MIDDLE_BUTTON_DOWN; |
64 case 3: | 58 case 3: |
65 return ui::EF_RIGHT_BUTTON_DOWN; | 59 return ui::EF_RIGHT_BUTTON_DOWN; |
66 } | 60 } |
67 | 61 |
68 DLOG(WARNING) << "Unexpected button (" << button << ") received."; | 62 DLOG(WARNING) << "Unexpected button (" << button << ") received."; |
69 return 0; | 63 return 0; |
70 } | 64 } |
71 | 65 |
72 #if defined(HAVE_XINPUT2) | |
73 int GetButtonMaskForX2Event(XIDeviceEvent* xievent) { | 66 int GetButtonMaskForX2Event(XIDeviceEvent* xievent) { |
74 int buttonflags = 0; | 67 int buttonflags = 0; |
75 | 68 |
76 for (int i = 0; i < 8 * xievent->buttons.mask_len; i++) { | 69 for (int i = 0; i < 8 * xievent->buttons.mask_len; i++) { |
77 if (XIMaskIsSet(xievent->buttons.mask, i)) { | 70 if (XIMaskIsSet(xievent->buttons.mask, i)) { |
78 buttonflags |= GetEventFlagsForButton(i); | 71 buttonflags |= GetEventFlagsForButton(i); |
79 } | 72 } |
80 } | 73 } |
81 | 74 |
82 return buttonflags; | 75 return buttonflags; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 } | 107 } |
115 | 108 |
116 int GetTouchIDFromXEvent(XEvent* xev) { | 109 int GetTouchIDFromXEvent(XEvent* xev) { |
117 float slot = 0; | 110 float slot = 0; |
118 if (!TouchFactory::GetInstance()->ExtractTouchParam( | 111 if (!TouchFactory::GetInstance()->ExtractTouchParam( |
119 *xev, TouchFactory::TP_SLOT_ID, &slot)) | 112 *xev, TouchFactory::TP_SLOT_ID, &slot)) |
120 LOG(ERROR) << "Could not get the slot ID for the event. Using 0."; | 113 LOG(ERROR) << "Could not get the slot ID for the event. Using 0."; |
121 return slot; | 114 return slot; |
122 } | 115 } |
123 | 116 |
124 #endif // HAVE_XINPUT2 | |
125 | |
126 ui::EventType EventTypeFromNative(NativeEvent2 native_event) { | 117 ui::EventType EventTypeFromNative(NativeEvent2 native_event) { |
127 switch (native_event->type) { | 118 switch (native_event->type) { |
128 case KeyPress: | 119 case KeyPress: |
129 return ui::ET_KEY_PRESSED; | 120 return ui::ET_KEY_PRESSED; |
130 case KeyRelease: | 121 case KeyRelease: |
131 return ui::ET_KEY_RELEASED; | 122 return ui::ET_KEY_RELEASED; |
132 case ButtonPress: | 123 case ButtonPress: |
133 if (native_event->xbutton.button == 4 || | 124 if (native_event->xbutton.button == 4 || |
134 native_event->xbutton.button == 5) | 125 native_event->xbutton.button == 5) |
135 return ui::ET_MOUSEWHEEL; | 126 return ui::ET_MOUSEWHEEL; |
136 return ui::ET_MOUSE_PRESSED; | 127 return ui::ET_MOUSE_PRESSED; |
137 case ButtonRelease: | 128 case ButtonRelease: |
138 if (native_event->xbutton.button == 4 || | 129 if (native_event->xbutton.button == 4 || |
139 native_event->xbutton.button == 5) | 130 native_event->xbutton.button == 5) |
140 return ui::ET_MOUSEWHEEL; | 131 return ui::ET_MOUSEWHEEL; |
141 return ui::ET_MOUSE_RELEASED; | 132 return ui::ET_MOUSE_RELEASED; |
142 case MotionNotify: | 133 case MotionNotify: |
143 if (native_event->xmotion.state & | 134 if (native_event->xmotion.state & |
144 (Button1Mask | Button2Mask | Button3Mask)) | 135 (Button1Mask | Button2Mask | Button3Mask)) |
145 return ui::ET_MOUSE_DRAGGED; | 136 return ui::ET_MOUSE_DRAGGED; |
146 return ui::ET_MOUSE_MOVED; | 137 return ui::ET_MOUSE_MOVED; |
147 #if defined(HAVE_XINPUT2) | |
148 case GenericEvent: { | 138 case GenericEvent: { |
149 XIDeviceEvent* xievent = | 139 XIDeviceEvent* xievent = |
150 static_cast<XIDeviceEvent*>(native_event->xcookie.data); | 140 static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
151 if (TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid)) | 141 if (TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid)) |
152 return GetTouchEventType(native_event); | 142 return GetTouchEventType(native_event); |
153 switch (xievent->evtype) { | 143 switch (xievent->evtype) { |
154 case XI_ButtonPress: | 144 case XI_ButtonPress: |
155 return (xievent->detail == 4 || xievent->detail == 5) ? | 145 return (xievent->detail == 4 || xievent->detail == 5) ? |
156 ui::ET_MOUSEWHEEL : ui::ET_MOUSE_PRESSED; | 146 ui::ET_MOUSEWHEEL : ui::ET_MOUSE_PRESSED; |
157 case XI_ButtonRelease: | 147 case XI_ButtonRelease: |
158 return (xievent->detail == 4 || xievent->detail == 5) ? | 148 return (xievent->detail == 4 || xievent->detail == 5) ? |
159 ui::ET_MOUSEWHEEL : ui::ET_MOUSE_RELEASED; | 149 ui::ET_MOUSEWHEEL : ui::ET_MOUSE_RELEASED; |
160 case XI_Motion: | 150 case XI_Motion: |
161 return GetButtonMaskForX2Event(xievent) ? ui::ET_MOUSE_DRAGGED : | 151 return GetButtonMaskForX2Event(xievent) ? ui::ET_MOUSE_DRAGGED : |
162 ui::ET_MOUSE_MOVED; | 152 ui::ET_MOUSE_MOVED; |
163 } | 153 } |
164 } | 154 } |
165 #endif | |
166 default: | 155 default: |
167 NOTREACHED(); | 156 NOTREACHED(); |
168 break; | 157 break; |
169 } | 158 } |
170 return ui::ET_UNKNOWN; | 159 return ui::ET_UNKNOWN; |
171 } | 160 } |
172 | 161 |
173 int GetMouseWheelOffset(XEvent* xev) { | 162 int GetMouseWheelOffset(XEvent* xev) { |
174 #if defined(HAVE_XINPUT2) | |
175 if (xev->type == GenericEvent) { | 163 if (xev->type == GenericEvent) { |
176 XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev->xcookie.data); | 164 XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev->xcookie.data); |
177 return xiev->detail == 4 ? kWheelScrollAmount : -kWheelScrollAmount; | 165 return xiev->detail == 4 ? kWheelScrollAmount : -kWheelScrollAmount; |
178 } | 166 } |
179 #endif | |
180 return xev->xbutton.button == 4 ? kWheelScrollAmount : -kWheelScrollAmount; | 167 return xev->xbutton.button == 4 ? kWheelScrollAmount : -kWheelScrollAmount; |
181 } | 168 } |
182 | 169 |
183 gfx::Point GetEventLocation(XEvent* xev) { | 170 gfx::Point GetEventLocation(XEvent* xev) { |
184 switch (xev->type) { | 171 switch (xev->type) { |
185 case ButtonPress: | 172 case ButtonPress: |
186 case ButtonRelease: | 173 case ButtonRelease: |
187 return gfx::Point(xev->xbutton.x, xev->xbutton.y); | 174 return gfx::Point(xev->xbutton.x, xev->xbutton.y); |
188 | 175 |
189 case MotionNotify: | 176 case MotionNotify: |
190 return gfx::Point(xev->xmotion.x, xev->xmotion.y); | 177 return gfx::Point(xev->xmotion.x, xev->xmotion.y); |
191 | 178 |
192 #if defined(HAVE_XINPUT2) | |
193 case GenericEvent: { | 179 case GenericEvent: { |
194 XIDeviceEvent* xievent = | 180 XIDeviceEvent* xievent = |
195 static_cast<XIDeviceEvent*>(xev->xcookie.data); | 181 static_cast<XIDeviceEvent*>(xev->xcookie.data); |
196 return gfx::Point(static_cast<int>(xievent->event_x), | 182 return gfx::Point(static_cast<int>(xievent->event_x), |
197 static_cast<int>(xievent->event_y)); | 183 static_cast<int>(xievent->event_y)); |
198 } | 184 } |
199 #endif | |
200 } | 185 } |
201 | 186 |
202 return gfx::Point(); | 187 return gfx::Point(); |
203 } | 188 } |
204 | 189 |
205 int GetLocatedEventFlags(XEvent* xev) { | 190 int GetLocatedEventFlags(XEvent* xev) { |
206 switch (xev->type) { | 191 switch (xev->type) { |
207 case ButtonPress: | 192 case ButtonPress: |
208 case ButtonRelease: | 193 case ButtonRelease: |
209 return GetEventFlagsFromXState(xev->xbutton.state) | | 194 return GetEventFlagsFromXState(xev->xbutton.state) | |
210 GetEventFlagsForButton(xev->xbutton.button); | 195 GetEventFlagsForButton(xev->xbutton.button); |
211 | 196 |
212 case MotionNotify: | 197 case MotionNotify: |
213 return GetEventFlagsFromXState(xev->xmotion.state); | 198 return GetEventFlagsFromXState(xev->xmotion.state); |
214 | 199 |
215 #if defined(HAVE_XINPUT2) | |
216 case GenericEvent: { | 200 case GenericEvent: { |
217 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); | 201 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); |
218 bool touch = | 202 bool touch = |
219 TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid); | 203 TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid); |
220 switch (xievent->evtype) { | 204 switch (xievent->evtype) { |
221 case XI_ButtonPress: | 205 case XI_ButtonPress: |
222 case XI_ButtonRelease: | 206 case XI_ButtonRelease: |
223 return GetButtonMaskForX2Event(xievent) | | 207 return GetButtonMaskForX2Event(xievent) | |
224 GetEventFlagsFromXState(xievent->mods.effective) | | 208 GetEventFlagsFromXState(xievent->mods.effective) | |
225 (touch ? 0 : GetEventFlagsForButton(xievent->detail)); | 209 (touch ? 0 : GetEventFlagsForButton(xievent->detail)); |
226 | 210 |
227 case XI_Motion: | 211 case XI_Motion: |
228 return GetButtonMaskForX2Event(xievent) | | 212 return GetButtonMaskForX2Event(xievent) | |
229 GetEventFlagsFromXState(xievent->mods.effective); | 213 GetEventFlagsFromXState(xievent->mods.effective); |
230 } | 214 } |
231 } | 215 } |
232 #endif | |
233 } | 216 } |
234 | 217 |
235 return 0; | 218 return 0; |
236 } | 219 } |
237 | 220 |
238 uint16 GetCharacterFromXKeyEvent(XKeyEvent* key) { | 221 uint16 GetCharacterFromXKeyEvent(XKeyEvent* key) { |
239 char buf[6]; | 222 char buf[6]; |
240 int bytes_written = XLookupString(key, buf, 6, NULL, NULL); | 223 int bytes_written = XLookupString(key, buf, 6, NULL, NULL); |
241 DCHECK_LE(bytes_written, 6); | 224 DCHECK_LE(bytes_written, 6); |
242 | 225 |
243 string16 result; | 226 string16 result; |
244 return (bytes_written > 0 && UTF8ToUTF16(buf, bytes_written, &result) && | 227 return (bytes_written > 0 && UTF8ToUTF16(buf, bytes_written, &result) && |
245 result.length() == 1) ? result[0] : 0; | 228 result.length() == 1) ? result[0] : 0; |
246 } | 229 } |
247 | 230 |
248 float GetTouchRadiusFromXEvent(XEvent* xev) { | 231 float GetTouchRadiusFromXEvent(XEvent* xev) { |
249 float diameter = 0.0; | 232 float diameter = 0.0; |
250 | |
251 #if defined(HAVE_XINPUT2) | |
252 TouchFactory* touch_factory = TouchFactory::GetInstance(); | 233 TouchFactory* touch_factory = TouchFactory::GetInstance(); |
253 touch_factory->ExtractTouchParam(*xev, TouchFactory::TP_TOUCH_MAJOR, | 234 touch_factory->ExtractTouchParam(*xev, TouchFactory::TP_TOUCH_MAJOR, |
254 &diameter); | 235 &diameter); |
255 #endif | |
256 | |
257 return diameter / 2.0; | 236 return diameter / 2.0; |
258 } | 237 } |
259 | 238 |
260 float GetTouchAngleFromXEvent(XEvent* xev) { | 239 float GetTouchAngleFromXEvent(XEvent* xev) { |
261 float angle = 0.0; | 240 float angle = 0.0; |
262 | |
263 #if defined(HAVE_XINPUT2) | |
264 TouchFactory* touch_factory = TouchFactory::GetInstance(); | 241 TouchFactory* touch_factory = TouchFactory::GetInstance(); |
265 touch_factory->ExtractTouchParam(*xev, TouchFactory::TP_ORIENTATION, | 242 touch_factory->ExtractTouchParam(*xev, TouchFactory::TP_ORIENTATION, |
266 &angle); | 243 &angle); |
267 #endif | |
268 | |
269 return angle; | 244 return angle; |
270 } | 245 } |
271 | 246 |
272 | 247 |
273 float GetTouchRatioFromXEvent(XEvent* xev) { | 248 float GetTouchRatioFromXEvent(XEvent* xev) { |
274 float ratio = 1.0; | 249 float ratio = 1.0; |
275 | |
276 #if defined(HAVE_XINPUT2) | |
277 TouchFactory* touch_factory = TouchFactory::GetInstance(); | 250 TouchFactory* touch_factory = TouchFactory::GetInstance(); |
278 float major_v = -1.0; | 251 float major_v = -1.0; |
279 float minor_v = -1.0; | 252 float minor_v = -1.0; |
280 | 253 |
281 if (!touch_factory->ExtractTouchParam(*xev, | 254 if (!touch_factory->ExtractTouchParam(*xev, |
282 TouchFactory::TP_TOUCH_MAJOR, | 255 TouchFactory::TP_TOUCH_MAJOR, |
283 &major_v) || | 256 &major_v) || |
284 !touch_factory->ExtractTouchParam(*xev, | 257 !touch_factory->ExtractTouchParam(*xev, |
285 TouchFactory::TP_TOUCH_MINOR, | 258 TouchFactory::TP_TOUCH_MINOR, |
286 &minor_v)) | 259 &minor_v)) |
287 return ratio; | 260 return ratio; |
288 | 261 |
289 // In case minor axis exists but is zero. | 262 // In case minor axis exists but is zero. |
290 if (minor_v > 0.0) | 263 if (minor_v > 0.0) |
291 ratio = major_v / minor_v; | 264 ratio = major_v / minor_v; |
292 #endif | |
293 | 265 |
294 return ratio; | 266 return ratio; |
295 } | 267 } |
296 | 268 |
297 } // namespace | 269 } // namespace |
298 | 270 |
299 //////////////////////////////////////////////////////////////////////////////// | 271 //////////////////////////////////////////////////////////////////////////////// |
300 // Event, private: | 272 // Event, private: |
301 | 273 |
302 void Event::InitWithNativeEvent2(NativeEvent2 native_event_2, | 274 void Event::InitWithNativeEvent2(NativeEvent2 native_event_2, |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 | 381 |
410 MouseWheelEvent::MouseWheelEvent(NativeEvent2 native_event_2, | 382 MouseWheelEvent::MouseWheelEvent(NativeEvent2 native_event_2, |
411 FromNativeEvent2 from_native) | 383 FromNativeEvent2 from_native) |
412 : MouseEvent(native_event_2, from_native), | 384 : MouseEvent(native_event_2, from_native), |
413 offset_(GetMouseWheelOffset(native_event_2)) { | 385 offset_(GetMouseWheelOffset(native_event_2)) { |
414 } | 386 } |
415 | 387 |
416 //////////////////////////////////////////////////////////////////////////////// | 388 //////////////////////////////////////////////////////////////////////////////// |
417 // TouchEvent, public: | 389 // TouchEvent, public: |
418 | 390 |
419 #if defined(HAVE_XINPUT2) | |
420 TouchEvent::TouchEvent(NativeEvent2 native_event_2, | 391 TouchEvent::TouchEvent(NativeEvent2 native_event_2, |
421 FromNativeEvent2 from_native) | 392 FromNativeEvent2 from_native) |
422 : LocatedEvent(native_event_2, from_native), | 393 : LocatedEvent(native_event_2, from_native), |
423 touch_id_(GetTouchIDFromXEvent(native_event_2)), | 394 touch_id_(GetTouchIDFromXEvent(native_event_2)), |
424 radius_(GetTouchRadiusFromXEvent(native_event_2)), | 395 radius_(GetTouchRadiusFromXEvent(native_event_2)), |
425 angle_(GetTouchAngleFromXEvent(native_event_2)), | 396 angle_(GetTouchAngleFromXEvent(native_event_2)), |
426 ratio_(GetTouchRatioFromXEvent(native_event_2)) { | 397 ratio_(GetTouchRatioFromXEvent(native_event_2)) { |
427 if (type() == ui::ET_TOUCH_PRESSED || type() == ui::ET_TOUCH_RELEASED) { | 398 if (type() == ui::ET_TOUCH_PRESSED || type() == ui::ET_TOUCH_RELEASED) { |
428 TouchFactory* factory = TouchFactory::GetInstance(); | 399 TouchFactory* factory = TouchFactory::GetInstance(); |
429 float slot; | 400 float slot; |
430 if (factory->ExtractTouchParam(*native_event_2, | 401 if (factory->ExtractTouchParam(*native_event_2, |
431 TouchFactory::TP_SLOT_ID, &slot)) { | 402 TouchFactory::TP_SLOT_ID, &slot)) { |
432 factory->SetSlotUsed(slot, type() == ui::ET_TOUCH_PRESSED); | 403 factory->SetSlotUsed(slot, type() == ui::ET_TOUCH_PRESSED); |
433 } | 404 } |
434 } | 405 } |
435 } | 406 } |
436 #endif | |
437 | 407 |
438 } // namespace views | 408 } // namespace views |
OLD | NEW |