0

[XProto] Remove more functions from ui/gfx/x/x11.h

R=sky
BUG=1066670

Change-Id: Ia9232be6f923aaea4c9860d6c0087dd91340ba5e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2432141
Commit-Queue: Thomas Anderson <thomasanderson@chromium.org>
Reviewed-by: Scott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#811581}
This commit is contained in:
Tom Anderson
2020-09-29 05:22:18 +00:00
committed by Commit Bot
parent 47ed05349e
commit 254b3cf700
27 changed files with 104 additions and 127 deletions

@ -113,10 +113,10 @@ bool VulkanSurfaceX11::Reshape(const gfx::Size& size,
gfx::OverlayTransform pre_transform) {
DCHECK_EQ(pre_transform, gfx::OVERLAY_TRANSFORM_NONE);
Display* display = gfx::GetXDisplay();
XResizeWindow(display, static_cast<uint32_t>(window_), size.width(),
size.height());
XFlush(display);
auto* connection = x11::Connection::Get();
connection->ConfigureWindow(
{.window = window_, .width = size.width(), .height = size.height()});
connection->Flush();
return VulkanSurface::Reshape(size, pre_transform);
}

@ -179,7 +179,7 @@ void UserInputMonitorLinuxCore::StartMonitor() {
// Register OnConnectionData() to be called every time there is something to
// read from |connection_|.
watch_controller_ = base::FileDescriptorWatcher::WatchReadable(
XConnectionNumber(connection_->display()),
connection_->GetFd(),
base::BindRepeating(&UserInputMonitorLinuxCore::OnConnectionData,
base::Unretained(this)));

@ -77,7 +77,7 @@ void ClipboardX11::Start(
base::Unretained(this)));
x_connection_watch_controller_ = base::FileDescriptorWatcher::WatchReadable(
XConnectionNumber(connection_->display()),
connection_->GetFd(),
base::BindRepeating(&ClipboardX11::PumpXEvents, base::Unretained(this)));
PumpXEvents();
}

