Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, the SerenityOS developers.
3 * Copyright (c) 2022, kleines Filmröllchen <filmroellchen@serenityos.org>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#include "VirtualScreenBackend.h"
9#include "ScreenBackend.h"
10#include <AK/Try.h>
11#include <AK/kmalloc.h>
12#include <LibGfx/Color.h>
13
14namespace WindowServer {
15
16VirtualScreenBackend::~VirtualScreenBackend()
17{
18 MUST(unmap_framebuffer());
19}
20
21ErrorOr<void> VirtualScreenBackend::open()
22{
23 m_can_device_flush_buffers = true;
24 m_can_set_head_buffer = true;
25 return {};
26}
27
28void VirtualScreenBackend::set_head_buffer(int index)
29{
30 VERIFY(index <= 1 && index >= 0);
31 m_first_buffer_active = index == 0;
32}
33
34ErrorOr<void> VirtualScreenBackend::set_safe_head_mode_setting()
35{
36 return {};
37}
38
39ErrorOr<void> VirtualScreenBackend::set_head_mode_setting(GraphicsHeadModeSetting mode_setting)
40{
41 m_height = mode_setting.vertical_active;
42
43 if (mode_setting.horizontal_stride == 0)
44 mode_setting.horizontal_stride = static_cast<int>(mode_setting.horizontal_active * sizeof(Gfx::ARGB32));
45 m_pitch = mode_setting.horizontal_stride;
46 if (static_cast<int>(mode_setting.horizontal_active * sizeof(Gfx::ARGB32)) != mode_setting.horizontal_stride)
47 return Error::from_string_literal("Unsupported pitch");
48
49 m_width = mode_setting.horizontal_active;
50 return {};
51}
52
53ErrorOr<GraphicsHeadModeSetting> VirtualScreenBackend::get_head_mode_setting()
54{
55 return GraphicsHeadModeSetting {
56 .horizontal_stride = m_pitch,
57 .pixel_clock_in_khz = 0,
58 .horizontal_active = m_width,
59 .horizontal_front_porch_pixels = 0,
60 .horizontal_sync_time_pixels = 0,
61 .horizontal_blank_pixels = 0,
62 .vertical_active = m_height,
63 .vertical_front_porch_lines = 0,
64 .vertical_sync_time_lines = 0,
65 .vertical_blank_lines = 0,
66 .horizontal_offset = 0,
67 .vertical_offset = 0,
68 };
69}
70
71ErrorOr<void> VirtualScreenBackend::map_framebuffer()
72{
73 m_size_in_bytes = static_cast<unsigned long>(m_pitch) * m_height * 2;
74 m_framebuffer = new Gfx::ARGB32[static_cast<unsigned long>(m_width) * m_height * 2];
75 if (m_framebuffer == nullptr)
76 return Error::from_errno(ENOMEM);
77
78 m_back_buffer_offset = m_size_in_bytes / 2;
79 m_first_buffer_active = true;
80
81 return {};
82}
83
84ErrorOr<void> VirtualScreenBackend::unmap_framebuffer()
85{
86 delete[] m_framebuffer;
87 return {};
88}
89
90}