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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: ui/events/platform/x11/x11_event_source_libevent.cc
diff --git a/ui/events/platform/x11/x11_event_source_libevent.cc b/ui/events/platform/x11/x11_event_source_libevent.cc
index a3ff7a50f94486676686ff6308f08c8938b7335a..41be11cca9abb23a231c495088b48f5bb976498b 100644
--- a/ui/events/platform/x11/x11_event_source_libevent.cc
+++ b/ui/events/platform/x11/x11_event_source_libevent.cc
@@ -2,67 +2,200 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/events/platform/x11/x11_event_source.h"
+#include "ui/events/platform/x11/x11_event_source_libevent.h"
#include <X11/Xlib.h>
+#include <X11/extensions/XInput2.h>
-#include "base/macros.h"
#include "base/message_loop/message_loop.h"
-#include "base/message_loop/message_pump_libevent.h"
+#include "ui/events/event.h"
+#include "ui/events/keycodes/keyboard_code_conversion_x.h"
+#include "ui/events/platform/platform_event_dispatcher.h"
+#include "ui/events/x/events_x_utils.h"
namespace ui {
namespace {
-class X11EventSourceLibevent : public X11EventSource,
- public base::MessagePumpLibevent::Watcher {
- public:
- explicit X11EventSourceLibevent(XDisplay* display)
- : X11EventSource(display),
- initialized_(false) {
- AddEventWatcher();
+// Translates XI2 XEvent into a ui::Event.
+ui::Event* TranslateXI2EventToEvent(const XEvent& xev) {
+ XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev.xcookie.data);
+ EventType event_type = EventTypeFromXEvent(xev);
+ gfx::Point location = gfx::Point(xievent->event_x, xievent->event_y);
+ 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
+ int flags = EventFlagsFromXEvent(xev);
+ switch (event_type) {
+ case ET_KEY_PRESSED:
+ case ET_KEY_RELEASED:
+ return new KeyEvent(event_type, KeyboardCodeFromXKeyEvent(&xev), flags);
+ case ET_MOUSE_PRESSED:
+ case ET_MOUSE_MOVED:
+ case ET_MOUSE_DRAGGED:
+ case ET_MOUSE_RELEASED:
+ return new MouseEvent(event_type, location, root_location,
+ EventTimeFromXEvent(xev), flags,
+ GetChangedMouseButtonFlagsFromXEvent(xev));
+ case ET_MOUSEWHEEL:
+ return new MouseWheelEvent(GetMouseWheelOffsetFromXEvent(xev), location,
+ root_location, EventTimeFromXEvent(xev), flags,
+ GetChangedMouseButtonFlagsFromXEvent(xev));
+ case ET_SCROLL_FLING_START:
+ case ET_SCROLL_FLING_CANCEL: {
+ float x_offset, y_offset, x_offset_ordinal, y_offset_ordinal;
+ GetFlingDataFromXEvent(xev, &x_offset, &y_offset, &x_offset_ordinal,
+ &y_offset_ordinal, nullptr);
+ return new ScrollEvent(event_type, location, EventTimeFromXEvent(xev),
+ flags, x_offset, y_offset, x_offset_ordinal,
+ y_offset_ordinal, 0);
+ }
+ case ET_SCROLL: {
+ float x_offset, y_offset, x_offset_ordinal, y_offset_ordinal;
+ int finger_count;
+ GetScrollOffsetsFromXEvent(xev, &x_offset, &y_offset, &x_offset_ordinal,
+ &y_offset_ordinal, &finger_count);
+ return new ScrollEvent(event_type, location, EventTimeFromXEvent(xev),
+ flags, x_offset, y_offset, x_offset_ordinal,
+ y_offset_ordinal, finger_count);
+ }
+ case ET_TOUCH_MOVED:
+ case ET_TOUCH_PRESSED:
+ case ET_TOUCH_CANCELLED:
+ case ET_TOUCH_RELEASED:
+ return new TouchEvent(event_type, location, GetTouchIdFromXEvent(xev),
+ EventTimeFromXEvent(xev));
+ case ET_UNKNOWN:
+ return nullptr;
+ default:
+ break;
}
+ return nullptr;
+}
- ~X11EventSourceLibevent() override {
+// Translates a XEvent into a ui::Event.
+ui::Event* TranslateXEventToEvent(const XEvent& xev) {
+ int flags = EventFlagsFromXEvent(xev);
+ switch (xev.type) {
+ case LeaveNotify:
+ case EnterNotify:
+ // EnterNotify creates ET_MOUSE_MOVED. Mark as synthesized as this is
+ // not real mouse move event.
+ // int flags = GetEventFlagsFromXState(xev.xcrossing.state);
+ if (xev.type == EnterNotify)
+ flags |= EF_IS_SYNTHESIZED;
+ return new MouseEvent(
+ ET_MOUSE_MOVED, gfx::Point(xev.xcrossing.x, xev.xcrossing.y),
+ gfx::Point(xev.xcrossing.x_root, xev.xcrossing.y_root),
+ EventTimeFromXEvent(xev), flags, 0);
+
+ case KeyPress:
+ case KeyRelease:
+ return new KeyEvent(EventTypeFromXEvent(xev),
+ KeyboardCodeFromXKeyEvent(&xev), flags);
+
+ case ButtonPress:
+ case ButtonRelease: {
+ gfx::Point location = gfx::Point(xev.xbutton.x, xev.xbutton.y);
+ gfx::Point root_location =
+ gfx::Point(xev.xbutton.x_root, xev.xbutton.y_root);
+ switch (EventTypeFromXEvent(xev)) {
+ case ET_MOUSEWHEEL:
+ return new MouseWheelEvent(GetMouseWheelOffsetFromXEvent(xev),
+ location, root_location,
+ EventTimeFromXEvent(xev), flags, 0);
+ case ET_MOUSE_PRESSED:
+ case ET_MOUSE_RELEASED:
+ return new MouseEvent(EventTypeFromXEvent(xev), location,
+ root_location, EventTimeFromXEvent(xev), flags,
+ GetChangedMouseButtonFlagsFromXEvent(xev));
+ case ET_UNKNOWN:
+ // No event is created for X11-release events for mouse-wheel
+ // buttons.
+ break;
+ default:
+ NOTREACHED();
+ }
+ break;
+ }
+
+ case GenericEvent:
+ return TranslateXI2EventToEvent(xev);
}
sadrul 2016/02/08 17:28:32 Use Event[System]LocationFromXEvent in this functi
kylechar 2016/02/08 19:08:09 Done.
+ return nullptr;
+}
- private:
- void AddEventWatcher() {
- if (initialized_)
- return;
- if (!base::MessageLoop::current())
- return;
-
- int fd = ConnectionNumber(display());
- base::MessageLoopForUI::current()->WatchFileDescriptor(fd, true,
- base::MessagePumpLibevent::WATCH_READ, &watcher_controller_, this);
- initialized_ = true;
- }
+} // namespace
- // PlatformEventSource:
- void OnDispatcherListChanged() override {
- AddEventWatcher();
- }
+X11EventSourceLibevent::X11EventSourceLibevent(XDisplay* display) {
+ event_source_.reset(new X11EventSource(this, display));
+ AddEventWatcher();
+}
- // base::MessagePumpLibevent::Watcher:
- void OnFileCanReadWithoutBlocking(int fd) override {
- DispatchXEvents();
- }
+X11EventSourceLibevent::~X11EventSourceLibevent() {}
+
+// static
+X11EventSourceLibevent* X11EventSourceLibevent::GetInstance() {
+ return static_cast<X11EventSourceLibevent*>(
+ PlatformEventSource::GetInstance());
+}
- void OnFileCanWriteWithoutBlocking(int fd) override {
- NOTREACHED();
+void X11EventSourceLibevent::ProcessXEvent(XEvent* xevent) {
+ 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.
+ if (translated_event) {
+ DispatchEvent(translated_event);
+ } else {
+ // Only if we can't translate XEvent into ui::Event, try to dispatch XEvent
+ // directly to XEventDispatchers.
+ DispatchXEventToXEventDispatchers(xevent);
}
+}
- base::MessagePumpLibevent::FileDescriptorWatcher watcher_controller_;
- bool initialized_;
+void X11EventSourceLibevent::AddXEventDispatcher(XEventDispatcher* dispatcher) {
+ dispatchers_xevent_.AddObserver(dispatcher);
+}
- DISALLOW_COPY_AND_ASSIGN(X11EventSourceLibevent);
-};
+void X11EventSourceLibevent::RemoveXEventDispatcher(
+ XEventDispatcher* dispatcher) {
+ dispatchers_xevent_.RemoveObserver(dispatcher);
+}
-} // namespace
+void X11EventSourceLibevent::StopCurrentEventStream() {
+ event_source_->StopCurrentEventStream();
+}
+
+void X11EventSourceLibevent::OnDispatcherListChanged() {
+ AddEventWatcher();
+ event_source_->OnDispatcherListChanged();
+}
+
+void X11EventSourceLibevent::AddEventWatcher() {
+ if (initialized_)
+ return;
+ if (!base::MessageLoop::current())
+ return;
+
+ int fd = ConnectionNumber(event_source_->display());
+ base::MessageLoopForUI::current()->WatchFileDescriptor(
+ fd, true, base::MessagePumpLibevent::WATCH_READ, &watcher_controller_,
+ this);
+ initialized_ = true;
+}
+
+void X11EventSourceLibevent::DispatchXEventToXEventDispatchers(XEvent* xevent) {
+ if (dispatchers_xevent_.might_have_observers()) {
+ base::ObserverList<XEventDispatcher>::Iterator iter(&dispatchers_xevent_);
+ while (XEventDispatcher* dispatcher = iter.GetNext()) {
+ if (dispatcher->DispatchXEvent(xevent))
+ break;
+ }
+ }
+}
+
+void X11EventSourceLibevent::OnFileCanReadWithoutBlocking(int fd) {
+ event_source_->DispatchXEvents();
+}
-scoped_ptr<PlatformEventSource> PlatformEventSource::CreateDefault() {
- return make_scoped_ptr(new X11EventSourceLibevent(gfx::GetXDisplay()));
+void X11EventSourceLibevent::OnFileCanWriteWithoutBlocking(int fd) {
+ NOTREACHED();
}
} // namespace ui

Powered by Google App Engine
This is Rietveld 408576698