summaryrefslogtreecommitdiffstats
path: root/src/wayland.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wayland.hpp')
-rw-r--r--src/wayland.hpp212
1 files changed, 212 insertions, 0 deletions
diff --git a/src/wayland.hpp b/src/wayland.hpp
new file mode 100644
index 0000000..5cafd1a
--- /dev/null
+++ b/src/wayland.hpp
@@ -0,0 +1,212 @@
+#ifndef WM_WAYLAND_HPP
+#define WM_WAYLAND_HPP
+
+#include "ivi-controller-client-protocol.h"
+
+#include "util.h"
+
+#include <functional>
+#include <map>
+#include <memory>
+
+// _ _
+// __ ____ _ _ _| | __ _ _ __ __| | _ __ _ __ _____ ___ _
+// \ \ /\ / / _` | | | | |/ _` | '_ \ / _` | | '_ \| '__/ _ \ \/ / | | |
+// \ V V / (_| | |_| | | (_| | | | | (_| | | |_) | | | (_) > <| |_| |
+// \_/\_/ \__,_|\__, |_|\__,_|_| |_|\__,_|____| .__/|_| \___/_/\_\\__, |
+// |___/ |_____|_| |___/
+template <typename ProxyT>
+struct wayland_proxy {
+ ProxyT *proxy;
+
+ wayland_proxy(void *p) : proxy(static_cast<ProxyT *>(p)) {}
+
+ virtual ~wayland_proxy() {
+ // If this is the nullptr, then it means it already was destroyed by a
+ // custom wayland dtor
+ logdebug("%s %p @ %p", __func__, this, this->proxy);
+ if (proxy) {
+ wl_proxy_destroy(reinterpret_cast<wl_proxy *>(proxy));
+ }
+ }
+};
+
+// _
+// _ __ __ _ _ __ ___ ___ ___ _ __ __ _ ___ ___ __ _| |
+// | '_ \ / _` | '_ ` _ \ / _ \/ __| '_ \ / _` |/ __/ _ \ \ \ /\ / / |
+// | | | | (_| | | | | | | __/\__ \ |_) | (_| | (_| __/ \ V V /| |
+// |_| |_|\__,_|_| |_| |_|\___||___/ .__/ \__,_|\___\___| \_/\_/ |_|
+// |_|
+namespace wl {
+struct registry;
+
+// _ _ _
+// __| (_)___ _ __ | | __ _ _ _
+// / _` | / __| '_ \| |/ _` | | | |
+// | (_| | \__ \ |_) | | (_| | |_| |
+// \__,_|_|___/ .__/|_|\__,_|\__, |
+// |_| |___/
+struct display {
+ std::unique_ptr<wl_display, void (*)(wl_display *)> d;
+ std::unique_ptr<registry> r;
+
+ display();
+ void roundtrip();
+};
+
+// _ _
+// _ __ ___ __ _(_)___| |_ _ __ _ _
+// | '__/ _ \/ _` | / __| __| '__| | | |
+// | | | __/ (_| | \__ \ |_| | | |_| |
+// |_| \___|\__, |_|___/\__|_| \__, |
+// |___/ |___/
+struct registry : public wayland_proxy<wl_registry> {
+ typedef std::function<void(wl_registry *, uint32_t, uint32_t)> binder;
+ std::map<std::string, binder> bindings;
+
+ registry(wl_display *d);
+ ~registry();
+
+ void add_global_handler(char const *iface, binder bind);
+
+ void event_global(uint32_t name, char const *iface, uint32_t v);
+ void event_global_remove(uint32_t name);
+
+ static void s_global(void *data, struct wl_registry *r, uint32_t name,
+ char const *iface, uint32_t v);
+
+ static void s_global_remove(void *data, struct wl_registry *r,
+ uint32_t name);
+
+ static constexpr wl_registry_listener listener = {s_global, s_global_remove};
+};
+
+// _ _
+// ___ _ _| |_ _ __ _ _| |_
+// / _ \| | | | __| '_ \| | | | __|
+// | (_) | |_| | |_| |_) | |_| | |_
+// \___/ \__,_|\__| .__/ \__,_|\__|
+// |_|
+struct output : wayland_proxy<wl_output> {
+ output(wl_registry *registry, uint32_t name, uint32_t version);
+
+ void event_geometry(int32_t x, int32_t y, int32_t pw, int32_t ph,
+ int32_t subpel, char const *make, char const *model,
+ int32_t tx);
+ void event_mode(uint32_t flags, int32_t w, int32_t h, int32_t r);
+ void event_done();
+ void event_scale(int32_t factor);
+
+ static void s_geometry(void *data, struct wl_output *wl_output, int32_t x,
+ int32_t y, int32_t physical_width,
+ int32_t physical_height, int32_t subpixel,
+ const char *make, const char *model,
+ int32_t transform);
+
+ static void s_mode(void *data, struct wl_output *wl_output, uint32_t flags,
+ int32_t width, int32_t height, int32_t refresh);
+
+ static void s_done(void *data, struct wl_output *wl_output);
+
+ static void s_scale(void *data, struct wl_output *wl_output, int32_t factor);
+
+ static constexpr wl_output_listener listener = {s_geometry, s_mode, s_done,
+ s_scale};
+};
+};
+
+// _ __ __ _ _ __ ___ ___ ___ _ __ __ _ ___ ___
+// | '_ \ / _` | '_ ` _ \ / _ \/ __| '_ \ / _` |/ __/ _ \
+// | | | | (_| | | | | | | __/\__ \ |_) | (_| | (_| __/
+// |_| |_|\__,_|_| |_| |_|\___||___/ .__/ \__,_|\___\___|
+// |_|
+// _ _
+// __ _ ___ _ __ (_)_ _(_)
+// / _` |/ _ \ '_ \| \ \ / / |
+// | (_| | __/ | | | |\ V /| |
+// \__, |\___|_| |_|_| \_/ |_|
+// |___/
+namespace genivi {
+
+// __
+// ___ _ _ _ __ / _| __ _ ___ ___
+// / __| | | | '__| |_ / _` |/ __/ _ \
+// \__ \ |_| | | | _| (_| | (_| __/
+// |___/\__,_|_| |_| \__,_|\___\___|
+//
+struct surface : public wayland_proxy<ivi_controller_surface> {
+ uint32_t id;
+
+ surface(uint32_t i, ivi_controller *c);
+ ~surface() override;
+
+ static constexpr ivi_controller_surface_listener listener = {};
+};
+
+// _
+// | | __ _ _ _ ___ _ __
+// | |/ _` | | | |/ _ \ '__|
+// | | (_| | |_| | __/ |
+// |_|\__,_|\__, |\___|_|
+// |___/
+struct layer : public wayland_proxy<ivi_controller_layer> {
+ uint32_t id;
+
+ layer(uint32_t i, ivi_controller *c);
+ ~layer() override;
+
+ static constexpr ivi_controller_layer_listener listener = {};
+};
+
+//
+// ___ ___ _ __ ___ ___ _ __
+/// __|/ __| '__/ _ \/ _ \ '_ \
+//\__ \ (__| | | __/ __/ | | |
+//|___/\___|_| \___|\___|_| |_|
+//
+struct screen : public wayland_proxy<ivi_controller_screen> {
+ uint32_t id;
+
+ screen(uint32_t i, ivi_controller_screen *p);
+};
+
+// _ _ _
+// ___ ___ _ __ | |_ _ __ ___ | | | ___ _ __
+// / __/ _ \| '_ \| __| '__/ _ \| | |/ _ \ '__|
+// | (_| (_) | | | | |_| | | (_) | | | __/ |
+// \___\___/|_| |_|\__|_| \___/|_|_|\___|_|
+//
+struct controller : public wayland_proxy<ivi_controller> {
+ std::map<uint32_t, std::unique_ptr<surface>> surfaces;
+ std::map<uint32_t, std::unique_ptr<layer>> layers;
+ std::map<uint32_t, std::unique_ptr<screen>> screens;
+
+ controller(wl_registry *r, uint32_t name, uint32_t version);
+ ~controller() override;
+
+ void event_screen(uint32_t id, ivi_controller_screen *screen);
+ void event_layer(uint32_t id);
+ void event_surface(uint32_t id);
+ void event_error(int32_t oid, int32_t otype, int32_t code, char const *text);
+
+ // thunks...
+ static void s_screen(void *data, struct ivi_controller *ivi_controller,
+ uint32_t id_screen,
+ struct ivi_controller_screen *screen);
+
+ static void s_layer(void *data, struct ivi_controller *ivi_controller,
+ uint32_t id_layer);
+
+ static void s_surface(void *data, struct ivi_controller *ivi_controller,
+ uint32_t id_surface);
+
+ static void s_error(void *data, struct ivi_controller *ivi_controller,
+ int32_t object_id, int32_t object_type,
+ int32_t error_code, const char *error_text);
+
+ static constexpr ivi_controller_listener listener = {s_screen, s_layer,
+ s_surface, s_error};
+};
+}
+
+#endif // !WM_WAYLAND_HPP