#include "fs/devices/FramebufferDevice.h" #include "arch/MMU.h" #include "memory/SharedMemory.h" #include "video/Framebuffer.h" #include #include Result FramebufferDevice::create() { auto device = (SharedPtr)TRY(make_shared()); return DeviceRegistry::register_special_device(DeviceRegistry::Framebuffer, 0, device, 0600); } Result FramebufferDevice::read(u8*, usize, usize) const { return 0; } Result FramebufferDevice::write(const u8* buf, usize offset, usize length) { if ((offset + length) > size()) length = size() - offset; memcpy(Framebuffer::ptr() + offset, buf, length); return length; } Result FramebufferDevice::query_shared_memory(off_t offset, usize count) { if (offset + (count * ARCH_PAGE_SIZE) > Framebuffer::size()) return err(EINVAL); if (!m_shmid.has_value()) { u64 shmid = TRY(SharedMemory::create(Framebuffer::ptr() + offset, offset, count)); m_shmid = shmid; auto* shm = g_shared_memory_map.try_get_ref(shmid); shm->device = SharedPtr { this }; return shmid; } auto* shm = g_shared_memory_map.try_get_ref(*m_shmid); if (!shm) { m_shmid = {}; return query_shared_memory(offset, count); } if (shm->offset > offset) { TRY(shm->grow_backward(Framebuffer::ptr() + offset, (shm->offset - offset) / ARCH_PAGE_SIZE)); } if (shm->frames.size() < count) { TRY(shm->grow_forward(Framebuffer::ptr() + offset + (shm->frames.size() * ARCH_PAGE_SIZE), count - shm->frames.size())); } return *m_shmid; } usize FramebufferDevice::size() const { return Framebuffer::size(); } bool FramebufferDevice::will_block_if_read() const { return false; } Result FramebufferDevice::ioctl(int request, void*) { switch (request) { case FB_GET_WIDTH: return (u64)Framebuffer::width(); case FB_GET_HEIGHT: return (u64)Framebuffer::height(); case FB_GET_SCANLINE: return (u64)Framebuffer::scanline(); default: return err(EINVAL); } }