Index: ui/events/platform/x11/x11_event_source_ozone.cc |
diff --git a/ui/events/platform/x11/x11_event_source_ozone.cc b/ui/events/platform/x11/x11_event_source_ozone.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..50f93ef56304660180e56654cadd52b2d7702db1 |
--- /dev/null |
+++ b/ui/events/platform/x11/x11_event_source_ozone.cc |
@@ -0,0 +1,140 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// 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 <X11/Xlib.h> |
+#include <X11/extensions/XInput2.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 { |
+ |
+// 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); |
+ 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; |
+} |
+ |
+// 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); |
+ } |
+ return nullptr; |
+} |
+ |
+} // namespace |
+ |
+uint32_t X11EventSource::DispatchEvent(base::NativeEvent native_event) { |
+ XEvent* xevent = static_cast<XEvent*>(native_event); |
+ uint32_t action = POST_DISPATCH_STOP_PROPAGATION; |
+ base::NativeEvent translated_event = TranslateXEventToEvent(*xevent); |
+ if (translated_event) { |
+ action = PlatformEventSource::DispatchEvent(translated_event); |
+ } else { |
+ DispatchXEventToXEventDispatchers(xevent); |
spang
2016/01/26 21:37:40
I think the X ones should run first. If it's consu
|
+ } |
+ PostDispatchEvent(xevent); |
+ return action; |
+} |
+ |
+} // namespace ui |