cpp, simple wrappers for most of what we need, ivi_* still incomplete
[staging/windowmanager.git] / src / wayland.hpp
1 #ifndef WM_WAYLAND_HPP
2 #define WM_WAYLAND_HPP
3
4 #include "ivi-controller-client-protocol.h"
5
6 #include "util.h"
7
8 #include <functional>
9 #include <map>
10 #include <memory>
11
12 //                      _                 _
13 // __      ____ _ _   _| | __ _ _ __   __| |     _ __  _ __ _____  ___   _
14 // \ \ /\ / / _` | | | | |/ _` | '_ \ / _` |    | '_ \| '__/ _ \ \/ / | | |
15 //  \ V  V / (_| | |_| | | (_| | | | | (_| |    | |_) | | | (_) >  <| |_| |
16 //   \_/\_/ \__,_|\__, |_|\__,_|_| |_|\__,_|____| .__/|_|  \___/_/\_\\__, |
17 //                |___/                   |_____|_|                  |___/
18 template <typename ProxyT>
19 struct wayland_proxy {
20    ProxyT *proxy;
21
22    wayland_proxy(void *p) : proxy(static_cast<ProxyT *>(p)) {}
23
24    virtual ~wayland_proxy() {
25       // If this is the nullptr, then it means it already was destroyed by a
26       // custom wayland dtor
27       logdebug("%s %p @ %p", __func__, this, this->proxy);
28       if (proxy) {
29          wl_proxy_destroy(reinterpret_cast<wl_proxy *>(proxy));
30       }
31    }
32 };
33
34 //                                                                  _
35 //  _ __   __ _ _ __ ___   ___  ___ _ __   __ _  ___ ___  __      _| |
36 // | '_ \ / _` | '_ ` _ \ / _ \/ __| '_ \ / _` |/ __/ _ \ \ \ /\ / / |
37 // | | | | (_| | | | | | |  __/\__ \ |_) | (_| | (_|  __/  \ V  V /| |
38 // |_| |_|\__,_|_| |_| |_|\___||___/ .__/ \__,_|\___\___|   \_/\_/ |_|
39 //                                 |_|
40 namespace wl {
41 struct registry;
42
43 //      _ _           _
44 //   __| (_)___ _ __ | | __ _ _   _
45 //  / _` | / __| '_ \| |/ _` | | | |
46 // | (_| | \__ \ |_) | | (_| | |_| |
47 //  \__,_|_|___/ .__/|_|\__,_|\__, |
48 //             |_|            |___/
49 struct display {
50    std::unique_ptr<wl_display, void (*)(wl_display *)> d;
51    std::unique_ptr<registry> r;
52
53    display();
54    void roundtrip();
55 };
56
57 //                 _     _
58 //  _ __ ___  __ _(_)___| |_ _ __ _   _
59 // | '__/ _ \/ _` | / __| __| '__| | | |
60 // | | |  __/ (_| | \__ \ |_| |  | |_| |
61 // |_|  \___|\__, |_|___/\__|_|   \__, |
62 //           |___/                |___/
63 struct registry : public wayland_proxy<wl_registry> {
64    typedef std::function<void(wl_registry *, uint32_t, uint32_t)> binder;
65    std::map<std::string, binder> bindings;
66
67    registry(wl_display *d);
68    ~registry();
69
70    void add_global_handler(char const *iface, binder bind);
71
72    void event_global(uint32_t name, char const *iface, uint32_t v);
73    void event_global_remove(uint32_t name);
74
75    static void s_global(void *data, struct wl_registry *r, uint32_t name,
76                         char const *iface, uint32_t v);
77
78    static void s_global_remove(void *data, struct wl_registry *r,
79                                uint32_t name);
80
81    static constexpr wl_registry_listener listener = {s_global, s_global_remove};
82 };
83
84 //              _               _
85 //   ___  _   _| |_ _ __  _   _| |_
86 //  / _ \| | | | __| '_ \| | | | __|
87 // | (_) | |_| | |_| |_) | |_| | |_
88 //  \___/ \__,_|\__| .__/ \__,_|\__|
89 //                 |_|
90 struct output : wayland_proxy<wl_output> {
91    output(wl_registry *registry, uint32_t name, uint32_t version);
92
93    void event_geometry(int32_t x, int32_t y, int32_t pw, int32_t ph,
94                        int32_t subpel, char const *make, char const *model,
95                        int32_t tx);
96    void event_mode(uint32_t flags, int32_t w, int32_t h, int32_t r);
97    void event_done();
98    void event_scale(int32_t factor);
99
100    static void s_geometry(void *data, struct wl_output *wl_output, int32_t x,
101                           int32_t y, int32_t physical_width,
102                           int32_t physical_height, int32_t subpixel,
103                           const char *make, const char *model,
104                           int32_t transform);
105
106    static void s_mode(void *data, struct wl_output *wl_output, uint32_t flags,
107                       int32_t width, int32_t height, int32_t refresh);
108
109    static void s_done(void *data, struct wl_output *wl_output);
110
111    static void s_scale(void *data, struct wl_output *wl_output, int32_t factor);
112
113    static constexpr wl_output_listener listener = {s_geometry, s_mode, s_done,
114                                                    s_scale};
115 };
116 };
117
118 //  _ __   __ _ _ __ ___   ___  ___ _ __   __ _  ___ ___
119 // | '_ \ / _` | '_ ` _ \ / _ \/ __| '_ \ / _` |/ __/ _ \
120 // | | | | (_| | | | | | |  __/\__ \ |_) | (_| | (_|  __/
121 // |_| |_|\__,_|_| |_| |_|\___||___/ .__/ \__,_|\___\___|
122 //                                 |_|
123 //                   _       _
124 //   __ _  ___ _ __ (_)_   _(_)
125 //  / _` |/ _ \ '_ \| \ \ / / |
126 // | (_| |  __/ | | | |\ V /| |
127 //  \__, |\___|_| |_|_| \_/ |_|
128 //  |___/
129 namespace genivi {
130
131 //                  __
132 //  ___ _   _ _ __ / _| __ _  ___ ___
133 // / __| | | | '__| |_ / _` |/ __/ _ \
134 // \__ \ |_| | |  |  _| (_| | (_|  __/
135 // |___/\__,_|_|  |_|  \__,_|\___\___|
136 //
137 struct surface : public wayland_proxy<ivi_controller_surface> {
138    uint32_t id;
139
140    surface(uint32_t i, ivi_controller *c);
141    ~surface() override;
142
143    static constexpr ivi_controller_surface_listener listener = {};
144 };
145
146 //  _
147 // | | __ _ _   _  ___ _ __
148 // | |/ _` | | | |/ _ \ '__|
149 // | | (_| | |_| |  __/ |
150 // |_|\__,_|\__, |\___|_|
151 //          |___/
152 struct layer : public wayland_proxy<ivi_controller_layer> {
153    uint32_t id;
154
155    layer(uint32_t i, ivi_controller *c);
156    ~layer() override;
157
158    static constexpr ivi_controller_layer_listener listener = {};
159 };
160
161 //
162 // ___  ___ _ __ ___  ___ _ __
163 /// __|/ __| '__/ _ \/ _ \ '_ \
164 //\__ \ (__| | |  __/  __/ | | |
165 //|___/\___|_|  \___|\___|_| |_|
166 //
167 struct screen : public wayland_proxy<ivi_controller_screen> {
168    uint32_t id;
169
170    screen(uint32_t i, ivi_controller_screen *p);
171 };
172
173 //                  _             _ _
174 //   ___ ___  _ __ | |_ _ __ ___ | | | ___ _ __
175 //  / __/ _ \| '_ \| __| '__/ _ \| | |/ _ \ '__|
176 // | (_| (_) | | | | |_| | | (_) | | |  __/ |
177 //  \___\___/|_| |_|\__|_|  \___/|_|_|\___|_|
178 //
179 struct controller : public wayland_proxy<ivi_controller> {
180    std::map<uint32_t, std::unique_ptr<surface>> surfaces;
181    std::map<uint32_t, std::unique_ptr<layer>> layers;
182    std::map<uint32_t, std::unique_ptr<screen>> screens;
183
184    controller(wl_registry *r, uint32_t name, uint32_t version);
185    ~controller() override;
186
187    void event_screen(uint32_t id, ivi_controller_screen *screen);
188    void event_layer(uint32_t id);
189    void event_surface(uint32_t id);
190    void event_error(int32_t oid, int32_t otype, int32_t code, char const *text);
191
192    // thunks...
193    static void s_screen(void *data, struct ivi_controller *ivi_controller,
194                         uint32_t id_screen,
195                         struct ivi_controller_screen *screen);
196
197    static void s_layer(void *data, struct ivi_controller *ivi_controller,
198                        uint32_t id_layer);
199
200    static void s_surface(void *data, struct ivi_controller *ivi_controller,
201                          uint32_t id_surface);
202
203    static void s_error(void *data, struct ivi_controller *ivi_controller,
204                        int32_t object_id, int32_t object_type,
205                        int32_t error_code, const char *error_text);
206
207    static constexpr ivi_controller_listener listener = {s_screen, s_layer,
208                                                         s_surface, s_error};
209 };
210 }
211
212 #endif  // !WM_WAYLAND_HPP