@ -180,7 +180,7 @@ void DesktopResizerX11::SetResolution(const ScreenResolution& resolution) {
// Grab the X server while we're changing the display resolution. This ensures
// that the display configuration doesn't change under our feet.
ScopedXGrabServer grabber(connection_.display());
ScopedXGrabServer grabber(&connection_);
if (exact_resize_)
SetResolutionNewMode(resolution);

@ -162,7 +162,7 @@ void LocalHotkeyInputMonitorX11::Core::StartOnInputThread() {
// Register OnConnectionData() to be called every time there is
// something to read from |connection_|.
controller_ = base::FileDescriptorWatcher::WatchReadable(
XConnectionNumber(connection_->display()),
connection_->GetFd(),
base::BindRepeating(&Core::OnConnectionData, base::Unretained(this)));
// Fetch pending events if any.

@ -156,7 +156,7 @@ void LocalMouseInputMonitorX11::Core::StartOnInputThread() {
// Register OnConnectionData() to be called every time there is
// something to read from |connection_|.
controller_ = base::FileDescriptorWatcher::WatchReadable(
XConnectionNumber(connection_->display()),
connection_->GetFd(),
base::BindRepeating(&Core::OnConnectionData, base::Unretained(this)));
// Fetch pending events if any.

@ -162,7 +162,7 @@ void GdkLayoutMonitorOnGtkThread::Start() {
});
connection_->Flush();
controller_ = base::FileDescriptorWatcher::WatchReadable(
XConnectionNumber(connection_->display()),
connection_->GetFd(),
base::BindRepeating(&GdkLayoutMonitorOnGtkThread::OnConnectionData,
base::Unretained(this)));
}

@ -36,13 +36,14 @@ int ScopedXErrorHandler::HandleXErrors(Display* display, XErrorEvent* error) {
return 0;
}
ScopedXGrabServer::ScopedXGrabServer(Display* display) : display_(display) {
XGrabServer(display_);
ScopedXGrabServer::ScopedXGrabServer(x11::Connection* connection)
: connection_(connection) {
connection_->GrabServer({});
}
ScopedXGrabServer::~ScopedXGrabServer() {
XUngrabServer(display_);
XFlush(display_);
connection_->UngrabServer({});
connection_->Flush();
}
bool IgnoreXServerGrabs(x11::Connection* connection, bool ignore) {

@ -44,21 +44,19 @@ class ScopedXErrorHandler {
DISALLOW_COPY_AND_ASSIGN(ScopedXErrorHandler);
};
// Grab/release the X server within a scope. This can help avoid race
// conditions that would otherwise lead to X errors.
class ScopedXGrabServer {
public:
ScopedXGrabServer(Display* display);
explicit ScopedXGrabServer(x11::Connection* connection);
~ScopedXGrabServer();
private:
Display* display_;
x11::Connection* connection_;
DISALLOW_COPY_AND_ASSIGN(ScopedXGrabServer);
};
// 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.
bool IgnoreXServerGrabs(x11::Connection* connection, bool ignore);

@ -70,11 +70,11 @@ bool ShouldUseMitShm(x11::Connection* connection) {
// codepath. It may be possible in contrived cases for there to be a
// false-positive, but in that case we'll just fallback to the non-SHM
// codepath.
char* display_string = XDisplayString(connection->display());
const std::string& display_string = connection->DisplayString();
char* host = nullptr;
int display_id = 0;
int screen = 0;
if (xcb_parse_display(display_string, &host, &display_id, &screen)) {
if (xcb_parse_display(display_string.c_str(), &host, &display_id, &screen)) {
std::string name = host;
free(host);
if (IsRemoteHost(name))

@ -57,7 +57,7 @@ int main(int argc, char* argv[]) {
connection.MapWindow({dummy_window});
connection.Flush();
int display_fd = XConnectionNumber(connection.display());
int display_fd = connection.GetFd();
// Set deadline as 30s.
struct timespec now, deadline;

@ -22,7 +22,7 @@ void X11EventWatcherFdWatch::StartWatching() {
DCHECK(event_source_->connection()) << "Unable to get connection to X server";
int fd = XConnectionNumber(event_source_->connection()->display());
int fd = event_source_->connection()->GetFd();
base::CurrentUIThread::Get()->WatchFileDescriptor(
fd, true, base::MessagePumpForUI::WATCH_READ, &watcher_controller_, this);
started_ = true;

@ -60,12 +60,12 @@ void X11EventWatcherGlib::StartWatching() {
if (started_)
return;
XDisplay* display = event_source_->connection()->display();
if (!display)
auto* connection = event_source_->connection();
if (!connection->Ready())
return;
x_poll_ = std::make_unique<GPollFD>();
x_poll_->fd = XConnectionNumber(display);
x_poll_->fd = connection->GetFd();
x_poll_->events = G_IO_IN;
x_poll_->revents = 0;

@ -120,8 +120,7 @@ x11::Event CreateXInput2Event(int deviceid,
event.detail = tracking_id;
event.event_x = ToFp1616(location.x()),
event.event_y = ToFp1616(location.y()),
event.event =
static_cast<x11::Window>(XDefaultRootWindow(gfx::GetXDisplay()));
event.event = x11::Connection::Get()->default_root();
event.button_mask = {0, 0};
return x11::Event(std::move(event));
}

@ -232,7 +232,14 @@ void Connection::Set(std::unique_ptr<x11::Connection> connection) {
}
Connection::Connection(const std::string& address)
: XProto(this), display_(OpenNewXDisplay(address)) {
: XProto(this),
display_(OpenNewXDisplay(address)),
display_string_(address) {
char* host = nullptr;
int display = 0;
xcb_parse_display(address.c_str(), &host, &display, &default_screen_id_);
if (host)
free(host);
if (display_) {
XSetEventQueueOwner(display_, XCBOwnsEventQueue);
@ -298,12 +305,22 @@ bool Connection::HasNextResponse() const {
requests_.front().sequence) >= 0;
}
int Connection::GetFd() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return Ready() ? xcb_get_file_descriptor(XcbConnection()) : -1;
}
const std::string& Connection::DisplayString() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return display_string_;
}
int Connection::DefaultScreenId() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// This is not part of the setup data as the server has no concept of a
// default screen. Instead, it's part of the display name. Eg in
// "localhost:0.0", the screen ID is the second "0".
return XDefaultScreen(display_);
return default_screen_id_;
}
bool Connection::Ready() const {
@ -339,7 +356,7 @@ void Connection::ReadResponses() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
while (auto* event = xcb_poll_for_event(XcbConnection())) {
events_.emplace_back(base::MakeRefCounted<MallocedRefCountedMemory>(event),
this);
this, true);
}
}
@ -350,10 +367,9 @@ Event Connection::WaitForNextEvent() {
events_.pop_front();
return event;
}
auto* xcb_event = xcb_wait_for_event(XcbConnection());
if (xcb_event) {
if (auto* xcb_event = xcb_wait_for_event(XcbConnection())) {
return Event(base::MakeRefCounted<MallocedRefCountedMemory>(xcb_event),
this);
this, true);
}
return Event();
}
@ -396,7 +412,7 @@ KeySym Connection::KeycodeToKeysym(uint32_t keycode, unsigned int modifiers) {
std::unique_ptr<Connection> Connection::Clone() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return std::make_unique<Connection>(display_ ? XDisplayString(display_) : "");
return std::make_unique<Connection>(display_string_);
}
void Connection::DetachFromSequence() {

@ -79,6 +79,12 @@ class COMPONENT_EXPORT(X11) Connection : public XProto,
return *default_root_visual_;
}
// Returns the underlying socket's FD if the connection is valid, or -1
// otherwise.
int GetFd();
const std::string& DisplayString() const;
int DefaultScreenId() const;
template <typename T>
@ -172,6 +178,8 @@ class COMPONENT_EXPORT(X11) Connection : public XProto,
uint32_t extended_max_request_length_ = 0;
std::string display_string_;
int default_screen_id_ = 0;
Setup setup_;
Screen* default_screen_ = nullptr;
Depth* default_root_depth_ = nullptr;

@ -25,7 +25,7 @@ void ReadEvent(Event* event, Connection* connection, ReadBuffer* buffer);
class COMPONENT_EXPORT(X11) Event {
public:
template <typename T>
explicit Event(T&& xproto_event) {
explicit Event(T&& xproto_event, bool sequence_valid = true) {
using DecayT = std::decay_t<T>;
sequence_valid_ = true;
sequence_ = xproto_event.sequence;
@ -34,6 +34,7 @@ class COMPONENT_EXPORT(X11) Event {
auto* event = new DecayT(std::forward<T>(xproto_event));
event_ = event;
window_ = event->GetWindow();
sequence_valid_ = sequence_valid;
}
Event();

@ -47,29 +47,6 @@ using XErrorEvent = struct _XErrorEvent {
unsigned char minor_code;
};
using XRectangle = struct _XRectangle {
short x, y;
unsigned short width, height;
};
using XSetWindowAttributes = struct {
Pixmap background_pixmap;
unsigned long background_pixel;
Pixmap border_pixmap;
unsigned long border_pixel;
int bit_gravity;
int win_gravity;
int backing_store;
unsigned long backing_planes;
unsigned long backing_pixel;
Bool save_under;
long event_mask;
long do_not_propagate_mask;
Bool override_redirect;
Colormap colormap;
Cursor cursor;
};
using XModifierKeymap = struct {
int max_keypermod;
KeyCode* modifiermap;
@ -81,12 +58,9 @@ using XIOErrorHandler = int (*)(Display*);
Status XInitThreads(void);
Display* XOpenDisplay(const char*);
int XCloseDisplay(Display*);
char* XDisplayString(Display*);
int XFlush(Display*);
xcb_connection_t* XGetXCBConnection(Display* dpy);
void XSetEventQueueOwner(Display* dpy, enum XEventQueueOwner owner);
int XDefaultScreen(Display*);
Window XDefaultRootWindow(Display*);
unsigned long XLastKnownRequestProcessed(Display*);
int (*XSynchronize(Display*, Bool))(Display*);
int XGetErrorDatabaseText(Display*,
@ -98,26 +72,11 @@ int XGetErrorDatabaseText(Display*,
int XGetErrorText(Display*, int, char*, int);
XErrorHandler XSetErrorHandler(XErrorHandler);
XIOErrorHandler XSetIOErrorHandler(XIOErrorHandler);
void XLockDisplay(Display*);
extern void XUnlockDisplay(Display*);
int XConnectionNumber(Display*);
int XSelectInput(Display*, Window, long);
int XSetWindowBackgroundPixmap(Display*, Window, Pixmap);
int XResizeWindow(Display*, Window, unsigned int, unsigned int);
int XMapWindow(Display*, Window);
KeyCode XKeysymToKeycode(Display*, KeySym);
char* XKeysymToString(KeySym);
XModifierKeymap* XGetModifierMapping(Display*);
int XFreeModifiermap(XModifierKeymap*);
int XGrabServer(Display*);
int XUngrabServer(Display*);
unsigned long XBlackPixel(Display*, int);
int XStoreName(Display*, Window, const char*);
Status XIconifyWindow(Display*, Window, int);
int XConvertSelection(Display*, Atom, Atom, Atom, Window, Time);
Window XGetSelectionOwner(Display*, Atom);
int XSetSelectionOwner(Display*, Atom, Window, Time);
Status XInternAtoms(Display*, char**, int, Bool, Atom*);
int XDisplayKeycodes(Display*, int*, int*);
KeySym* XGetKeyboardMapping(Display*, KeyCode, int, int*);
KeySym XStringToKeysym(const char*);

@ -17,11 +17,6 @@ std::unique_ptr<std::vector<x11::Rectangle>> CreateRegionFromSkRegion(
auto result = std::make_unique<std::vector<x11::Rectangle>>();
for (SkRegion::Iterator i(region); !i.done(); i.next()) {
XRectangle rect;
rect.x = i.rect().x();
rect.y = i.rect().y();
rect.width = i.rect().width();
rect.height = i.rect().height();
result->push_back({
.x = i.rect().x(),
.y = i.rect().y(),

@ -19,8 +19,4 @@ XDisplay* GetXDisplay() {
return x11::Connection::Get()->display();
}
XDisplay* CloneXDisplay(XDisplay* display) {
return XOpenDisplay(XDisplayString(display));
}
} // namespace gfx

@ -40,10 +40,6 @@ using XScopedPtr = std::unique_ptr<T, D>;
// Get the XDisplay singleton. Prefer x11::Connection::Get() instead.
GFX_EXPORT XDisplay* GetXDisplay();
// Given a connection to an X server, opens a new parallel connection to the
// same X server. It's the caller's responsibility to call XCloseDisplay().
GFX_EXPORT XDisplay* CloneXDisplay(XDisplay* display);
} // namespace gfx
#endif // UI_GFX_X_X11_UTIL_H_

@ -73,9 +73,9 @@ std::string DriverEGL::GetClientExtensions() {
#if defined(USE_GLX)
std::string DriverGLX::GetPlatformExtensions() {
Display* display = gfx::GetXDisplay();
const int screen = (display == EGL_NO_DISPLAY ? 0 : XDefaultScreen(display));
const char* str = glXQueryExtensionsString(display, screen);
auto* connection = x11::Connection::Get();
const int screen = connection ? connection->DefaultScreenId() : 0;
const char* str = glXQueryExtensionsString(connection->display(), screen);
return str ? std::string(str) : "";
}
#endif

@ -43,11 +43,11 @@ bool GLImageGLX::Initialize(XID pixmap) {
auto fbconfig_id =
GLVisualPickerGLX::GetInstance()->GetFbConfigForFormat(format_);
auto* display = gfx::GetXDisplay();
auto* connection = x11::Connection::Get();
int attrs[] = {GLX_FBCONFIG_ID, static_cast<uint32_t>(fbconfig_id), 0};
int nitems;
gfx::XScopedPtr<GLXFBConfig> configs(
glXChooseFBConfig(display, XDefaultScreen(display), attrs, &nitems));
gfx::XScopedPtr<GLXFBConfig> configs(glXChooseFBConfig(
connection->display(), connection->DefaultScreenId(), attrs, &nitems));
if (!nitems)
return false;

@ -86,8 +86,11 @@ gfx::SwapResult NativeViewGLSurfaceEGLX11::SwapBuffers(
// views::DesktopWindowTreeHostX11::InitX11Window back to None for the
// XWindow associated to this surface after the first SwapBuffers has
// happened, to avoid showing a weird white background while resizing.
if (GetXNativeConnection()->display() && !has_swapped_buffers_) {
XSetWindowBackgroundPixmap(GetXNativeConnection()->display(), window_, 0);
if (GetXNativeConnection()->Ready() && !has_swapped_buffers_) {
GetXNativeConnection()->ChangeWindowAttributes({
.window = static_cast<x11::Window>(window_),
.background_pixmap = x11::Pixmap::None,
});
GetXNativeConnection()->Flush();
has_swapped_buffers_ = true;
}

@ -555,12 +555,12 @@ void GLSurfaceGLX::ShutdownOneOff() {
// static
std::string GLSurfaceGLX::QueryGLXExtensions() {
Display* display = gfx::GetXDisplay();
const int screen = (display ? XDefaultScreen(display) : 0);
const char* extensions = glXQueryExtensionsString(display, screen);
if (extensions) {
auto* connection = x11::Connection::Get();
const int screen = connection ? connection->DefaultScreenId() : 0;
const char* extensions =
glXQueryExtensionsString(connection->display(), screen);
if (extensions)
return std::string(extensions);
}
return "";
}
@ -739,8 +739,8 @@ bool NativeViewGLSurfaceGLX::Resize(const gfx::Size& size,
bool has_alpha) {
size_ = size;
glXWaitGL();
XResizeWindow(gfx::GetXDisplay(), static_cast<uint32_t>(window_),
size.width(), size.height());
x11::Connection::Get()->ConfigureWindow(
{.window = window_, .width = size.width(), .height = size.height()});
glXWaitX();
return true;
}
@ -756,16 +756,18 @@ gfx::SwapResult NativeViewGLSurfaceGLX::SwapBuffers(
GLSurfacePresentationHelper::ScopedSwapBuffers scoped_swap_buffers(
presentation_helper_.get(), std::move(callback));
XDisplay* display = gfx::GetXDisplay();
glXSwapBuffers(display, GetDrawableHandle());
auto* connection = x11::Connection::Get();
glXSwapBuffers(connection->display(), GetDrawableHandle());
// We need to restore the background pixel that we set to WhitePixel on
// views::DesktopWindowTreeHostX11::InitX11Window back to None for the
// XWindow associated to this surface after the first SwapBuffers has
// happened, to avoid showing a weird white background while resizing.
if (!has_swapped_buffers_) {
XSetWindowBackgroundPixmap(display, static_cast<uint32_t>(parent_window_),
0);
connection->ChangeWindowAttributes({
.window = static_cast<x11::Window>(parent_window_),
.background_pixmap = x11::Pixmap::None,
});
has_swapped_buffers_ = true;
}

@ -10,6 +10,7 @@
#include <xcb/xproto.h>
#include "base/memory/singleton.h"
#include "ui/base/x/x11_util.h"
#include "ui/events/platform/x11/x11_event_source.h"
#include "ui/gfx/x/event.h"
#include "ui/gfx/x/x11.h"
@ -73,23 +74,19 @@ void GtkEventLoopX11::ProcessGdkEventKey(const GdkEventKey& gdk_event_key) {
// case. ibus-gtk is used through gtk-immodule to support IMEs.
auto* conn = x11::Connection::Get();
XDisplay* display = conn->display();
xcb_generic_event_t generic_event;
memset(&generic_event, 0, sizeof(generic_event));
auto* key_event = reinterpret_cast<xcb_key_press_event_t*>(&generic_event);
key_event->response_type = gdk_event_key.type == GDK_KEY_PRESS
? x11::KeyEvent::Press
: x11::KeyEvent::Release;
if (gdk_event_key.send_event)
key_event->response_type |= x11::kSendEventMask;
key_event->event = gdk_x11_window_get_xid(gdk_event_key.window);
key_event->root = XDefaultRootWindow(display);
key_event->time = gdk_event_key.time;
key_event->detail = gdk_event_key.hardware_keycode;
key_event->same_screen = true;
x11::Event event(&generic_event, conn, false);
x11::KeyEvent key{
.opcode = gdk_event_key.type == GDK_KEY_PRESS ? x11::KeyEvent::Press
: x11::KeyEvent::Release,
.send_event = gdk_event_key.send_event,
.detail = static_cast<x11::KeyCode>(gdk_event_key.hardware_keycode),
.time = static_cast<x11::Time>(gdk_event_key.time),
.root = ui::GetX11RootWindow(),
.event = static_cast<x11::Window>(
gdk_x11_window_get_xid(gdk_event_key.window)),
.same_screen = true,
};
x11::Event event(key, false);
// The key state is 16 bits on the wire, but ibus-gtk adds additional flags
// that may be outside this range, so set the state after conversion from

@ -96,6 +96,12 @@ class StackingClientListWaiter : public ui::X11PropertyChangeWaiter {
DISALLOW_COPY_AND_ASSIGN(StackingClientListWaiter);
};
void IconifyWindow(x11::Connection* connection, x11::Window window) {
ui::SendClientMessage(window, ui::GetX11RootWindow(),
gfx::GetAtom("WM_CHANGE_STATE"),
{ui::WM_STATE_ICONIC, 0, 0, 0, 0});
}
} // namespace
class X11TopmostWindowFinderTest : public test::DesktopWidgetTestInteractive {
@ -160,7 +166,7 @@ class X11TopmostWindowFinderTest : public test::DesktopWidgetTestInteractive {
// Shows |window| and sets its bounds.
void ShowAndSetXWindowBounds(x11::Window window, const gfx::Rect& bounds) {
XMapWindow(xdisplay(), static_cast<uint32_t>(window));
connection()->MapWindow({window});
connection()->ConfigureWindow({
.window = window,
@ -285,7 +291,7 @@ TEST_F(X11TopmostWindowFinderTest, Minimized) {
EXPECT_EQ(x11_window1, FindTopmostXWindowAt(150, 150));
{
MinimizeWaiter minimize_waiter(x11_window1);
XIconifyWindow(xdisplay(), static_cast<uint32_t>(x11_window1), 0);
IconifyWindow(connection(), x11_window1);
minimize_waiter.Wait();
}
EXPECT_NE(x11_window1, FindTopmostXWindowAt(150, 150));
@ -296,7 +302,7 @@ TEST_F(X11TopmostWindowFinderTest, Minimized) {
EXPECT_EQ(x11_window2, FindTopmostXWindowAt(350, 150));
{
MinimizeWaiter minimize_waiter(x11_window2);
XIconifyWindow(xdisplay(), static_cast<uint32_t>(x11_window2), 0);
IconifyWindow(connection(), x11_window2);
minimize_waiter.Wait();
}
EXPECT_NE(x11_window1, FindTopmostXWindowAt(350, 150));