Commit 0f27deab authored by Tom Anderson's avatar Tom Anderson Committed by Commit Bot

[XProto] Remove XInput, XTest, and XRecord extensions

XTest/XRecord include XInput, so we need to get rid of those too
if we want to get rid of the macros etc that XInput provides.

Depends on WebRTC CL:
https://webrtc-review.googlesource.com/c/src/+/180773

BUG=1066670
R=nickdiego,sky

Change-Id: Id3b3cb61196cf10bc47976957d8b290877020d5c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2327373
Commit-Queue: Thomas Anderson <thomasanderson@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarLambros Lambrou <lambroslambrou@chromium.org>
Reviewed-by: default avatarNick Yamane <nickdiego@igalia.com>
Cr-Commit-Position: refs/heads/master@{#797453}
parent aa0943f0
...@@ -45,9 +45,7 @@ config("x11") { ...@@ -45,9 +45,7 @@ config("x11") {
"Xdamage", "Xdamage",
"Xext", "Xext",
"Xfixes", "Xfixes",
"Xi",
"Xrender", "Xrender",
"Xtst",
] ]
} }
...@@ -67,14 +65,6 @@ config("libcap") { ...@@ -67,14 +65,6 @@ config("libcap") {
libs = [ "cap" ] libs = [ "cap" ]
} }
config("xi") {
libs = [ "Xi" ]
}
config("xtst") {
libs = [ "Xtst" ]
}
config("libresolv") { config("libresolv") {
libs = [ "resolv" ] libs = [ "resolv" ]
} }
......
...@@ -6262,10 +6262,6 @@ if (!is_android) { ...@@ -6262,10 +6262,6 @@ if (!is_android) {
sources += [ "../browser/downgrade/user_data_snapshot_browsertest.cc" ] sources += [ "../browser/downgrade/user_data_snapshot_browsertest.cc" ]
} }
if (use_x11) {
configs += [ "//build/config/linux:xtst" ]
}
if (enable_extensions) { if (enable_extensions) {
# TODO(rockot) bug 505926: The chrome_extensions_interactive_uitests # TODO(rockot) bug 505926: The chrome_extensions_interactive_uitests
# target should be deleted and this line removed. See the # target should be deleted and this line removed. See the
......
...@@ -384,6 +384,7 @@ source_set("base") { ...@@ -384,6 +384,7 @@ source_set("base") {
sources += [ "user_input_monitor_linux.cc" ] sources += [ "user_input_monitor_linux.cc" ]
deps += [ deps += [
"//ui/events:events_base", "//ui/events:events_base",
"//ui/events/devices/x11",
"//ui/gfx/x", "//ui/gfx/x",
] ]
} else if (is_mac) { } else if (is_mac) {
......
This diff is collapsed.
...@@ -132,7 +132,7 @@ BasicDesktopEnvironment::BasicDesktopEnvironment( ...@@ -132,7 +132,7 @@ BasicDesktopEnvironment::BasicDesktopEnvironment(
DCHECK(caller_task_runner_->BelongsToCurrentThread()); DCHECK(caller_task_runner_->BelongsToCurrentThread());
#if defined(USE_X11) #if defined(USE_X11)
if (!features::IsUsingOzonePlatform()) if (!features::IsUsingOzonePlatform())
IgnoreXServerGrabs(desktop_capture_options().x_display()->display(), true); desktop_capture_options().x_display()->IgnoreXServerGrabs();
#elif defined(OS_WIN) #elif defined(OS_WIN)
// The options passed to this instance are determined by a process running in // The options passed to this instance are determined by a process running in
// Session 0. Access to DirectX functions in Session 0 is limited so the // Session 0. Access to DirectX functions in Session 0 is limited so the
......
...@@ -10,7 +10,9 @@ ...@@ -10,7 +10,9 @@
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "remoting/base/logging.h" #include "remoting/base/logging.h"
#include "remoting/host/client_session_control.h" #include "remoting/host/client_session_control.h"
#include "ui/gfx/x/x11.h" #include "ui/gfx/x/connection.h"
#include "ui/gfx/x/xinput.h"
#include "ui/gfx/x/xproto_types.h"
namespace remoting { namespace remoting {
...@@ -28,8 +30,7 @@ class CurtainModeLinux : public CurtainMode { ...@@ -28,8 +30,7 @@ class CurtainModeLinux : public CurtainMode {
DISALLOW_COPY_AND_ASSIGN(CurtainModeLinux); DISALLOW_COPY_AND_ASSIGN(CurtainModeLinux);
}; };
CurtainModeLinux::CurtainModeLinux() { CurtainModeLinux::CurtainModeLinux() = default;
}
bool CurtainModeLinux::Activate() { bool CurtainModeLinux::Activate() {
// We can't curtain the session in run-time in Linux. // We can't curtain the session in run-time in Linux.
...@@ -48,60 +49,60 @@ bool CurtainModeLinux::IsVirtualSession() { ...@@ -48,60 +49,60 @@ bool CurtainModeLinux::IsVirtualSession() {
// Try to identify a virtual session. Since there's no way to tell from the // Try to identify a virtual session. Since there's no way to tell from the
// vendor string, we check for known virtual input devices. // vendor string, we check for known virtual input devices.
// TODO(rmsousa): Find a similar way to determine that the *output* is secure. // TODO(rmsousa): Find a similar way to determine that the *output* is secure.
Display* display = XOpenDisplay(nullptr); x11::Connection connection;
int opcode, event, error; if (!connection.xinput().present()) {
if (!XQueryExtension(display, "XInputExtension", &opcode, &event, &error)) {
// If XInput is not available, assume it is not a virtual session. // If XInput is not available, assume it is not a virtual session.
LOG(ERROR) << "X Input extension not available: " << error; LOG(ERROR) << "X Input extension not available";
XCloseDisplay(display);
return false; return false;
} }
int num_devices;
XDeviceInfo* devices; auto devices = connection.xinput().ListInputDevices({}).Sync();
if (!devices) {
LOG(ERROR) << "ListInputDevices failed";
return false;
}
bool found_xvfb_mouse = false; bool found_xvfb_mouse = false;
bool found_xvfb_keyboard = false; bool found_xvfb_keyboard = false;
bool found_crd_void_input = false; bool found_crd_void_input = false;
bool found_other_devices = false; bool found_other_devices = false;
devices = XListInputDevices(display, &num_devices); for (size_t i = 0; i < devices->devices.size(); i++) {
for (int i = 0; i < num_devices; i++) { const auto& device_info = devices->devices[i];
XDeviceInfo* device_info = &devices[i]; const std::string& name = devices->names[i].name;
if (device_info->use == IsXExtensionPointer) { if (device_info.device_use == x11::Input::DeviceUse::IsXExtensionPointer) {
if (strcmp(device_info->name, "Xvfb mouse") == 0) { if (name == "Xvfb mouse") {
found_xvfb_mouse = true; found_xvfb_mouse = true;
} else if (strcmp(device_info->name, } else if (name == "Chrome Remote Desktop Input") {
"Chrome Remote Desktop Input") == 0) {
found_crd_void_input = true; found_crd_void_input = true;
} else if (strcmp(device_info->name, "Virtual core XTEST pointer") != 0) { } else if (name != "Virtual core XTEST pointer") {
found_other_devices = true; found_other_devices = true;
HOST_LOG << "Non-virtual mouse found: " << device_info->name; HOST_LOG << "Non-virtual mouse found: " << name;
} }
} else if (device_info->use == IsXExtensionKeyboard) { } else if (device_info.device_use ==
if (strcmp(device_info->name, "Xvfb keyboard") == 0) { x11::Input::DeviceUse::IsXExtensionKeyboard) {
if (name == "Xvfb keyboard") {
found_xvfb_keyboard = true; found_xvfb_keyboard = true;
} else if (strcmp(device_info->name, } else if (name != "Virtual core XTEST keyboard") {
"Virtual core XTEST keyboard") != 0) {
found_other_devices = true; found_other_devices = true;
HOST_LOG << "Non-virtual keyboard found: " << device_info->name; HOST_LOG << "Non-virtual keyboard found: " << name;
} }
} else if (device_info->use == IsXPointer) { } else if (device_info.device_use == x11::Input::DeviceUse::IsXPointer) {
if (strcmp(device_info->name, "Virtual core pointer") != 0) { if (name != "Virtual core pointer") {
found_other_devices = true; found_other_devices = true;
HOST_LOG << "Non-virtual mouse found: " << device_info->name; HOST_LOG << "Non-virtual mouse found: " << name;
} }
} else if (device_info->use == IsXKeyboard) { } else if (device_info.device_use == x11::Input::DeviceUse::IsXKeyboard) {
if (strcmp(device_info->name, "Virtual core keyboard") != 0) { if (name != "Virtual core keyboard") {
found_other_devices = true; found_other_devices = true;
HOST_LOG << "Non-virtual keyboard found: " << device_info->name; HOST_LOG << "Non-virtual keyboard found: " << name;
} }
} else { } else {
found_other_devices = true; found_other_devices = true;
HOST_LOG << "Non-virtual device found: " << device_info->name; HOST_LOG << "Non-virtual device found: " << name;
} }
} }
XFreeDeviceList(devices); return ((found_xvfb_mouse && found_xvfb_keyboard) || found_crd_void_input) &&
XCloseDisplay(display); !found_other_devices;
return ((found_xvfb_mouse && found_xvfb_keyboard) || found_crd_void_input)
&& !found_other_devices;
} }
// static // static
......
This diff is collapsed.
...@@ -18,7 +18,10 @@ ...@@ -18,7 +18,10 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/sequence_checker.h" #include "base/sequence_checker.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "ui/events/devices/x11/xinput_util.h"
#include "ui/gfx/x/connection.h"
#include "ui/gfx/x/x11.h" #include "ui/gfx/x/x11.h"
#include "ui/gfx/x/xinput.h"
namespace remoting { namespace remoting {
...@@ -34,7 +37,8 @@ class LocalHotkeyInputMonitorX11 : public LocalHotkeyInputMonitor { ...@@ -34,7 +37,8 @@ class LocalHotkeyInputMonitorX11 : public LocalHotkeyInputMonitor {
private: private:
// The implementation resides in LocalHotkeyInputMonitorX11::Core class. // The implementation resides in LocalHotkeyInputMonitorX11::Core class.
class Core : public base::RefCountedThreadSafe<Core> { class Core : public base::RefCountedThreadSafe<Core>,
public x11::Connection::Delegate {
public: public:
Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
...@@ -45,18 +49,17 @@ class LocalHotkeyInputMonitorX11 : public LocalHotkeyInputMonitor { ...@@ -45,18 +49,17 @@ class LocalHotkeyInputMonitorX11 : public LocalHotkeyInputMonitor {
private: private:
friend class base::RefCountedThreadSafe<Core>; friend class base::RefCountedThreadSafe<Core>;
~Core(); ~Core() override;
void StartOnInputThread(); void StartOnInputThread();
void StopOnInputThread(); void StopOnInputThread();
// Called when there are pending X events. // Called when there are pending X events.
void OnPendingXEvents(); void OnConnectionData();
// Processes key events. // x11::Connection::Delegate:
void ProcessXEvent(xEvent* event); bool ShouldContinueStream() const override;
void DispatchXEvent(x11::Event* event) override;
static void ProcessReply(XPointer self, XRecordInterceptData* data);
// Task runner on which public methods of this class must be called. // Task runner on which public methods of this class must be called.
scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
...@@ -76,10 +79,7 @@ class LocalHotkeyInputMonitorX11 : public LocalHotkeyInputMonitor { ...@@ -76,10 +79,7 @@ class LocalHotkeyInputMonitorX11 : public LocalHotkeyInputMonitor {
// True when Ctrl is pressed. // True when Ctrl is pressed.
bool ctrl_pressed_ = false; bool ctrl_pressed_ = false;
Display* display_ = nullptr; std::unique_ptr<x11::Connection> connection_;
Display* x_record_display_ = nullptr;
XRecordRange* x_record_range_ = nullptr;
XRecordContext x_record_context_ = 0;
DISALLOW_COPY_AND_ASSIGN(Core); DISALLOW_COPY_AND_ASSIGN(Core);
}; };
...@@ -132,114 +132,58 @@ void LocalHotkeyInputMonitorX11::Core::Stop() { ...@@ -132,114 +132,58 @@ void LocalHotkeyInputMonitorX11::Core::Stop() {
} }
LocalHotkeyInputMonitorX11::Core::~Core() { LocalHotkeyInputMonitorX11::Core::~Core() {
DCHECK(!display_); DCHECK(!connection_);
DCHECK(!x_record_display_);
DCHECK(!x_record_range_);
DCHECK(!x_record_context_);
} }
void LocalHotkeyInputMonitorX11::Core::StartOnInputThread() { void LocalHotkeyInputMonitorX11::Core::StartOnInputThread() {
DCHECK(input_task_runner_->BelongsToCurrentThread()); DCHECK(input_task_runner_->BelongsToCurrentThread());
DCHECK(!display_); DCHECK(!connection_);
DCHECK(!x_record_display_);
DCHECK(!x_record_range_);
DCHECK(!x_record_context_);
// TODO(jamiewalch): We should pass the display in. At that point, since
// XRecord needs a private connection to the X Server for its data channel
// and both channels are used from a separate thread, we'll need to duplicate
// them with something like the following:
// XOpenDisplay(DisplayString(display));
display_ = XOpenDisplay(nullptr);
x_record_display_ = XOpenDisplay(nullptr);
if (!display_ || !x_record_display_) {
LOG(ERROR) << "Couldn't open X display";
return;
}
int xr_opcode, xr_event, xr_error;
if (!XQueryExtension(display_, "RECORD", &xr_opcode, &xr_event, &xr_error)) {
LOG(ERROR) << "X Record extension not available.";
return;
}
x_record_range_ = XRecordAllocRange(); // TODO(jamiewalch): We should pass the connection in.
if (!x_record_range_) { connection_ = std::make_unique<x11::Connection>();
LOG(ERROR) << "XRecordAllocRange failed.";
return;
}
x_record_range_->device_events.first = x11::KeyEvent::Press;
x_record_range_->device_events.last = x11::KeyEvent::Release;
XRecordClientSpec client_spec = XRecordAllClients;
x_record_context_ = XRecordCreateContext(x_record_display_, 0, &client_spec,
1, &x_record_range_, 1);
if (!x_record_context_) {
LOG(ERROR) << "XRecordCreateContext failed.";
return;
}
if (!XRecordEnableContextAsync(x_record_display_, x_record_context_, if (!connection_->xinput().present()) {
&Core::ProcessReply, LOG(ERROR) << "X Record extension not available.";
reinterpret_cast<XPointer>(this))) {
LOG(ERROR) << "XRecordEnableContextAsync failed.";
return; return;
} }
// Let the server know the client XInput version.
// Register OnPendingXEvents() to be called every time there is connection_->xinput().XIQueryVersion(
// something to read from |x_record_display_|. {x11::Input::major_version, x11::Input::minor_version});
x11::Input::XIEventMask mask;
ui::SetXinputMask(&mask, x11::Input::RawDeviceEvent::RawKeyPress);
ui::SetXinputMask(&mask, x11::Input::RawDeviceEvent::RawKeyRelease);
connection_->xinput().XISelectEvents(
{connection_->default_root(),
{{x11::Input::DeviceId::AllMaster, {mask}}}});
connection_->Flush();
// Register OnConnectionData() to be called every time there is
// something to read from |connection_|.
controller_ = base::FileDescriptorWatcher::WatchReadable( controller_ = base::FileDescriptorWatcher::WatchReadable(
ConnectionNumber(x_record_display_), ConnectionNumber(connection_->display()),
base::BindRepeating(&Core::OnPendingXEvents, base::Unretained(this))); base::BindRepeating(&Core::OnConnectionData, base::Unretained(this)));
// Fetch pending events if any. // Fetch pending events if any.
while (XPending(x_record_display_)) { OnConnectionData();
XEvent ev;
XNextEvent(x_record_display_, &ev);
}
} }
void LocalHotkeyInputMonitorX11::Core::StopOnInputThread() { void LocalHotkeyInputMonitorX11::Core::StopOnInputThread() {
DCHECK(input_task_runner_->BelongsToCurrentThread()); DCHECK(input_task_runner_->BelongsToCurrentThread());
// Context must be disabled via the control channel because we can't send
// any X protocol traffic over the data channel while it's recording.
if (x_record_context_) {
XRecordDisableContext(display_, x_record_context_);
XFlush(display_);
}
controller_.reset(); controller_.reset();
connection_.reset();
if (x_record_range_) {
XFree(x_record_range_);
x_record_range_ = nullptr;
}
if (x_record_context_) {
XRecordFreeContext(x_record_display_, x_record_context_);
x_record_context_ = 0;
}
if (x_record_display_) {
XCloseDisplay(x_record_display_);
x_record_display_ = nullptr;
}
if (display_) {
XCloseDisplay(display_);
display_ = nullptr;
}
} }
void LocalHotkeyInputMonitorX11::Core::OnPendingXEvents() { void LocalHotkeyInputMonitorX11::Core::OnConnectionData() {
DCHECK(input_task_runner_->BelongsToCurrentThread()); DCHECK(input_task_runner_->BelongsToCurrentThread());
connection_->Dispatch(this);
}
// Fetch pending events if any. bool LocalHotkeyInputMonitorX11::Core::ShouldContinueStream() const {
while (XPending(x_record_display_)) { return true;
XEvent ev;
XNextEvent(x_record_display_, &ev);
}
} }
void LocalHotkeyInputMonitorX11::Core::ProcessXEvent(xEvent* event) { void LocalHotkeyInputMonitorX11::Core::DispatchXEvent(x11::Event* event) {
DCHECK(input_task_runner_->BelongsToCurrentThread()); DCHECK(input_task_runner_->BelongsToCurrentThread());
// Ignore input if we've already initiated a disconnect. // Ignore input if we've already initiated a disconnect.
...@@ -247,27 +191,21 @@ void LocalHotkeyInputMonitorX11::Core::ProcessXEvent(xEvent* event) { ...@@ -247,27 +191,21 @@ void LocalHotkeyInputMonitorX11::Core::ProcessXEvent(xEvent* event) {
return; return;
} }
int key_code = event->u.u.detail; auto* raw = event->As<x11::Input::RawDeviceEvent>();
bool down = event->u.u.type == x11::KeyEvent::Press; DCHECK(raw);
KeySym key_sym = XkbKeycodeToKeysym(display_, key_code, 0, 0); DCHECK(raw->opcode == x11::Input::RawDeviceEvent::RawKeyPress ||
if (key_sym == XK_Control_L || key_sym == XK_Control_R) { raw->opcode == x11::Input::RawDeviceEvent::RawKeyRelease);
bool down = raw->opcode == x11::Input::RawDeviceEvent::RawKeyPress;
auto key_sym =
static_cast<uint32_t>(connection_->KeycodeToKeysym(raw->detail, 0));
if (key_sym == XK_Control_L || key_sym == XK_Control_R)
ctrl_pressed_ = down; ctrl_pressed_ = down;
} else if (key_sym == XK_Alt_L || key_sym == XK_Alt_R) { else if (key_sym == XK_Alt_L || key_sym == XK_Alt_R)
alt_pressed_ = down; alt_pressed_ = down;
} else if (key_sym == XK_Escape && down && alt_pressed_ && ctrl_pressed_) { else if (key_sym == XK_Escape && down && alt_pressed_ && ctrl_pressed_)
caller_task_runner_->PostTask(FROM_HERE, std::move(disconnect_callback_)); caller_task_runner_->PostTask(FROM_HERE, std::move(disconnect_callback_));
}
}
// static
void LocalHotkeyInputMonitorX11::Core::ProcessReply(
XPointer self,
XRecordInterceptData* data) {
if (data->category == XRecordFromServer) {
xEvent* event = reinterpret_cast<xEvent*>(data->data);
reinterpret_cast<Core*>(self)->ProcessXEvent(event);
}
XRecordFreeData(data);
} }
} // namespace } // namespace
......
...@@ -19,8 +19,11 @@ ...@@ -19,8 +19,11 @@
#include "base/sequence_checker.h" #include "base/sequence_checker.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
#include "ui/events/devices/x11/xinput_util.h"
#include "ui/events/event.h" #include "ui/events/event.h"
#include "ui/gfx/x/x11.h" #include "ui/gfx/x/x11.h"
#include "ui/gfx/x/xinput.h"
#include "ui/gfx/x/xproto.h"
namespace remoting { namespace remoting {
...@@ -37,7 +40,8 @@ class LocalMouseInputMonitorX11 : public LocalPointerInputMonitor { ...@@ -37,7 +40,8 @@ class LocalMouseInputMonitorX11 : public LocalPointerInputMonitor {
private: private:
// The actual implementation resides in LocalMouseInputMonitorX11::Core class. // The actual implementation resides in LocalMouseInputMonitorX11::Core class.
class Core : public base::RefCountedThreadSafe<Core> { class Core : public base::RefCountedThreadSafe<Core>,
public x11::Connection::Delegate {
public: public:
Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
...@@ -48,18 +52,17 @@ class LocalMouseInputMonitorX11 : public LocalPointerInputMonitor { ...@@ -48,18 +52,17 @@ class LocalMouseInputMonitorX11 : public LocalPointerInputMonitor {
private: private:
friend class base::RefCountedThreadSafe<Core>; friend class base::RefCountedThreadSafe<Core>;
~Core(); ~Core() override;
void StartOnInputThread(); void StartOnInputThread();
void StopOnInputThread(); void StopOnInputThread();
// Called when there are pending X events. // Called when there are pending X events.
void OnPendingXEvents(); void OnConnectionData();
// Processes key and mouse events. // x11::Connection::Delegate:
void ProcessXEvent(xEvent* event); bool ShouldContinueStream() const override;
void DispatchXEvent(x11::Event* event) override;
static void ProcessReply(XPointer self, XRecordInterceptData* data);
// Task runner on which public methods of this class must be called. // Task runner on which public methods of this class must be called.
scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
...@@ -73,10 +76,7 @@ class LocalMouseInputMonitorX11 : public LocalPointerInputMonitor { ...@@ -73,10 +76,7 @@ class LocalMouseInputMonitorX11 : public LocalPointerInputMonitor {
// Controls watching X events. // Controls watching X events.
std::unique_ptr<base::FileDescriptorWatcher::Controller> controller_; std::unique_ptr<base::FileDescriptorWatcher::Controller> controller_;
Display* display_ = nullptr; std::unique_ptr<x11::Connection> connection_;
Display* x_record_display_ = nullptr;
XRecordRange* x_record_range_ = nullptr;
XRecordContext x_record_context_ = 0;
DISALLOW_COPY_AND_ASSIGN(Core); DISALLOW_COPY_AND_ASSIGN(Core);
}; };
...@@ -128,133 +128,77 @@ void LocalMouseInputMonitorX11::Core::Stop() { ...@@ -128,133 +128,77 @@ void LocalMouseInputMonitorX11::Core::Stop() {
} }
LocalMouseInputMonitorX11::Core::~Core() { LocalMouseInputMonitorX11::Core::~Core() {
DCHECK(!display_); DCHECK(!connection_);
DCHECK(!x_record_display_);
DCHECK(!x_record_range_);
DCHECK(!x_record_context_);
} }
void LocalMouseInputMonitorX11::Core::StartOnInputThread() { void LocalMouseInputMonitorX11::Core::StartOnInputThread() {
DCHECK(input_task_runner_->BelongsToCurrentThread()); DCHECK(input_task_runner_->BelongsToCurrentThread());
DCHECK(!display_); DCHECK(!connection_);
DCHECK(!x_record_display_);
DCHECK(!x_record_range_);
DCHECK(!x_record_context_);
// TODO(jamiewalch): We should pass the display in. At that point, since
// XRecord needs a private connection to the X Server for its data channel
// and both channels are used from a separate thread, we'll need to duplicate
// them with something like the following:
// XOpenDisplay(DisplayString(display));
display_ = XOpenDisplay(nullptr);
x_record_display_ = XOpenDisplay(nullptr);
if (!display_ || !x_record_display_) {
LOG(ERROR) << "Couldn't open X display";
return;
}
int xr_opcode, xr_event, xr_error; // TODO(jamiewalch): We should pass the connection in.
if (!XQueryExtension(display_, "RECORD", &xr_opcode, &xr_event, &xr_error)) { connection_ = std::make_unique<x11::Connection>();
LOG(ERROR) << "X Record extension not available.";
return;
}
x_record_range_ = XRecordAllocRange(); if (!connection_->xinput().present()) {
if (!x_record_range_) { LOG(ERROR) << "X Record extension not available.";
LOG(ERROR) << "XRecordAllocRange failed.";
return;
}
x_record_range_->device_events.first = MotionNotify;
x_record_range_->device_events.last = MotionNotify;
XRecordClientSpec client_spec = XRecordAllClients;
x_record_context_ = XRecordCreateContext(x_record_display_, 0, &client_spec,
1, &x_record_range_, 1);
if (!x_record_context_) {
LOG(ERROR) << "XRecordCreateContext failed.";
return;
}
if (!XRecordEnableContextAsync(x_record_display_, x_record_context_,
&Core::ProcessReply,
reinterpret_cast<XPointer>(this))) {
LOG(ERROR) << "XRecordEnableContextAsync failed.";
return; return;
} }
// Let the server know the client XInput version.
// Register OnPendingXEvents() to be called every time there is connection_->xinput().XIQueryVersion(
// something to read from |x_record_display_|. {x11::Input::major_version, x11::Input::minor_version});
x11::Input::XIEventMask mask;
ui::SetXinputMask(&mask, x11::Input::RawDeviceEvent::RawMotion);
connection_->xinput().XISelectEvents(
{connection_->default_root(),
{{x11::Input::DeviceId::AllMaster, {mask}}}});
connection_->Flush();
// Register OnConnectionData() to be called every time there is
// something to read from |connection_|.
controller_ = base::FileDescriptorWatcher::WatchReadable( controller_ = base::FileDescriptorWatcher::WatchReadable(
ConnectionNumber(x_record_display_), ConnectionNumber(connection_->display()),
base::BindRepeating(&Core::OnPendingXEvents, base::Unretained(this))); base::BindRepeating(&Core::OnConnectionData, base::Unretained(this)));
// Fetch pending events if any. // Fetch pending events if any.
while (XPending(x_record_display_)) { OnConnectionData();
XEvent ev;
XNextEvent(x_record_display_, &ev);
}
} }
void LocalMouseInputMonitorX11::Core::StopOnInputThread() { void LocalMouseInputMonitorX11::Core::StopOnInputThread() {
DCHECK(input_task_runner_->BelongsToCurrentThread()); DCHECK(input_task_runner_->BelongsToCurrentThread());
// Context must be disabled via the control channel because we can't send
// any X protocol traffic over the data channel while it's recording.
if (x_record_context_) {
XRecordDisableContext(display_, x_record_context_);
XFlush(display_);
}
controller_.reset(); controller_.reset();
connection_.reset();
if (x_record_range_) {
XFree(x_record_range_);
x_record_range_ = nullptr;
}
if (x_record_context_) {
XRecordFreeContext(x_record_display_, x_record_context_);
x_record_context_ = 0;
}
if (x_record_display_) {
XCloseDisplay(x_record_display_);
x_record_display_ = nullptr;
}
if (display_) {
XCloseDisplay(display_);
display_ = nullptr;
}
} }
void LocalMouseInputMonitorX11::Core::OnPendingXEvents() { void LocalMouseInputMonitorX11::Core::OnConnectionData() {
DCHECK(input_task_runner_->BelongsToCurrentThread()); DCHECK(input_task_runner_->BelongsToCurrentThread());
connection_->Dispatch(this);
}
// Fetch pending events if any. bool LocalMouseInputMonitorX11::Core::ShouldContinueStream() const {
while (XPending(x_record_display_)) { return true;
XEvent ev;
XNextEvent(x_record_display_, &ev);
}
} }
void LocalMouseInputMonitorX11::Core::ProcessXEvent(xEvent* event) { void LocalMouseInputMonitorX11::Core::DispatchXEvent(x11::Event* event) {
DCHECK(input_task_runner_->BelongsToCurrentThread()); DCHECK(input_task_runner_->BelongsToCurrentThread());
if (event->u.u.type != MotionNotify) {
return;
}
webrtc::DesktopVector position(event->u.keyButtonPointer.rootX, auto* raw = event->As<x11::Input::RawDeviceEvent>();
event->u.keyButtonPointer.rootY); DCHECK(raw);
caller_task_runner_->PostTask( DCHECK(raw->opcode == x11::Input::RawDeviceEvent::RawMotion);
FROM_HERE, base::BindOnce(on_mouse_move_, position, ui::ET_MOUSE_MOVED));
} connection_->QueryPointer({connection_->default_root()})
.OnResponse(base::BindOnce(
// static [](scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
void LocalMouseInputMonitorX11::Core::ProcessReply(XPointer self, LocalInputMonitor::PointerMoveCallback on_mouse_move,
XRecordInterceptData* data) { x11::QueryPointerResponse response) {
if (data->category == XRecordFromServer) { if (!response)
xEvent* event = reinterpret_cast<xEvent*>(data->data); return;
reinterpret_cast<Core*>(self)->ProcessXEvent(event); webrtc::DesktopVector position(response->root_x, response->root_y);
} caller_task_runner->PostTask(
XRecordFreeData(data); FROM_HERE,
base::BindOnce(on_mouse_move, position, ui::ET_MOUSE_MOVED));
},
caller_task_runner_, on_mouse_move_));
connection_->Flush();
} }
} // namespace } // namespace
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "remoting/host/linux/unicode_to_keysym.h" #include "remoting/host/linux/unicode_to_keysym.h"
#include "ui/gfx/x/x11.h" #include "ui/gfx/x/x11.h"
#include "ui/gfx/x/x11_types.h" #include "ui/gfx/x/x11_types.h"
#include "ui/gfx/x/xtest.h"
namespace { namespace {
...@@ -30,12 +31,12 @@ bool FindKeycodeForKeySym(Display* display, ...@@ -30,12 +31,12 @@ bool FindKeycodeForKeySym(Display* display,
}; };
// TODO(sergeyu): Is there a better way to find modifiers state? // TODO(sergeyu): Is there a better way to find modifiers state?
for (size_t i = 0; i < base::size(kModifiersToTry); ++i) { for (auto i : kModifiersToTry) {
unsigned long key_sym_with_mods; unsigned long key_sym_with_mods;
if (XkbLookupKeySym(display, found_keycode, kModifiersToTry[i], nullptr, if (XkbLookupKeySym(display, found_keycode, i, nullptr,
&key_sym_with_mods) && &key_sym_with_mods) &&
key_sym_with_mods == key_sym) { key_sym_with_mods == key_sym) {
*modifiers = kModifiersToTry[i]; *modifiers = i;
*keycode = found_keycode; *keycode = found_keycode;
return true; return true;
} }
...@@ -47,7 +48,8 @@ bool FindKeycodeForKeySym(Display* display, ...@@ -47,7 +48,8 @@ bool FindKeycodeForKeySym(Display* display,
namespace remoting { namespace remoting {
X11KeyboardImpl::X11KeyboardImpl(Display* display) : display_(display) {} X11KeyboardImpl::X11KeyboardImpl(x11::Connection* connection)
: connection_(connection), display_(connection->display()) {}
X11KeyboardImpl::~X11KeyboardImpl() = default; X11KeyboardImpl::~X11KeyboardImpl() = default;
...@@ -80,8 +82,8 @@ std::vector<uint32_t> X11KeyboardImpl::GetUnusedKeycodes() { ...@@ -80,8 +82,8 @@ std::vector<uint32_t> X11KeyboardImpl::GetUnusedKeycodes() {
void X11KeyboardImpl::PressKey(uint32_t keycode, uint32_t modifiers) { void X11KeyboardImpl::PressKey(uint32_t keycode, uint32_t modifiers) {
XkbLockModifiers(display_, XkbUseCoreKbd, modifiers, modifiers); XkbLockModifiers(display_, XkbUseCoreKbd, modifiers, modifiers);
XTestFakeKeyEvent(display_, keycode, x11::True, x11::CurrentTime); connection_->xtest().FakeInput({x11::KeyEvent::Press, keycode});
XTestFakeKeyEvent(display_, keycode, x11::False, x11::CurrentTime); connection_->xtest().FakeInput({x11::KeyEvent::Release, keycode});
XkbLockModifiers(display_, XkbUseCoreKbd, modifiers, 0); XkbLockModifiers(display_, XkbUseCoreKbd, modifiers, 0);
} }
......
...@@ -14,7 +14,7 @@ namespace remoting { ...@@ -14,7 +14,7 @@ namespace remoting {
class X11KeyboardImpl : public X11Keyboard { class X11KeyboardImpl : public X11Keyboard {
public: public:
X11KeyboardImpl(Display* display); explicit X11KeyboardImpl(x11::Connection* connection);
~X11KeyboardImpl() override; ~X11KeyboardImpl() override;
// KeyboardInterface overrides. // KeyboardInterface overrides.
...@@ -34,6 +34,7 @@ class X11KeyboardImpl : public X11Keyboard { ...@@ -34,6 +34,7 @@ class X11KeyboardImpl : public X11Keyboard {
private: private:
// X11 graphics context. // X11 graphics context.
x11::Connection* connection_;
Display* display_; Display* display_;
DISALLOW_COPY_AND_ASSIGN(X11KeyboardImpl); DISALLOW_COPY_AND_ASSIGN(X11KeyboardImpl);
......
...@@ -6,14 +6,14 @@ ...@@ -6,14 +6,14 @@
#include "base/bind.h" #include "base/bind.h"
#include "ui/gfx/x/x11.h" #include "ui/gfx/x/x11.h"
#include "ui/gfx/x/xtest.h"
namespace remoting { namespace remoting {
static ScopedXErrorHandler* g_handler = nullptr; static ScopedXErrorHandler* g_handler = nullptr;
ScopedXErrorHandler::ScopedXErrorHandler(const Handler& handler): ScopedXErrorHandler::ScopedXErrorHandler(const Handler& handler)
handler_(handler), : handler_(handler), ok_(true) {
ok_(true) {
// This is a non-exhaustive check for incorrect usage. It doesn't handle the // This is a non-exhaustive check for incorrect usage. It doesn't handle the
// case where a mix of ScopedXErrorHandler and raw XSetErrorHandler calls are // case where a mix of ScopedXErrorHandler and raw XSetErrorHandler calls are
// used, and it disallows nested ScopedXErrorHandlers on the same thread, // used, and it disallows nested ScopedXErrorHandlers on the same thread,
...@@ -36,9 +36,7 @@ int ScopedXErrorHandler::HandleXErrors(Display* display, XErrorEvent* error) { ...@@ -36,9 +36,7 @@ int ScopedXErrorHandler::HandleXErrors(Display* display, XErrorEvent* error) {
return 0; return 0;
} }
ScopedXGrabServer::ScopedXGrabServer(Display* display) : display_(display) {
ScopedXGrabServer::ScopedXGrabServer(Display* display)
: display_(display) {
XGrabServer(display_); XGrabServer(display_);
} }
...@@ -47,17 +45,14 @@ ScopedXGrabServer::~ScopedXGrabServer() { ...@@ -47,17 +45,14 @@ ScopedXGrabServer::~ScopedXGrabServer() {
XFlush(display_); XFlush(display_);
} }
bool IgnoreXServerGrabs(Display* display, bool ignore) { bool IgnoreXServerGrabs(x11::Connection* connection, bool ignore) {
int test_event_base = 0; if (!connection->xtest()
int test_error_base = 0; .GetVersion({x11::Test::major_version, x11::Test::minor_version})
int major = 0; .Sync()) {
int minor = 0;
if (!XTestQueryExtension(display, &test_event_base, &test_error_base,
&major, &minor)) {
return false; return false;
} }
XTestGrabControl(display, ignore); connection->xtest().GrabControl({ignore});
return true; return true;
} }
......
...@@ -61,7 +61,7 @@ class ScopedXGrabServer { ...@@ -61,7 +61,7 @@ class ScopedXGrabServer {
// Make a connection to the X Server impervious to X Server grabs. Returns // Make a connection to the X Server impervious to X Server grabs. Returns
// true if successful or false if the required XTEST extension is not present. // true if successful or false if the required XTEST extension is not present.
bool IgnoreXServerGrabs(Display* display, bool ignore); bool IgnoreXServerGrabs(x11::Connection* connection, bool ignore);
} // namespace remoting } // namespace remoting
......
diff -ru xcbproto/src/randr.xml src/src/randr.xml diff -ru xcbproto/src/randr.xml src/src/randr.xml
--- xcbproto/src/randr.xml 2020-07-29 09:55:07.897405223 -0700 --- xcbproto/src/randr.xml 2020-08-03 10:33:29.404868416 -0700
+++ src/src/randr.xml 2020-07-29 09:52:58.484783705 -0700 +++ src/src/randr.xml 2020-08-03 10:29:36.503609230 -0700
@@ -803,64 +803,6 @@ @@ -803,64 +803,6 @@
<item name="Lease"> <value>6</value></item> <item name="Lease"> <value>6</value></item>
</enum> </enum>
...@@ -174,8 +174,8 @@ diff -ru xcbproto/src/randr.xml src/src/randr.xml ...@@ -174,8 +174,8 @@ diff -ru xcbproto/src/randr.xml src/src/randr.xml
</event> </event>
</xcb> </xcb>
diff -ru xcbproto/src/xinput.xml src/src/xinput.xml diff -ru xcbproto/src/xinput.xml src/src/xinput.xml
--- xcbproto/src/xinput.xml 2020-07-29 09:55:07.897405223 -0700 --- xcbproto/src/xinput.xml 2020-08-03 10:33:29.408868437 -0700
+++ src/src/xinput.xml 2020-07-29 09:52:58.484783705 -0700 +++ src/src/xinput.xml 2020-08-03 10:29:36.503609230 -0700
@@ -200,7 +200,12 @@ @@ -200,7 +200,12 @@
<list type="STR" name="names"> <list type="STR" name="names">
<fieldref>devices_len</fieldref> <fieldref>devices_len</fieldref>
...@@ -190,9 +190,19 @@ diff -ru xcbproto/src/xinput.xml src/src/xinput.xml ...@@ -190,9 +190,19 @@ diff -ru xcbproto/src/xinput.xml src/src/xinput.xml
</reply> </reply>
</request> </request>
@@ -1347,7 +1352,8 @@
<!-- XIQueryPointer -->
- <enum name="Device">
+ <!-- Chromium patch: Rename so that this will get merged with DeviceId -->
+ <enum name="DEVICE_ID">
<item name="All"> <value>0</value> </item>
<item name="AllMaster"> <value>1</value> </item>
</enum>
diff -ru xcbproto/src/xproto.xml src/src/xproto.xml diff -ru xcbproto/src/xproto.xml src/src/xproto.xml
--- xcbproto/src/xproto.xml 2020-07-29 09:55:07.901405242 -0700 --- xcbproto/src/xproto.xml 2020-08-03 10:33:29.408868437 -0700
+++ src/src/xproto.xml 2020-07-29 09:52:58.484783705 -0700 +++ src/src/xproto.xml 2020-08-03 10:29:36.503609230 -0700
@@ -4686,7 +4686,7 @@ @@ -4686,7 +4686,7 @@
<field type="CARD8" name="left_pad" /> <field type="CARD8" name="left_pad" />
<field type="CARD8" name="depth" /> <field type="CARD8" name="depth" />
......
...@@ -1352,7 +1352,8 @@ authorization from the authors. ...@@ -1352,7 +1352,8 @@ authorization from the authors.
<!-- XIQueryPointer --> <!-- XIQueryPointer -->
<enum name="Device"> <!-- Chromium patch: Rename so that this will get merged with DeviceId -->
<enum name="DEVICE_ID">
<item name="All"> <value>0</value> </item> <item name="All"> <value>0</value> </item>
<item name="AllMaster"> <value>1</value> </item> <item name="AllMaster"> <value>1</value> </item>
</enum> </enum>
......
...@@ -263,7 +263,7 @@ void DeviceDataManagerX11::UpdateDeviceList(x11::Connection* connection) { ...@@ -263,7 +263,7 @@ void DeviceDataManagerX11::UpdateDeviceList(x11::Connection* connection) {
// Find all the touchpad devices. // Find all the touchpad devices.
const XDeviceList& dev_list = const XDeviceList& dev_list =
ui::DeviceListCacheX11::GetInstance()->GetXDeviceList(connection); ui::DeviceListCacheX11::GetInstance()->GetXDeviceList(connection);
x11::Atom xi_touchpad = gfx::GetAtom(XI_TOUCHPAD); x11::Atom xi_touchpad = gfx::GetAtom("TOUCHPAD");
for (const auto& device : dev_list) { for (const auto& device : dev_list) {
if (device.device_type == xi_touchpad) if (device.device_type == xi_touchpad)
touchpads_[device.device_id] = true; touchpads_[device.device_id] = true;
......
...@@ -339,7 +339,7 @@ class EVENTS_DEVICES_X11_EXPORT DeviceDataManagerX11 ...@@ -339,7 +339,7 @@ class EVENTS_DEVICES_X11_EXPORT DeviceDataManagerX11
DeviceDataManagerX11::ScrollInfo::AxisInfo* axis, DeviceDataManagerX11::ScrollInfo::AxisInfo* axis,
double valuator) const; double valuator) const;
static const int kMaxXIEventType = XI_LASTEVENT + 1; static const int kMaxXIEventType = 32;
static const int kMaxSlotNum = 10; static const int kMaxSlotNum = 10;
// Major opcode for the XInput extension. Used to identify XInput events. // Major opcode for the XInput extension. Used to identify XInput events.
......
...@@ -200,42 +200,35 @@ void TouchFactory::SetupXI2ForXWindow(x11::Window window) { ...@@ -200,42 +200,35 @@ void TouchFactory::SetupXI2ForXWindow(x11::Window window) {
// the events from uninteresting devices. We do the latter because that's // the events from uninteresting devices. We do the latter because that's
// simpler. // simpler.
XDisplay* display = gfx::GetXDisplay(); auto* connection = x11::Connection::Get();
unsigned char mask[XIMaskLen(XI_LASTEVENT)]; x11::Input::EventMask mask{};
memset(mask, 0, sizeof(mask));
SetXinputMask(mask, x11::Input::CrossingEvent::Enter); SetXinputMask(&mask, x11::Input::CrossingEvent::Enter);
SetXinputMask(mask, x11::Input::CrossingEvent::Leave); SetXinputMask(&mask, x11::Input::CrossingEvent::Leave);
SetXinputMask(mask, x11::Input::CrossingEvent::FocusIn); SetXinputMask(&mask, x11::Input::CrossingEvent::FocusIn);
SetXinputMask(mask, x11::Input::CrossingEvent::FocusOut); SetXinputMask(&mask, x11::Input::CrossingEvent::FocusOut);
SetXinputMask(mask, x11::Input::DeviceEvent::TouchBegin); SetXinputMask(&mask, x11::Input::DeviceEvent::TouchBegin);
SetXinputMask(mask, x11::Input::DeviceEvent::TouchUpdate); SetXinputMask(&mask, x11::Input::DeviceEvent::TouchUpdate);
SetXinputMask(mask, x11::Input::DeviceEvent::TouchEnd); SetXinputMask(&mask, x11::Input::DeviceEvent::TouchEnd);
SetXinputMask(mask, x11::Input::DeviceEvent::ButtonPress); SetXinputMask(&mask, x11::Input::DeviceEvent::ButtonPress);
SetXinputMask(mask, x11::Input::DeviceEvent::ButtonRelease); SetXinputMask(&mask, x11::Input::DeviceEvent::ButtonRelease);
SetXinputMask(mask, x11::Input::DeviceEvent::Motion); SetXinputMask(&mask, x11::Input::DeviceEvent::Motion);
// HierarchyChanged and DeviceChanged allow X11EventSource to still pick up // HierarchyChanged and DeviceChanged allow X11EventSource to still pick up
// these events. // these events.
SetXinputMask(mask, x11::Input::HierarchyEvent::opcode); SetXinputMask(&mask, x11::Input::HierarchyEvent::opcode);
SetXinputMask(mask, x11::Input::DeviceChangedEvent::opcode); SetXinputMask(&mask, x11::Input::DeviceChangedEvent::opcode);
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
// XGrabKey() must be replaced with XI2 keyboard grab if XI2 key events are
// enabled on desktop Linux.
if (base::SysInfo::IsRunningOnChromeOS()) { if (base::SysInfo::IsRunningOnChromeOS()) {
SetXinputMask(mask, x11::Input::DeviceEvent::KeyPress); SetXinputMask(&mask, x11::Input::DeviceEvent::KeyPress);
SetXinputMask(mask, x11::Input::DeviceEvent::KeyRelease); SetXinputMask(&mask, x11::Input::DeviceEvent::KeyRelease);
} }
#endif #endif
XIEventMask evmask; connection->xinput().XISelectEvents({window, {mask}});
evmask.deviceid = XIAllDevices; connection->Flush();
evmask.mask_len = sizeof(mask);
evmask.mask = mask;
XISelectEvents(display, static_cast<uint32_t>(window), &evmask, 1);
XFlush(display);
} }
void TouchFactory::SetTouchDeviceList( void TouchFactory::SetTouchDeviceList(
......
...@@ -35,12 +35,6 @@ ...@@ -35,12 +35,6 @@
#include "ui/gfx/x/x11_atom_cache.h" #include "ui/gfx/x/x11_atom_cache.h"
#include "ui/gfx/x/x11_types.h" #include "ui/gfx/x/x11_types.h"
#ifndef XI_PROP_PRODUCT_ID
#define XI_PROP_PRODUCT_ID "Device Product ID"
#endif
#undef Absolute
namespace ui { namespace ui {
namespace { namespace {
...@@ -79,21 +73,28 @@ struct UiCallbacks { ...@@ -79,21 +73,28 @@ struct UiCallbacks {
base::OnceClosure hotplug_finished_callback; base::OnceClosure hotplug_finished_callback;
}; };
// Stores a copy of the XIValuatorClassInfo values so X11 device processing can // Identical to FP3232_TO_DOUBLE from libxi's XExtInt.c
// happen on a worker thread. This is needed since X11 structs are not copyable. double Fp3232ToDouble(const x11::Input::Fp3232& x) {
return static_cast<double>(x.integral) +
static_cast<double>(x.frac) / (1ULL << 32);
}
// Stores a copy of the x11::Input::ValuatorClass values so X11 device
// processing can happen on a worker thread. This is needed since X11 structs
// are not copyable.
struct ValuatorClassInfo { struct ValuatorClassInfo {
explicit ValuatorClassInfo(const XIValuatorClassInfo& info) explicit ValuatorClassInfo(const x11::Input::ValuatorClass& info)
: label(static_cast<x11::Atom>(info.label)), : label(static_cast<x11::Atom>(info.label)),
max(info.max), max(Fp3232ToDouble(info.max)),
min(info.min), min(Fp3232ToDouble(info.min)),
mode(info.mode), mode(info.mode),
number(info.number) {} number(info.number) {}
x11::Atom label; x11::Atom label;
double max; double max;
double min; double min;
int mode; x11::Input::ValuatorMode mode;
int number; uint16_t number;
}; };
// Stores a copy of the XITouchClassInfo values so X11 device processing can // Stores a copy of the XITouchClassInfo values so X11 device processing can
...@@ -156,12 +157,6 @@ struct DisplayState { ...@@ -156,12 +157,6 @@ struct DisplayState {
x11::Atom mt_position_y; x11::Atom mt_position_y;
}; };
// Identical to FP3232_TO_DOUBLE from libxi's XExtInt.c
double Fp3232ToDouble(const x11::Input::Fp3232& x) {
return static_cast<double>(x.integral) +
static_cast<double>(x.frac) / (1ULL << 32);
}
// Returns true if |name| is the name of a known invalid keyboard device. Note, // Returns true if |name| is the name of a known invalid keyboard device. Note,
// this may return false negatives. // this may return false negatives.
bool IsKnownInvalidKeyboardDevice(const std::string& name) { bool IsKnownInvalidKeyboardDevice(const std::string& name) {
...@@ -414,13 +409,13 @@ void X11HotplugEventHandler::OnHotplugEvent() { ...@@ -414,13 +409,13 @@ void X11HotplugEventHandler::OnHotplugEvent() {
continue; continue;
x11::Atom type = device.device_type; x11::Atom type = device.device_type;
if (type == gfx::GetAtom(XI_KEYBOARD)) if (type == gfx::GetAtom("KEYBOARD"))
device_types[id] = DEVICE_TYPE_KEYBOARD; device_types[id] = DEVICE_TYPE_KEYBOARD;
else if (type == gfx::GetAtom(XI_MOUSE)) else if (type == gfx::GetAtom("MOUSE"))
device_types[id] = DEVICE_TYPE_MOUSE; device_types[id] = DEVICE_TYPE_MOUSE;
else if (type == gfx::GetAtom(XI_TOUCHPAD)) else if (type == gfx::GetAtom("TOUCHPAD"))
device_types[id] = DEVICE_TYPE_TOUCHPAD; device_types[id] = DEVICE_TYPE_TOUCHPAD;
else if (type == gfx::GetAtom(XI_TOUCHSCREEN)) else if (type == gfx::GetAtom("TOUCHSCREEN"))
device_types[id] = DEVICE_TYPE_TOUCHSCREEN; device_types[id] = DEVICE_TYPE_TOUCHSCREEN;
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/notreached.h" #include "base/notreached.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "ui/events/devices/x11/touch_factory_x11.h" #include "ui/events/devices/x11/touch_factory_x11.h"
#include "ui/events/devices/x11/xinput_util.h"
#include "ui/events/event_constants.h" #include "ui/events/event_constants.h"
#include "ui/events/event_utils.h" #include "ui/events/event_utils.h"
#include "ui/events/keycodes/keyboard_code_conversion_x.h" #include "ui/events/keycodes/keyboard_code_conversion_x.h"
...@@ -227,7 +228,7 @@ void ScopedXI2Event::InitGenericButtonEvent(int deviceid, ...@@ -227,7 +228,7 @@ void ScopedXI2Event::InitGenericButtonEvent(int deviceid,
dev_event->detail = XButtonEventButton(type, flags); dev_event->detail = XButtonEventButton(type, flags);
dev_event->event_x = ToFp1616(location.x()), dev_event->event_x = ToFp1616(location.x()),
dev_event->event_y = ToFp1616(location.y()), dev_event->event_y = ToFp1616(location.y()),
XISetMask(dev_event->button_mask.data(), XButtonEventButton(type, flags)); SetXinputMask(dev_event->button_mask.data(), XButtonEventButton(type, flags));
// Setup an empty valuator list for generic button events. // Setup an empty valuator list for generic button events.
SetUpValuators(std::vector<Valuator>()); SetUpValuators(std::vector<Valuator>());
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "ui/events/devices/x11/device_data_manager_x11.h" #include "ui/events/devices/x11/device_data_manager_x11.h"
#include "ui/events/devices/x11/device_list_cache_x11.h" #include "ui/events/devices/x11/device_list_cache_x11.h"
#include "ui/events/devices/x11/touch_factory_x11.h" #include "ui/events/devices/x11/touch_factory_x11.h"
#include "ui/events/devices/x11/xinput_util.h"
#include "ui/events/keycodes/keyboard_code_conversion_x.h" #include "ui/events/keycodes/keyboard_code_conversion_x.h"
#include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
...@@ -226,7 +227,7 @@ int GetEventFlagsForButton(x11::Button button) { ...@@ -226,7 +227,7 @@ int GetEventFlagsForButton(x11::Button button) {
int GetButtonMaskForX2Event(const x11::Input::DeviceEvent& xievent) { int GetButtonMaskForX2Event(const x11::Input::DeviceEvent& xievent) {
int buttonflags = 0; int buttonflags = 0;
for (size_t i = 0; i < 32 * xievent.button_mask.size(); i++) { for (size_t i = 0; i < 32 * xievent.button_mask.size(); i++) {
if (XIMaskIsSet(xievent.button_mask.data(), i)) { if (ui::IsXinputMaskSet(xievent.button_mask.data(), i)) {
int button = int button =
(xievent.sourceid == xievent.deviceid) (xievent.sourceid == xievent.deviceid)
? ui::DeviceDataManagerX11::GetInstance()->GetMappedButton(i) ? ui::DeviceDataManagerX11::GetInstance()->GetMappedButton(i)
......
...@@ -50,12 +50,14 @@ auto CompareSequenceIds(T t, U u) { ...@@ -50,12 +50,14 @@ auto CompareSequenceIds(T t, U u) {
return static_cast<SignedType>(t0 - u0); return static_cast<SignedType>(t0 - u0);
} }
XDisplay* OpenNewXDisplay() { XDisplay* OpenNewXDisplay(const std::string& address) {
if (!XInitThreads()) if (!XInitThreads())
return nullptr; return nullptr;
std::string display_str = std::string display_str =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( address.empty()
switches::kX11Display); ? base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kX11Display)
: address;
return XOpenDisplay(display_str.empty() ? nullptr : display_str.c_str()); return XOpenDisplay(display_str.empty() ? nullptr : display_str.c_str());
} }
...@@ -206,7 +208,8 @@ Connection* Connection::Get() { ...@@ -206,7 +208,8 @@ Connection* Connection::Get() {
return instance; return instance;
} }
Connection::Connection() : XProto(this), display_(OpenNewXDisplay()) { Connection::Connection(const std::string& address)
: XProto(this), display_(OpenNewXDisplay(address)) {
if (display_) { if (display_) {
XSetEventQueueOwner(display_, XCBOwnsEventQueue); XSetEventQueueOwner(display_, XCBOwnsEventQueue);
...@@ -337,6 +340,10 @@ KeySym Connection::KeycodeToKeysym(uint32_t keycode, unsigned int modifiers) { ...@@ -337,6 +340,10 @@ KeySym Connection::KeycodeToKeysym(uint32_t keycode, unsigned int modifiers) {
return sym == static_cast<KeySym>(XK_VoidSymbol) ? kNoSymbol : sym; return sym == static_cast<KeySym>(XK_VoidSymbol) ? kNoSymbol : sym;
} }
std::unique_ptr<Connection> Connection::Clone() const {
return std::make_unique<Connection>(XDisplayString(display_));
}
void Connection::Dispatch(Delegate* delegate) { void Connection::Dispatch(Delegate* delegate) {
DCHECK(display_); DCHECK(display_);
......
...@@ -36,7 +36,7 @@ class COMPONENT_EXPORT(X11) Connection : public XProto, ...@@ -36,7 +36,7 @@ class COMPONENT_EXPORT(X11) Connection : public XProto,
// Gets or creates the singleton connection. // Gets or creates the singleton connection.
static Connection* Get(); static Connection* Get();
explicit Connection(); explicit Connection(const std::string& address = "");
~Connection(); ~Connection();
Connection(const Connection&) = delete; Connection(const Connection&) = delete;
...@@ -93,6 +93,8 @@ class COMPONENT_EXPORT(X11) Connection : public XProto, ...@@ -93,6 +93,8 @@ class COMPONENT_EXPORT(X11) Connection : public XProto,
// Access the event buffer. Clients can add, delete, or modify events. // Access the event buffer. Clients can add, delete, or modify events.
std::list<Event>& events() { return events_; } std::list<Event>& events() { return events_; }
std::unique_ptr<Connection> Clone() const;
private: private:
friend class FutureBase; friend class FutureBase;
......
...@@ -4,15 +4,6 @@ ...@@ -4,15 +4,6 @@
#include "ui/gfx/x/event.h" #include "ui/gfx/x/event.h"
#include <X11/Xlibint.h>
#include <X11/extensions/XInput2.h>
// Xlibint.h defines those as macros, which breaks the C++ versions in
// the std namespace.
#undef max
#undef min
#undef Data
#include <cstring> #include <cstring>
#include "base/check_op.h" #include "base/check_op.h"
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#define UI_GFX_X_EVENT_H_ #define UI_GFX_X_EVENT_H_
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/extensions/XInput2.h>
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include <cstdint> #include <cstdint>
......
...@@ -189,6 +189,7 @@ RENAME = { ...@@ -189,6 +189,7 @@ RENAME = {
'COLORMAP': 'ColorMap', 'COLORMAP': 'ColorMap',
'Connection': 'RandRConnection', 'Connection': 'RandRConnection',
'CP': 'CreatePictureAttribute', 'CP': 'CreatePictureAttribute',
'CS': 'ClientSpec',
'CW': 'CreateWindowAttribute', 'CW': 'CreateWindowAttribute',
'DAMAGE': 'DamageId', 'DAMAGE': 'DamageId',
'DIRECTFORMAT': 'DirectFormat', 'DIRECTFORMAT': 'DirectFormat',
......
...@@ -23,15 +23,9 @@ extern "C" { ...@@ -23,15 +23,9 @@ extern "C" {
#include <X11/Xregion.h> #include <X11/Xregion.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include <X11/cursorfont.h> #include <X11/cursorfont.h>
#include <X11/extensions/XI2.h>
#include <X11/extensions/XInput.h>
#include <X11/extensions/XInput2.h>
#include <X11/extensions/XIproto.h>
#include <X11/extensions/XShm.h> #include <X11/extensions/XShm.h>
#include <X11/extensions/XTest.h>
#include <X11/extensions/Xfixes.h> #include <X11/extensions/Xfixes.h>
#include <X11/extensions/Xrender.h> #include <X11/extensions/Xrender.h>
#include <X11/extensions/record.h>
#include <X11/extensions/sync.h> #include <X11/extensions/sync.h>
// Define XK_xxx before the #include of <X11/keysym.h> so that <X11/keysym.h> // Define XK_xxx before the #include of <X11/keysym.h> so that <X11/keysym.h>
...@@ -90,12 +84,6 @@ extern "C" { ...@@ -90,12 +84,6 @@ extern "C" {
#undef RootWindow // Defined by X11/Xlib.h #undef RootWindow // Defined by X11/Xlib.h
#undef DestroyAll // Defined by X11/X.h to 0 #undef DestroyAll // Defined by X11/X.h to 0
#undef Always // Defined by X11/X.h to 2 #undef Always // Defined by X11/X.h to 2
#undef AddToList // Defined by X11/extensions/XI.h to 0
#undef COUNT // Defined by X11/extensions/XI.h to 0
#undef CREATE // Defined by X11/extensions/XI.h to 1
#undef DeviceAdded // Defined by X11/extensions/XI.h to 0
#undef DeviceMode // Defined by X11/extensions/XI.h to 1
#undef DeviceRemoved // Defined by X11/extensions/XI.h to 1
#undef FocusIn // Defined by X.h to 9 #undef FocusIn // Defined by X.h to 9
#undef FocusOut // Defined by X.h to 10 #undef FocusOut // Defined by X.h to 10
#undef None // Defined by X11/X.h to 0L #undef None // Defined by X11/X.h to 0L
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment