mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 12:17:44 +00:00
LibEDID: Add API for conveniently querying EDID from framebuffer device
This commit is contained in:
parent
03c45b1865
commit
49c902d581
2 changed files with 59 additions and 0 deletions
|
@ -8,6 +8,13 @@
|
||||||
#include <AK/QuickSort.h>
|
#include <AK/QuickSort.h>
|
||||||
#include <LibEDID/EDID.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 {
|
namespace EDID {
|
||||||
|
|
||||||
// clang doesn't like passing around pointers to members in packed structures,
|
// 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;
|
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)
|
Parser::Parser(ReadonlyBytes bytes)
|
||||||
: m_bytes(move(bytes))
|
: m_bytes(move(bytes))
|
||||||
{
|
{
|
||||||
|
|
|
@ -77,6 +77,11 @@ public:
|
||||||
static ErrorOr<Parser> from_bytes(ReadonlyBytes);
|
static ErrorOr<Parser> from_bytes(ReadonlyBytes);
|
||||||
static ErrorOr<Parser> from_bytes(ByteBuffer&&);
|
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;
|
String legacy_manufacturer_id() const;
|
||||||
u16 product_code() const;
|
u16 product_code() const;
|
||||||
u32 serial_number() const;
|
u32 serial_number() const;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue