summaryrefslogtreecommitdiff
path: root/Userland/Services
diff options
context:
space:
mode:
authorkleines Filmröllchen <filmroellchen@serenityos.org>2022-03-31 18:49:26 +0200
committerLinus Groh <mail@linusgroh.de>2022-04-21 13:41:55 +0200
commitbe98ce0f9fac36a646079c6729c643ee1b2ad420 (patch)
treee0ecfb7b009eec78fa863713b0a7af06d5bcec67 /Userland/Services
parente95ae4a1431039fbb34a09b274f3ebf096609a2a (diff)
downloadserenity-be98ce0f9fac36a646079c6729c643ee1b2ad420.zip
WindowServer: Add the screen mode property in the screen configuration
This will allow us to change between a couple of properties, for now it's only Device and Virtual. (How about Remote :^) ) These get handled by a different screen backend in the Screen.
Diffstat (limited to 'Userland/Services')
-rw-r--r--Userland/Services/WindowServer/Screen.cpp21
-rw-r--r--Userland/Services/WindowServer/ScreenLayout.h23
-rw-r--r--Userland/Services/WindowServer/ScreenLayout.ipp28
-rw-r--r--Userland/Services/WindowServer/main.cpp3
4 files changed, 58 insertions, 17 deletions
diff --git a/Userland/Services/WindowServer/Screen.cpp b/Userland/Services/WindowServer/Screen.cpp
index 52200b9afc..816dec3ea9 100644
--- a/Userland/Services/WindowServer/Screen.cpp
+++ b/Userland/Services/WindowServer/Screen.cpp
@@ -98,7 +98,7 @@ bool Screen::apply_layout(ScreenLayout&& screen_layout, String& error_msg)
for (auto& it : screens_with_resolution_change) {
auto& existing_screen = *it.key;
- dbgln("Closing device {} in preparation for resolution change", layout_backup.screens[existing_screen.index()].device);
+ dbgln("Closing device {} in preparation for resolution change", layout_backup.screens[existing_screen.index()].device.value_or("<virtual screen>"));
existing_screen.close_device();
}
@@ -229,15 +229,20 @@ bool Screen::open_device()
auto& info = screen_layout_info();
// TODO: Support other backends
- m_backend = make<HardwareScreenBackend>(info.device);
- auto return_value = m_backend->open();
- if (return_value.is_error()) {
- dbgln("Screen #{}: Failed to open backend: {}", index(), return_value.error());
- return false;
+ if (info.mode == ScreenLayout::Screen::Mode::Device) {
+ m_backend = make<HardwareScreenBackend>(info.device.value());
+ auto return_value = m_backend->open();
+ if (return_value.is_error()) {
+ dbgln("Screen #{}: Failed to open backend: {}", index(), return_value.error());
+ return false;
+ }
+
+ set_resolution(true);
+ return true;
}
- set_resolution(true);
- return true;
+ dbgln("Unsupported screen type {}", ScreenLayout::Screen::mode_to_string(info.mode));
+ return false;
}
void Screen::close_device()
diff --git a/Userland/Services/WindowServer/ScreenLayout.h b/Userland/Services/WindowServer/ScreenLayout.h
index 4e4becc7bf..5fb3eddee8 100644
--- a/Userland/Services/WindowServer/ScreenLayout.h
+++ b/Userland/Services/WindowServer/ScreenLayout.h
@@ -18,7 +18,12 @@ namespace WindowServer {
class ScreenLayout {
public:
struct Screen {
- String device;
+ enum class Mode {
+ Invalid,
+ Device,
+ Virtual,
+ } mode;
+ Optional<String> device;
Gfx::IntPoint location;
Gfx::IntSize resolution;
int scale_factor;
@@ -28,6 +33,22 @@ public:
return { location, { resolution.width() / scale_factor, resolution.height() / scale_factor } };
}
+ static StringView mode_to_string(Mode mode)
+ {
+#define __ENUMERATE_MODE_ENUM(val) \
+ case Mode::val: \
+ return #val;
+
+ switch (mode) {
+ __ENUMERATE_MODE_ENUM(Invalid)
+ __ENUMERATE_MODE_ENUM(Device)
+ __ENUMERATE_MODE_ENUM(Virtual)
+ }
+ VERIFY_NOT_REACHED();
+
+#undef __ENUMERATE_MODE_ENUM
+ }
+
bool operator==(Screen const&) const = default;
};
diff --git a/Userland/Services/WindowServer/ScreenLayout.ipp b/Userland/Services/WindowServer/ScreenLayout.ipp
index 9de1512b51..2c8d8b4b87 100644
--- a/Userland/Services/WindowServer/ScreenLayout.ipp
+++ b/Userland/Services/WindowServer/ScreenLayout.ipp
@@ -33,7 +33,7 @@ bool ScreenLayout::is_valid(String* error_msg) const
int smallest_y = 0;
for (size_t i = 0; i < screens.size(); i++) {
auto& screen = screens[i];
- if (screen.device.is_null() || screen.device.is_empty()) {
+ if (screen.mode == Screen::Mode::Device && (screen.device->is_empty() || screen.device->is_null())) {
if (error_msg)
*error_msg = String::formatted("Screen #{} has no path", i);
return false;
@@ -235,7 +235,16 @@ bool ScreenLayout::load_config(const Core::ConfigFile& config_file, String* erro
auto group_name = String::formatted("Screen{}", index);
if (!config_file.has_group(group_name))
break;
- screens.append({ config_file.read_entry(group_name, "Device"),
+ auto str_mode = config_file.read_entry(group_name, "Mode");
+ auto mode = str_mode == "Device" ? Screen::Mode::Device : str_mode == "Virtual" ? Screen::Mode::Virtual
+ : Screen::Mode::Invalid;
+ if (mode == Screen::Mode::Invalid) {
+ *error_msg = String::formatted("Invalid screen mode '{}'", str_mode);
+ *this = {};
+ return false;
+ }
+ auto device = (mode == Screen::Mode::Device) ? config_file.read_entry(group_name, "Device") : Optional<String> {};
+ screens.append({ mode, device,
{ config_file.read_num_entry(group_name, "Left"), config_file.read_num_entry(group_name, "Top") },
{ config_file.read_num_entry(group_name, "Width"), config_file.read_num_entry(group_name, "Height") },
config_file.read_num_entry(group_name, "ScaleFactor", 1) });
@@ -255,7 +264,9 @@ bool ScreenLayout::save_config(Core::ConfigFile& config_file, bool sync) const
while (index < screens.size()) {
auto& screen = screens[index];
auto group_name = String::formatted("Screen{}", index);
- config_file.write_entry(group_name, "Device", screen.device);
+ config_file.write_entry(group_name, "Mode", Screen::mode_to_string(screen.mode));
+ if (screen.mode == Screen::Mode::Device)
+ config_file.write_entry(group_name, "Device", screen.device.value());
config_file.write_num_entry(group_name, "Left", screen.location.x());
config_file.write_num_entry(group_name, "Top", screen.location.y());
config_file.write_num_entry(group_name, "Width", screen.resolution.width());
@@ -321,7 +332,8 @@ bool ScreenLayout::try_auto_add_framebuffer(String const& device_path)
}
auto append_screen = [&](Gfx::IntRect const& new_screen_rect) {
- screens.append({ .device = device_path,
+ screens.append({ .mode = Screen::Mode::Device,
+ .device = device_path,
.location = new_screen_rect.location(),
.resolution = new_screen_rect.size(),
.scale_factor = 1 });
@@ -379,13 +391,15 @@ namespace IPC {
bool encode(Encoder& encoder, const WindowServer::ScreenLayout::Screen& screen)
{
- encoder << screen.device << screen.location << screen.resolution << screen.scale_factor;
+ encoder << screen.mode << screen.device << screen.location << screen.resolution << screen.scale_factor;
return true;
}
ErrorOr<void> decode(Decoder& decoder, WindowServer::ScreenLayout::Screen& screen)
{
- String device;
+ WindowServer::ScreenLayout::Screen::Mode mode;
+ TRY(decoder.decode(mode));
+ Optional<String> device;
TRY(decoder.decode(device));
Gfx::IntPoint location;
TRY(decoder.decode(location));
@@ -393,7 +407,7 @@ ErrorOr<void> decode(Decoder& decoder, WindowServer::ScreenLayout::Screen& scree
TRY(decoder.decode(resolution));
int scale_factor = 0;
TRY(decoder.decode(scale_factor));
- screen = { device, location, resolution, scale_factor };
+ screen = { mode, device, location, resolution, scale_factor };
return {};
}
diff --git a/Userland/Services/WindowServer/main.cpp b/Userland/Services/WindowServer/main.cpp
index 2c56729bd7..6f3511c17a 100644
--- a/Userland/Services/WindowServer/main.cpp
+++ b/Userland/Services/WindowServer/main.cpp
@@ -92,7 +92,8 @@ ErrorOr<int> serenity_main(Main::Arguments)
if (screen_layout.load_config(*wm_config, &error_msg)) {
for (auto& screen_info : screen_layout.screens)
- fb_devices_configured.set(screen_info.device);
+ if (screen_info.mode == WindowServer::ScreenLayout::Screen::Mode::Device)
+ fb_devices_configured.set(screen_info.device.value());
add_unconfigured_devices();