summaryrefslogtreecommitdiff
path: root/libraries/pake/source/window.cpp
diff options
context:
space:
mode:
authorBenji Dial <benji@benjidial.net>2024-07-29 19:59:52 -0400
committerBenji Dial <benji@benjidial.net>2024-07-29 19:59:52 -0400
commite6c3a80b01ffb52079783cddd9be6d392d0f7039 (patch)
tree148276b9878f287bc81638f90249ec4d7b86eaf0 /libraries/pake/source/window.cpp
parentbe691582ee12613278af24cb5a824eeb357f6324 (diff)
downloadhilbert-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.cpp78
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();
+
+ }
+
+}