Commit 24f9819d authored by Julie Jeongeun Kim's avatar Julie Jeongeun Kim Committed by Commit Bot

[ozone/x11] Add initial X11ScreenOzone implementation

It adds X11ScreenOzone for PlatformScreen which has basic
implementation.

When it creates PlatformScreen for Ozone/X11, X11ScreenOzone
is created and it creates X11DisplayFetcherOzone, which
communicates with 'x11::xrandr'. The way to get display
information in X11DisplayFetcherOzone is similar to
DesktopScreenX11. Once it builds display information from
'x11::xrandr', it adds the information to display list from
X11ScreenOzone.

This patch also moves 'GetICCProfileForMonitor' to x11_util.cc
to share it with X11ScreenOzone.

Bug: 891175
Test: ozone_x11_unittests
Change-Id: I2d901f72ca2d9609ef19eef7da35bf99aec62d2a
Reviewed-on: https://chromium-review.googlesource.com/c/1293290Reviewed-by: default avatarkylechar <kylechar@chromium.org>
Reviewed-by: default avatarDan Erat <derat@chromium.org>
Commit-Queue: Julie Jeongeun Kim <jkim@igalia.com>
Cr-Commit-Position: refs/heads/master@{#604826}
parent 9ce5a674
......@@ -13,6 +13,8 @@ jumbo_component("x") {
sources = [
"ui_base_x_export.h",
"x11_display_util.cc",
"x11_display_util.h",
"x11_menu_list.cc",
"x11_menu_list.h",
"x11_pointer_grab.cc",
......@@ -24,7 +26,10 @@ jumbo_component("x") {
"x11_window_event_manager.h",
]
configs += [ "//build/config/linux:x11" ]
configs += [
"//build/config/linux:x11",
"//build/config/linux:xrandr",
]
defines = [ "UI_BASE_X_IMPLEMENTATION" ]
......@@ -32,21 +37,11 @@ jumbo_component("x") {
"//base",
"//base:i18n",
"//skia",
"//ui/display/util",
"//ui/events",
"//ui/events/devices/x11",
"//ui/events/keycodes:x11",
"//ui/gfx",
"//ui/gfx/x",
]
if (!is_chromeos) {
sources += [
"x11_display_util.cc",
"x11_display_util.h",
]
configs += [ "//build/config/linux:xrandr" ]
deps += [ "//ui/display/util" ]
}
}
......@@ -28,7 +28,7 @@ jumbo_component("util") {
"//ui/gfx/geometry",
]
if (use_x11 || (ozone_platform_x11 && !is_chromeos)) {
if (use_x11 || ozone_platform_x11) {
sources += [
"x11/edid_parser_x11.cc",
"x11/edid_parser_x11.h",
......
......@@ -24,6 +24,10 @@ source_set("x11") {
"x11_cursor_factory_ozone.h",
"x11_cursor_ozone.cc",
"x11_cursor_ozone.h",
"x11_display_fetcher_ozone.cc",
"x11_display_fetcher_ozone.h",
"x11_screen_ozone.cc",
"x11_screen_ozone.h",
"x11_surface_factory.cc",
"x11_surface_factory.h",
"x11_window_manager_ozone.cc",
......@@ -59,7 +63,10 @@ source_set("x11") {
deps += [ "//gpu/vulkan/x" ]
}
configs += [ "//build/config/linux:x11" ]
configs += [
"//build/config/linux:x11",
"//build/config/linux:xrandr",
]
public_configs = [ "//third_party/khronos:khronos_headers" ]
}
......@@ -68,6 +75,7 @@ source_set("x11_unittests") {
testonly = true
sources = [
"x11_cursor_factory_ozone_unittest.cc",
"x11_screen_ozone_unittest.cc",
"x11_window_ozone_unittest.cc",
]
......
......@@ -17,6 +17,7 @@
#include "ui/gfx/x/x11.h"
#include "ui/ozone/common/stub_overlay_manager.h"
#include "ui/ozone/platform/x11/x11_cursor_factory_ozone.h"
#include "ui/ozone/platform/x11/x11_screen_ozone.h"
#include "ui/ozone/platform/x11/x11_surface_factory.h"
#include "ui/ozone/platform/x11/x11_window_manager_ozone.h"
#include "ui/ozone/platform/x11/x11_window_ozone.h"
......@@ -76,6 +77,10 @@ class OzonePlatformX11 : public OzonePlatform {
return std::make_unique<display::FakeDisplayDelegate>();
}
std::unique_ptr<PlatformScreen> CreateScreen() override {
return std::make_unique<X11ScreenOzone>();
}
void InitializeUI(const InitParams& params) override {
InitializeCommon(params);
CreatePlatformEventSource();
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/ozone/platform/x11/x11_display_fetcher_ozone.h"
#include <dlfcn.h>
#include "base/logging.h"
#include "base/memory/protected_memory_cfi.h"
#include "ui/base/x/x11_display_util.h"
#include "ui/base/x/x11_util.h"
#include "ui/display/display.h"
#include "ui/display/util/display_util.h"
#include "ui/display/util/x11/edid_parser_x11.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/gfx/x/x11.h"
#include "ui/gfx/x/x11_atom_cache.h"
#include "ui/gfx/x/x11_types.h"
namespace ui {
namespace {
constexpr int kMinVersionXrandr = 103; // Need at least xrandr version 1.3.
float GetDeviceScaleFactor() {
float device_scale_factor = 1.0f;
// TODO(jkim) : https://crbug.com/891175
// Get device scale factor using scale factor and resolution like
// 'GtkUi::GetRawDeviceScaleFactor'.
if (display::Display::HasForceDeviceScaleFactor())
device_scale_factor = display::Display::GetForcedDeviceScaleFactor();
return device_scale_factor;
}
} // namespace
////////////////////////////////////////////////////////////////////////////////
// X11DisplayFetcherOzone, public:
X11DisplayFetcherOzone::X11DisplayFetcherOzone(
X11DisplayFetcherOzone::Delegate* delegate)
: xdisplay_(gfx::GetXDisplay()),
x_root_window_(DefaultRootWindow(xdisplay_)),
xrandr_version_(GetXrandrVersion(xdisplay_)),
delegate_(delegate) {
DCHECK(delegate_);
float scale = GetDeviceScaleFactor();
std::vector<display::Display> displays;
// Need at least xrandr version 1.3.
if (xrandr_version_ >= kMinVersionXrandr) {
int error_base_ignored = 0;
XRRQueryExtension(xdisplay_, &xrandr_event_base_, &error_base_ignored);
if (PlatformEventSource::GetInstance())
PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
XRRSelectInput(xdisplay_, x_root_window_,
RRScreenChangeNotifyMask | RROutputChangeNotifyMask |
RRCrtcChangeNotifyMask);
displays = BuildDisplaysFromXRandRInfo(xrandr_version_, scale,
&primary_display_index_);
} else {
displays = GetFallbackDisplayList(scale);
}
for (auto& display : displays)
delegate_->AddDisplay(display, display.id() == primary_display_index_);
}
X11DisplayFetcherOzone::~X11DisplayFetcherOzone() {
if (xrandr_version_ >= kMinVersionXrandr &&
PlatformEventSource::GetInstance()) {
PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
}
}
bool X11DisplayFetcherOzone::CanDispatchEvent(const ui::PlatformEvent& event) {
// TODO(jkim): https://crbug.com/891175
NOTIMPLEMENTED_LOG_ONCE();
return false;
}
uint32_t X11DisplayFetcherOzone::DispatchEvent(const ui::PlatformEvent& event) {
// TODO(jkim): https://crbug.com/891175
NOTIMPLEMENTED_LOG_ONCE();
return ui::POST_DISPATCH_NONE;
}
} // namespace ui
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_OZONE_PLATFORM_X11_X11_DISPLAY_FETCHER_OZONE_H_
#define UI_OZONE_PLATFORM_X11_X11_DISPLAY_FETCHER_OZONE_H_
#include <stdint.h>
#include "ui/display/types/native_display_delegate.h"
#include "ui/events/platform/platform_event_dispatcher.h"
#include "ui/gfx/x/x11_types.h"
namespace display {
class Display;
} // namespace display
namespace ui {
// X11DisplayFetcherOzone talks to xrandr to get the information of the outputs
// for a screen and updates Display to X11DisplayFetcherOzone::Delegate. The
// minimum required version of xrandr is 1.3.
class X11DisplayFetcherOzone : public ui::PlatformEventDispatcher {
public:
class Delegate {
public:
virtual void AddDisplay(const display::Display& display,
bool is_primary) = 0;
virtual void RemoveDisplay(const display::Display& display) = 0;
};
explicit X11DisplayFetcherOzone(X11DisplayFetcherOzone::Delegate* delegate);
~X11DisplayFetcherOzone() override;
// ui::PlatformEventDispatcher:
bool CanDispatchEvent(const ui::PlatformEvent& event) override;
uint32_t DispatchEvent(const ui::PlatformEvent& event) override;
private:
int64_t primary_display_index_ = 0;
XDisplay* const xdisplay_;
XID x_root_window_;
// XRandR version. MAJOR * 100 + MINOR. Zero if no xrandr is present.
const int xrandr_version_;
// The base of the event numbers used to represent XRandr events used in
// decoding events regarding output add/remove.
int xrandr_event_base_ = 0;
Delegate* const delegate_;
DISALLOW_COPY_AND_ASSIGN(X11DisplayFetcherOzone);
};
} // namespace ui
#endif // UI_OZONE_PLATFORM_X11_X11_DISPLAY_FETCHER_OZONE_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/ozone/platform/x11/x11_screen_ozone.h"
#include "ui/display/display.h"
#include "ui/display/display_finder.h"
#include "ui/display/display_observer.h"
#include "ui/gfx/font_render_params.h"
#include "ui/gfx/geometry/dip_util.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/size.h"
namespace ui {
X11ScreenOzone::X11ScreenOzone() {
// Creates |display_fetcher_| instead of adding it to a member initializer
// list as it requires |this|.
display_fetcher_ = std::make_unique<X11DisplayFetcherOzone>(this);
}
X11ScreenOzone::~X11ScreenOzone() = default;
const std::vector<display::Display>& X11ScreenOzone::GetAllDisplays() const {
return display_list_.displays();
}
display::Display X11ScreenOzone::GetPrimaryDisplay() const {
auto iter = display_list_.GetPrimaryDisplayIterator();
if (iter == display_list_.displays().end())
return display::Display::GetDefaultDisplay();
return *iter;
}
display::Display X11ScreenOzone::GetDisplayForAcceleratedWidget(
gfx::AcceleratedWidget widget) const {
// TODO(jkim): https://crbug.com/891175
NOTIMPLEMENTED_LOG_ONCE();
return GetPrimaryDisplay();
}
gfx::Point X11ScreenOzone::GetCursorScreenPoint() const {
// TODO(jkim): https://crbug.com/891175
NOTIMPLEMENTED_LOG_ONCE();
return gfx::Point();
}
gfx::AcceleratedWidget X11ScreenOzone::GetAcceleratedWidgetAtScreenPoint(
const gfx::Point& point) const {
// TODO(jkim): https://crbug.com/891175
NOTIMPLEMENTED_LOG_ONCE();
return gfx::kNullAcceleratedWidget;
}
display::Display X11ScreenOzone::GetDisplayNearestPoint(
const gfx::Point& point) const {
// TODO(jkim): https://crbug.com/891175
NOTIMPLEMENTED_LOG_ONCE();
return GetPrimaryDisplay();
}
display::Display X11ScreenOzone::GetDisplayMatching(
const gfx::Rect& match_rect) const {
// TODO(jkim): https://crbug.com/891175
NOTIMPLEMENTED_LOG_ONCE();
return GetPrimaryDisplay();
}
void X11ScreenOzone::AddObserver(display::DisplayObserver* observer) {
display_list_.AddObserver(observer);
}
void X11ScreenOzone::RemoveObserver(display::DisplayObserver* observer) {
display_list_.RemoveObserver(observer);
}
void X11ScreenOzone::AddDisplay(const display::Display& display,
bool is_primary) {
display_list_.AddDisplay(
display, is_primary ? display::DisplayList::Type::PRIMARY
: display::DisplayList::Type::NOT_PRIMARY);
if (is_primary) {
gfx::SetFontRenderParamsDeviceScaleFactor(
GetPrimaryDisplay().device_scale_factor());
}
}
void X11ScreenOzone::RemoveDisplay(const display::Display& display) {
display_list_.RemoveDisplay(display.id());
}
} // namespace ui
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_OZONE_PLATFORM_X11_X11_SCREEN_OZONE_H_
#define UI_OZONE_PLATFORM_X11_X11_SCREEN_OZONE_H_
#include <vector>
#include "base/macros.h"
#include "base/observer_list.h"
#include "ui/display/display_list.h"
#include "ui/ozone/platform/x11/x11_display_fetcher_ozone.h"
#include "ui/ozone/public/ozone_platform.h"
#include "ui/ozone/public/platform_screen.h"
namespace ui {
// A PlatformScreen implementation for X11.
class X11ScreenOzone : public PlatformScreen,
public X11DisplayFetcherOzone::Delegate {
public:
X11ScreenOzone();
~X11ScreenOzone() override;
// PlatformScreen implementation.
const std::vector<display::Display>& GetAllDisplays() const override;
display::Display GetPrimaryDisplay() const override;
display::Display GetDisplayForAcceleratedWidget(
gfx::AcceleratedWidget widget) const override;
gfx::Point GetCursorScreenPoint() const override;
gfx::AcceleratedWidget GetAcceleratedWidgetAtScreenPoint(
const gfx::Point& point) const override;
display::Display GetDisplayNearestPoint(
const gfx::Point& point) const override;
display::Display GetDisplayMatching(
const gfx::Rect& match_rect) const override;
void AddObserver(display::DisplayObserver* observer) override;
void RemoveObserver(display::DisplayObserver* observer) override;
// X11DisplayFetcherOzone::Delegate overrides:
void AddDisplay(const display::Display& display, bool is_primary) override;
void RemoveDisplay(const display::Display& display) override;
private:
display::DisplayList display_list_;
base::ObserverList<display::DisplayObserver> observers_;
std::unique_ptr<X11DisplayFetcherOzone> display_fetcher_;
DISALLOW_COPY_AND_ASSIGN(X11ScreenOzone);
};
} // namespace ui
#endif // UI_OZONE_PLATFORM_X11_X11_SCREEN_OZONE_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/ozone/platform/x11/x11_screen_ozone.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/display/display.h"
namespace ui {
// This test ensures that PlatformScreen fetches display.
TEST(X11ScreenOzoneTest, FetchDisplay) {
constexpr uint32_t kNumberOfDisplays = 1;
std::unique_ptr<X11ScreenOzone> platform_screen =
std::make_unique<X11ScreenOzone>();
// Ensure there is only one display, which is the primary one.
auto& all_displays = platform_screen->GetAllDisplays();
EXPECT_EQ(all_displays.size(), kNumberOfDisplays);
}
} // namespace ui
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