wind: Handle CreateWindow IPC messages
This commit is contained in:
parent
ac5dd05d2e
commit
4bcea9b141
@ -6,6 +6,9 @@ set(SOURCES
|
|||||||
Mouse.cpp
|
Mouse.cpp
|
||||||
Window.h
|
Window.h
|
||||||
Window.cpp
|
Window.cpp
|
||||||
|
IPC.cpp
|
||||||
|
IPC.h
|
||||||
|
Client.h
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(wind ${SOURCES})
|
add_executable(wind ${SOURCES})
|
||||||
|
11
wind/Client.h
Normal file
11
wind/Client.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Window.h"
|
||||||
|
#include <os/LocalServer.h>
|
||||||
|
|
||||||
|
struct Client
|
||||||
|
{
|
||||||
|
os::LocalServer::Client conn;
|
||||||
|
Vector<Window*> windows;
|
||||||
|
bool rpc_in_progress { false };
|
||||||
|
u8 rpc_id { 0 };
|
||||||
|
};
|
75
wind/IPC.cpp
Normal file
75
wind/IPC.cpp
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include "IPC.h"
|
||||||
|
#include <luna/String.h>
|
||||||
|
#include <os/File.h>
|
||||||
|
|
||||||
|
static Result<void> 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<int>(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<void> 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<void> 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);
|
||||||
|
}
|
||||||
|
}
|
10
wind/IPC.h
Normal file
10
wind/IPC.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Client.h"
|
||||||
|
#include <ui/ipc/Server.h>
|
||||||
|
|
||||||
|
namespace wind
|
||||||
|
{
|
||||||
|
Result<void> handle_ipc_message(Client& client, u8 id);
|
||||||
|
|
||||||
|
Result<void> handle_ipc(Client& client);
|
||||||
|
}
|
@ -38,7 +38,7 @@ void Window::focus()
|
|||||||
g_windows.append(this);
|
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();
|
auto font = ui::Font::default_font();
|
||||||
if (surface.width < 36) surface.width = 36;
|
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) };
|
contents = ui::Rect { 0, font->height() + 20, surface.width, surface.height - (font->height() + 20) };
|
||||||
g_windows.append(this);
|
g_windows.append(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Window::titlebar_height()
|
||||||
|
{
|
||||||
|
auto font = ui::Font::default_font();
|
||||||
|
return font->height() + 20;
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <luna/LinkedList.h>
|
#include <luna/LinkedList.h>
|
||||||
#include <luna/StringView.h>
|
#include <luna/String.h>
|
||||||
#include <ui/Canvas.h>
|
#include <ui/Canvas.h>
|
||||||
#include <ui/Color.h>
|
#include <ui/Color.h>
|
||||||
#include <ui/Rect.h>
|
#include <ui/Rect.h>
|
||||||
@ -12,9 +12,11 @@ struct Window : public LinkedListNode<Window>
|
|||||||
ui::Rect close_button;
|
ui::Rect close_button;
|
||||||
ui::Rect contents;
|
ui::Rect contents;
|
||||||
ui::Color color;
|
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();
|
void focus();
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#include "Client.h"
|
||||||
|
#include "IPC.h"
|
||||||
#include "Mouse.h"
|
#include "Mouse.h"
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
@ -20,7 +22,7 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
srand((unsigned)time(NULL));
|
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 socket_path = "/tmp/wind.sock";
|
||||||
StringView user;
|
StringView user;
|
||||||
@ -82,17 +84,13 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
|
|
||||||
ui::Color background = ui::BLACK;
|
ui::Color background = ui::BLACK;
|
||||||
|
|
||||||
TRY(make<Window>(ui::Rect { 200, 200, 600, 400 }, ui::GREEN, "Calculator"_sv));
|
Vector<Client> clients;
|
||||||
TRY(make<Window>(ui::Rect { 100, 100, 300, 200 }, ui::RED, "Settings"_sv));
|
|
||||||
TRY(make<Window>(ui::Rect { 600, 130, 350, 250 }, ui::CYAN, "File Manager"_sv));
|
|
||||||
|
|
||||||
Vector<os::LocalServer::Client> clients;
|
|
||||||
Vector<struct pollfd> fds;
|
Vector<struct pollfd> fds;
|
||||||
TRY(fds.try_append({ .fd = mouse->fd(), .events = POLLIN, .revents = 0 }));
|
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 = keyboard->fd(), .events = POLLIN, .revents = 0 }));
|
||||||
TRY(fds.try_append({ .fd = server->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)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -117,24 +115,22 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
moon::KeyboardPacket packet;
|
moon::KeyboardPacket packet;
|
||||||
TRY(keyboard->read_typed(packet));
|
TRY(keyboard->read_typed(packet));
|
||||||
if (!packet.released)
|
os::println("%s key %d", packet.released ? "Released" : "Pressed", packet.key);
|
||||||
{
|
|
||||||
TRY(make<Window>(ui::Rect { rand() % screen.canvas().width, rand() % screen.canvas().height,
|
|
||||||
rand() % screen.canvas().width, rand() % screen.canvas().height },
|
|
||||||
ui::Color::from_rgb(static_cast<u8>(rand() % 256), static_cast<u8>(rand() % 256),
|
|
||||||
static_cast<u8>(rand() % 256)),
|
|
||||||
strerror(packet.key)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (usize i = 0; i < clients.size(); i++)
|
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)
|
if (fds[i + 3].revents & POLLHUP)
|
||||||
{
|
{
|
||||||
os::println("wind: Client %d disconnected", i);
|
os::println("wind: Client %d disconnected", i);
|
||||||
fds.remove_at(i + 3);
|
fds.remove_at(i + 3);
|
||||||
auto client = clients.remove_at(i);
|
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)
|
if (fds[2].revents & POLLIN)
|
||||||
@ -142,7 +138,8 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
auto client = TRY(server->accept());
|
auto client = TRY(server->accept());
|
||||||
os::println("wind: New client connected!");
|
os::println("wind: New client connected!");
|
||||||
TRY(fds.try_append({ .fd = client.fd(), .events = POLLIN, .revents = 0 }));
|
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)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user