95 lines
2.4 KiB
C++
95 lines
2.4 KiB
C++
#include <errno.h>
|
|
#include <os/ArgumentParser.h>
|
|
#include <os/File.h>
|
|
#include <os/LocalClient.h>
|
|
#include <sys/mman.h>
|
|
#include <ui/Canvas.h>
|
|
#include <ui/ipc/Server.h>
|
|
#include <unistd.h>
|
|
|
|
struct Window
|
|
{
|
|
ui::Canvas canvas;
|
|
int id;
|
|
|
|
void set_title(os::LocalClient& client, const char* title)
|
|
{
|
|
ui::SetWindowTitleRequest request;
|
|
request.window = id;
|
|
SET_IPC_STRING(request.title, title);
|
|
os::IPC::send_async(client, request);
|
|
}
|
|
|
|
void redraw(os::LocalClient& client)
|
|
{
|
|
ui::InvalidateRequest request;
|
|
request.window = id;
|
|
os::IPC::send_async(client, request);
|
|
}
|
|
};
|
|
|
|
Result<void> handle_ipc_client_event(os::LocalClient&, u8)
|
|
{
|
|
todo();
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
Result<Window> create_window(os::LocalClient& client, ui::Rect rect)
|
|
{
|
|
ui::CreateWindowRequest request;
|
|
request.rect = rect;
|
|
auto response = TRY(os::IPC::send_sync<ui::CreateWindowResponse>(client, request));
|
|
u32* pixels = TRY(create_shm_region(response.shm_path, nullptr, rect));
|
|
return Window { ui::Canvas { rect.width, rect.height, rect.width, (u8*)pixels }, response.window };
|
|
}
|
|
|
|
Result<int> luna_main(int argc, char** argv)
|
|
{
|
|
StringView socket_path = "/tmp/wind.sock";
|
|
|
|
os::ArgumentParser parser;
|
|
parser.add_description("A graphical user interface client."_sv);
|
|
parser.add_system_program_info("gclient"_sv);
|
|
parser.add_value_argument(socket_path, 's', "socket"_sv, "the path for the local IPC socket"_sv);
|
|
parser.parse(argc, argv);
|
|
|
|
auto client = TRY(os::LocalClient::connect(socket_path, false));
|
|
|
|
Window window = TRY(create_window(*client, ui::Rect { 200, 200, 400, 300 }));
|
|
os::println("Created new window with id %d!", window.id);
|
|
|
|
sleep(3);
|
|
|
|
window.set_title(*client, "Example Window");
|
|
|
|
sleep(3);
|
|
|
|
window.canvas.fill(ui::CYAN);
|
|
window.redraw(*client);
|
|
|
|
sleep(3);
|
|
|
|
return 0;
|
|
}
|