#pragma once #include "Framebuffer.h" #include "Window.h" #include #include #include #include #include #include #include #include #include #include class WindowServer { public: struct ClientData { size_t in_buffer_size { 0 }; BAN::Array in_buffer; size_t out_buffer_size { 0 }; BAN::Array out_buffer; }; public: WindowServer(Framebuffer& framebuffer, int32_t corner_radius); BAN::ErrorOr set_background_image(BAN::UniqPtr); void on_window_create(int fd, const LibGUI::WindowPacket::WindowCreate&); void on_window_invalidate(int fd, const LibGUI::WindowPacket::WindowInvalidate&); void on_window_set_position(int fd, const LibGUI::WindowPacket::WindowSetPosition&); void on_window_set_attributes(int fd, const LibGUI::WindowPacket::WindowSetAttributes&); void on_window_set_mouse_relative(int fd, const LibGUI::WindowPacket::WindowSetMouseRelative&); void on_window_set_size(int fd, const LibGUI::WindowPacket::WindowSetSize&); void on_window_set_min_size(int fd, const LibGUI::WindowPacket::WindowSetMinSize&); void on_window_set_max_size(int fd, const LibGUI::WindowPacket::WindowSetMaxSize&); void on_window_set_fullscreen(int fd, const LibGUI::WindowPacket::WindowSetFullscreen&); void on_window_set_title(int fd, const LibGUI::WindowPacket::WindowSetTitle&); void on_window_set_cursor(int fd, const LibGUI::WindowPacket::WindowSetCursor&); void on_key_event(LibInput::KeyEvent event); void on_mouse_button(LibInput::MouseButtonEvent event); void on_mouse_move(LibInput::MouseMoveEvent event); void on_mouse_move_abs(LibInput::MouseMoveAbsEvent event); void on_mouse_scroll(LibInput::MouseScrollEvent event); void set_focused_window(BAN::RefPtr window); void invalidate(Rectangle area); void sync(); Rectangle cursor_area() const; Rectangle resize_area(Position cursor) const; BAN::ErrorOr add_client_fd(int fd); void remove_client_fd(int fd); ClientData& get_client_data(int fd); bool is_stopped() const { return m_is_stopped; } private: void on_mouse_move_impl(int32_t new_x, int32_t new_y); void merge_damaged_areas(); void add_damaged_area(Rectangle area); void add_damaged_area_impl(Rectangle area); bool resize_window(BAN::RefPtr window, uint32_t width, uint32_t height); BAN::RefPtr find_window_with_fd(int fd) const; BAN::RefPtr find_hovered_window() const; template BAN::ErrorOr append_serialized_packet(const T& packet, int fd); private: enum class State { Normal, Fullscreen, Moving, Resizing, }; private: Framebuffer& m_framebuffer; BAN::Vector> m_client_windows; BAN::HashMap m_client_data; const int32_t m_corner_radius; static constexpr size_t m_max_damaged_areas = 32; size_t m_damaged_area_count { 0 }; BAN::Array m_damaged_areas; // NOTE: same size as framebuffer BAN::Vector m_background_image; State m_state { State::Normal }; bool m_is_mod_key_held { false }; BAN::RefPtr m_focused_window; BAN::Array, 5> m_mouse_button_windows; Position m_cursor; Rectangle m_non_full_screen_rect; uint8_t m_resize_quadrant { 0 }; Position m_resize_start; bool m_is_mouse_relative { false }; bool m_is_stopped { false }; bool m_is_bouncing_window = false; LibFont::Font m_font; };