Commit 290ab090 authored by Tom Anderson's avatar Tom Anderson Committed by Commit Bot

Reland "[XProto] Remove all remaining non-event usages of XRandR"

This is a reland of 0af7d7aa

Original change's description:
> [XProto] Remove all remaining non-event usages of XRandR
>
> BUG=1066670
> R=msisov
> CC=sky
>
> Change-Id: Iecd593c0c77878a80bf84e9e3c504fd90815db6c
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2220686
> Commit-Queue: Thomas Anderson <thomasanderson@chromium.org>
> Reviewed-by: Maksim Sisov <msisov@igalia.com>
> Reviewed-by: Jamie Walch <jamiewalch@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#773876}

Bug: 1066670
R=msisov
TBR=jamiewalch

Change-Id: Id24ace289778fc9f6feb8de9ed2744a2630be766
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2226785Reviewed-by: default avatarThomas Anderson <thomasanderson@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Auto-Submit: Thomas Anderson <thomasanderson@chromium.org>
Commit-Queue: Scott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#774348}
parent 2974dd77
This diff is collapsed.
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "ui/base/x/x11_display_util.h" #include "ui/base/x/x11_display_util.h"
#include "ui/gfx/x/randr.h"
#include "ui/gfx/x/x11.h" #include "ui/gfx/x/x11.h"
#include "ui/gfx/x/x11_atom_cache.h" #include "ui/gfx/x/x11_atom_cache.h"
...@@ -22,21 +23,22 @@ constexpr int kMinXrandrVersion = 103; // Need at least xrandr version 1.3 ...@@ -22,21 +23,22 @@ constexpr int kMinXrandrVersion = 103; // Need at least xrandr version 1.3
XDisplayManager::XDisplayManager(Delegate* delegate) XDisplayManager::XDisplayManager(Delegate* delegate)
: delegate_(delegate), : delegate_(delegate),
xdisplay_(gfx::GetXDisplay()), connection_(x11::Connection::Get()),
x_root_window_(DefaultRootWindow(xdisplay_)), x_root_window_(connection_->default_screen()->root),
xrandr_version_(GetXrandrVersion(xdisplay_)), xrandr_version_(GetXrandrVersion()),
workspace_handler_(this) {} workspace_handler_(this) {}
XDisplayManager::~XDisplayManager() = default; XDisplayManager::~XDisplayManager() = default;
void XDisplayManager::Init() { void XDisplayManager::Init() {
if (IsXrandrAvailable()) { if (IsXrandrAvailable()) {
int error_base_ignored = 0; auto* randr = connection_->randr();
XRRQueryExtension(xdisplay_, &xrandr_event_base_, &error_base_ignored); xrandr_event_base_ = randr->first_event();
XRRSelectInput(xdisplay_, x_root_window_, randr->SelectInput(
RRScreenChangeNotifyMask | RROutputChangeNotifyMask | {x_root_window_, x11::RandR::NotifyMask::ScreenChange |
RRCrtcChangeNotifyMask); x11::RandR::NotifyMask::OutputChange |
x11::RandR::NotifyMask::CrtcChange});
} }
FetchDisplayList(); FetchDisplayList();
} }
...@@ -60,10 +62,11 @@ void XDisplayManager::RemoveObserver(display::DisplayObserver* observer) { ...@@ -60,10 +62,11 @@ void XDisplayManager::RemoveObserver(display::DisplayObserver* observer) {
} }
bool XDisplayManager::CanProcessEvent(const XEvent& xev) { bool XDisplayManager::CanProcessEvent(const XEvent& xev) {
return xev.type - xrandr_event_base_ == RRScreenChangeNotify || return xev.type - xrandr_event_base_ ==
xev.type - xrandr_event_base_ == RRNotify || x11::RandR::ScreenChangeNotifyEvent::opcode ||
xev.type - xrandr_event_base_ == x11::RandR::NotifyEvent::opcode ||
(xev.type == PropertyNotify && (xev.type == PropertyNotify &&
xev.xproperty.window == x_root_window_ && static_cast<x11::Window>(xev.xproperty.window) == x_root_window_ &&
xev.xproperty.atom == xev.xproperty.atom ==
static_cast<uint32_t>(gfx::GetAtom("_NET_WORKAREA"))); static_cast<uint32_t>(gfx::GetAtom("_NET_WORKAREA")));
} }
...@@ -71,12 +74,12 @@ bool XDisplayManager::CanProcessEvent(const XEvent& xev) { ...@@ -71,12 +74,12 @@ bool XDisplayManager::CanProcessEvent(const XEvent& xev) {
bool XDisplayManager::ProcessEvent(XEvent* xev) { bool XDisplayManager::ProcessEvent(XEvent* xev) {
DCHECK(xev); DCHECK(xev);
int ev_type = xev->type - xrandr_event_base_; int ev_type = xev->type - xrandr_event_base_;
if (ev_type == RRScreenChangeNotify) { if (ev_type == x11::RandR::ScreenChangeNotifyEvent::opcode) {
// Pass the event through to xlib. // Pass the event through to xlib.
XRRUpdateConfiguration(xev); XRRUpdateConfiguration(xev);
return true; return true;
} }
if (ev_type == RRNotify || if (ev_type == x11::RandR::NotifyEvent::opcode ||
(xev->type == PropertyNotify && (xev->type == PropertyNotify &&
xev->xproperty.atom == xev->xproperty.atom ==
static_cast<uint32_t>(gfx::GetAtom("_NET_WORKAREA")))) { static_cast<uint32_t>(gfx::GetAtom("_NET_WORKAREA")))) {
...@@ -125,13 +128,9 @@ void XDisplayManager::DispatchDelayedDisplayListUpdate() { ...@@ -125,13 +128,9 @@ void XDisplayManager::DispatchDelayedDisplayListUpdate() {
} }
gfx::Point XDisplayManager::GetCursorLocation() const { gfx::Point XDisplayManager::GetCursorLocation() const {
XID root, child; if (auto response = connection_->QueryPointer({x_root_window_}).Sync())
int root_x, root_y, win_x, win_y; return {response->root_x, response->root_y};
unsigned int mask; return {};
XQueryPointer(xdisplay_, x_root_window_, &root, &child, &root_x, &root_y,
&win_x, &win_y, &mask);
return gfx::Point(root_x, root_y);
} }
std::string XDisplayManager::GetCurrentWorkspace() { std::string XDisplayManager::GetCurrentWorkspace() {
......
...@@ -76,8 +76,8 @@ class COMPONENT_EXPORT(UI_BASE_X) XDisplayManager ...@@ -76,8 +76,8 @@ class COMPONENT_EXPORT(UI_BASE_X) XDisplayManager
std::vector<display::Display> displays_; std::vector<display::Display> displays_;
display::DisplayChangeNotifier change_notifier_; display::DisplayChangeNotifier change_notifier_;
XDisplay* const xdisplay_; x11::Connection* const connection_;
XID x_root_window_; x11::Window x_root_window_;
int64_t primary_display_index_ = 0; int64_t primary_display_index_ = 0;
// XRandR version. MAJOR * 100 + MINOR. Zero if no xrandr is present. // XRandR version. MAJOR * 100 + MINOR. Zero if no xrandr is present.
......
...@@ -28,6 +28,8 @@ namespace { ...@@ -28,6 +28,8 @@ namespace {
constexpr int kMinVersionXrandr = 103; // Need at least xrandr version 1.3. constexpr int kMinVersionXrandr = 103; // Need at least xrandr version 1.3.
constexpr const char kRandrEdidProperty[] = "EDID";
std::map<x11::RandR::Output, int> GetMonitors(int version, std::map<x11::RandR::Output, int> GetMonitors(int version,
x11::RandR* randr, x11::RandR* randr,
x11::Window window) { x11::Window window) {
...@@ -138,7 +140,7 @@ std::vector<uint8_t> GetEDIDProperty(x11::RandR* randr, ...@@ -138,7 +140,7 @@ std::vector<uint8_t> GetEDIDProperty(x11::RandR* randr,
x11::RandR::Output output) { x11::RandR::Output output) {
auto future = randr->GetOutputProperty({ auto future = randr->GetOutputProperty({
.output = output, .output = output,
.property = gfx::GetAtom(RR_PROPERTY_RANDR_EDID), .property = gfx::GetAtom(kRandrEdidProperty),
.long_length = 128, .long_length = 128,
}); });
auto response = future.Sync(); auto response = future.Sync();
...@@ -150,16 +152,19 @@ std::vector<uint8_t> GetEDIDProperty(x11::RandR* randr, ...@@ -150,16 +152,19 @@ std::vector<uint8_t> GetEDIDProperty(x11::RandR* randr,
} // namespace } // namespace
int GetXrandrVersion(XDisplay* xdisplay) { int GetXrandrVersion() {
int xrandr_version = 0; auto impl = []() -> int {
// We only support 1.3+. There were library changes before this and we should auto* randr = x11::Connection::Get()->randr();
// use the new interface instead of the 1.2 one. if (!randr)
int randr_version_major = 0; return 0;
int randr_version_minor = 0; auto future = randr->QueryVersion(
if (XRRQueryVersion(xdisplay, &randr_version_major, &randr_version_minor)) { {x11::RandR::major_version, x11::RandR::minor_version});
xrandr_version = randr_version_major * 100 + randr_version_minor; if (auto response = future.Sync())
} return response->major_version * 100 + response->minor_version;
return xrandr_version; return 0;
};
static int version = impl();
return version;
} }
std::vector<display::Display> GetFallbackDisplayList(float scale) { std::vector<display::Display> GetFallbackDisplayList(float scale) {
......
...@@ -16,7 +16,7 @@ namespace ui { ...@@ -16,7 +16,7 @@ namespace ui {
// Return the version for xrandr. It multiplies the major number by 100 and // Return the version for xrandr. It multiplies the major number by 100 and
// adds the minor like MAJOR * 100 + MINOR. It returns zero if no xrandr is // adds the minor like MAJOR * 100 + MINOR. It returns zero if no xrandr is
// present. // present.
COMPONENT_EXPORT(UI_BASE_X) int GetXrandrVersion(XDisplay* xdisplay); COMPONENT_EXPORT(UI_BASE_X) int GetXrandrVersion();
// Builds a list of displays for fallback. // Builds a list of displays for fallback.
COMPONENT_EXPORT(UI_BASE_X) COMPONENT_EXPORT(UI_BASE_X)
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "ui/gfx/x/connection.h" #include "ui/gfx/x/connection.h"
#include <X11/Xlib-xcb.h> #include <X11/Xlib-xcb.h>
#include <X11/Xlib.h>
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include <algorithm> #include <algorithm>
...@@ -51,25 +52,25 @@ XDisplay* OpenNewXDisplay() { ...@@ -51,25 +52,25 @@ XDisplay* OpenNewXDisplay() {
} // namespace } // namespace
Connection* Connection::Get() { Connection* Connection::Get() {
static Connection* instance = new Connection(OpenNewXDisplay()); static Connection* instance = new Connection;
return instance; return instance;
} }
Connection::Connection(XDisplay* display) : XProto(this), display_(display) { Connection::Connection() : XProto(this), display_(OpenNewXDisplay()) {
if (!display_) if (!display_)
return; return;
setup_ = std::make_unique<x11::Setup>(x11::Read<x11::Setup>( setup_ = std::make_unique<Setup>(Read<Setup>(
reinterpret_cast<const uint8_t*>(xcb_get_setup(XcbConnection())))); reinterpret_cast<const uint8_t*>(xcb_get_setup(XcbConnection()))));
default_screen_ = &setup_->roots[DefaultScreen(display)]; default_screen_ = &setup_->roots[DefaultScreen(display_)];
default_root_depth_ = &*std::find_if( default_root_depth_ = &*std::find_if(
default_screen_->allowed_depths.begin(), default_screen_->allowed_depths.begin(),
default_screen_->allowed_depths.end(), [&](const x11::Depth& depth) { default_screen_->allowed_depths.end(), [&](const Depth& depth) {
return depth.depth == default_screen_->root_depth; return depth.depth == default_screen_->root_depth;
}); });
defualt_root_visual_ = &*std::find_if( defualt_root_visual_ = &*std::find_if(
default_root_depth_->visuals.begin(), default_root_depth_->visuals.end(), default_root_depth_->visuals.begin(), default_root_depth_->visuals.end(),
[&](const x11::VisualType visual) { [&](const VisualType visual) {
return visual.visual_id == default_screen_->root_visual; return visual.visual_id == default_screen_->root_visual;
}); });
...@@ -80,7 +81,10 @@ Connection::Connection(XDisplay* display) : XProto(this), display_(display) { ...@@ -80,7 +81,10 @@ Connection::Connection(XDisplay* display) : XProto(this), display_(display) {
} }
} }
Connection::~Connection() = default; Connection::~Connection() {
if (display_)
XCloseDisplay(display_);
}
xcb_connection_t* Connection::XcbConnection() { xcb_connection_t* Connection::XcbConnection() {
if (!display()) if (!display())
......
...@@ -29,6 +29,9 @@ class COMPONENT_EXPORT(X11) Connection : public XProto, ...@@ -29,6 +29,9 @@ class COMPONENT_EXPORT(X11) Connection : public XProto,
// Gets or creates the singeton connection. // Gets or creates the singeton connection.
static Connection* Get(); static Connection* Get();
explicit Connection();
~Connection();
Connection(const Connection&) = delete; Connection(const Connection&) = delete;
Connection(Connection&&) = delete; Connection(Connection&&) = delete;
...@@ -39,12 +42,10 @@ class COMPONENT_EXPORT(X11) Connection : public XProto, ...@@ -39,12 +42,10 @@ class COMPONENT_EXPORT(X11) Connection : public XProto,
return extended_max_request_length_; return extended_max_request_length_;
} }
const x11::Setup* setup() const { return setup_.get(); } const Setup* setup() const { return setup_.get(); }
const x11::Screen* default_screen() const { return default_screen_; } const Screen* default_screen() const { return default_screen_; }
const x11::Depth* default_root_depth() const { return default_root_depth_; } const Depth* default_root_depth() const { return default_root_depth_; }
const x11::VisualType* default_root_visual() const { const VisualType* default_root_visual() const { return defualt_root_visual_; }
return defualt_root_visual_;
}
void Dispatch(Delegate* delegate); void Dispatch(Delegate* delegate);
...@@ -60,19 +61,16 @@ class COMPONENT_EXPORT(X11) Connection : public XProto, ...@@ -60,19 +61,16 @@ class COMPONENT_EXPORT(X11) Connection : public XProto,
FutureBase::ResponseCallback callback; FutureBase::ResponseCallback callback;
}; };
explicit Connection(XDisplay* display);
~Connection();
void AddRequest(unsigned int sequence, FutureBase::ResponseCallback callback); void AddRequest(unsigned int sequence, FutureBase::ResponseCallback callback);
XDisplay* const display_; XDisplay* const display_;
uint32_t extended_max_request_length_ = 0; uint32_t extended_max_request_length_ = 0;
std::unique_ptr<x11::Setup> setup_; std::unique_ptr<Setup> setup_;
const x11::Screen* default_screen_ = nullptr; const Screen* default_screen_ = nullptr;
const x11::Depth* default_root_depth_ = nullptr; const Depth* default_root_depth_ = nullptr;
const x11::VisualType* defualt_root_visual_ = nullptr; const VisualType* defualt_root_visual_ = nullptr;
std::queue<Request> requests_; std::queue<Request> requests_;
}; };
......
...@@ -1100,6 +1100,7 @@ class GenXproto(FileWriter): ...@@ -1100,6 +1100,7 @@ class GenXproto(FileWriter):
self.write('class Connection;') self.write('class Connection;')
self.write() self.write()
self.namespace = ['x11']
if not self.module.namespace.is_ext: if not self.module.namespace.is_ext:
for (name, item) in self.module.all: for (name, item) in self.module.all:
self.declare_type(item, name) self.declare_type(item, name)
...@@ -1110,8 +1111,19 @@ class GenXproto(FileWriter): ...@@ -1110,8 +1111,19 @@ class GenXproto(FileWriter):
self.namespace = ['x11', self.class_name] self.namespace = ['x11', self.class_name]
self.write('public:') self.write('public:')
if self.module.namespace.is_ext: if self.module.namespace.is_ext:
self.write(name + self.write('static constexpr unsigned major_version = %s;' %
'(Connection* connection, uint8_t major_opcode);') self.module.namespace.major_version)
self.write('static constexpr unsigned minor_version = %s;' %
self.module.namespace.minor_version)
self.write()
self.write(name + '(')
self.write(' Connection* connection, uint8_t major_opcode,')
self.write(' uint8_t first_event, uint8_t first_error);')
self.write()
with Indent(self, 'uint8_t first_event() const {', '}'):
self.write('return first_event_;')
with Indent(self, 'uint8_t first_error() const {', '}'):
self.write('return first_error_;')
else: else:
self.write('explicit %s(Connection* connection);' % name) self.write('explicit %s(Connection* connection);' % name)
self.write() self.write()
...@@ -1121,13 +1133,14 @@ class GenXproto(FileWriter): ...@@ -1121,13 +1133,14 @@ class GenXproto(FileWriter):
for (name, item) in self.module.all: for (name, item) in self.module.all:
if self.module.namespace.is_ext: if self.module.namespace.is_ext:
self.declare_type(item, name) self.declare_type(item, name)
else: elif isinstance(item, self.xcbgen.xtypes.Request):
if isinstance(item, self.xcbgen.xtypes.Request): self.declare_request(item)
self.declare_request(item)
self.write('private:') self.write('private:')
self.write('x11::Connection* const connection_;') self.write('x11::Connection* const connection_;')
if self.module.namespace.is_ext: if self.module.namespace.is_ext:
self.write('uint8_t major_opcode_;') self.write('const uint8_t major_opcode_;')
self.write('const uint8_t first_event_;')
self.write('const uint8_t first_error_;')
self.write() self.write()
self.write('} // namespace x11') self.write('} // namespace x11')
...@@ -1158,9 +1171,11 @@ class GenXproto(FileWriter): ...@@ -1158,9 +1171,11 @@ class GenXproto(FileWriter):
self.write() self.write()
ctor = '%s::%s' % (self.class_name, self.class_name) ctor = '%s::%s' % (self.class_name, self.class_name)
if self.module.namespace.is_ext: if self.module.namespace.is_ext:
self.write(ctor + '(x11::Connection* connection, uint8_t opcode)') self.write(ctor + '(x11::Connection* connection, uint8_t opcode,')
self.write( self.write(' uint8_t first_event, uint8_t first_error)')
' : connection_(connection), major_opcode_(opcode) {}') self.write(' : connection_(connection), major_opcode_(opcode),')
self.write(' first_event_(first_event),')
self.write(' first_error_(first_error) {}')
else: else:
self.write(ctor + self.write(ctor +
'(Connection* connection) : connection_(connection) {}') '(Connection* connection) : connection_(connection) {}')
...@@ -1221,7 +1236,7 @@ class GenExtensionManager(FileWriter): ...@@ -1221,7 +1236,7 @@ class GenExtensionManager(FileWriter):
(extension.class_name, name, name)) (extension.class_name, name, name))
self.write() self.write()
self.write('protected:') self.write('protected:')
self.write('void Init(XProto* xproto);') self.write('void Init(Connection* conn);')
self.write() self.write()
self.write('private:') self.write('private:')
for extension in self.extensions: for extension in self.extensions:
...@@ -1237,28 +1252,32 @@ class GenExtensionManager(FileWriter): ...@@ -1237,28 +1252,32 @@ class GenExtensionManager(FileWriter):
'w') 'w')
self.write('#include "ui/gfx/x/extension_manager.h"') self.write('#include "ui/gfx/x/extension_manager.h"')
self.write() self.write()
self.write('#include "ui/gfx/x/connection.h"')
for genproto in self.genprotos: for genproto in self.genprotos:
self.write('#include "ui/gfx/x/%s.h"' % genproto.proto) self.write('#include "ui/gfx/x/%s.h"' % genproto.proto)
self.write() self.write()
self.write('namespace x11 {') self.write('namespace x11 {')
self.write() self.write()
init = 'void ExtensionManager::Init' init = 'void ExtensionManager::Init'
with Indent(self, init + '(XProto* xproto) {', '}'): with Indent(self, init + '(Connection* conn) {', '}'):
self.write('Connection* connection = xproto->connection();') self.write('if (!conn)')
self.write('if (!connection)')
self.write(' return;') self.write(' return;')
self.write()
for extension in self.extensions: for extension in self.extensions:
self.write( self.write(
'auto %s_future = xproto->QueryExtension({"%s"});' % 'auto %s_future = conn->QueryExtension({"%s"});' %
(extension.proto, extension.module.namespace.ext_xname)) (extension.proto, extension.module.namespace.ext_xname))
self.write() self.write()
for extension in self.extensions: for extension in self.extensions:
name = extension.proto name = extension.proto
self.write('auto {0}_reply = {0}_future.Sync();'.format(name)) self.write('auto {0}_reply = {0}_future.Sync();'.format(name))
self.write('if ({0}_reply && {0}_reply->present)'.format(name)) cond = 'if ({0}_reply && {0}_reply->present) {{'.format(name)
args = 'connection, %s_reply->major_opcode' % name with Indent(self, cond, '}'):
self.write(' %s_ = std::make_unique<%s>(%s);' % self.write('auto* reply = %s_reply.reply.get();' % name)
(name, extension.class_name, args)) self.write(' %s_ = std::make_unique<%s>(' %
(name, extension.class_name))
self.write(' conn, reply->major_opcode,')
self.write(' reply->first_event, reply->first_error);')
self.write() self.write()
self.write('ExtensionManager::ExtensionManager() = default;') self.write('ExtensionManager::ExtensionManager() = default;')
self.write('ExtensionManager::~ExtensionManager() = default;') self.write('ExtensionManager::~ExtensionManager() = default;')
......
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