1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/gfx/x/connection.h"
#include "base/memory/ref_counted_memory.h"
#include "base/numerics/safe_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/x/event.h"
#include "ui/gfx/x/future.h"
#include "ui/gfx/x/xproto.h"
namespace x11 {
namespace {
Window CreateWindow(Connection* connection) {
Window window = connection->GenerateId<Window>();
auto create_window_future = connection->CreateWindow({
.depth = connection->default_root_depth().depth,
.wid = window,
.parent = connection->default_screen().root,
.width = 1,
.height = 1,
.override_redirect = Bool32(true),
});
auto create_window_response = create_window_future.Sync();
EXPECT_FALSE(create_window_response.error);
return window;
}
} // namespace
// Connection setup and teardown.
TEST(X11ConnectionTest, Basic) {
Connection connection;
ASSERT_TRUE(connection.Ready());
}
TEST(X11ConnectionTest, Request) {
Connection connection;
ASSERT_TRUE(connection.Ready());
Window window = CreateWindow(&connection);
auto attributes = connection.GetWindowAttributes({window}).Sync();
ASSERT_TRUE(attributes);
EXPECT_EQ(attributes->map_state, MapState::Unmapped);
EXPECT_TRUE(attributes->override_redirect);
auto geometry = connection.GetGeometry(window).Sync();
ASSERT_TRUE(geometry);
EXPECT_EQ(geometry->x, 0);
EXPECT_EQ(geometry->y, 0);
EXPECT_EQ(geometry->width, 1u);
EXPECT_EQ(geometry->height, 1u);
}
TEST(X11ConnectionTest, Event) {
Connection connection;
ASSERT_TRUE(connection.Ready());
Window window = CreateWindow(&connection);
auto cwa_future = connection.ChangeWindowAttributes({
.window = window,
.event_mask = EventMask::PropertyChange,
});
EXPECT_FALSE(cwa_future.Sync().error);
std::vector<uint8_t> data{0};
auto prop_future = connection.ChangeProperty({
.window = static_cast<Window>(window),
.property = Atom::WM_NAME,
.type = Atom::STRING,
.format = CHAR_BIT,
.data_len = base::checked_cast<uint32_t>(data.size()),
.data = base::MakeRefCounted<base::RefCountedBytes>(std::move(data)),
});
EXPECT_FALSE(prop_future.Sync().error);
connection.ReadResponses();
ASSERT_EQ(connection.events().size(), 1u);
auto* prop = connection.events().front().As<PropertyNotifyEvent>();
ASSERT_TRUE(prop);
EXPECT_EQ(prop->atom, Atom::WM_NAME);
EXPECT_EQ(prop->state, Property::NewValue);
}
TEST(X11ConnectionTest, Error) {
Connection connection;
ASSERT_TRUE(connection.Ready());
Window invalid_window = connection.GenerateId<Window>();
auto geometry = connection.GetGeometry(invalid_window).Sync();
ASSERT_FALSE(geometry);
auto* error = geometry.error.get();
ASSERT_TRUE(error);
// TODO(thomasanderson): Implement As<> for errors, similar to events.
auto* drawable_error = reinterpret_cast<DrawableError*>(error);
EXPECT_EQ(drawable_error->bad_value, static_cast<uint32_t>(invalid_window));
}
TEST(X11ConnectionTest, LargeQueryTree) {
Connection connection;
ASSERT_TRUE(connection.Ready());
Window root = CreateWindow(&connection);
for (size_t i = 0; i < 0x10000; i++) {
connection.CreateWindow({
.depth = connection.default_root_depth().depth,
.wid = connection.GenerateId<Window>(),
.parent = root,
.width = 1,
.height = 1,
.override_redirect = Bool32(true),
});
}
// Ensure large QueryTree requests don't cause a crash.
connection.QueryTree(root).Sync();
}
} // namespace x11
|