Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: ui/events/platform/x11/x11_event_source_libevent.cc

Issue 1602173005: Add PlatformWindow/Event related code for Ozone X11. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixes for comments. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/events/platform/x11/x11_event_source.h" 5 #include "ui/events/platform/x11/x11_event_source_libevent.h"
6 6
7 #include <X11/Xlib.h> 7 #include <X11/Xlib.h>
8 8 #include <X11/extensions/XInput2.h>
9 #include "base/macros.h" 9
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
11 #include "base/message_loop/message_pump_libevent.h" 11 #include "ui/events/event.h"
12 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
13 #include "ui/events/platform/platform_event_dispatcher.h"
14 #include "ui/events/x/events_x_utils.h"
12 15
13 namespace ui { 16 namespace ui {
14 17
15 namespace { 18 namespace {
16 19
17 class X11EventSourceLibevent : public X11EventSource, 20 // Translates XI2 XEvent into a ui::Event.
18 public base::MessagePumpLibevent::Watcher { 21 ui::Event* TranslateXI2EventToEvent(const XEvent& xev) {
19 public: 22 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev.xcookie.data);
20 explicit X11EventSourceLibevent(XDisplay* display) 23 EventType event_type = EventTypeFromXEvent(xev);
21 : X11EventSource(display), 24 gfx::Point location = gfx::Point(xievent->event_x, xievent->event_y);
22 initialized_(false) { 25 gfx::Point root_location = gfx::Point(xievent->root_x, xievent->root_y);
sadrul 2016/02/08 17:28:32 Can you use Event[System]LocationFromXEvent instea
kylechar 2016/02/08 19:08:09 Yep, Event[System]LocationFromXEvent works fine. A
23 AddEventWatcher(); 26 int flags = EventFlagsFromXEvent(xev);
24 } 27 switch (event_type) {
25 28 case ET_KEY_PRESSED:
26 ~X11EventSourceLibevent() override { 29 case ET_KEY_RELEASED:
27 } 30 return new KeyEvent(event_type, KeyboardCodeFromXKeyEvent(&xev), flags);
28 31 case ET_MOUSE_PRESSED:
29 private: 32 case ET_MOUSE_MOVED:
30 void AddEventWatcher() { 33 case ET_MOUSE_DRAGGED:
31 if (initialized_) 34 case ET_MOUSE_RELEASED:
32 return; 35 return new MouseEvent(event_type, location, root_location,
33 if (!base::MessageLoop::current()) 36 EventTimeFromXEvent(xev), flags,
34 return; 37 GetChangedMouseButtonFlagsFromXEvent(xev));
35 38 case ET_MOUSEWHEEL:
36 int fd = ConnectionNumber(display()); 39 return new MouseWheelEvent(GetMouseWheelOffsetFromXEvent(xev), location,
37 base::MessageLoopForUI::current()->WatchFileDescriptor(fd, true, 40 root_location, EventTimeFromXEvent(xev), flags,
38 base::MessagePumpLibevent::WATCH_READ, &watcher_controller_, this); 41 GetChangedMouseButtonFlagsFromXEvent(xev));
39 initialized_ = true; 42 case ET_SCROLL_FLING_START:
40 } 43 case ET_SCROLL_FLING_CANCEL: {
41 44 float x_offset, y_offset, x_offset_ordinal, y_offset_ordinal;
42 // PlatformEventSource: 45 GetFlingDataFromXEvent(xev, &x_offset, &y_offset, &x_offset_ordinal,
43 void OnDispatcherListChanged() override { 46 &y_offset_ordinal, nullptr);
44 AddEventWatcher(); 47 return new ScrollEvent(event_type, location, EventTimeFromXEvent(xev),
45 } 48 flags, x_offset, y_offset, x_offset_ordinal,
46 49 y_offset_ordinal, 0);
47 // base::MessagePumpLibevent::Watcher: 50 }
48 void OnFileCanReadWithoutBlocking(int fd) override { 51 case ET_SCROLL: {
49 DispatchXEvents(); 52 float x_offset, y_offset, x_offset_ordinal, y_offset_ordinal;
50 } 53 int finger_count;
51 54 GetScrollOffsetsFromXEvent(xev, &x_offset, &y_offset, &x_offset_ordinal,
52 void OnFileCanWriteWithoutBlocking(int fd) override { 55 &y_offset_ordinal, &finger_count);
53 NOTREACHED(); 56 return new ScrollEvent(event_type, location, EventTimeFromXEvent(xev),
54 } 57 flags, x_offset, y_offset, x_offset_ordinal,
55 58 y_offset_ordinal, finger_count);
56 base::MessagePumpLibevent::FileDescriptorWatcher watcher_controller_; 59 }
57 bool initialized_; 60 case ET_TOUCH_MOVED:
58 61 case ET_TOUCH_PRESSED:
59 DISALLOW_COPY_AND_ASSIGN(X11EventSourceLibevent); 62 case ET_TOUCH_CANCELLED:
60 }; 63 case ET_TOUCH_RELEASED:
64 return new TouchEvent(event_type, location, GetTouchIdFromXEvent(xev),
65 EventTimeFromXEvent(xev));
66 case ET_UNKNOWN:
67 return nullptr;
68 default:
69 break;
70 }
71 return nullptr;
72 }
73
74 // Translates a XEvent into a ui::Event.
75 ui::Event* TranslateXEventToEvent(const XEvent& xev) {
76 int flags = EventFlagsFromXEvent(xev);
77 switch (xev.type) {
78 case LeaveNotify:
79 case EnterNotify:
80 // EnterNotify creates ET_MOUSE_MOVED. Mark as synthesized as this is
81 // not real mouse move event.
82 // int flags = GetEventFlagsFromXState(xev.xcrossing.state);
83 if (xev.type == EnterNotify)
84 flags |= EF_IS_SYNTHESIZED;
85 return new MouseEvent(
86 ET_MOUSE_MOVED, gfx::Point(xev.xcrossing.x, xev.xcrossing.y),
87 gfx::Point(xev.xcrossing.x_root, xev.xcrossing.y_root),
88 EventTimeFromXEvent(xev), flags, 0);
89
90 case KeyPress:
91 case KeyRelease:
92 return new KeyEvent(EventTypeFromXEvent(xev),
93 KeyboardCodeFromXKeyEvent(&xev), flags);
94
95 case ButtonPress:
96 case ButtonRelease: {
97 gfx::Point location = gfx::Point(xev.xbutton.x, xev.xbutton.y);
98 gfx::Point root_location =
99 gfx::Point(xev.xbutton.x_root, xev.xbutton.y_root);
100 switch (EventTypeFromXEvent(xev)) {
101 case ET_MOUSEWHEEL:
102 return new MouseWheelEvent(GetMouseWheelOffsetFromXEvent(xev),
103 location, root_location,
104 EventTimeFromXEvent(xev), flags, 0);
105 case ET_MOUSE_PRESSED:
106 case ET_MOUSE_RELEASED:
107 return new MouseEvent(EventTypeFromXEvent(xev), location,
108 root_location, EventTimeFromXEvent(xev), flags,
109 GetChangedMouseButtonFlagsFromXEvent(xev));
110 case ET_UNKNOWN:
111 // No event is created for X11-release events for mouse-wheel
112 // buttons.
113 break;
114 default:
115 NOTREACHED();
116 }
117 break;
118 }
119
120 case GenericEvent:
121 return TranslateXI2EventToEvent(xev);
122 }
sadrul 2016/02/08 17:28:32 Use Event[System]LocationFromXEvent in this functi
kylechar 2016/02/08 19:08:09 Done.
123 return nullptr;
124 }
61 125
62 } // namespace 126 } // namespace
63 127
64 scoped_ptr<PlatformEventSource> PlatformEventSource::CreateDefault() { 128 X11EventSourceLibevent::X11EventSourceLibevent(XDisplay* display) {
65 return make_scoped_ptr(new X11EventSourceLibevent(gfx::GetXDisplay())); 129 event_source_.reset(new X11EventSource(this, display));
130 AddEventWatcher();
131 }
132
133 X11EventSourceLibevent::~X11EventSourceLibevent() {}
134
135 // static
136 X11EventSourceLibevent* X11EventSourceLibevent::GetInstance() {
137 return static_cast<X11EventSourceLibevent*>(
138 PlatformEventSource::GetInstance());
139 }
140
141 void X11EventSourceLibevent::ProcessXEvent(XEvent* xevent) {
142 base::NativeEvent translated_event = TranslateXEventToEvent(*xevent);
sadrul 2016/02/08 17:28:32 Looks like |translated_event| here is leaking? Upd
kylechar 2016/02/08 19:08:09 Yeah, good catch. Done.
143 if (translated_event) {
144 DispatchEvent(translated_event);
145 } else {
146 // Only if we can't translate XEvent into ui::Event, try to dispatch XEvent
147 // directly to XEventDispatchers.
148 DispatchXEventToXEventDispatchers(xevent);
149 }
150 }
151
152 void X11EventSourceLibevent::AddXEventDispatcher(XEventDispatcher* dispatcher) {
153 dispatchers_xevent_.AddObserver(dispatcher);
154 }
155
156 void X11EventSourceLibevent::RemoveXEventDispatcher(
157 XEventDispatcher* dispatcher) {
158 dispatchers_xevent_.RemoveObserver(dispatcher);
159 }
160
161 void X11EventSourceLibevent::StopCurrentEventStream() {
162 event_source_->StopCurrentEventStream();
163 }
164
165 void X11EventSourceLibevent::OnDispatcherListChanged() {
166 AddEventWatcher();
167 event_source_->OnDispatcherListChanged();
168 }
169
170 void X11EventSourceLibevent::AddEventWatcher() {
171 if (initialized_)
172 return;
173 if (!base::MessageLoop::current())
174 return;
175
176 int fd = ConnectionNumber(event_source_->display());
177 base::MessageLoopForUI::current()->WatchFileDescriptor(
178 fd, true, base::MessagePumpLibevent::WATCH_READ, &watcher_controller_,
179 this);
180 initialized_ = true;
181 }
182
183 void X11EventSourceLibevent::DispatchXEventToXEventDispatchers(XEvent* xevent) {
184 if (dispatchers_xevent_.might_have_observers()) {
185 base::ObserverList<XEventDispatcher>::Iterator iter(&dispatchers_xevent_);
186 while (XEventDispatcher* dispatcher = iter.GetNext()) {
187 if (dispatcher->DispatchXEvent(xevent))
188 break;
189 }
190 }
191 }
192
193 void X11EventSourceLibevent::OnFileCanReadWithoutBlocking(int fd) {
194 event_source_->DispatchXEvents();
195 }
196
197 void X11EventSourceLibevent::OnFileCanWriteWithoutBlocking(int fd) {
198 NOTREACHED();
66 } 199 }
67 200
68 } // namespace ui 201 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698