summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
Diffstat (limited to 'ui')
-rw-r--r--ui/aura/window_tree_host_x11.cc1
-rw-r--r--ui/base/dragdrop/os_exchange_data_provider_aurax11_unittest.cc4
-rw-r--r--ui/events/platform/x11/BUILD.gn18
-rw-r--r--ui/events/platform/x11/x11_event_source.cc66
-rw-r--r--ui/events/platform/x11/x11_event_source.h50
-rw-r--r--ui/events/platform/x11/x11_event_source_glib.cc91
-rw-r--r--ui/events/platform/x11/x11_event_source_glib.h53
-rw-r--r--ui/events/platform/x11/x11_event_source_libevent.cc208
-rw-r--r--ui/events/platform/x11/x11_event_source_libevent.h79
-rw-r--r--ui/events/platform/x11/x11_events_platform.gyp13
-rw-r--r--ui/events/x/BUILD.gn5
-rw-r--r--ui/events/x/events_x_utils.h8
-rw-r--r--ui/ozone/platform/x11/BUILD.gn2
-rw-r--r--ui/ozone/platform/x11/ozone_platform_x11.cc13
-rw-r--r--ui/platform_window/x11/BUILD.gn19
-rw-r--r--ui/platform_window/x11/x11_window.cc305
-rw-r--r--ui/platform_window/x11/x11_window.gyp2
-rw-r--r--ui/platform_window/x11/x11_window.h65
-rw-r--r--ui/platform_window/x11/x11_window_base.cc284
-rw-r--r--ui/platform_window/x11/x11_window_base.h100
-rw-r--r--ui/platform_window/x11/x11_window_ozone.cc51
-rw-r--r--ui/platform_window/x11/x11_window_ozone.h42
-rw-r--r--ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc2
-rw-r--r--ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc1
24 files changed, 961 insertions, 521 deletions
diff --git a/ui/aura/window_tree_host_x11.cc b/ui/aura/window_tree_host_x11.cc
index 43f7265..a5675e9 100644
--- a/ui/aura/window_tree_host_x11.cc
+++ b/ui/aura/window_tree_host_x11.cc
@@ -45,6 +45,7 @@
#include "ui/events/event_utils.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/events/platform/platform_event_observer.h"
+#include "ui/events/platform/platform_event_source.h"
#include "ui/events/platform/x11/x11_event_source.h"
#include "ui/gfx/screen.h"
diff --git a/ui/base/dragdrop/os_exchange_data_provider_aurax11_unittest.cc b/ui/base/dragdrop/os_exchange_data_provider_aurax11_unittest.cc
index 457ba6b..90fa7c2 100644
--- a/ui/base/dragdrop/os_exchange_data_provider_aurax11_unittest.cc
+++ b/ui/base/dragdrop/os_exchange_data_provider_aurax11_unittest.cc
@@ -13,7 +13,7 @@
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/dragdrop/file_info.h"
-#include "ui/events/platform/x11/x11_event_source.h"
+#include "ui/events/platform/x11/x11_event_source_glib.h"
#include "url/gurl.h"
const char kFileURL[] = "file:///home/user/file.txt";
@@ -39,7 +39,7 @@ class OSExchangeDataProviderAuraX11Test : public testing::Test {
protected:
base::MessageLoopForUI message_loop;
- X11EventSource event_source;
+ X11EventSourceGlib event_source;
ui::OSExchangeDataProviderAuraX11 provider;
};
diff --git a/ui/events/platform/x11/BUILD.gn b/ui/events/platform/x11/BUILD.gn
index e55afc7..929613c 100644
--- a/ui/events/platform/x11/BUILD.gn
+++ b/ui/events/platform/x11/BUILD.gn
@@ -3,8 +3,9 @@
# found in the LICENSE file.
import("//build/config/ui.gni")
+import("//ui/ozone/ozone.gni")
-assert(use_x11)
+assert(use_x11 || ozone_platform_x11)
component("x11") {
output_name = "x11_events_platform"
@@ -12,8 +13,6 @@ component("x11") {
sources = [
"x11_event_source.cc",
"x11_event_source.h",
- "x11_event_source_glib.cc",
- "x11_event_source_libevent.cc",
"x11_hotplug_event_handler.cc",
"x11_hotplug_event_handler.h",
]
@@ -27,6 +26,7 @@ component("x11") {
"//ui/events:events_base",
"//ui/events/devices",
"//ui/events/platform",
+ "//ui/events/x",
"//ui/gfx/x",
]
@@ -34,11 +34,17 @@ component("x11") {
"//base",
]
- if (is_linux) {
- sources -= [ "x11_event_source_libevent.cc" ]
+ if (use_glib) {
+ sources += [
+ "x11_event_source_glib.cc",
+ "x11_event_source_glib.h",
+ ]
configs += [ "//build/config/linux:glib" ]
} else {
- sources -= [ "x11_event_source_glib.cc" ]
+ sources += [
+ "x11_event_source_libevent.cc",
+ "x11_event_source_libevent.h",
+ ]
}
}
diff --git a/ui/events/platform/x11/x11_event_source.cc b/ui/events/platform/x11/x11_event_source.cc
index ba55e0b..f450227 100644
--- a/ui/events/platform/x11/x11_event_source.cc
+++ b/ui/events/platform/x11/x11_event_source.cc
@@ -4,51 +4,19 @@
#include "ui/events/platform/x11/x11_event_source.h"
-#include <X11/extensions/XInput2.h>
-#include <X11/X.h>
-#include <X11/Xlib.h>
#include <X11/XKBlib.h>
+#include <X11/Xlib.h>
#include "base/logging.h"
#include "ui/events/devices/x11/device_data_manager_x11.h"
#include "ui/events/event_utils.h"
#include "ui/events/platform/platform_event_dispatcher.h"
#include "ui/events/platform/x11/x11_hotplug_event_handler.h"
-#include "ui/gfx/x/x11_types.h"
namespace ui {
namespace {
-int g_xinput_opcode = -1;
-
-bool InitializeXInput2(XDisplay* display) {
- if (!display)
- return false;
-
- int event, err;
-
- int xiopcode;
- if (!XQueryExtension(display, "XInputExtension", &xiopcode, &event, &err)) {
- DVLOG(1) << "X Input extension not available.";
- return false;
- }
- g_xinput_opcode = xiopcode;
-
- int major = 2, minor = 2;
- if (XIQueryVersion(display, &major, &minor) == BadRequest) {
- DVLOG(1) << "XInput2 not supported in the server.";
- return false;
- }
- if (major < 2 || (major == 2 && minor < 2)) {
- DVLOG(1) << "XI version on server is " << major << "." << minor << ". "
- << "But 2.2 is required.";
- return false;
- }
-
- return true;
-}
-
bool InitializeXkb(XDisplay* display) {
if (!display)
return false;
@@ -74,21 +42,29 @@ bool InitializeXkb(XDisplay* display) {
} // namespace
-X11EventSource::X11EventSource(XDisplay* display)
- : display_(display),
- continue_stream_(true) {
- CHECK(display_);
+X11EventSource* X11EventSource::instance_ = nullptr;
+
+X11EventSource::X11EventSource(X11EventSourceDelegate* delegate,
+ XDisplay* display)
+ : delegate_(delegate), display_(display), continue_stream_(true) {
+ DCHECK(!instance_);
+ instance_ = this;
+
+ DCHECK(delegate_);
+ DCHECK(display_);
DeviceDataManagerX11::CreateInstance();
- InitializeXInput2(display_);
InitializeXkb(display_);
}
X11EventSource::~X11EventSource() {
+ DCHECK_EQ(this, instance_);
+ instance_ = nullptr;
}
// static
X11EventSource* X11EventSource::GetInstance() {
- return static_cast<X11EventSource*>(PlatformEventSource::GetInstance());
+ DCHECK(instance_);
+ return instance_;
}
////////////////////////////////////////////////////////////////////////////////
@@ -118,22 +94,21 @@ void X11EventSource::BlockUntilWindowMapped(XID window) {
}
////////////////////////////////////////////////////////////////////////////////
-// X11EventSource, private
+// X11EventSource, protected
-uint32_t X11EventSource::ExtractCookieDataDispatchEvent(XEvent* xevent) {
+void X11EventSource::ExtractCookieDataDispatchEvent(XEvent* xevent) {
bool have_cookie = false;
if (xevent->type == GenericEvent &&
XGetEventData(xevent->xgeneric.display, &xevent->xcookie)) {
have_cookie = true;
}
- uint32_t action = DispatchEvent(xevent);
+ delegate_->ProcessXEvent(xevent);
+ PostDispatchEvent(xevent);
if (have_cookie)
XFreeEventData(xevent->xgeneric.display, &xevent->xcookie);
- return action;
}
-uint32_t X11EventSource::DispatchEvent(XEvent* xevent) {
- uint32_t action = PlatformEventSource::DispatchEvent(xevent);
+void X11EventSource::PostDispatchEvent(XEvent* xevent) {
if (xevent->type == GenericEvent &&
(xevent->xgeneric.evtype == XI_HierarchyChanged ||
xevent->xgeneric.evtype == XI_DeviceChanged)) {
@@ -147,7 +122,6 @@ uint32_t X11EventSource::DispatchEvent(XEvent* xevent) {
// Clear stored scroll data
ui::DeviceDataManagerX11::GetInstance()->InvalidateScrollClasses();
}
- return action;
}
void X11EventSource::StopCurrentEventStream() {
diff --git a/ui/events/platform/x11/x11_event_source.h b/ui/events/platform/x11/x11_event_source.h
index 26d6460..5816908 100644
--- a/ui/events/platform/x11/x11_event_source.h
+++ b/ui/events/platform/x11/x11_event_source.h
@@ -10,11 +10,8 @@
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "ui/events/events_export.h"
-#include "ui/events/platform/platform_event_source.h"
#include "ui/gfx/x/x11_types.h"
-typedef struct _GPollFD GPollFD;
-typedef struct _GSource GSource;
typedef union _XEvent XEvent;
typedef unsigned long XID;
@@ -22,16 +19,30 @@ namespace ui {
class X11HotplugEventHandler;
-// A PlatformEventSource implementation for reading events from X11 server and
-// dispatching the events to the appropriate dispatcher.
-class EVENTS_EXPORT X11EventSource : public PlatformEventSource {
+// Responsible for notifying X11EventSource when new XEvents are available and
+// processing/dispatching XEvents. Implementations will likely be a
+// PlatformEventSource.
+class X11EventSourceDelegate {
public:
- explicit X11EventSource(XDisplay* display);
- ~X11EventSource() override;
+ X11EventSourceDelegate() = default;
+
+ // Processes (if necessary) and handles dispatching XEvents.
+ virtual void ProcessXEvent(XEvent* xevent) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(X11EventSourceDelegate);
+};
+
+// Receives X11 events and sends them to X11EventSourceDelegate. Handles
+// receiving, pre-process and post-processing XEvents.
+class EVENTS_EXPORT X11EventSource {
+ public:
+ X11EventSource(X11EventSourceDelegate* delegate, XDisplay* display);
+ ~X11EventSource();
static X11EventSource* GetInstance();
- // Called by the glib source dispatch function. Processes all (if any)
+ // Called when there is a new XEvent available. Processes all (if any)
// available X events.
void DispatchXEvents();
@@ -46,26 +57,31 @@ class EVENTS_EXPORT X11EventSource : public PlatformEventSource {
// functions which require a mapped window.
void BlockUntilWindowMapped(XID window);
- protected:
XDisplay* display() { return display_; }
- private:
+ void StopCurrentEventStream();
+ void OnDispatcherListChanged();
+
+ protected:
// Extracts cookie data from |xevent| if it's of GenericType, and dispatches
// the event. This function also frees up the cookie data after dispatch is
// complete.
- uint32_t ExtractCookieDataDispatchEvent(XEvent* xevent);
+ void ExtractCookieDataDispatchEvent(XEvent* xevent);
+
+ // Handles updates after event has been dispatched.
+ void PostDispatchEvent(XEvent* xevent);
+
+ private:
+ static X11EventSource* instance_;
- // PlatformEventSource:
- uint32_t DispatchEvent(XEvent* xevent) override;
- void StopCurrentEventStream() override;
- void OnDispatcherListChanged() override;
+ X11EventSourceDelegate* delegate_;
// The connection to the X11 server used to receive the events.
XDisplay* display_;
// Keeps track of whether this source should continue to dispatch all the
// available events.
- bool continue_stream_;
+ bool continue_stream_ = true;
scoped_ptr<X11HotplugEventHandler> hotplug_event_handler_;
diff --git a/ui/events/platform/x11/x11_event_source_glib.cc b/ui/events/platform/x11/x11_event_source_glib.cc
index 2151601..1eb272a 100644
--- a/ui/events/platform/x11/x11_event_source_glib.cc
+++ b/ui/events/platform/x11/x11_event_source_glib.cc
@@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/macros.h"
-#include "ui/events/platform/x11/x11_event_source.h"
+#include "ui/events/platform/x11/x11_event_source_glib.h"
#include <glib.h>
#include <X11/Xlib.h>
@@ -48,52 +47,52 @@ GSourceFuncs XSourceFuncs = {
NULL
};
-class X11EventSourceGlib : public X11EventSource {
- public:
- explicit X11EventSourceGlib(XDisplay* display)
- : X11EventSource(display),
- x_source_(NULL) {
- InitXSource(ConnectionNumber(display));
- }
-
- ~X11EventSourceGlib() override {
- g_source_destroy(x_source_);
- g_source_unref(x_source_);
- }
-
- private:
- void InitXSource(int fd) {
- CHECK(!x_source_);
- CHECK(display()) << "Unable to get connection to X server";
-
- x_poll_.reset(new GPollFD());
- x_poll_->fd = fd;
- x_poll_->events = G_IO_IN;
- x_poll_->revents = 0;
-
- GLibX11Source* glib_x_source = static_cast<GLibX11Source*>
- (g_source_new(&XSourceFuncs, sizeof(GLibX11Source)));
- glib_x_source->display = display();
- glib_x_source->poll_fd = x_poll_.get();
-
- x_source_ = glib_x_source;
- g_source_add_poll(x_source_, x_poll_.get());
- g_source_set_can_recurse(x_source_, TRUE);
- g_source_set_callback(x_source_, NULL, this, NULL);
- g_source_attach(x_source_, g_main_context_default());
- }
-
- // The GLib event source for X events.
- GSource* x_source_;
-
- // The poll attached to |x_source_|.
- scoped_ptr<GPollFD> x_poll_;
-
- DISALLOW_COPY_AND_ASSIGN(X11EventSourceGlib);
-};
-
} // namespace
+X11EventSourceGlib::X11EventSourceGlib(XDisplay* display)
+ : event_source_(this, display) {
+ InitXSource(ConnectionNumber(display));
+}
+
+X11EventSourceGlib::~X11EventSourceGlib() {
+ g_source_destroy(x_source_);
+ g_source_unref(x_source_);
+}
+
+void X11EventSourceGlib::ProcessXEvent(XEvent* xevent) {
+ DispatchEvent(xevent);
+}
+
+void X11EventSourceGlib::StopCurrentEventStream() {
+ event_source_.StopCurrentEventStream();
+}
+
+void X11EventSourceGlib::OnDispatcherListChanged() {
+ event_source_.OnDispatcherListChanged();
+}
+
+void X11EventSourceGlib::InitXSource(int fd) {
+ DCHECK(!x_source_);
+ DCHECK(event_source_.display()) << "Unable to get connection to X server";
+
+ x_poll_.reset(new GPollFD());
+ x_poll_->fd = fd;
+ x_poll_->events = G_IO_IN;
+ x_poll_->revents = 0;
+
+ GLibX11Source* glib_x_source = static_cast<GLibX11Source*>(
+ g_source_new(&XSourceFuncs, sizeof(GLibX11Source)));
+ glib_x_source->display = event_source_.display();
+ glib_x_source->poll_fd = x_poll_.get();
+
+ x_source_ = glib_x_source;
+ g_source_add_poll(x_source_, x_poll_.get());
+ g_source_set_can_recurse(x_source_, TRUE);
+ g_source_set_callback(x_source_, NULL, &event_source_, NULL);
+ g_source_attach(x_source_, g_main_context_default());
+}
+
+// static
scoped_ptr<PlatformEventSource> PlatformEventSource::CreateDefault() {
return make_scoped_ptr(new X11EventSourceGlib(gfx::GetXDisplay()));
}
diff --git a/ui/events/platform/x11/x11_event_source_glib.h b/ui/events/platform/x11/x11_event_source_glib.h
new file mode 100644
index 0000000..67a38b1
--- /dev/null
+++ b/ui/events/platform/x11/x11_event_source_glib.h
@@ -0,0 +1,53 @@
+// 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.
+
+#ifndef UI_EVENTS_PLATFORM_X11_X11_EVENT_SOURCE_GLIB_H_
+#define UI_EVENTS_PLATFORM_X11_X11_EVENT_SOURCE_GLIB_H_
+
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "ui/events/events_export.h"
+#include "ui/events/platform/platform_event_source.h"
+#include "ui/events/platform/x11/x11_event_source.h"
+#include "ui/gfx/x/x11_types.h"
+
+typedef struct _GPollFD GPollFD;
+typedef struct _GSource GSource;
+
+namespace ui {
+
+// A PlatformEventSource implementation for X11. Dispatches XEvents and uses
+// Glib to be notified for incoming XEvents.
+class EVENTS_EXPORT X11EventSourceGlib : public X11EventSourceDelegate,
+ public PlatformEventSource {
+ public:
+ explicit X11EventSourceGlib(XDisplay* display);
+ ~X11EventSourceGlib() override;
+
+ // X11EventSourceDelegate:
+ void ProcessXEvent(XEvent* xevent) override;
+
+ private:
+ // PlatformEventSource:
+ void StopCurrentEventStream() override;
+ void OnDispatcherListChanged() override;
+
+ void InitXSource(int fd);
+
+ X11EventSource event_source_;
+
+ // The GLib event source for X events.
+ GSource* x_source_ = nullptr;
+
+ // The poll attached to |x_source_|.
+ scoped_ptr<GPollFD> x_poll_;
+
+ DISALLOW_COPY_AND_ASSIGN(X11EventSourceGlib);
+};
+
+} // namespace ui
+
+#endif // UI_EVENTS_PLATFORM_X11_X11_EVENT_SOURCE_GLIB_H_
diff --git a/ui/events/platform/x11/x11_event_source_libevent.cc b/ui/events/platform/x11/x11_event_source_libevent.cc
index a3ff7a5..0dfbf3f 100644
--- a/ui/events/platform/x11/x11_event_source_libevent.cc
+++ b/ui/events/platform/x11/x11_event_source_libevent.cc
@@ -2,67 +2,197 @@
// 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.
+scoped_ptr<ui::Event> TranslateXI2EventToEvent(const XEvent& xev) {
+ EventType event_type = EventTypeFromXEvent(xev);
+ switch (event_type) {
+ case ET_KEY_PRESSED:
+ case ET_KEY_RELEASED:
+ return make_scoped_ptr(new KeyEvent(event_type,
+ KeyboardCodeFromXKeyEvent(&xev),
+ EventFlagsFromXEvent(xev)));
+ case ET_MOUSE_PRESSED:
+ case ET_MOUSE_MOVED:
+ case ET_MOUSE_DRAGGED:
+ case ET_MOUSE_RELEASED:
+ return make_scoped_ptr(
+ new MouseEvent(event_type, EventLocationFromXEvent(xev),
+ EventSystemLocationFromXEvent(xev),
+ EventTimeFromXEvent(xev), EventFlagsFromXEvent(xev),
+ GetChangedMouseButtonFlagsFromXEvent(xev)));
+ case ET_MOUSEWHEEL:
+ return make_scoped_ptr(new MouseWheelEvent(
+ GetMouseWheelOffsetFromXEvent(xev), EventLocationFromXEvent(xev),
+ EventSystemLocationFromXEvent(xev), EventTimeFromXEvent(xev),
+ EventFlagsFromXEvent(xev),
+ 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 make_scoped_ptr(new ScrollEvent(
+ event_type, EventLocationFromXEvent(xev), EventTimeFromXEvent(xev),
+ EventFlagsFromXEvent(xev), 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 make_scoped_ptr(new ScrollEvent(
+ event_type, EventLocationFromXEvent(xev), EventTimeFromXEvent(xev),
+ EventFlagsFromXEvent(xev), 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 make_scoped_ptr(
+ new TouchEvent(event_type, EventLocationFromXEvent(xev),
+ GetTouchIdFromXEvent(xev), EventTimeFromXEvent(xev)));
+ case ET_UNKNOWN:
+ return nullptr;
+ default:
+ break;
}
+ return nullptr;
+}
- ~X11EventSourceLibevent() override {
+// Translates a XEvent into a ui::Event.
+scoped_ptr<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.
+ if (xev.type == EnterNotify)
+ flags |= EF_IS_SYNTHESIZED;
+ return make_scoped_ptr(
+ new MouseEvent(ET_MOUSE_MOVED, EventLocationFromXEvent(xev),
+ EventSystemLocationFromXEvent(xev),
+ EventTimeFromXEvent(xev), flags, 0));
+
+ case KeyPress:
+ case KeyRelease:
+ return make_scoped_ptr(new KeyEvent(
+ EventTypeFromXEvent(xev), KeyboardCodeFromXKeyEvent(&xev), flags));
+
+ case ButtonPress:
+ case ButtonRelease: {
+ switch (EventTypeFromXEvent(xev)) {
+ case ET_MOUSEWHEEL:
+ return make_scoped_ptr(new MouseWheelEvent(
+ GetMouseWheelOffsetFromXEvent(xev), EventLocationFromXEvent(xev),
+ EventSystemLocationFromXEvent(xev), EventTimeFromXEvent(xev),
+ flags, 0));
+ case ET_MOUSE_PRESSED:
+ case ET_MOUSE_RELEASED:
+ return make_scoped_ptr(new MouseEvent(
+ EventTypeFromXEvent(xev), EventLocationFromXEvent(xev),
+ EventSystemLocationFromXEvent(xev), 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;
+}
- 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_(this, display) {
+ AddEventWatcher();
+}
+
+X11EventSourceLibevent::~X11EventSourceLibevent() {}
- // base::MessagePumpLibevent::Watcher:
- void OnFileCanReadWithoutBlocking(int fd) override {
- DispatchXEvents();
+void X11EventSourceLibevent::AddXEventDispatcher(XEventDispatcher* dispatcher) {
+ dispatchers_xevent_.AddObserver(dispatcher);
+}
+
+void X11EventSourceLibevent::RemoveXEventDispatcher(
+ XEventDispatcher* dispatcher) {
+ dispatchers_xevent_.RemoveObserver(dispatcher);
+}
+
+void X11EventSourceLibevent::ProcessXEvent(XEvent* xevent) {
+ scoped_ptr<ui::Event> translated_event = TranslateXEventToEvent(*xevent);
+ if (translated_event) {
+ DispatchEvent(translated_event.get());
+ } else {
+ // Only if we can't translate XEvent into ui::Event, try to dispatch XEvent
+ // directly to XEventDispatchers.
+ DispatchXEventToXEventDispatchers(xevent);
}
+}
- void OnFileCanWriteWithoutBlocking(int fd) override {
- NOTREACHED();
+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;
+ }
}
+}
- base::MessagePumpLibevent::FileDescriptorWatcher watcher_controller_;
- bool initialized_;
+void X11EventSourceLibevent::StopCurrentEventStream() {
+ event_source_.StopCurrentEventStream();
+}
- DISALLOW_COPY_AND_ASSIGN(X11EventSourceLibevent);
-};
+void X11EventSourceLibevent::OnDispatcherListChanged() {
+ AddEventWatcher();
+ event_source_.OnDispatcherListChanged();
+}
-} // namespace
+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
diff --git a/ui/events/platform/x11/x11_event_source_libevent.h b/ui/events/platform/x11/x11_event_source_libevent.h
new file mode 100644
index 0000000..b9f2eba
--- /dev/null
+++ b/ui/events/platform/x11/x11_event_source_libevent.h
@@ -0,0 +1,79 @@
+// 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.
+
+#ifndef UI_EVENTS_PLATFORM_X11_X11_EVENT_SOURCE_LIBEVENT_H_
+#define UI_EVENTS_PLATFORM_X11_X11_EVENT_SOURCE_LIBEVENT_H_
+
+#include "base/macros.h"
+#include "base/message_loop/message_pump_libevent.h"
+#include "ui/events/events_export.h"
+#include "ui/events/platform/platform_event_source.h"
+#include "ui/events/platform/x11/x11_event_source.h"
+
+namespace ui {
+
+// Interface for classes that want to receive XEvent directly. Only used with
+// Ozone X11 currently and only events that can't be translated into ui::Events
+// are sent via this path.
+class EVENTS_EXPORT XEventDispatcher {
+ public:
+ // Sends XEvent to XEventDispatcher for handling. Returns true if the XEvent
+ // was dispatched, otherwise false. After the first XEventDispatcher returns
+ // true XEvent dispatching stops.
+ virtual bool DispatchXEvent(XEvent* xevent) = 0;
+
+ protected:
+ virtual ~XEventDispatcher() {}
+};
+
+// A PlatformEventSource implementation for Ozone X11. Converts XEvents to
+// ui::Events before dispatching. For X11 specific events a separate list of
+// XEventDispatchers is maintained. Uses Libevent to be notified for incoming
+// XEvents.
+class EVENTS_EXPORT X11EventSourceLibevent
+ : public X11EventSourceDelegate,
+ public PlatformEventSource,
+ public base::MessagePumpLibevent::Watcher {
+ public:
+ explicit X11EventSourceLibevent(XDisplay* display);
+ ~X11EventSourceLibevent() override;
+
+ // Adds a XEvent dispatcher to the XEvent dispatcher list.
+ void AddXEventDispatcher(XEventDispatcher* dispatcher);
+
+ // Removes a XEvent dispatcher fERrom the XEvent dispatcher list.
+ void RemoveXEventDispatcher(XEventDispatcher* dispatcher);
+
+ // X11EventSourceDelegate:
+ void ProcessXEvent(XEvent* xevent) override;
+
+ private:
+ // Registers event watcher with Libevent.
+ void AddEventWatcher();
+
+ // Sends XEvent to registered XEventDispatchers.
+ void DispatchXEventToXEventDispatchers(XEvent* xevent);
+
+ // PlatformEventSource:
+ void StopCurrentEventStream() override;
+ void OnDispatcherListChanged() override;
+
+ // base::MessagePumpLibevent::Watcher:
+ void OnFileCanReadWithoutBlocking(int fd) override;
+ void OnFileCanWriteWithoutBlocking(int fd) override;
+
+ X11EventSource event_source_;
+
+ // Keep track of all XEventDispatcher to send XEvents directly to.
+ base::ObserverList<XEventDispatcher> dispatchers_xevent_;
+
+ base::MessagePumpLibevent::FileDescriptorWatcher watcher_controller_;
+ bool initialized_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(X11EventSourceLibevent);
+};
+
+} // namespace ui
+
+#endif // UI_EVENTS_PLATFORM_X11_X11_EVENT_SOURCE_LIBEVENT_H_
diff --git a/ui/events/platform/x11/x11_events_platform.gyp b/ui/events/platform/x11/x11_events_platform.gyp
index cb1bbcd..a624722 100644
--- a/ui/events/platform/x11/x11_events_platform.gyp
+++ b/ui/events/platform/x11/x11_events_platform.gyp
@@ -20,13 +20,12 @@
'../../devices/events_devices.gyp:events_devices',
'../../events.gyp:events',
'../../events.gyp:events_base',
+ '../../x/events_x.gyp:events_x',
'../events_platform.gyp:events_platform',
],
'sources': [
'x11_event_source.cc',
'x11_event_source.h',
- 'x11_event_source_glib.cc',
- 'x11_event_source_libevent.cc',
'x11_hotplug_event_handler.cc',
'x11_hotplug_event_handler.h',
],
@@ -35,13 +34,15 @@
'dependencies': [
'../../../../build/linux/system.gyp:glib',
],
- 'sources!': [
- 'x11_event_source_libevent.cc',
+ 'sources': [
+ 'x11_event_source_glib.cc',
+ 'x11_event_source_glib.h',
],
}, {
# use_glib == 0
- 'sources!': [
- 'x11_event_source_glib.cc',
+ 'sources': [
+ 'x11_event_source_libevent.cc',
+ 'x11_event_source_libevent.h',
],
}],
],
diff --git a/ui/events/x/BUILD.gn b/ui/events/x/BUILD.gn
index 2329946..991ce6e 100644
--- a/ui/events/x/BUILD.gn
+++ b/ui/events/x/BUILD.gn
@@ -16,8 +16,5 @@ component("x") {
"//ui/events/devices",
"//ui/gfx/x",
]
- configs += [
- "//build/config/linux:glib",
- "//build/config/linux:x11",
- ]
+ configs += [ "//build/config/linux:x11" ]
}
diff --git a/ui/events/x/events_x_utils.h b/ui/events/x/events_x_utils.h
index 15c4e38..0a07061 100644
--- a/ui/events/x/events_x_utils.h
+++ b/ui/events/x/events_x_utils.h
@@ -16,16 +16,16 @@ typedef union _XEvent XEvent;
namespace ui {
-// Get the EventType from a XEvent.
+// Gets the EventType from a XEvent.
EVENTS_X_EXPORT EventType EventTypeFromXEvent(const XEvent& xev);
-// Get the EventFlags from a XEvent.
+// Gets the EventFlags from a XEvent.
EVENTS_X_EXPORT int EventFlagsFromXEvent(const XEvent& xev);
-// Get the timestamp from a XEvent.
+// Gets the timestamp from a XEvent.
EVENTS_X_EXPORT base::TimeDelta EventTimeFromXEvent(const XEvent& xev);
-// Get the location from a XEvent. The coordinate system of the resultant
+// Gets the location from a XEvent. The coordinate system of the resultant
// |Point| has the origin at top-left of the "root window". The nature of
// this "root window" and how it maps to platform-specific drawing surfaces is
// defined in ui/aura/root_window.* and ui/aura/window_tree_host*.
diff --git a/ui/ozone/platform/x11/BUILD.gn b/ui/ozone/platform/x11/BUILD.gn
index b853381..fdffd9f 100644
--- a/ui/ozone/platform/x11/BUILD.gn
+++ b/ui/ozone/platform/x11/BUILD.gn
@@ -22,11 +22,13 @@ source_set("x11") {
"//ui/events/devices",
"//ui/events/ozone:events_ozone",
"//ui/events/platform",
+ "//ui/events/platform/x11",
"//ui/events/x",
"//ui/gfx",
"//ui/gfx/geometry",
"//ui/gfx/x",
"//ui/ozone:ozone_base",
+ "//ui/platform_window/x11",
]
configs += [ "//build/config/linux:x11" ]
diff --git a/ui/ozone/platform/x11/ozone_platform_x11.cc b/ui/ozone/platform/x11/ozone_platform_x11.cc
index 9dca688..34db2f3 100644
--- a/ui/ozone/platform/x11/ozone_platform_x11.cc
+++ b/ui/ozone/platform/x11/ozone_platform_x11.cc
@@ -8,6 +8,7 @@
#include "base/memory/scoped_ptr.h"
#include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h"
+#include "ui/events/platform/x11/x11_event_source_libevent.h"
#include "ui/ozone/common/native_display_delegate_ozone.h"
#include "ui/ozone/common/stub_overlay_manager.h"
#include "ui/ozone/platform/x11/x11_surface_factory.h"
@@ -17,6 +18,7 @@
#include "ui/ozone/public/ozone_platform.h" // nogncheck
#include "ui/ozone/public/system_input_injector.h"
#include "ui/platform_window/platform_window.h"
+#include "ui/platform_window/x11/x11_window_ozone.h"
namespace ui {
@@ -60,9 +62,11 @@ class OzonePlatformX11 : public OzonePlatform {
scoped_ptr<PlatformWindow> CreatePlatformWindow(
PlatformWindowDelegate* delegate,
const gfx::Rect& bounds) override {
- // TODO(kylechar): Add PlatformWindow creation here.
- NOTREACHED();
- return nullptr;
+ scoped_ptr<X11WindowOzone> window =
+ make_scoped_ptr(new X11WindowOzone(event_source_.get(), delegate));
+ window->SetBounds(bounds);
+ window->Create();
+ return std::move(window);
}
scoped_ptr<NativeDisplayDelegate> CreateNativeDisplayDelegate() override {
@@ -74,7 +78,7 @@ class OzonePlatformX11 : public OzonePlatform {
}
void InitializeUI() override {
- // TODO(kylechar): Add PlatformEventSource creation here.
+ event_source_.reset(new X11EventSourceLibevent(gfx::GetXDisplay()));
surface_factory_ozone_.reset(new X11SurfaceFactory());
overlay_manager_.reset(new StubOverlayManager());
input_controller_ = CreateStubInputController();
@@ -89,6 +93,7 @@ class OzonePlatformX11 : public OzonePlatform {
private:
// Objects in the Browser process.
+ scoped_ptr<X11EventSourceLibevent> event_source_;
scoped_ptr<OverlayManagerOzone> overlay_manager_;
scoped_ptr<InputController> input_controller_;
scoped_ptr<BitmapCursorFactoryOzone> cursor_factory_ozone_;
diff --git a/ui/platform_window/x11/BUILD.gn b/ui/platform_window/x11/BUILD.gn
index 4775aa7..002f6de 100644
--- a/ui/platform_window/x11/BUILD.gn
+++ b/ui/platform_window/x11/BUILD.gn
@@ -3,8 +3,9 @@
# found in the LICENSE file.
import("//build/config/ui.gni")
+import("//ui/ozone/ozone.gni")
-assert(use_x11)
+assert(use_x11 || ozone_platform_x11)
component("x11") {
output_name = "x11_window"
@@ -25,8 +26,20 @@ component("x11") {
defines = [ "X11_WINDOW_IMPLEMENTATION" ]
sources = [
- "x11_window.cc",
- "x11_window.h",
+ "x11_window_base.cc",
+ "x11_window_base.h",
"x11_window_export.h",
]
+
+ if (ozone_platform_x11) {
+ sources += [
+ "x11_window_ozone.cc",
+ "x11_window_ozone.h",
+ ]
+ } else if (use_x11) {
+ sources += [
+ "x11_window.cc",
+ "x11_window.h",
+ ]
+ }
}
diff --git a/ui/platform_window/x11/x11_window.cc b/ui/platform_window/x11/x11_window.cc
index 6900a44..f54b416 100644
--- a/ui/platform_window/x11/x11_window.cc
+++ b/ui/platform_window/x11/x11_window.cc
@@ -5,74 +5,30 @@
#include "ui/platform_window/x11/x11_window.h"
#include <X11/extensions/XInput2.h>
-#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#include "base/strings/utf_string_conversions.h"
#include "ui/events/devices/x11/touch_factory_x11.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
-#include "ui/events/platform/platform_event_dispatcher.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/events/platform/x11/x11_event_source.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/x/x11_atom_cache.h"
-#include "ui/gfx/x/x11_types.h"
#include "ui/platform_window/platform_window_delegate.h"
namespace ui {
-namespace {
-
-const char* kAtomsToCache[] = {
- "UTF8_STRING",
- "WM_DELETE_WINDOW",
- "_NET_WM_NAME",
- "_NET_WM_PID",
- "_NET_WM_PING",
- NULL
-};
-
-XID FindXEventTarget(XEvent* xevent) {
- XID target = xevent->xany.window;
- if (xevent->type == GenericEvent)
- target = static_cast<XIDeviceEvent*>(xevent->xcookie.data)->event;
- return target;
-}
-
-bool g_override_redirect = false;
-
-} // namespace
-
X11Window::X11Window(PlatformWindowDelegate* delegate)
- : delegate_(delegate),
- xdisplay_(gfx::GetXDisplay()),
- xwindow_(None),
- xroot_window_(DefaultRootWindow(xdisplay_)),
- atom_cache_(xdisplay_, kAtomsToCache),
- window_mapped_(false) {
- CHECK(delegate_);
- TouchFactory::SetTouchDeviceListFromCommandLine();
+ : X11WindowBase(delegate) {
+ DCHECK(PlatformEventSource::GetInstance());
+ PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
}
X11Window::~X11Window() {
- Destroy();
-}
-
-void X11Window::Destroy() {
- if (xwindow_ == None)
- return;
-
- // Stop processing events.
PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
- XID xwindow = xwindow_;
- XDisplay* xdisplay = xdisplay_;
- xwindow_ = None;
- delegate_->OnClosed();
- // |this| might be deleted because of the above call.
+}
- XDestroyWindow(xdisplay, xwindow);
+void X11Window::SetCursor(PlatformCursor cursor) {
+ XDefineCursor(xdisplay(), xwindow(), cursor);
}
void X11Window::ProcessXInput2Event(XEvent* xev) {
@@ -83,7 +39,7 @@ void X11Window::ProcessXInput2Event(XEvent* xev) {
case ET_KEY_PRESSED:
case ET_KEY_RELEASED: {
KeyEvent key_event(xev);
- delegate_->DispatchEvent(&key_event);
+ delegate()->DispatchEvent(&key_event);
break;
}
case ET_MOUSE_PRESSED:
@@ -91,19 +47,19 @@ void X11Window::ProcessXInput2Event(XEvent* xev) {
case ET_MOUSE_DRAGGED:
case ET_MOUSE_RELEASED: {
MouseEvent mouse_event(xev);
- delegate_->DispatchEvent(&mouse_event);
+ delegate()->DispatchEvent(&mouse_event);
break;
}
case ET_MOUSEWHEEL: {
MouseWheelEvent wheel_event(xev);
- delegate_->DispatchEvent(&wheel_event);
+ delegate()->DispatchEvent(&wheel_event);
break;
}
case ET_SCROLL_FLING_START:
case ET_SCROLL_FLING_CANCEL:
case ET_SCROLL: {
ScrollEvent scroll_event(xev);
- delegate_->DispatchEvent(&scroll_event);
+ delegate()->DispatchEvent(&scroll_event);
break;
}
case ET_TOUCH_MOVED:
@@ -111,7 +67,7 @@ void X11Window::ProcessXInput2Event(XEvent* xev) {
case ET_TOUCH_CANCELLED:
case ET_TOUCH_RELEASED: {
TouchEvent touch_event(xev);
- delegate_->DispatchEvent(&touch_event);
+ delegate()->DispatchEvent(&touch_event);
break;
}
default:
@@ -119,182 +75,8 @@ void X11Window::ProcessXInput2Event(XEvent* xev) {
}
}
-void X11Window::Show() {
- if (window_mapped_)
- return;
-
- CHECK(PlatformEventSource::GetInstance());
- PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
-
- XSetWindowAttributes swa;
- memset(&swa, 0, sizeof(swa));
- swa.background_pixmap = None;
- swa.bit_gravity = NorthWestGravity;
- swa.override_redirect = g_override_redirect;
- xwindow_ = XCreateWindow(xdisplay_,
- xroot_window_,
- requested_bounds_.x(),
- requested_bounds_.y(),
- requested_bounds_.width(),
- requested_bounds_.height(),
- 0, // border width
- CopyFromParent, // depth
- InputOutput,
- CopyFromParent, // visual
- CWBackPixmap | CWBitGravity | CWOverrideRedirect,
- &swa);
-
- long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask |
- KeyPressMask | KeyReleaseMask | EnterWindowMask |
- LeaveWindowMask | ExposureMask | VisibilityChangeMask |
- StructureNotifyMask | PropertyChangeMask |
- PointerMotionMask;
- XSelectInput(xdisplay_, xwindow_, event_mask);
-
- unsigned char mask[XIMaskLen(XI_LASTEVENT)];
- memset(mask, 0, sizeof(mask));
-
- XISetMask(mask, XI_TouchBegin);
- XISetMask(mask, XI_TouchUpdate);
- XISetMask(mask, XI_TouchEnd);
- XISetMask(mask, XI_ButtonPress);
- XISetMask(mask, XI_ButtonRelease);
- XISetMask(mask, XI_Motion);
- XISetMask(mask, XI_KeyPress);
- XISetMask(mask, XI_KeyRelease);
-
- XIEventMask evmask;
- evmask.deviceid = XIAllDevices;
- evmask.mask_len = sizeof(mask);
- evmask.mask = mask;
- XISelectEvents(xdisplay_, xwindow_, &evmask, 1);
- XFlush(xdisplay_);
-
- ::Atom protocols[2];
- protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW");
- protocols[1] = atom_cache_.GetAtom("_NET_WM_PING");
- XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);
-
- // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with
- // the desktop environment.
- XSetWMProperties(
- xdisplay_, xwindow_, NULL, NULL, NULL, 0, NULL, NULL, NULL);
-
- // Likewise, the X server needs to know this window's pid so it knows which
- // program to kill if the window hangs.
- // XChangeProperty() expects "pid" to be long.
- static_assert(sizeof(long) >= sizeof(pid_t),
- "pid_t should not be larger than long");
- long pid = getpid();
- XChangeProperty(xdisplay_,
- xwindow_,
- atom_cache_.GetAtom("_NET_WM_PID"),
- XA_CARDINAL,
- 32,
- PropModeReplace,
- reinterpret_cast<unsigned char*>(&pid),
- 1);
- // Before we map the window, set size hints. Otherwise, some window managers
- // will ignore toplevel XMoveWindow commands.
- XSizeHints size_hints;
- size_hints.flags = PPosition | PWinGravity;
- size_hints.x = requested_bounds_.x();
- size_hints.y = requested_bounds_.y();
- // Set StaticGravity so that the window position is not affected by the
- // frame width when running with window manager.
- size_hints.win_gravity = StaticGravity;
- XSetWMNormalHints(xdisplay_, xwindow_, &size_hints);
-
- XMapWindow(xdisplay_, xwindow_);
-
- // We now block until our window is mapped. Some X11 APIs will crash and
- // burn if passed |xwindow_| before the window is mapped, and XMapWindow is
- // asynchronous.
- if (X11EventSource::GetInstance())
- X11EventSource::GetInstance()->BlockUntilWindowMapped(xwindow_);
- window_mapped_ = true;
-
- // TODO(sky): provide real scale factor.
- delegate_->OnAcceleratedWidgetAvailable(xwindow_, 1.f);
-}
-
-void X11Window::Hide() {
- if (!window_mapped_)
- return;
- XWithdrawWindow(xdisplay_, xwindow_, 0);
- window_mapped_ = false;
-}
-
-void X11Window::Close() {
- Destroy();
-}
-
-void X11Window::SetBounds(const gfx::Rect& bounds) {
- requested_bounds_ = bounds;
- if (!window_mapped_)
- return;
- XWindowChanges changes = {0};
- unsigned value_mask = CWX | CWY | CWWidth | CWHeight;
- changes.x = bounds.x();
- changes.y = bounds.y();
- changes.width = bounds.width();
- changes.height = bounds.height();
- XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes);
-}
-
-gfx::Rect X11Window::GetBounds() {
- return confirmed_bounds_;
-}
-
-void X11Window::SetTitle(const base::string16& title) {
- if (window_title_ == title)
- return;
- window_title_ = title;
- std::string utf8str = base::UTF16ToUTF8(title);
- XChangeProperty(xdisplay_,
- xwindow_,
- atom_cache_.GetAtom("_NET_WM_NAME"),
- atom_cache_.GetAtom("UTF8_STRING"),
- 8,
- PropModeReplace,
- reinterpret_cast<const unsigned char*>(utf8str.c_str()),
- utf8str.size());
- XTextProperty xtp;
- char *c_utf8_str = const_cast<char *>(utf8str.c_str());
- if (Xutf8TextListToTextProperty(xdisplay_, &c_utf8_str, 1,
- XUTF8StringStyle, &xtp) == Success) {
- XSetWMName(xdisplay_, xwindow_, &xtp);
- XFree(xtp.value);
- }
-}
-
-void X11Window::SetCapture() {}
-
-void X11Window::ReleaseCapture() {}
-
-void X11Window::ToggleFullscreen() {}
-
-void X11Window::Maximize() {}
-
-void X11Window::Minimize() {}
-
-void X11Window::Restore() {}
-
-void X11Window::SetCursor(PlatformCursor cursor) {
- XDefineCursor(xdisplay_, xwindow_, cursor);
-}
-
-void X11Window::MoveCursorTo(const gfx::Point& location) {}
-
-void X11Window::ConfineCursorToBounds(const gfx::Rect& bounds) {
-}
-
-PlatformImeController* X11Window::GetPlatformImeController() {
- return nullptr;
-}
-
-bool X11Window::CanDispatchEvent(const PlatformEvent& event) {
- return FindXEventTarget(event) == xwindow_;
+bool X11Window::CanDispatchEvent(const PlatformEvent& xev) {
+ return IsEventForXWindow(*xev);
}
uint32_t X11Window::DispatchEvent(const PlatformEvent& event) {
@@ -306,28 +88,19 @@ uint32_t X11Window::DispatchEvent(const PlatformEvent& event) {
MouseEvent mouse_event(xev);
CHECK_EQ(ET_MOUSE_MOVED, mouse_event.type());
mouse_event.set_flags(mouse_event.flags() | EF_IS_SYNTHESIZED);
- delegate_->DispatchEvent(&mouse_event);
+ delegate()->DispatchEvent(&mouse_event);
break;
}
case LeaveNotify: {
MouseEvent mouse_event(xev);
- delegate_->DispatchEvent(&mouse_event);
- break;
- }
-
- case Expose: {
- gfx::Rect damage_rect(xev->xexpose.x,
- xev->xexpose.y,
- xev->xexpose.width,
- xev->xexpose.height);
- delegate_->OnDamageRect(damage_rect);
+ delegate()->DispatchEvent(&mouse_event);
break;
}
case KeyPress:
case KeyRelease: {
KeyEvent key_event(xev);
- delegate_->DispatchEvent(&key_event);
+ delegate()->DispatchEvent(&key_event);
break;
}
@@ -336,13 +109,13 @@ uint32_t X11Window::DispatchEvent(const PlatformEvent& event) {
switch (EventTypeFromNative(xev)) {
case ET_MOUSEWHEEL: {
MouseWheelEvent mouseev(xev);
- delegate_->DispatchEvent(&mouseev);
+ delegate()->DispatchEvent(&mouseev);
break;
}
case ET_MOUSE_PRESSED:
case ET_MOUSE_RELEASED: {
MouseEvent mouseev(xev);
- delegate_->DispatchEvent(&mouseev);
+ delegate()->DispatchEvent(&mouseev);
break;
}
case ET_UNKNOWN:
@@ -355,40 +128,11 @@ uint32_t X11Window::DispatchEvent(const PlatformEvent& event) {
break;
}
+ case Expose:
case FocusOut:
- if (xev->xfocus.mode != NotifyGrab)
- delegate_->OnLostCapture();
- break;
-
- case ConfigureNotify: {
- DCHECK_EQ(xwindow_, xev->xconfigure.event);
- DCHECK_EQ(xwindow_, xev->xconfigure.window);
- gfx::Rect bounds(xev->xconfigure.x,
- xev->xconfigure.y,
- xev->xconfigure.width,
- xev->xconfigure.height);
- if (confirmed_bounds_ != bounds) {
- confirmed_bounds_ = bounds;
- delegate_->OnBoundsChanged(confirmed_bounds_);
- }
- break;
- }
-
+ case ConfigureNotify:
case ClientMessage: {
- Atom message = static_cast<Atom>(xev->xclient.data.l[0]);
- if (message == atom_cache_.GetAtom("WM_DELETE_WINDOW")) {
- delegate_->OnCloseRequest();
- } else if (message == atom_cache_.GetAtom("_NET_WM_PING")) {
- XEvent reply_event = *xev;
- reply_event.xclient.window = xroot_window_;
-
- XSendEvent(xdisplay_,
- reply_event.xclient.window,
- False,
- SubstructureRedirectMask | SubstructureNotifyMask,
- &reply_event);
- XFlush(xdisplay_);
- }
+ ProcessXWindowEvent(xev);
break;
}
@@ -400,11 +144,4 @@ uint32_t X11Window::DispatchEvent(const PlatformEvent& event) {
return POST_DISPATCH_STOP_PROPAGATION;
}
-namespace test {
-
-void SetUseOverrideRedirectWindowByDefault(bool override_redirect) {
- g_override_redirect = override_redirect;
-}
-
-} // namespace test
} // namespace ui
diff --git a/ui/platform_window/x11/x11_window.gyp b/ui/platform_window/x11/x11_window.gyp
index 0dd840a..f4b948a 100644
--- a/ui/platform_window/x11/x11_window.gyp
+++ b/ui/platform_window/x11/x11_window.gyp
@@ -26,6 +26,8 @@
'sources': [
'x11_window.cc',
'x11_window.h',
+ 'x11_window_base.cc',
+ 'x11_window_base.h',
'x11_window_export.h',
],
}],
diff --git a/ui/platform_window/x11/x11_window.h b/ui/platform_window/x11/x11_window.h
index 54bbed8..c3f15cf 100644
--- a/ui/platform_window/x11/x11_window.h
+++ b/ui/platform_window/x11/x11_window.h
@@ -5,86 +5,33 @@
#ifndef UI_PLATFORM_WINDOW_X11_X11_WINDOW_H_
#define UI_PLATFORM_WINDOW_X11_X11_WINDOW_H_
-#include <stdint.h>
-
#include "base/macros.h"
#include "ui/events/platform/platform_event_dispatcher.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/x/x11_atom_cache.h"
-#include "ui/platform_window/platform_window.h"
-#include "ui/platform_window/platform_window_delegate.h"
+#include "ui/platform_window/x11/x11_window_base.h"
#include "ui/platform_window/x11/x11_window_export.h"
-typedef struct _XDisplay XDisplay;
-typedef unsigned long XID;
-
namespace ui {
-class X11_WINDOW_EXPORT X11Window : public PlatformWindow,
+// PlatformWindow implementation for X11. PlatformEvents are XEvents.
+class X11_WINDOW_EXPORT X11Window : public X11WindowBase,
public PlatformEventDispatcher {
public:
explicit X11Window(PlatformWindowDelegate* delegate);
~X11Window() override;
- private:
- void Destroy();
-
- void ProcessXInput2Event(XEvent* xevent);
-
// PlatformWindow:
- void Show() override;
- void Hide() override;
- void Close() override;
- void SetBounds(const gfx::Rect& bounds) override;
- gfx::Rect GetBounds() override;
- void SetTitle(const base::string16& title) override;
- void SetCapture() override;
- void ReleaseCapture() override;
- void ToggleFullscreen() override;
- void Maximize() override;
- void Minimize() override;
- void Restore() override;
void SetCursor(PlatformCursor cursor) override;
- void MoveCursorTo(const gfx::Point& location) override;
- void ConfineCursorToBounds(const gfx::Rect& bounds) override;
- PlatformImeController* GetPlatformImeController() override;
+
+ private:
+ void ProcessXInput2Event(XEvent* xev);
// PlatformEventDispatcher:
bool CanDispatchEvent(const PlatformEvent& event) override;
uint32_t DispatchEvent(const PlatformEvent& event) override;
- PlatformWindowDelegate* delegate_;
-
- XDisplay* xdisplay_;
- XID xwindow_;
- XID xroot_window_;
- X11AtomCache atom_cache_;
-
- base::string16 window_title_;
-
- // Setting the bounds is an asynchronous operation in X11. |requested_bounds_|
- // is the bounds requested using XConfigureWindow, and |confirmed_bounds_| is
- // the bounds the X11 server has set on the window.
- gfx::Rect requested_bounds_;
- gfx::Rect confirmed_bounds_;
-
- bool window_mapped_;
-
DISALLOW_COPY_AND_ASSIGN(X11Window);
};
-namespace test {
-
-// Sets the value of the |override_redirect| flag when creating an X11 window.
-// It is necessary to set this flag on for various tests, otherwise the call to
-// X11Window::Show() blocks because it never receives the MapNotify event. It is
-// unclear why this is necessary, but might be related to calls to
-// XInitThreads().
-X11_WINDOW_EXPORT void SetUseOverrideRedirectWindowByDefault(
- bool override_redirect);
-
-} // namespace test
-
} // namespace ui
#endif // UI_PLATFORM_WINDOW_X11_X11_WINDOW_H_
diff --git a/ui/platform_window/x11/x11_window_base.cc b/ui/platform_window/x11/x11_window_base.cc
new file mode 100644
index 0000000..4c24d7e
--- /dev/null
+++ b/ui/platform_window/x11/x11_window_base.cc
@@ -0,0 +1,284 @@
+// 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/platform_window/x11/x11_window_base.h"
+
+#include <X11/extensions/XInput2.h>
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include <string>
+
+#include "base/strings/utf_string_conversions.h"
+#include "ui/events/devices/x11/touch_factory_x11.h"
+#include "ui/events/event.h"
+#include "ui/events/event_utils.h"
+#include "ui/events/platform/platform_event_dispatcher.h"
+#include "ui/events/platform/platform_event_source.h"
+#include "ui/events/platform/x11/x11_event_source.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/x/x11_atom_cache.h"
+#include "ui/gfx/x/x11_types.h"
+#include "ui/platform_window/platform_window_delegate.h"
+
+namespace ui {
+
+namespace {
+
+const char* kAtomsToCache[] = {"UTF8_STRING", "WM_DELETE_WINDOW",
+ "_NET_WM_NAME", "_NET_WM_PID",
+ "_NET_WM_PING", NULL};
+
+bool g_override_redirect = false;
+
+XID FindXEventTarget(const XEvent& xev) {
+ XID target = xev.xany.window;
+ if (xev.type == GenericEvent)
+ target = static_cast<XIDeviceEvent*>(xev.xcookie.data)->event;
+ return target;
+}
+
+} // namespace
+
+X11WindowBase::X11WindowBase(PlatformWindowDelegate* delegate)
+ : delegate_(delegate),
+ xdisplay_(gfx::GetXDisplay()),
+ xwindow_(None),
+ xroot_window_(DefaultRootWindow(xdisplay_)),
+ atom_cache_(xdisplay_, kAtomsToCache) {
+ DCHECK(delegate_);
+ TouchFactory::SetTouchDeviceListFromCommandLine();
+}
+
+X11WindowBase::~X11WindowBase() {
+ Destroy();
+}
+
+void X11WindowBase::Destroy() {
+ if (xwindow_ == None)
+ return;
+
+ // Stop processing events.
+ XID xwindow = xwindow_;
+ XDisplay* xdisplay = xdisplay_;
+ xwindow_ = None;
+ delegate_->OnClosed();
+ // |this| might be deleted because of the above call.
+
+ XDestroyWindow(xdisplay, xwindow);
+}
+
+void X11WindowBase::Create() {
+ XSetWindowAttributes swa;
+ memset(&swa, 0, sizeof(swa));
+ swa.background_pixmap = None;
+ swa.bit_gravity = NorthWestGravity;
+ swa.override_redirect = g_override_redirect;
+ xwindow_ = XCreateWindow(
+ xdisplay_, xroot_window_, requested_bounds_.x(), requested_bounds_.y(),
+ requested_bounds_.width(), requested_bounds_.height(),
+ 0, // border width
+ CopyFromParent, // depth
+ InputOutput,
+ CopyFromParent, // visual
+ CWBackPixmap | CWBitGravity | CWOverrideRedirect, &swa);
+
+ long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask |
+ KeyPressMask | KeyReleaseMask | EnterWindowMask |
+ LeaveWindowMask | ExposureMask | VisibilityChangeMask |
+ StructureNotifyMask | PropertyChangeMask |
+ PointerMotionMask;
+ XSelectInput(xdisplay_, xwindow_, event_mask);
+
+ unsigned char mask[XIMaskLen(XI_LASTEVENT)];
+ memset(mask, 0, sizeof(mask));
+
+ XISetMask(mask, XI_TouchBegin);
+ XISetMask(mask, XI_TouchUpdate);
+ XISetMask(mask, XI_TouchEnd);
+ XISetMask(mask, XI_ButtonPress);
+ XISetMask(mask, XI_ButtonRelease);
+ XISetMask(mask, XI_Motion);
+ XISetMask(mask, XI_KeyPress);
+ XISetMask(mask, XI_KeyRelease);
+
+ XIEventMask evmask;
+ evmask.deviceid = XIAllDevices;
+ evmask.mask_len = sizeof(mask);
+ evmask.mask = mask;
+ XISelectEvents(xdisplay_, xwindow_, &evmask, 1);
+ XFlush(xdisplay_);
+
+ ::Atom protocols[2];
+ protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW");
+ protocols[1] = atom_cache_.GetAtom("_NET_WM_PING");
+ XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);
+
+ // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with
+ // the desktop environment.
+ XSetWMProperties(xdisplay_, xwindow_, NULL, NULL, NULL, 0, NULL, NULL, NULL);
+
+ // Likewise, the X server needs to know this window's pid so it knows which
+ // program to kill if the window hangs.
+ // XChangeProperty() expects "pid" to be long.
+ static_assert(sizeof(long) >= sizeof(pid_t),
+ "pid_t should not be larger than long");
+ long pid = getpid();
+ XChangeProperty(xdisplay_, xwindow_, atom_cache_.GetAtom("_NET_WM_PID"),
+ XA_CARDINAL, 32, PropModeReplace,
+ reinterpret_cast<unsigned char*>(&pid), 1);
+ // Before we map the window, set size hints. Otherwise, some window managers
+ // will ignore toplevel XMoveWindow commands.
+ XSizeHints size_hints;
+ size_hints.flags = PPosition | PWinGravity;
+ size_hints.x = requested_bounds_.x();
+ size_hints.y = requested_bounds_.y();
+ // Set StaticGravity so that the window position is not affected by the
+ // frame width when running with window manager.
+ size_hints.win_gravity = StaticGravity;
+ XSetWMNormalHints(xdisplay_, xwindow_, &size_hints);
+
+ // TODO(sky): provide real scale factor.
+ delegate_->OnAcceleratedWidgetAvailable(xwindow_, 1.f);
+}
+
+void X11WindowBase::Show() {
+ if (window_mapped_)
+ return;
+ if (xwindow_ == None)
+ Create();
+
+ XMapWindow(xdisplay_, xwindow_);
+
+ // We now block until our window is mapped. Some X11 APIs will crash and
+ // burn if passed |xwindow_| before the window is mapped, and XMapWindow is
+ // asynchronous.
+ if (X11EventSource::GetInstance())
+ X11EventSource::GetInstance()->BlockUntilWindowMapped(xwindow_);
+ window_mapped_ = true;
+}
+
+void X11WindowBase::Hide() {
+ if (!window_mapped_)
+ return;
+ XWithdrawWindow(xdisplay_, xwindow_, 0);
+ window_mapped_ = false;
+}
+
+void X11WindowBase::Close() {
+ Destroy();
+}
+
+void X11WindowBase::SetBounds(const gfx::Rect& bounds) {
+ requested_bounds_ = bounds;
+ if (!window_mapped_ || bounds == confirmed_bounds_)
+ return;
+ XWindowChanges changes = {0};
+ unsigned value_mask = CWX | CWY | CWWidth | CWHeight;
+ changes.x = bounds.x();
+ changes.y = bounds.y();
+ changes.width = bounds.width();
+ changes.height = bounds.height();
+ XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes);
+}
+
+gfx::Rect X11WindowBase::GetBounds() {
+ return confirmed_bounds_;
+}
+
+void X11WindowBase::SetTitle(const base::string16& title) {
+ if (window_title_ == title)
+ return;
+ window_title_ = title;
+ std::string utf8str = base::UTF16ToUTF8(title);
+ XChangeProperty(xdisplay_, xwindow_, atom_cache_.GetAtom("_NET_WM_NAME"),
+ atom_cache_.GetAtom("UTF8_STRING"), 8, PropModeReplace,
+ reinterpret_cast<const unsigned char*>(utf8str.c_str()),
+ utf8str.size());
+ XTextProperty xtp;
+ char* c_utf8_str = const_cast<char*>(utf8str.c_str());
+ if (Xutf8TextListToTextProperty(xdisplay_, &c_utf8_str, 1, XUTF8StringStyle,
+ &xtp) == Success) {
+ XSetWMName(xdisplay_, xwindow_, &xtp);
+ XFree(xtp.value);
+ }
+}
+
+void X11WindowBase::SetCapture() {}
+
+void X11WindowBase::ReleaseCapture() {}
+
+void X11WindowBase::ToggleFullscreen() {}
+
+void X11WindowBase::Maximize() {}
+
+void X11WindowBase::Minimize() {}
+
+void X11WindowBase::Restore() {}
+
+void X11WindowBase::MoveCursorTo(const gfx::Point& location) {}
+
+void X11WindowBase::ConfineCursorToBounds(const gfx::Rect& bounds) {}
+
+PlatformImeController* X11WindowBase::GetPlatformImeController() {
+ return nullptr;
+}
+
+bool X11WindowBase::IsEventForXWindow(const XEvent& xev) const {
+ return xwindow_ != None && FindXEventTarget(xev) == xwindow_;
+}
+
+void X11WindowBase::ProcessXWindowEvent(XEvent* xev) {
+ switch (xev->type) {
+ case Expose: {
+ gfx::Rect damage_rect(xev->xexpose.x, xev->xexpose.y, xev->xexpose.width,
+ xev->xexpose.height);
+ delegate_->OnDamageRect(damage_rect);
+ break;
+ }
+
+ case FocusOut:
+ if (xev->xfocus.mode != NotifyGrab)
+ delegate_->OnLostCapture();
+ break;
+
+ case ConfigureNotify: {
+ DCHECK_EQ(xwindow_, xev->xconfigure.event);
+ DCHECK_EQ(xwindow_, xev->xconfigure.window);
+ gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y,
+ xev->xconfigure.width, xev->xconfigure.height);
+ if (confirmed_bounds_ != bounds) {
+ confirmed_bounds_ = bounds;
+ delegate_->OnBoundsChanged(confirmed_bounds_);
+ }
+ break;
+ }
+
+ case ClientMessage: {
+ Atom message = static_cast<Atom>(xev->xclient.data.l[0]);
+ if (message == atom_cache_.GetAtom("WM_DELETE_WINDOW")) {
+ delegate_->OnCloseRequest();
+ } else if (message == atom_cache_.GetAtom("_NET_WM_PING")) {
+ XEvent reply_event = *xev;
+ reply_event.xclient.window = xroot_window_;
+
+ XSendEvent(xdisplay_, reply_event.xclient.window, False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &reply_event);
+ XFlush(xdisplay_);
+ }
+ break;
+ }
+ }
+}
+
+namespace test {
+
+void SetUseOverrideRedirectWindowByDefault(bool override_redirect) {
+ g_override_redirect = override_redirect;
+}
+
+} // namespace test
+} // namespace ui
diff --git a/ui/platform_window/x11/x11_window_base.h b/ui/platform_window/x11/x11_window_base.h
new file mode 100644
index 0000000..da35725
--- /dev/null
+++ b/ui/platform_window/x11/x11_window_base.h
@@ -0,0 +1,100 @@
+// 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.
+
+#ifndef UI_PLATFORM_WINDOW_X11_X11_WINDOW_BASE_H_
+#define UI_PLATFORM_WINDOW_X11_X11_WINDOW_BASE_H_
+
+#include <stdint.h>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/x/x11_atom_cache.h"
+#include "ui/platform_window/platform_window.h"
+#include "ui/platform_window/platform_window_delegate.h"
+#include "ui/platform_window/x11/x11_window_export.h"
+
+typedef struct _XDisplay XDisplay;
+typedef unsigned long XID;
+typedef union _XEvent XEvent;
+
+namespace ui {
+
+// Abstract base implementation for a X11 based PlatformWindow. Methods that
+// are platform specific are left unimplemented.
+class X11_WINDOW_EXPORT X11WindowBase : public PlatformWindow {
+ public:
+ explicit X11WindowBase(PlatformWindowDelegate* delegate);
+ ~X11WindowBase() override;
+
+ // Creates new underlying XWindow. Does not map XWindow.
+ void Create();
+
+ // PlatformWindow:
+ void Show() override;
+ void Hide() override;
+ void Close() override;
+ void SetBounds(const gfx::Rect& bounds) override;
+ gfx::Rect GetBounds() override;
+ void SetTitle(const base::string16& title) override;
+ void SetCapture() override;
+ void ReleaseCapture() override;
+ void ToggleFullscreen() override;
+ void Maximize() override;
+ void Minimize() override;
+ void Restore() override;
+ void MoveCursorTo(const gfx::Point& location) override;
+ void ConfineCursorToBounds(const gfx::Rect& bounds) override;
+ PlatformImeController* GetPlatformImeController() override;
+
+ protected:
+ void Destroy();
+
+ PlatformWindowDelegate* delegate() { return delegate_; }
+ XDisplay* xdisplay() { return xdisplay_; }
+ XID xwindow() const { return xwindow_; }
+
+ // Checks if XEvent is for this XWindow.
+ bool IsEventForXWindow(const XEvent& xev) const;
+
+ // Processes events for this XWindow.
+ void ProcessXWindowEvent(XEvent* xev);
+
+ private:
+ PlatformWindowDelegate* delegate_;
+
+ XDisplay* xdisplay_;
+ XID xwindow_;
+ XID xroot_window_;
+ X11AtomCache atom_cache_;
+
+ base::string16 window_title_;
+
+ // Setting the bounds is an asynchronous operation in X11. |requested_bounds_|
+ // is the bounds requested using XConfigureWindow, and |confirmed_bounds_| is
+ // the bounds the X11 server has set on the window.
+ gfx::Rect requested_bounds_;
+ gfx::Rect confirmed_bounds_;
+
+ bool window_mapped_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(X11WindowBase);
+};
+
+namespace test {
+
+// Sets the value of the |override_redirect| flag when creating an X11 window.
+// It is necessary to set this flag on for various tests, otherwise the call to
+// X11WindowBase::Show() blocks because it never receives the MapNotify event.
+// It is
+// unclear why this is necessary, but might be related to calls to
+// XInitThreads().
+X11_WINDOW_EXPORT void SetUseOverrideRedirectWindowByDefault(
+ bool override_redirect);
+
+} // namespace test
+
+} // namespace ui
+
+#endif // UI_PLATFORM_WINDOW_X11_X11_WINDOW_BASE_H_
diff --git a/ui/platform_window/x11/x11_window_ozone.cc b/ui/platform_window/x11/x11_window_ozone.cc
new file mode 100644
index 0000000..6193b1f
--- /dev/null
+++ b/ui/platform_window/x11/x11_window_ozone.cc
@@ -0,0 +1,51 @@
+// 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/platform_window/x11/x11_window_ozone.h"
+
+#include <X11/Xlib.h>
+
+#include "ui/events/event.h"
+#include "ui/events/ozone/events_ozone.h"
+#include "ui/events/platform/x11/x11_event_source.h"
+#include "ui/gfx/geometry/point.h"
+
+namespace ui {
+
+X11WindowOzone::X11WindowOzone(X11EventSourceLibevent* event_source,
+ PlatformWindowDelegate* delegate)
+ : X11WindowBase(delegate), event_source_(event_source) {
+ DCHECK(event_source_);
+ event_source_->AddPlatformEventDispatcher(this);
+ event_source_->AddXEventDispatcher(this);
+}
+
+X11WindowOzone::~X11WindowOzone() {
+ event_source_->RemovePlatformEventDispatcher(this);
+ event_source_->RemoveXEventDispatcher(this);
+}
+
+void X11WindowOzone::SetCursor(PlatformCursor cursor) {}
+
+bool X11WindowOzone::DispatchXEvent(XEvent* xev) {
+ if (!IsEventForXWindow(*xev))
+ return false;
+
+ ProcessXWindowEvent(xev);
+ return true;
+}
+
+bool X11WindowOzone::CanDispatchEvent(const PlatformEvent& event) {
+ // TODO(kylechar): This is broken, there is no way to include XID of XWindow
+ // in ui::Event. Fix or use similar hack to DrmWindowHost.
+ return xwindow() != None;
+}
+
+uint32_t X11WindowOzone::DispatchEvent(const PlatformEvent& platform_event) {
+ Event* event = static_cast<Event*>(platform_event);
+ delegate()->DispatchEvent(event);
+ return POST_DISPATCH_STOP_PROPAGATION;
+}
+
+} // namespace ui
diff --git a/ui/platform_window/x11/x11_window_ozone.h b/ui/platform_window/x11/x11_window_ozone.h
new file mode 100644
index 0000000..b6c4573
--- /dev/null
+++ b/ui/platform_window/x11/x11_window_ozone.h
@@ -0,0 +1,42 @@
+// 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.
+
+#ifndef UI_PLATFORM_WINDOW_X11_X11_WINDOW_OZONE_H_
+#define UI_PLATFORM_WINDOW_X11_X11_WINDOW_OZONE_H_
+
+#include "base/macros.h"
+#include "ui/events/platform/platform_event_dispatcher.h"
+#include "ui/events/platform/x11/x11_event_source_libevent.h"
+#include "ui/platform_window/x11/x11_window_base.h"
+
+namespace ui {
+
+// PlatformWindow implementation for X11 Ozone. PlatformEvents are ui::Events.
+class X11_WINDOW_EXPORT X11WindowOzone : public X11WindowBase,
+ public PlatformEventDispatcher,
+ public XEventDispatcher {
+ public:
+ X11WindowOzone(X11EventSourceLibevent* event_source,
+ PlatformWindowDelegate* delegate);
+ ~X11WindowOzone() override;
+
+ // PlatformWindow:
+ void SetCursor(PlatformCursor cursor) override;
+
+ // XEventDispatcher:
+ bool DispatchXEvent(XEvent* event) override;
+
+ private:
+ // PlatformEventDispatcher:
+ bool CanDispatchEvent(const PlatformEvent& event) override;
+ uint32_t DispatchEvent(const PlatformEvent& event) override;
+
+ X11EventSourceLibevent* event_source_;
+
+ DISALLOW_COPY_AND_ASSIGN(X11WindowOzone);
+};
+
+} // namespace ui
+
+#endif // UI_PLATFORM_WINDOW_X11_X11_WINDOW_OZONE_H_
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
index 162cf3c..327c3d5 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
@@ -24,7 +24,7 @@
#include "ui/base/hit_test.h"
#include "ui/base/x/x11_util.h"
#include "ui/events/devices/x11/touch_factory_x11.h"
-#include "ui/events/platform/x11/x11_event_source.h"
+#include "ui/events/platform/x11/x11_event_source_glib.h"
#include "ui/events/test/platform_event_source_test_api.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
diff --git a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
index a33f12f..34eb824 100644
--- a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
+++ b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
@@ -22,6 +22,7 @@
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/events/keycodes/keyboard_code_conversion_x.h"
+#include "ui/events/platform/platform_event_source.h"
#include "ui/events/platform/scoped_event_dispatcher.h"
#include "ui/events/platform/x11/x11_event_source.h"
#include "ui/views/widget/desktop_aura/x11_pointer_grab.h"