#include #include //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 &&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(); } }