diff --git a/LibGUI/Window.cpp b/LibGUI/Window.cpp index c7fa5c19..e000aa99 100644 --- a/LibGUI/Window.cpp +++ b/LibGUI/Window.cpp @@ -1,6 +1,7 @@ #include "LibGUI/Window.h" #include +#include #include #include #include @@ -17,24 +18,46 @@ namespace LibGUI close(m_server_fd); } - BAN::ErrorOr> Window::create(uint32_t width, uint32_t height) + BAN::ErrorOr> Window::create(uint32_t width, uint32_t height, BAN::StringView title) { + if (title.size() >= sizeof(WindowCreatePacket::title)) + return BAN::Error::from_errno(EINVAL); + int server_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0); if (server_fd == -1) return BAN::Error::from_errno(errno); - sockaddr_un server_address; - server_address.sun_family = AF_UNIX; - strcpy(server_address.sun_path, s_window_server_socket.data()); - if (connect(server_fd, (sockaddr*)&server_address, sizeof(server_address)) == -1) + timespec start_time; + clock_gettime(CLOCK_MONOTONIC, &start_time); + + for (;;) { - close(server_fd); - return BAN::Error::from_errno(errno); + sockaddr_un server_address; + server_address.sun_family = AF_UNIX; + strcpy(server_address.sun_path, s_window_server_socket.data()); + if (connect(server_fd, (sockaddr*)&server_address, sizeof(server_address)) == 0) + break; + + timespec current_time; + clock_gettime(CLOCK_MONOTONIC, ¤t_time); + time_t duration_s = (current_time.tv_sec - start_time.tv_sec) + (current_time.tv_nsec >= start_time.tv_nsec); + if (duration_s > 10) + { + close(server_fd); + return BAN::Error::from_errno(ETIMEDOUT); + } + + timespec sleep_time; + sleep_time.tv_sec = 0; + sleep_time.tv_nsec = 1'000'000; + nanosleep(&sleep_time, nullptr); } WindowCreatePacket packet; packet.width = width; packet.height = height; + strncpy(packet.title, title.data(), title.size()); + packet.title[title.size()] = '\0'; if (send(server_fd, &packet, sizeof(packet), 0) != sizeof(packet)) { close(server_fd); @@ -92,6 +115,14 @@ namespace LibGUI switch (packet.type) { + case EventPacket::Type::DestroyWindow: + exit(1); + case EventPacket::Type::CloseWindow: + if (m_close_window_event_callback) + m_close_window_event_callback(); + else + exit(0); + break; case EventPacket::Type::KeyEvent: if (m_key_event_callback) m_key_event_callback(packet.key_event); diff --git a/LibGUI/include/LibGUI/Window.h b/LibGUI/include/LibGUI/Window.h index d13a2add..1e473bf5 100644 --- a/LibGUI/include/LibGUI/Window.h +++ b/LibGUI/include/LibGUI/Window.h @@ -20,6 +20,7 @@ namespace LibGUI INVALID, CreateWindow, Invalidate, + COUNT }; struct WindowCreatePacket @@ -27,6 +28,7 @@ namespace LibGUI WindowPacketType type = WindowPacketType::CreateWindow; uint32_t width; uint32_t height; + char title[52]; }; struct WindowInvalidatePacket @@ -61,6 +63,8 @@ namespace LibGUI { enum class Type : uint8_t { + DestroyWindow, + CloseWindow, KeyEvent, MouseButtonEvent, MouseMoveEvent, @@ -97,7 +101,7 @@ namespace LibGUI public: ~Window(); - static BAN::ErrorOr> create(uint32_t width, uint32_t height); + static BAN::ErrorOr> create(uint32_t width, uint32_t height, BAN::StringView title); void set_pixel(uint32_t x, uint32_t y, uint32_t color) { @@ -112,6 +116,7 @@ namespace LibGUI uint32_t height() const { return m_height; } void poll_events(); + void set_close_window_event_callback(BAN::Function callback) { m_close_window_event_callback = callback; } void set_key_event_callback(BAN::Function callback) { m_key_event_callback = callback; } void set_mouse_button_event_callback(BAN::Function callback) { m_mouse_button_event_callback = callback; } void set_mouse_move_event_callback(BAN::Function callback) { m_mouse_move_event_callback = callback; } @@ -131,6 +136,7 @@ namespace LibGUI uint32_t m_width; uint32_t m_height; + BAN::Function m_close_window_event_callback; BAN::Function m_key_event_callback; BAN::Function m_mouse_button_event_callback; BAN::Function m_mouse_move_event_callback;