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 "ui/base/events.h" | 5 #include "ui/base/events.h" |
6 | 6 |
7 #include <X11/Xlib.h> | 7 #include <X11/Xlib.h> |
8 #include <X11/extensions/XInput2.h> | 8 #include <X11/extensions/XInput2.h> |
9 #include <string.h> | 9 #include <string.h> |
10 | 10 |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "ui/base/keycodes/keyboard_code_conversion_x.h" | 12 #include "ui/base/keycodes/keyboard_code_conversion_x.h" |
13 #include "ui/base/touch/touch_factory.h" | 13 #include "ui/base/touch/touch_factory.h" |
14 #include "ui/base/x/x11_util.h" | |
14 #include "ui/gfx/point.h" | 15 #include "ui/gfx/point.h" |
15 | 16 |
16 #if !defined(TOOLKIT_USES_GTK) | 17 #if !defined(TOOLKIT_USES_GTK) |
17 #include "base/message_pump_x.h" | 18 #include "base/message_pump_x.h" |
18 #endif | 19 #endif |
19 | 20 |
20 namespace { | 21 namespace { |
21 | 22 |
22 // Scroll amount for each wheelscroll event. 53 is also the value used for GTK+. | 23 // Scroll amount for each wheelscroll event. 53 is also the value used for GTK+. |
23 static const int kWheelScrollAmount = 53; | 24 static const int kWheelScrollAmount = 53; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
63 return ui::EF_LEFT_BUTTON_DOWN; | 64 return ui::EF_LEFT_BUTTON_DOWN; |
64 case 2: | 65 case 2: |
65 return ui::EF_MIDDLE_BUTTON_DOWN; | 66 return ui::EF_MIDDLE_BUTTON_DOWN; |
66 case 3: | 67 case 3: |
67 return ui::EF_RIGHT_BUTTON_DOWN; | 68 return ui::EF_RIGHT_BUTTON_DOWN; |
68 default: | 69 default: |
69 return 0; | 70 return 0; |
70 } | 71 } |
71 } | 72 } |
72 | 73 |
74 int GetMappedButton(int button) { | |
75 static unsigned char map[256]; | |
76 static int count = 0; | |
77 if (!count) | |
78 count = XGetPointerMapping(ui::GetXDisplay(), map, arraysize(map)); | |
Daniel Erat
2011/12/04 15:51:45
i think that you need to refresh the cached copy o
sadrul
2011/12/07 16:36:12
Indeed. I thought about it, and assumed perhaps th
| |
79 return button > 0 && button <= count ? map[button - 1] : button; | |
80 } | |
81 | |
73 int GetButtonMaskForX2Event(XIDeviceEvent* xievent) { | 82 int GetButtonMaskForX2Event(XIDeviceEvent* xievent) { |
74 int buttonflags = 0; | 83 int buttonflags = 0; |
75 for (int i = 0; i < 8 * xievent->buttons.mask_len; i++) { | 84 for (int i = 0; i < 8 * xievent->buttons.mask_len; i++) { |
76 if (XIMaskIsSet(xievent->buttons.mask, i)) { | 85 if (XIMaskIsSet(xievent->buttons.mask, i)) { |
77 buttonflags |= GetEventFlagsForButton(i); | 86 int button = (xievent->sourceid == xievent->deviceid) ? |
87 GetMappedButton(i) : i; | |
Daniel Erat
2011/12/04 15:51:45
nit: indent one less space?
sadrul
2011/12/07 17:06:52
Done.
| |
88 buttonflags |= GetEventFlagsForButton(button); | |
78 } | 89 } |
79 } | 90 } |
80 return buttonflags; | 91 return buttonflags; |
81 } | 92 } |
82 | 93 |
83 ui::EventType GetTouchEventType(const base::NativeEvent& native_event) { | 94 ui::EventType GetTouchEventType(const base::NativeEvent& native_event) { |
84 XIDeviceEvent* event = | 95 XIDeviceEvent* event = |
85 static_cast<XIDeviceEvent*>(native_event->xcookie.data); | 96 static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
86 #if defined(USE_XI2_MT) | 97 #if defined(USE_XI2_MT) |
87 switch(event->evtype) { | 98 switch(event->evtype) { |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
178 return ET_MOUSE_MOVED; | 189 return ET_MOUSE_MOVED; |
179 case EnterNotify: | 190 case EnterNotify: |
180 return ET_MOUSE_ENTERED; | 191 return ET_MOUSE_ENTERED; |
181 case LeaveNotify: | 192 case LeaveNotify: |
182 return ET_MOUSE_EXITED; | 193 return ET_MOUSE_EXITED; |
183 case GenericEvent: { | 194 case GenericEvent: { |
184 XIDeviceEvent* xievent = | 195 XIDeviceEvent* xievent = |
185 static_cast<XIDeviceEvent*>(native_event->xcookie.data); | 196 static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
186 if (TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid)) | 197 if (TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid)) |
187 return GetTouchEventType(native_event); | 198 return GetTouchEventType(native_event); |
199 int button = EventButtonFromNative(native_event); | |
188 switch (xievent->evtype) { | 200 switch (xievent->evtype) { |
189 case XI_ButtonPress: | 201 case XI_ButtonPress: |
190 if (xievent->detail >= kMinWheelButton && | 202 if (button >= kMinWheelButton && |
191 xievent->detail <= kMaxWheelButton) | 203 button <= kMaxWheelButton) |
192 return ET_MOUSEWHEEL; | 204 return ET_MOUSEWHEEL; |
193 return ET_MOUSE_PRESSED; | 205 return ET_MOUSE_PRESSED; |
194 case XI_ButtonRelease: | 206 case XI_ButtonRelease: |
195 if (xievent->detail >= kMinWheelButton && | 207 if (button >= kMinWheelButton && |
196 xievent->detail <= kMaxWheelButton) | 208 button <= kMaxWheelButton) |
197 return ET_MOUSEWHEEL; | 209 return ET_MOUSEWHEEL; |
198 return ET_MOUSE_RELEASED; | 210 return ET_MOUSE_RELEASED; |
199 case XI_Motion: | 211 case XI_Motion: |
200 return GetButtonMaskForX2Event(xievent) ? | 212 return GetButtonMaskForX2Event(xievent) ? |
201 ET_MOUSE_DRAGGED : ET_MOUSE_MOVED; | 213 ET_MOUSE_DRAGGED : ET_MOUSE_MOVED; |
202 } | 214 } |
203 } | 215 } |
204 default: | 216 default: |
205 break; | 217 break; |
206 } | 218 } |
(...skipping 19 matching lines...) Expand all Loading... | |
226 XIDeviceEvent* xievent = | 238 XIDeviceEvent* xievent = |
227 static_cast<XIDeviceEvent*>(native_event->xcookie.data); | 239 static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
228 const bool touch = | 240 const bool touch = |
229 TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid); | 241 TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid); |
230 switch (xievent->evtype) { | 242 switch (xievent->evtype) { |
231 case XI_ButtonPress: | 243 case XI_ButtonPress: |
232 case XI_ButtonRelease: { | 244 case XI_ButtonRelease: { |
233 int flags = GetButtonMaskForX2Event(xievent) | | 245 int flags = GetButtonMaskForX2Event(xievent) | |
234 GetEventFlagsFromXState(xievent->mods.effective); | 246 GetEventFlagsFromXState(xievent->mods.effective); |
235 const EventType type = EventTypeFromNative(native_event); | 247 const EventType type = EventTypeFromNative(native_event); |
248 int button = EventButtonFromNative(native_event); | |
236 if ((type == ET_MOUSE_PRESSED || type == ET_MOUSE_RELEASED) && !touch) | 249 if ((type == ET_MOUSE_PRESSED || type == ET_MOUSE_RELEASED) && !touch) |
237 flags |= GetEventFlagsForButton(xievent->detail); | 250 flags |= GetEventFlagsForButton(button); |
238 return flags; | 251 return flags; |
239 } | 252 } |
240 case XI_Motion: | 253 case XI_Motion: |
241 return GetButtonMaskForX2Event(xievent) | | 254 return GetButtonMaskForX2Event(xievent) | |
242 GetEventFlagsFromXState(xievent->mods.effective); | 255 GetEventFlagsFromXState(xievent->mods.effective); |
243 } | 256 } |
244 } | 257 } |
245 } | 258 } |
246 return 0; | 259 return 0; |
247 } | 260 } |
(...skipping 26 matching lines...) Expand all Loading... | |
274 double y = xievent->event_y; | 287 double y = xievent->event_y; |
275 if (XIMaskIsSet(xievent->valuators.mask, 1)) | 288 if (XIMaskIsSet(xievent->valuators.mask, 1)) |
276 y = *valuators++ - (xievent->root_y - xievent->event_y); | 289 y = *valuators++ - (xievent->root_y - xievent->event_y); |
277 | 290 |
278 return gfx::Point(static_cast<int>(x), static_cast<int>(y)); | 291 return gfx::Point(static_cast<int>(x), static_cast<int>(y)); |
279 } | 292 } |
280 } | 293 } |
281 return gfx::Point(); | 294 return gfx::Point(); |
282 } | 295 } |
283 | 296 |
297 int EventButtonFromNative(const base::NativeEvent& native_event) { | |
298 CHECK_EQ(GenericEvent, native_event->type); | |
299 XIDeviceEvent* xievent = | |
300 static_cast<XIDeviceEvent*>(native_event->xcookie.data); | |
301 int button = xievent->detail; | |
302 | |
303 return (xievent->sourceid == xievent->deviceid) ? | |
304 GetMappedButton(button) : button; | |
Daniel Erat
2011/12/04 15:51:45
nit: indent one less space?
sadrul
2011/12/07 17:06:52
Done.
| |
305 } | |
306 | |
284 KeyboardCode KeyboardCodeFromNative(const base::NativeEvent& native_event) { | 307 KeyboardCode KeyboardCodeFromNative(const base::NativeEvent& native_event) { |
285 return KeyboardCodeFromXKeyEvent(native_event); | 308 return KeyboardCodeFromXKeyEvent(native_event); |
286 } | 309 } |
287 | 310 |
288 bool IsMouseEvent(const base::NativeEvent& native_event) { | 311 bool IsMouseEvent(const base::NativeEvent& native_event) { |
289 if (native_event->type == ButtonPress || | 312 if (native_event->type == ButtonPress || |
290 native_event->type == ButtonRelease || | 313 native_event->type == ButtonRelease || |
291 native_event->type == MotionNotify) | 314 native_event->type == MotionNotify) |
292 return true; | 315 return true; |
293 if (native_event->type == GenericEvent) { | 316 if (native_event->type == GenericEvent) { |
294 XIDeviceEvent* xievent = | 317 XIDeviceEvent* xievent = |
295 static_cast<XIDeviceEvent*>(native_event->xcookie.data); | 318 static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
296 return xievent->evtype == XI_ButtonPress || | 319 return xievent->evtype == XI_ButtonPress || |
297 xievent->evtype == XI_ButtonRelease || | 320 xievent->evtype == XI_ButtonRelease || |
298 xievent->evtype == XI_Motion; | 321 xievent->evtype == XI_Motion; |
299 } | 322 } |
300 return false; | 323 return false; |
301 } | 324 } |
302 | 325 |
303 int GetMouseWheelOffset(const base::NativeEvent& native_event) { | 326 int GetMouseWheelOffset(const base::NativeEvent& native_event) { |
304 int button; | 327 int button; |
305 if (native_event->type == GenericEvent) { | 328 if (native_event->type == GenericEvent) |
306 XIDeviceEvent* xiev = | 329 button = EventButtonFromNative(native_event); |
307 static_cast<XIDeviceEvent*>(native_event->xcookie.data); | 330 else |
308 button = xiev->detail; | |
309 } else { | |
310 button = native_event->xbutton.button; | 331 button = native_event->xbutton.button; |
311 } | |
312 switch (button) { | 332 switch (button) { |
313 case 4: | 333 case 4: |
314 #if defined(OS_CHROMEOS) | 334 #if defined(OS_CHROMEOS) |
315 case 8: | 335 case 8: |
316 #endif | 336 #endif |
317 return kWheelScrollAmount; | 337 return kWheelScrollAmount; |
318 | 338 |
319 case 5: | 339 case 5: |
320 #if defined(OS_CHROMEOS) | 340 #if defined(OS_CHROMEOS) |
321 case 9: | 341 case 9: |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
398 // Make sure we use atom from current xdisplay, which may | 418 // Make sure we use atom from current xdisplay, which may |
399 // change during the test. | 419 // change during the test. |
400 noop->xclient.message_type = XInternAtom( | 420 noop->xclient.message_type = XInternAtom( |
401 base::MessagePumpX::GetDefaultXDisplay(), | 421 base::MessagePumpX::GetDefaultXDisplay(), |
402 "noop", False); | 422 "noop", False); |
403 #endif | 423 #endif |
404 return noop; | 424 return noop; |
405 } | 425 } |
406 | 426 |
407 } // namespace ui | 427 } // namespace ui |
OLD | NEW |