Compare commits
9 Commits
c0ca99bc7c
...
397ed396d8
Author | SHA1 | Date | |
---|---|---|---|
397ed396d8 | |||
4bcea9b141 | |||
ac5dd05d2e | |||
a2fd838f5d | |||
56269f5187 | |||
2c2c6fbc2d | |||
753a56d14c | |||
b614fa04de | |||
561d737f6c |
@ -1,5 +1,23 @@
|
||||
#include <os/ArgumentParser.h>
|
||||
#include <os/File.h>
|
||||
#include <os/LocalClient.h>
|
||||
#include <ui/ipc/Server.h>
|
||||
#include <unistd.h>
|
||||
|
||||
Result<void> handle_ipc_client_event(os::LocalClient&, u8)
|
||||
{
|
||||
todo();
|
||||
}
|
||||
|
||||
Result<int> create_window(os::LocalClient& client, ui::Rect rect, StringView name, ui::Color color)
|
||||
{
|
||||
ui::CreateWindowRequest request;
|
||||
request.rect = rect;
|
||||
SET_IPC_STRING(request.name, name.chars());
|
||||
request.color = color;
|
||||
auto response = TRY(os::IPC::send_sync<ui::CreateWindowResponse>(client, request));
|
||||
return response.window;
|
||||
}
|
||||
|
||||
Result<int> luna_main(int argc, char** argv)
|
||||
{
|
||||
@ -13,8 +31,16 @@ Result<int> luna_main(int argc, char** argv)
|
||||
|
||||
auto client = TRY(os::LocalClient::connect(socket_path, false));
|
||||
|
||||
StringView message = "hello";
|
||||
TRY(client->send((const u8*)message.chars(), message.length()));
|
||||
int id = TRY(create_window(*client, ui::Rect { 200, 200, 400, 300 }, "My Window", ui::CYAN));
|
||||
os::println("Created new window with id %d!", id);
|
||||
|
||||
sleep(3);
|
||||
|
||||
id =
|
||||
TRY(create_window(*client, ui::Rect { 100, 100, 200, 150 }, "Super Long Name that is Way Too Long ", ui::BLUE));
|
||||
os::println("Created new window with id %d!", id);
|
||||
|
||||
sleep(6);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -69,6 +69,8 @@ class Socket : public VFS::FileInode
|
||||
|
||||
virtual bool can_read_data() const = 0;
|
||||
|
||||
virtual bool peer_disconnected() const = 0;
|
||||
|
||||
virtual ~Socket() = default;
|
||||
|
||||
protected:
|
||||
|
@ -27,6 +27,11 @@ class UnixSocket : public Socket
|
||||
return !m_listen_queue.is_empty();
|
||||
}
|
||||
|
||||
bool peer_disconnected() const override
|
||||
{
|
||||
return m_state == Reset;
|
||||
}
|
||||
|
||||
Result<usize> send(const u8*, usize, int) override;
|
||||
Result<usize> recv(u8*, usize, int) const override;
|
||||
|
||||
|
@ -56,6 +56,11 @@ Result<u64> sys_poll(Registers*, SyscallArgs args)
|
||||
fds_with_events++;
|
||||
kfds[i].revents |= POLLIN;
|
||||
}
|
||||
if (socket->peer_disconnected())
|
||||
{
|
||||
fds_with_events++;
|
||||
kfds[i].revents |= POLLHUP;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define POLLIN (1 << 0)
|
||||
#define POLLERR (1 << 1)
|
||||
#define POLLNVAL (1 << 2)
|
||||
#define POLLHUP (1 << 3)
|
||||
|
||||
typedef __u64_t nfds_t;
|
||||
|
||||
|
@ -16,6 +16,7 @@ set(SOURCES
|
||||
src/Security.cpp
|
||||
src/LocalServer.cpp
|
||||
src/LocalClient.cpp
|
||||
src/IPC.cpp
|
||||
)
|
||||
|
||||
add_library(os ${SOURCES})
|
||||
|
157
libos/include/os/IPC.h
Normal file
157
libos/include/os/IPC.h
Normal file
@ -0,0 +1,157 @@
|
||||
/**
|
||||
* @file IPC.h
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief Inter-process communication primitives.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <os/LocalClient.h>
|
||||
#include <os/LocalServer.h>
|
||||
|
||||
#define IPC_ENUM_SERVER(name) __##name##_SERVER_ERROR = 0
|
||||
#define IPC_ENUM_CLIENT(name) __##name##_CLIENT_ERROR = 0
|
||||
|
||||
/**
|
||||
* @brief Called to handle IPC events (client-side).
|
||||
*
|
||||
* @param conn The connection object being used.
|
||||
* @param id The ID of the message.
|
||||
* @return Result<void> Whether the operation succeded.
|
||||
*/
|
||||
extern Result<void> handle_ipc_client_event(os::LocalClient& conn, u8 id);
|
||||
|
||||
/**
|
||||
* @brief Called to handle IPC events (server-side).
|
||||
*
|
||||
* @param conn The connection object being used.
|
||||
* @param id The ID of the message.
|
||||
* @return Result<void> Whether the operation succeded.
|
||||
*/
|
||||
extern Result<void> handle_ipc_server_event(os::LocalServer::Client& conn, u8 id);
|
||||
|
||||
namespace os
|
||||
{
|
||||
namespace IPC
|
||||
{
|
||||
static constexpr usize IPC_STRING_LENGTH = 256;
|
||||
|
||||
#define IPC_STRING(name) char name[os::IPC::IPC_STRING_LENGTH];
|
||||
#define COPY_IPC_STRING(name) \
|
||||
TRY(String::from_string_view(StringView::from_fixed_size_cstring(name, os::IPC::IPC_STRING_LENGTH)))
|
||||
#define SET_IPC_STRING(name, value) strlcpy(name, value, os::IPC::IPC_STRING_LENGTH)
|
||||
|
||||
/**
|
||||
* @brief Sends an IPC message without waiting for a reply.
|
||||
*
|
||||
* @tparam Client The type of the client interface being used to communicate.
|
||||
* @tparam T The type of the message.
|
||||
* @param client The connection object being used to communicate.
|
||||
* @param message The IPC message.
|
||||
* @return Result<void> Whether the operation succeded.
|
||||
*/
|
||||
template <typename Client, typename T> Result<void> send_async(Client& client, const T& message)
|
||||
{
|
||||
u8 id = T::id;
|
||||
TRY(client.send_typed(id));
|
||||
TRY(client.send_typed(message));
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends an error result to the IPC connection, indicating that an operation could not be performed.
|
||||
*
|
||||
* @tparam Client The type of the client interface being used to communicate.
|
||||
* @param client The connection object being used to communicate.
|
||||
* @param error The error code.
|
||||
* @return Result<void> Whether the operation succeded.
|
||||
*/
|
||||
template <typename Client> Result<void> send_error(Client& client, int error)
|
||||
{
|
||||
u8 id = 0;
|
||||
TRY(client.send_typed(id));
|
||||
TRY(client.send_typed(error));
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends an IPC message and waits for a reply (client-only).
|
||||
*
|
||||
* @tparam ResponseType The type of the response.
|
||||
* @tparam T The type of the message.
|
||||
* @param client The connection object being used to communicate.
|
||||
* @param message The IPC message.
|
||||
* @param handler The function used to handle messages that do not match the reply.
|
||||
* @return Result<ResponseType> An error, or the response.
|
||||
*/
|
||||
template <typename ResponseType, typename T>
|
||||
Result<ResponseType> send_sync(os::LocalClient& client, const T& message,
|
||||
decltype(handle_ipc_client_event) handler = handle_ipc_client_event)
|
||||
{
|
||||
u8 id = T::id;
|
||||
TRY(client.send_typed(id));
|
||||
TRY(client.send_typed(message));
|
||||
|
||||
// We allow receiving 5 messages of different types, but if those have passed and we still don't have a
|
||||
// reply, fail with ENOMSG.
|
||||
int max_other_messages = 5;
|
||||
|
||||
while (max_other_messages)
|
||||
{
|
||||
u8 response_id;
|
||||
auto rc = client.recv_typed(response_id);
|
||||
if (rc.has_error() && rc.error() == EAGAIN) continue;
|
||||
|
||||
if (response_id == 0) // Error result
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
int code;
|
||||
rc = client.recv_typed(code);
|
||||
if (rc.has_error() && rc.error() == EAGAIN) continue;
|
||||
return err(code);
|
||||
}
|
||||
}
|
||||
|
||||
if (response_id != ResponseType::id)
|
||||
{
|
||||
TRY(handler(client, response_id));
|
||||
max_other_messages--;
|
||||
continue;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
ResponseType response;
|
||||
rc = client.recv_typed(response);
|
||||
if (rc.has_error() && rc.error() == EAGAIN) continue;
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
return err(ENOMSG);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check for new IPC messages on a connection and handle them appropriately.
|
||||
*
|
||||
* @param client The client connection.
|
||||
* @param handler The function used to handle messages.
|
||||
* @return Result<void> Whether the operation succeded.
|
||||
*/
|
||||
Result<void> check_for_messages(os::LocalClient& client,
|
||||
decltype(handle_ipc_client_event) handler = handle_ipc_client_event);
|
||||
|
||||
/**
|
||||
* @brief Check for new IPC messages on a connection and handle them appropriately.
|
||||
*
|
||||
* @param server The server connection.
|
||||
* @param handler The function used to handle messages.
|
||||
* @return Result<void> Whether the operation succeded.
|
||||
*/
|
||||
Result<void> check_for_messages(os::LocalServer::Client& server,
|
||||
decltype(handle_ipc_server_event) handler = handle_ipc_server_event);
|
||||
}
|
||||
}
|
@ -1,3 +1,12 @@
|
||||
/**
|
||||
* @file LocalClient.h
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief UNIX local domain client class.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <luna/OwnedPtr.h>
|
||||
#include <luna/StringView.h>
|
||||
|
@ -1,3 +1,12 @@
|
||||
/**
|
||||
* @file LocalServer.h
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief UNIX local domain server class.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <luna/OwnedPtr.h>
|
||||
#include <luna/Result.h>
|
||||
|
39
libos/src/IPC.cpp
Normal file
39
libos/src/IPC.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @file IPC.cpp
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief Inter-process communication primitives.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <os/IPC.h>
|
||||
|
||||
namespace os::IPC
|
||||
{
|
||||
Result<void> check_for_messages(os::LocalClient& client, decltype(handle_ipc_client_event) handler)
|
||||
{
|
||||
u8 id;
|
||||
auto rc = client.recv_typed(id);
|
||||
if (rc.has_error())
|
||||
{
|
||||
if (rc.error() == EAGAIN) return {}; // No messages, and the caller does not want us to block.
|
||||
return rc.release_error();
|
||||
}
|
||||
|
||||
return handler(client, id);
|
||||
}
|
||||
|
||||
Result<void> check_for_messages(os::LocalServer::Client& client, decltype(handle_ipc_server_event) handler)
|
||||
{
|
||||
u8 id;
|
||||
auto rc = client.recv_typed(id);
|
||||
if (rc.has_error())
|
||||
{
|
||||
if (rc.error() == EAGAIN) return {}; // No messages, and the caller does not want us to block.
|
||||
return rc.release_error();
|
||||
}
|
||||
|
||||
return handler(client, id);
|
||||
}
|
||||
}
|
@ -1,3 +1,12 @@
|
||||
/**
|
||||
* @file LocalClient.cpp
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief UNIX local domain client class.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <os/LocalClient.h>
|
||||
|
@ -1,3 +1,12 @@
|
||||
/**
|
||||
* @file LocalServer.cpp
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief UNIX local domain server class.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <os/FileSystem.h>
|
||||
|
@ -4,6 +4,8 @@ file(GLOB HEADERS include/ui/*.h)
|
||||
|
||||
set(SOURCES
|
||||
${HEADERS}
|
||||
include/ui/ipc/Server.h
|
||||
include/ui/ipc/Client.h
|
||||
src/Canvas.cpp
|
||||
src/Rect.cpp
|
||||
src/Font.cpp
|
||||
|
@ -1,3 +1,12 @@
|
||||
/**
|
||||
* @file Canvas.h
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief Drawable surfaces.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <luna/Result.h>
|
||||
#include <luna/Types.h>
|
||||
|
@ -1,3 +1,12 @@
|
||||
/**
|
||||
* @file Color.h
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief RGBA colors.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <luna/Types.h>
|
||||
|
||||
|
@ -1,3 +1,12 @@
|
||||
/**
|
||||
* @file Font.h
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief PSF font loading and rendering.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <luna/Buffer.h>
|
||||
#include <luna/SharedPtr.h>
|
||||
|
@ -1,3 +1,12 @@
|
||||
/**
|
||||
* @file Image.h
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief TGA image loading and rendering.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <luna/Buffer.h>
|
||||
#include <luna/SharedPtr.h>
|
||||
|
@ -1,3 +1,12 @@
|
||||
/**
|
||||
* @file Point.h
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief 2D space points.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ui
|
||||
|
@ -1,3 +1,12 @@
|
||||
/**
|
||||
* @file Rect.h
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief A simple 2D rectangle representation.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <ui/Point.h>
|
||||
|
||||
|
27
libui/include/ui/ipc/Client.h
Normal file
27
libui/include/ui/ipc/Client.h
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @file ipc/Client.h
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief IPC message definitions for UI messages sent to the client.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <os/IPC.h>
|
||||
|
||||
namespace ui
|
||||
{
|
||||
enum ClientMessages : u8
|
||||
{
|
||||
IPC_ENUM_CLIENT(ui),
|
||||
CREATE_WINDOW_RESPONSE_ID,
|
||||
};
|
||||
|
||||
struct CreateWindowResponse
|
||||
{
|
||||
static constexpr u8 id = CREATE_WINDOW_RESPONSE_ID;
|
||||
|
||||
int window;
|
||||
};
|
||||
}
|
33
libui/include/ui/ipc/Server.h
Normal file
33
libui/include/ui/ipc/Server.h
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* @file ipc/Server.h
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief IPC message definitions for UI messages sent to the server.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <os/IPC.h>
|
||||
#include <ui/Color.h>
|
||||
#include <ui/Rect.h>
|
||||
#include <ui/ipc/Client.h>
|
||||
|
||||
namespace ui
|
||||
{
|
||||
enum ServerMessages : u8
|
||||
{
|
||||
IPC_ENUM_SERVER(ui),
|
||||
CREATE_WINDOW_ID,
|
||||
};
|
||||
|
||||
struct CreateWindowRequest
|
||||
{
|
||||
using ResponseType = CreateWindowResponse;
|
||||
static constexpr u8 id = CREATE_WINDOW_ID;
|
||||
|
||||
ui::Rect rect;
|
||||
IPC_STRING(name);
|
||||
ui::Color color;
|
||||
};
|
||||
}
|
@ -1,3 +1,12 @@
|
||||
/**
|
||||
* @file Canvas.cpp
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief Drawable surfaces.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ui/Canvas.h>
|
||||
|
||||
namespace ui
|
||||
|
@ -1,3 +1,12 @@
|
||||
/**
|
||||
* @file Font.cpp
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief PSF font loading and rendering.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <luna/String.h>
|
||||
#include <os/File.h>
|
||||
#include <ui/Font.h>
|
||||
|
@ -1,3 +1,12 @@
|
||||
/**
|
||||
* @file Image.cpp
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief TGA image loading and rendering.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <os/File.h>
|
||||
#include <ui/Image.h>
|
||||
|
||||
|
@ -1,3 +1,12 @@
|
||||
/**
|
||||
* @file Rect.cpp
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief A simple 2D rectangle representation.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ui/Rect.h>
|
||||
|
||||
namespace ui
|
||||
|
@ -6,6 +6,9 @@ set(SOURCES
|
||||
Mouse.cpp
|
||||
Window.h
|
||||
Window.cpp
|
||||
IPC.cpp
|
||||
IPC.h
|
||||
Client.h
|
||||
)
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include <luna/LinkedList.h>
|
||||
#include <luna/StringView.h>
|
||||
#include <luna/String.h>
|
||||
#include <ui/Canvas.h>
|
||||
#include <ui/Color.h>
|
||||
#include <ui/Rect.h>
|
||||
@ -12,9 +12,11 @@ struct Window : public LinkedListNode<Window>
|
||||
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();
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include "Client.h"
|
||||
#include "IPC.h"
|
||||
#include "Mouse.h"
|
||||
#include "Screen.h"
|
||||
#include "Window.h"
|
||||
@ -20,7 +22,7 @@ Result<int> 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,13 +84,13 @@ Result<int> luna_main(int argc, char** argv)
|
||||
|
||||
ui::Color background = ui::BLACK;
|
||||
|
||||
TRY(make<Window>(ui::Rect { 200, 200, 600, 400 }, ui::GREEN, "Calculator"_sv));
|
||||
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<Client> clients;
|
||||
Vector<struct pollfd> 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 }));
|
||||
|
||||
Vector<os::LocalServer::Client> clients;
|
||||
|
||||
TRY(os::Security::pledge("stdio rpath unix", NULL));
|
||||
TRY(os::Security::pledge("stdio rpath unix signal proc", NULL));
|
||||
|
||||
while (1)
|
||||
{
|
||||
@ -97,13 +99,9 @@ Result<int> luna_main(int argc, char** argv)
|
||||
mouse_pointer.draw(screen.canvas());
|
||||
screen.sync();
|
||||
|
||||
struct pollfd fds[] = {
|
||||
{ .fd = mouse->fd(), .events = POLLIN, .revents = 0 },
|
||||
{ .fd = keyboard->fd(), .events = POLLIN, .revents = 0 },
|
||||
{ .fd = server->fd(), .events = POLLIN, .revents = 0 },
|
||||
};
|
||||
for (auto& pfd : fds) { pfd.revents = 0; }
|
||||
|
||||
int rc = poll(fds, 3, 1000);
|
||||
int rc = poll(fds.data(), fds.size(), 1000);
|
||||
if (!rc) continue;
|
||||
if (rc < 0 && errno != EINTR) { os::println("poll: error: %s", strerror(errno)); }
|
||||
|
||||
@ -117,20 +115,31 @@ Result<int> luna_main(int argc, char** argv)
|
||||
{
|
||||
moon::KeyboardPacket packet;
|
||||
TRY(keyboard->read_typed(packet));
|
||||
if (!packet.released)
|
||||
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) wind::handle_ipc(clients[i]);
|
||||
if (fds[i + 3].revents & POLLHUP)
|
||||
{
|
||||
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)));
|
||||
os::println("wind: Client %d disconnected", i);
|
||||
fds.remove_at(i + 3);
|
||||
auto client = clients.remove_at(i);
|
||||
client.conn.disconnect();
|
||||
for (auto& window : client.windows)
|
||||
{
|
||||
g_windows.remove(window);
|
||||
delete window;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fds[2].revents & POLLIN)
|
||||
{
|
||||
auto client = TRY(server->accept());
|
||||
os::println("wind: New client connected!");
|
||||
TRY(clients.try_append(move(client)));
|
||||
TRY(fds.try_append({ .fd = client.fd(), .events = POLLIN, .revents = 0 }));
|
||||
Client c { move(client), {} };
|
||||
TRY(clients.try_append(move(c)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user