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