From 4bcea9b141877f4d3369a13ddedc22df0becaed3 Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 14 Aug 2023 18:15:29 +0200 Subject: [PATCH] wind: Handle CreateWindow IPC messages --- wind/CMakeLists.txt | 3 ++ wind/Client.h | 11 +++++++ wind/IPC.cpp | 75 +++++++++++++++++++++++++++++++++++++++++++++ wind/IPC.h | 10 ++++++ wind/Window.cpp | 8 ++++- wind/Window.h | 8 +++-- wind/main.cpp | 33 +++++++++----------- 7 files changed, 126 insertions(+), 22 deletions(-) create mode 100644 wind/Client.h create mode 100644 wind/IPC.cpp create mode 100644 wind/IPC.h diff --git a/wind/CMakeLists.txt b/wind/CMakeLists.txt index 0ddb710f..5d79b2c8 100644 --- a/wind/CMakeLists.txt +++ b/wind/CMakeLists.txt @@ -6,6 +6,9 @@ set(SOURCES Mouse.cpp Window.h Window.cpp + IPC.cpp + IPC.h + Client.h ) add_executable(wind ${SOURCES}) diff --git a/wind/Client.h b/wind/Client.h new file mode 100644 index 00000000..30b402ad --- /dev/null +++ b/wind/Client.h @@ -0,0 +1,11 @@ +#pragma once +#include "Window.h" +#include + +struct Client +{ + os::LocalServer::Client conn; + Vector windows; + bool rpc_in_progress { false }; + u8 rpc_id { 0 }; +}; diff --git a/wind/IPC.cpp b/wind/IPC.cpp new file mode 100644 index 00000000..e63dd3c0 --- /dev/null +++ b/wind/IPC.cpp @@ -0,0 +1,75 @@ +#include "IPC.h" +#include +#include + +static Result handle_create_window_message(Client& client) +{ + ui::CreateWindowRequest request; + auto rc = client.conn.recv_typed(request); + if (rc.has_error()) + { + if (rc.error() == EAGAIN) + { + client.rpc_in_progress = true; + client.rpc_id = ui::CREATE_WINDOW_ID; + return {}; + } + else + return rc.release_error(); + } + + request.rect = request.rect.normalized(); + request.rect.height += Window::titlebar_height(); // Make sure we provide the full contents rect that was asked for. + + auto name = COPY_IPC_STRING(request.name); + + auto* window = new (std::nothrow) Window(request.rect, request.color, move(name)); + if (!window) + { + os::IPC::send_error(client.conn, ENOMEM); + return {}; + } + + int id = static_cast(client.windows.size()); + rc = client.windows.try_append(window); + if (rc.has_error()) + { + delete window; + os::IPC::send_error(client.conn, rc.error()); + return {}; + } + + ui::CreateWindowResponse response; + response.window = id; + os::IPC::send_async(client.conn, response); + return {}; +} + +namespace wind +{ + Result handle_ipc_message(Client& client, u8 id) + { + client.rpc_in_progress = false; + switch (id) + { + case ui::CREATE_WINDOW_ID: return handle_create_window_message(client); + default: os::eprintln("wind: Invalid IPC message from client!"); return err(EINVAL); + } + } + + Result handle_ipc(Client& client) + { + if (client.rpc_in_progress) return handle_ipc_message(client, client.rpc_id); + + u8 id; + auto rc = client.conn.recv_typed(id); + if (rc.has_error()) + { + if (rc.error() == EAGAIN) { return {}; } + else + return rc.release_error(); + } + + return handle_ipc_message(client, id); + } +} diff --git a/wind/IPC.h b/wind/IPC.h new file mode 100644 index 00000000..4c085302 --- /dev/null +++ b/wind/IPC.h @@ -0,0 +1,10 @@ +#pragma once +#include "Client.h" +#include + +namespace wind +{ + Result handle_ipc_message(Client& client, u8 id); + + Result handle_ipc(Client& client); +} diff --git a/wind/Window.cpp b/wind/Window.cpp index 43141247..bfe6a8b1 100644 --- a/wind/Window.cpp +++ b/wind/Window.cpp @@ -38,7 +38,7 @@ void Window::focus() g_windows.append(this); } -Window::Window(ui::Rect r, ui::Color c, StringView n) : surface(r), color(c), name(n) +Window::Window(ui::Rect r, ui::Color c, String&& n) : surface(r), color(c), name(move(n)) { auto font = ui::Font::default_font(); if (surface.width < 36) surface.width = 36; @@ -48,3 +48,9 @@ Window::Window(ui::Rect r, ui::Color c, StringView n) : surface(r), color(c), na contents = ui::Rect { 0, font->height() + 20, surface.width, surface.height - (font->height() + 20) }; g_windows.append(this); } + +int Window::titlebar_height() +{ + auto font = ui::Font::default_font(); + return font->height() + 20; +} diff --git a/wind/Window.h b/wind/Window.h index 86f638d2..b181e3e0 100644 --- a/wind/Window.h +++ b/wind/Window.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #include #include #include @@ -12,9 +12,11 @@ struct Window : public LinkedListNode ui::Rect close_button; ui::Rect contents; ui::Color color; - StringView name; + String name; - Window(ui::Rect, ui::Color, StringView); + static int titlebar_height(); + + Window(ui::Rect, ui::Color, String&&); void focus(); diff --git a/wind/main.cpp b/wind/main.cpp index 39e51aff..90889c89 100644 --- a/wind/main.cpp +++ b/wind/main.cpp @@ -1,3 +1,5 @@ +#include "Client.h" +#include "IPC.h" #include "Mouse.h" #include "Screen.h" #include "Window.h" @@ -20,7 +22,7 @@ Result luna_main(int argc, char** argv) { srand((unsigned)time(NULL)); - TRY(os::Security::pledge("stdio rpath wpath cpath unix proc exec tty id", NULL)); + TRY(os::Security::pledge("stdio rpath wpath cpath unix proc exec tty signal id", NULL)); StringView socket_path = "/tmp/wind.sock"; StringView user; @@ -82,17 +84,13 @@ Result luna_main(int argc, char** argv) ui::Color background = ui::BLACK; - TRY(make(ui::Rect { 200, 200, 600, 400 }, ui::GREEN, "Calculator"_sv)); - TRY(make(ui::Rect { 100, 100, 300, 200 }, ui::RED, "Settings"_sv)); - TRY(make(ui::Rect { 600, 130, 350, 250 }, ui::CYAN, "File Manager"_sv)); - - Vector clients; + Vector clients; Vector fds; TRY(fds.try_append({ .fd = mouse->fd(), .events = POLLIN, .revents = 0 })); TRY(fds.try_append({ .fd = keyboard->fd(), .events = POLLIN, .revents = 0 })); TRY(fds.try_append({ .fd = server->fd(), .events = POLLIN, .revents = 0 })); - TRY(os::Security::pledge("stdio rpath unix", NULL)); + TRY(os::Security::pledge("stdio rpath unix signal proc", NULL)); while (1) { @@ -117,24 +115,22 @@ Result luna_main(int argc, char** argv) { moon::KeyboardPacket packet; TRY(keyboard->read_typed(packet)); - if (!packet.released) - { - TRY(make(ui::Rect { rand() % screen.canvas().width, rand() % screen.canvas().height, - rand() % screen.canvas().width, rand() % screen.canvas().height }, - ui::Color::from_rgb(static_cast(rand() % 256), static_cast(rand() % 256), - static_cast(rand() % 256)), - strerror(packet.key))); - } + os::println("%s key %d", packet.released ? "Released" : "Pressed", packet.key); } for (usize i = 0; i < clients.size(); i++) { - if (fds[i + 3].revents & POLLIN) os::println("wind: Client %d sent data!", i); + if (fds[i + 3].revents & POLLIN) wind::handle_ipc(clients[i]); if (fds[i + 3].revents & POLLHUP) { os::println("wind: Client %d disconnected", i); fds.remove_at(i + 3); auto client = clients.remove_at(i); - client.disconnect(); + client.conn.disconnect(); + for (auto& window : client.windows) + { + g_windows.remove(window); + delete window; + } } } if (fds[2].revents & POLLIN) @@ -142,7 +138,8 @@ Result luna_main(int argc, char** argv) auto client = TRY(server->accept()); os::println("wind: New client connected!"); TRY(fds.try_append({ .fd = client.fd(), .events = POLLIN, .revents = 0 })); - TRY(clients.try_append(move(client))); + Client c { move(client), {} }; + TRY(clients.try_append(move(c))); } } }