diff options
author | Benji Dial <benji@benjidial.net> | 2024-07-29 19:59:52 -0400 |
---|---|---|
committer | Benji Dial <benji@benjidial.net> | 2024-07-29 19:59:52 -0400 |
commit | e6c3a80b01ffb52079783cddd9be6d392d0f7039 (patch) | |
tree | 148276b9878f287bc81638f90249ec4d7b86eaf0 /libraries/pake/source/window.cpp | |
parent | be691582ee12613278af24cb5a824eeb357f6324 (diff) | |
download | hilbert-os-e6c3a80b01ffb52079783cddd9be6d392d0f7039.tar.gz |
redesign compositor protocol, start widget library
Diffstat (limited to 'libraries/pake/source/window.cpp')
-rw-r--r-- | libraries/pake/source/window.cpp | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/libraries/pake/source/window.cpp b/libraries/pake/source/window.cpp new file mode 100644 index 0000000..c1c773f --- /dev/null +++ b/libraries/pake/source/window.cpp @@ -0,0 +1,78 @@ +#include <pake/window.hpp> +#include <cassert> + +//TODO: handle errors on socket connection, read, and write + +namespace pake { + + window::window(int width, int height, const std::string &title) + : width(width), height(height), contents(width, height), root() { + + euler::syscall::connect_to_socket("hilbert.compositor", socket); + + assert(width >= 0 && height >= 0); + + struct [[gnu::packed]] { uint8_t type; uint32_t width; uint32_t height; } + dimensions_pkt = {.type = 0x02, .width = (uint32_t)width, .height = (uint32_t)height }; + euler::syscall::write_to_stream(socket, sizeof(dimensions_pkt), &dimensions_pkt); + + assert(title.size() <= UINT32_MAX); + + struct [[gnu::packed]] { uint8_t type; uint32_t length; } + title_pkt = {.type = 0x03, .length = (uint32_t)title.size() }; + euler::syscall::write_to_stream(socket, sizeof(title_pkt), &title_pkt); + euler::syscall::write_to_stream(socket, title.size(), title.data()); + + } + + window::~window() { + euler::syscall::close_stream(socket); + } + + void window::show() { + uint8_t packet = 0; + euler::syscall::write_to_stream(socket, 1, &packet); + } + + void window::hide() { + uint8_t packet = 1; + euler::syscall::write_to_stream(socket, 1, &packet); + } + + void window::set_root(std::unique_ptr<widget> &&w) { + root = std::move(w); + root->notify_size(width, height); + root->render(contents, 0, 0, true); + } + + void window::render_and_send_to_compositor() { + + root->render(contents, 0, 0, false); + auto dirties = contents.get_dirty_regions(); + + for (auto it = dirties.cbegin(); it != dirties.cend(); ++it) { + + struct [[gnu::packed]] { + uint8_t type; + uint32_t start_x; uint32_t start_y; + uint32_t width; uint32_t height; + } update_pkt = { + .type = 0x04, + .start_x = (uint32_t)it->start_x, .start_y = (uint32_t)it->start_y, + . width = (uint32_t)it-> width, . height = (uint32_t)it-> height + }; + + euler::syscall::write_to_stream(socket, sizeof(update_pkt), &update_pkt); + + for (int y = it->start_y; y < it->start_y + it->height; ++y) + euler::syscall::write_to_stream(socket, + it->width * sizeof(daguerre::hilbert_color), + &contents.image.at(it->start_x, y)); + + } + + contents.clear_dirty(); + + } + +} |