OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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 "ui/events/platform/x11/x11_event_source.h" | |
6 | |
7 #include <X11/Xlib.h> | |
8 #include <X11/extensions/XInput2.h> | |
9 | |
10 #include "ui/events/event.h" | |
11 #include "ui/events/keycodes/keyboard_code_conversion_x.h" | |
12 #include "ui/events/platform/platform_event_dispatcher.h" | |
13 #include "ui/events/x/events_x_utils.h" | |
14 | |
15 namespace ui { | |
16 | |
17 namespace { | |
18 | |
19 // Translates XI2 XEvent into a ui::Event. | |
20 ui::Event* TranslateXI2EventToEvent(const XEvent& xev) { | |
21 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev.xcookie.data); | |
22 EventType event_type = EventTypeFromXEvent(xev); | |
23 gfx::Point location = gfx::Point(xievent->event_x, xievent->event_y); | |
24 gfx::Point root_location = gfx::Point(xievent->root_x, xievent->root_y); | |
25 int flags = EventFlagsFromXEvent(xev); | |
26 switch (event_type) { | |
27 case ET_KEY_PRESSED: | |
28 case ET_KEY_RELEASED: | |
29 return new KeyEvent(event_type, KeyboardCodeFromXKeyEvent(&xev), flags); | |
30 case ET_MOUSE_PRESSED: | |
31 case ET_MOUSE_MOVED: | |
32 case ET_MOUSE_DRAGGED: | |
33 case ET_MOUSE_RELEASED: | |
34 return new MouseEvent(event_type, location, root_location, | |
35 EventTimeFromXEvent(xev), flags, | |
36 GetChangedMouseButtonFlagsFromXEvent(xev)); | |
37 case ET_MOUSEWHEEL: | |
38 return new MouseWheelEvent(GetMouseWheelOffsetFromXEvent(xev), location, | |
39 root_location, EventTimeFromXEvent(xev), flags, | |
40 GetChangedMouseButtonFlagsFromXEvent(xev)); | |
41 case ET_SCROLL_FLING_START: | |
42 case ET_SCROLL_FLING_CANCEL: { | |
43 float x_offset, y_offset, x_offset_ordinal, y_offset_ordinal; | |
44 GetFlingDataFromXEvent(xev, &x_offset, &y_offset, &x_offset_ordinal, | |
45 &y_offset_ordinal, nullptr); | |
46 return new ScrollEvent(event_type, location, EventTimeFromXEvent(xev), | |
47 flags, x_offset, y_offset, x_offset_ordinal, | |
48 y_offset_ordinal, 0); | |
49 } | |
50 case ET_SCROLL: { | |
51 float x_offset, y_offset, x_offset_ordinal, y_offset_ordinal; | |
52 int finger_count; | |
53 GetScrollOffsetsFromXEvent(xev, &x_offset, &y_offset, &x_offset_ordinal, | |
54 &y_offset_ordinal, &finger_count); | |
55 return new ScrollEvent(event_type, location, EventTimeFromXEvent(xev), | |
56 flags, x_offset, y_offset, x_offset_ordinal, | |
57 y_offset_ordinal, finger_count); | |
58 } | |
59 case ET_TOUCH_MOVED: | |
60 case ET_TOUCH_PRESSED: | |
61 case ET_TOUCH_CANCELLED: | |
62 case ET_TOUCH_RELEASED: | |
63 return new TouchEvent(event_type, location, GetTouchIdFromXEvent(xev), | |
64 EventTimeFromXEvent(xev)); | |
65 case ET_UNKNOWN: | |
66 return nullptr; | |
67 default: | |
68 break; | |
69 } | |
70 return nullptr; | |
71 } | |
72 | |
73 // Translates a XEvent into a ui::Event. | |
74 ui::Event* TranslateXEventToEvent(const XEvent& xev) { | |
75 int flags = EventFlagsFromXEvent(xev); | |
76 switch (xev.type) { | |
77 case LeaveNotify: | |
78 case EnterNotify: | |
79 // EnterNotify creates ET_MOUSE_MOVED. Mark as synthesized as this is | |
80 // not real mouse move event. | |
81 // int flags = GetEventFlagsFromXState(xev.xcrossing.state); | |
82 if (xev.type == EnterNotify) | |
83 flags |= EF_IS_SYNTHESIZED; | |
84 return new MouseEvent( | |
85 ET_MOUSE_MOVED, gfx::Point(xev.xcrossing.x, xev.xcrossing.y), | |
86 gfx::Point(xev.xcrossing.x_root, xev.xcrossing.y_root), | |
87 EventTimeFromXEvent(xev), flags, 0); | |
88 | |
89 case KeyPress: | |
90 case KeyRelease: | |
91 return new KeyEvent(EventTypeFromXEvent(xev), | |
92 KeyboardCodeFromXKeyEvent(&xev), flags); | |
93 | |
94 case ButtonPress: | |
95 case ButtonRelease: { | |
96 gfx::Point location = gfx::Point(xev.xbutton.x, xev.xbutton.y); | |
97 gfx::Point root_location = | |
98 gfx::Point(xev.xbutton.x_root, xev.xbutton.y_root); | |
99 switch (EventTypeFromXEvent(xev)) { | |
100 case ET_MOUSEWHEEL: | |
101 return new MouseWheelEvent(GetMouseWheelOffsetFromXEvent(xev), | |
102 location, root_location, | |
103 EventTimeFromXEvent(xev), flags, 0); | |
104 case ET_MOUSE_PRESSED: | |
105 case ET_MOUSE_RELEASED: | |
106 return new MouseEvent(EventTypeFromXEvent(xev), location, | |
107 root_location, EventTimeFromXEvent(xev), flags, | |
108 GetChangedMouseButtonFlagsFromXEvent(xev)); | |
109 case ET_UNKNOWN: | |
110 // No event is created for X11-release events for mouse-wheel | |
111 // buttons. | |
112 break; | |
113 default: | |
114 NOTREACHED(); | |
115 } | |
116 break; | |
117 } | |
118 | |
119 case GenericEvent: | |
120 return TranslateXI2EventToEvent(xev); | |
121 } | |
122 return nullptr; | |
123 } | |
124 | |
125 } // namespace | |
126 | |
127 uint32_t X11EventSource::DispatchEvent(base::NativeEvent native_event) { | |
128 XEvent* xevent = static_cast<XEvent*>(native_event); | |
129 uint32_t action = POST_DISPATCH_STOP_PROPAGATION; | |
130 base::NativeEvent translated_event = TranslateXEventToEvent(*xevent); | |
131 if (translated_event) { | |
132 action = PlatformEventSource::DispatchEvent(translated_event); | |
133 } else { | |
134 DispatchXEventToXEventDispatchers(xevent); | |
spang
2016/01/26 21:37:40
I think the X ones should run first. If it's consu
| |
135 } | |
136 PostDispatchEvent(xevent); | |
137 return action; | |
138 } | |
139 | |
140 } // namespace ui | |
OLD | NEW |