diff options
author | Tom <tomut@yahoo.com> | 2022-01-17 09:57:08 -0700 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-01-23 22:45:21 +0000 |
commit | 49c902d581703bd6db5c7439dd7c1dc0a5b0e726 (patch) | |
tree | 65948c3a13f974213743a05f0c3fe1b17f42ace1 /Userland/Libraries/LibEDID | |
parent | 03c45b18653b960f1e7c1705ef0cdbb5b2d2f94d (diff) | |
download | serenity-49c902d581703bd6db5c7439dd7c1dc0a5b0e726.zip |
LibEDID: Add API for conveniently querying EDID from framebuffer device
Diffstat (limited to 'Userland/Libraries/LibEDID')
-rw-r--r-- | Userland/Libraries/LibEDID/EDID.cpp | 54 | ||||
-rw-r--r-- | Userland/Libraries/LibEDID/EDID.h | 5 |
2 files changed, 59 insertions, 0 deletions
diff --git a/Userland/Libraries/LibEDID/EDID.cpp b/Userland/Libraries/LibEDID/EDID.cpp index c4a36be73a..ecf333fbed 100644 --- a/Userland/Libraries/LibEDID/EDID.cpp +++ b/Userland/Libraries/LibEDID/EDID.cpp @@ -8,6 +8,13 @@ #include <AK/QuickSort.h> #include <LibEDID/EDID.h> +#ifndef KERNEL +# include <AK/ScopeGuard.h> +# include <Kernel/API/FB.h> +# include <fcntl.h> +# include <unistd.h> +#endif + namespace EDID { // clang doesn't like passing around pointers to members in packed structures, @@ -336,6 +343,53 @@ ErrorOr<Parser> Parser::from_bytes(ByteBuffer&& bytes) return edid; } +#ifndef KERNEL +ErrorOr<Parser> Parser::from_framebuffer_device(int framebuffer_fd, size_t head) +{ + RawBytes edid_bytes; + FBHeadEDID edid_info {}; + edid_info.head_index = head; + edid_info.bytes = &edid_bytes[0]; + edid_info.bytes_size = sizeof(edid_bytes); + if (fb_get_head_edid(framebuffer_fd, &edid_info) < 0) { + int err = errno; + if (err == EOVERFLOW) { + // We need a bigger buffer with at least bytes_size bytes + auto edid_byte_buffer = ByteBuffer::create_zeroed(edid_info.bytes_size); + if (!edid_byte_buffer.has_value()) + return Error::from_errno(ENOMEM); + edid_info.bytes = edid_byte_buffer.value().data(); + if (fb_get_head_edid(framebuffer_fd, &edid_info) < 0) { + err = errno; + return Error::from_errno(err); + } + + return from_bytes(edid_byte_buffer.release_value()); + } + + return Error::from_errno(err); + } + + auto edid_byte_buffer = ByteBuffer::copy((void const*)edid_bytes, sizeof(edid_bytes)); + if (!edid_byte_buffer.has_value()) + return Error::from_errno(ENOMEM); + return from_bytes(edid_byte_buffer.release_value()); +} + +ErrorOr<Parser> Parser::from_framebuffer_device(String const& framebuffer_device, size_t head) +{ + int framebuffer_fd = open(framebuffer_device.characters(), O_RDWR | O_CLOEXEC); + if (framebuffer_fd < 0) { + int err = errno; + return Error::from_errno(err); + } + ScopeGuard fd_guard([&] { + close(framebuffer_fd); + }); + return from_framebuffer_device(framebuffer_fd, head); +} +#endif + Parser::Parser(ReadonlyBytes bytes) : m_bytes(move(bytes)) { diff --git a/Userland/Libraries/LibEDID/EDID.h b/Userland/Libraries/LibEDID/EDID.h index 82aced81fe..da966708cd 100644 --- a/Userland/Libraries/LibEDID/EDID.h +++ b/Userland/Libraries/LibEDID/EDID.h @@ -77,6 +77,11 @@ public: static ErrorOr<Parser> from_bytes(ReadonlyBytes); static ErrorOr<Parser> from_bytes(ByteBuffer&&); +#ifndef KERNEL + static ErrorOr<Parser> from_framebuffer_device(int, size_t); + static ErrorOr<Parser> from_framebuffer_device(String const&, size_t); +#endif + String legacy_manufacturer_id() const; u16 product_code() const; u32 serial_number() const; |