diff options
| author | Joel Klinghed <the_jk@spawned.biz> | 2021-01-27 22:06:49 +0100 |
|---|---|---|
| committer | Joel Klinghed <the_jk@spawned.biz> | 2021-01-27 22:06:49 +0100 |
| commit | 06950aab233de6a2f47293d59575bb42f6131660 (patch) | |
| tree | 62f6eed4a6d35414f656d22b9ac7420849018a11 /src/xcb_colors.cc | |
| parent | 1ef9c463f1efc1adfb62e42ab3dd17e8c6394373 (diff) | |
Complete rewrite using C++ and with shared state support
Diffstat (limited to 'src/xcb_colors.cc')
| -rw-r--r-- | src/xcb_colors.cc | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/xcb_colors.cc b/src/xcb_colors.cc new file mode 100644 index 0000000..f4caca4 --- /dev/null +++ b/src/xcb_colors.cc @@ -0,0 +1,93 @@ +#include "common.hh" + +#include "xcb_colors.hh" +#include "xcb_connection.hh" +#include "xcb_event.hh" + +#include <map> +#include <vector> +#include <xcb/xproto.h> + +namespace xcb { + +namespace { + +class ColorsImpl : public Colors { +public: + ColorsImpl(shared_conn conn, xcb_colormap_t colormap) + : conn_(conn), colormap_(colormap), + storage_(std::make_shared<StorageImpl>()) {} + + Color get_with_fallback(uint8_t r, uint8_t g, uint8_t b, + uint32_t fallback) override { + auto key = make_key(r, g, b); + auto it = index_.find(key); + size_t index; + if (it == index_.end()) { + index = cookie_.size(); + cookie_.push_back(xcb_alloc_color(conn_.get(), colormap_, + static_cast<uint16_t>(r) << 8, + static_cast<uint16_t>(g) << 8, + static_cast<uint16_t>(b) << 8)); + fallback_.push_back(fallback); + index_.emplace(key, index); + } else { + index = it->second; + } + return Color(storage_, index); + } + + bool sync() override { + std::vector<uint32_t> colors; + colors.reserve(cookie_.size()); + for (size_t i = 0; i < cookie_.size(); ++i) { + xcb::reply<xcb_alloc_color_reply_t> reply( + xcb_alloc_color_reply(conn_.get(), cookie_[i], nullptr)); + if (reply) { + colors.push_back(reply->pixel); + } else { + colors.push_back(fallback_[i]); + } + } + storage_->set(std::move(colors)); + return true; + } + +private: + class StorageImpl : public Storage { + public: + uint32_t get(size_t id) const override { + assert(id < resolved_.size()); + return resolved_[id]; + } + + void set(std::vector<uint32_t> resolved) { + resolved_ = std::move(resolved); + } + + private: + std::vector<uint32_t> resolved_; + }; + + static uint32_t make_key(uint8_t r, uint8_t g, uint8_t b) { + return static_cast<uint32_t>(r) << 16 | + static_cast<uint32_t>(g) << 8 | b; + } + + shared_conn conn_; + xcb_colormap_t colormap_; + std::map<uint32_t, size_t> index_; + std::vector<xcb_alloc_color_cookie_t> cookie_; + std::vector<uint32_t> fallback_; + std::shared_ptr<StorageImpl> storage_; +}; + +} // namespace + +std::unique_ptr<Colors> Colors::create(shared_conn conn, + xcb_colormap_t colormap) { + return std::make_unique<ColorsImpl>(conn, colormap); +} + +} // namespace xcb + |
