2023-08-15 08:23:37 +00:00
|
|
|
/**
|
|
|
|
* @file Window.cpp
|
|
|
|
* @author apio (cloudapio.eu)
|
|
|
|
* @brief UI windows.
|
|
|
|
*
|
|
|
|
* @copyright Copyright (c) 2023, the Luna authors.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <sys/mman.h>
|
|
|
|
#include <ui/App.h>
|
|
|
|
#include <ui/Window.h>
|
|
|
|
#include <ui/ipc/Server.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
static Result<u32*> create_shm_region(const char* path, int* outfd, ui::Rect rect)
|
|
|
|
{
|
|
|
|
int fd = shm_open(path, O_RDWR, 0600);
|
|
|
|
shm_unlink(path);
|
|
|
|
if (fd < 0) return err(errno);
|
|
|
|
|
|
|
|
usize size = rect.width * rect.height * 4; // 4 bytes per pixel
|
|
|
|
|
|
|
|
void* p = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
|
|
|
if (p == MAP_FAILED)
|
|
|
|
{
|
|
|
|
shm_unlink(path);
|
|
|
|
close(fd);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (outfd) *outfd = fd;
|
|
|
|
else
|
|
|
|
close(fd);
|
|
|
|
return (u32*)p;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace ui
|
|
|
|
{
|
2023-08-15 09:20:17 +00:00
|
|
|
Result<Window*> Window::create(Rect rect)
|
2023-08-15 08:23:37 +00:00
|
|
|
{
|
|
|
|
auto window = TRY(make_owned<Window>());
|
|
|
|
|
|
|
|
ui::CreateWindowRequest request;
|
|
|
|
request.rect = rect;
|
|
|
|
auto response = TRY(os::IPC::send_sync<ui::CreateWindowResponse>(App::the().client(), request));
|
|
|
|
|
|
|
|
u32* pixels = TRY(create_shm_region(response.shm_path, nullptr, rect));
|
|
|
|
|
|
|
|
window->m_canvas = ui::Canvas { rect.width, rect.height, rect.width, (u8*)pixels };
|
|
|
|
window->m_id = response.window;
|
|
|
|
|
2023-08-15 09:20:17 +00:00
|
|
|
Window* p = window.ptr();
|
|
|
|
|
|
|
|
App::the().register_window(move(window), {});
|
|
|
|
|
|
|
|
return p;
|
2023-08-15 08:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Window::~Window()
|
|
|
|
{
|
|
|
|
if (m_canvas.ptr) munmap(m_canvas.ptr, ((usize)m_canvas.width) * ((usize)m_canvas.height) * 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Window::set_title(StringView title)
|
|
|
|
{
|
|
|
|
ui::SetWindowTitleRequest request;
|
|
|
|
request.window = m_id;
|
|
|
|
SET_IPC_STRING(request.title, title.chars());
|
|
|
|
os::IPC::send_async(App::the().client(), request);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Window::update()
|
|
|
|
{
|
|
|
|
ui::InvalidateRequest request;
|
|
|
|
request.window = m_id;
|
|
|
|
os::IPC::send_async(App::the().client(), request);
|
|
|
|
}
|
2023-08-15 09:20:17 +00:00
|
|
|
|
|
|
|
void Window::close()
|
|
|
|
{
|
|
|
|
App& app = App::the();
|
|
|
|
|
|
|
|
ui::CloseWindowRequest request;
|
|
|
|
request.window = m_id;
|
|
|
|
os::IPC::send_async(app.client(), request);
|
|
|
|
|
|
|
|
if (this == app.main_window()) app.set_should_close(true);
|
|
|
|
|
|
|
|
app.unregister_window(this, {});
|
|
|
|
}
|
2023-08-15 08:23:37 +00:00
|
|
|
}
|