cpp, more listeners
[staging/windowmanager.git] / src / main.cpp
1 #include "util.h"
2
3 #include "ivi-controller-client-protocol.h"
4
5 #include <stdlib.h>
6 #include <string.h>
7
8 #include <wayland-client.h>
9
10 #include <map>
11 #include <memory>
12 #include <string>
13 #include <vector>
14
15 struct ivi_surface;
16 struct ivi_layer;
17
18 struct conn {
19    wl_display *d;
20    wl_registry *r;
21    ivi_controller *c;
22    std::vector<std::unique_ptr<wl_output, void (*)(wl_output *)>> outputs;
23    std::map<uint32_t, std::unique_ptr<ivi_layer>> layers;
24    std::map<uint32_t, std::unique_ptr<ivi_surface>> surfaces;
25
26    ~conn();
27 };
28
29 struct ivi_surface {
30    ivi_controller_surface *controller;
31    uint32_t id;
32    conn *con;
33    ivi_surface(ivi_controller_surface *c, uint32_t i, conn *co)
34       : controller(c), id(i), con(co) {}
35    ~ivi_surface() { ivi_controller_surface_destroy(this->controller, 1); }
36 };
37
38 struct ivi_layer {
39    ivi_controller_layer *controller;
40    uint32_t id;
41    conn *con;
42    ivi_layer(ivi_controller_layer *c, uint32_t i, conn *co)
43       : controller(c), id(i), con(co) {}
44    ~ivi_layer() { ivi_controller_layer_destroy(this->controller, 1); }
45 };
46
47 conn::~conn() {
48    this->layers.clear();
49    this->surfaces.clear();
50    ivi_controller_destroy(this->c);
51    this->outputs.clear();
52    wl_registry_destroy(this->r);
53    wl_display_disconnect(this->d);
54 }
55
56 static ivi_controller_surface_listener cs_listener = {};
57
58 static ivi_controller_layer_listener cl_listener = {};
59
60 static void c_screen(void *data, struct ivi_controller *ivi_controller,
61                      uint32_t id_screen, struct ivi_controller_screen *screen) {
62    lognotice("ivi_controller @ %p screen %u (%x) @ %p", ivi_controller,
63              id_screen, id_screen, screen);
64 }
65
66 static void c_layer(void *data, struct ivi_controller *ivi_controller,
67                     uint32_t id_layer) {
68    lognotice("ivi_controller @ %p layer %u (%x)", ivi_controller, id_layer,
69              id_layer);
70    auto c = static_cast<conn *>(data);
71    auto i = std::make_unique<ivi_layer>(
72       ivi_controller_layer_create(c->c, id_layer, 0, 0), id_layer, c);
73    ivi_controller_layer_add_listener(i->controller, &cl_listener, i.get());
74    c->layers[id_layer] = std::move(i);
75 }
76
77 static void c_surface(void *data, struct ivi_controller *ivi_controller,
78                       uint32_t id_surface) {
79    lognotice("ivi_controller @ %p surface %u (%x)", ivi_controller, id_surface,
80              id_surface);
81    auto c = static_cast<conn *>(data);
82    auto i = std::make_unique<ivi_surface>(
83       ivi_controller_surface_create(c->c, id_surface), id_surface, c);
84    ivi_controller_surface_add_listener(i->controller, &cs_listener, i.get());
85    c->surfaces[id_surface] = std::move(i);
86 }
87
88 static void c_error(void *data, struct ivi_controller *ivi_controller,
89                     int32_t object_id, int32_t object_type, int32_t error_code,
90                     const char *error_text) {
91    lognotice("ivi_controller @ %p error o %i t %i c %i text %s", ivi_controller,
92              object_id, object_type, error_code, error_text);
93 }
94
95 static struct ivi_controller_listener c_listener = {c_screen, c_layer,
96                                                     c_surface, c_error};
97
98 static void o_geometry(void *data, struct wl_output *wl_output, int32_t x,
99                        int32_t y, int32_t physical_width,
100                        int32_t physical_height, int32_t subpixel,
101                        const char *make, const char *model, int32_t transform) {
102    lognotice("output @ %p x %i y %i w %i h %i spel %x make %s model %s tx %i",
103              wl_output, x, y, physical_width, physical_height, subpixel, make,
104              model, transform);
105 }
106
107 static void o_mode(void *data, struct wl_output *wl_output, uint32_t flags,
108                    int32_t width, int32_t height, int32_t refresh) {
109    lognotice("output @ %p mode f %x w %i h %i r %i", wl_output, flags, width,
110              height, refresh);
111 }
112
113 static void o_done(void *data, struct wl_output *wl_output) {
114    lognotice("output @ %p done");
115 }
116
117 static void o_scale(void *data, struct wl_output *wl_output, int32_t factor) {
118    lognotice("output @ %p scale %i", wl_output, factor);
119 }
120
121 static struct wl_output_listener o_listener = {o_geometry, o_mode, o_done,
122                                                o_scale};
123
124 static void r_global(void *data, struct wl_registry *r, uint32_t name,
125                      char const *iface, uint32_t v) {
126    struct conn *c = static_cast<conn *>(data);
127
128    if (strcmp(iface, "ivi_controller") == 0) {
129       c->c = static_cast<ivi_controller *>(
130          wl_registry_bind(r, name, &ivi_controller_interface, v));
131       ivi_controller_add_listener(c->c, &c_listener, c);
132    } else if (strcmp(iface, "wl_output") == 0) {
133       auto o = static_cast<wl_output *>(
134          wl_registry_bind(r, name, &wl_output_interface, v));
135       c->outputs.emplace_back(std::unique_ptr<wl_output, void (*)(wl_output *)>(
136          o, wl_output_destroy));
137       wl_output_add_listener(o, &o_listener, c);
138    } else {
139       lognotice("registry @ %p global n %u i %s v %u", r, name, iface, v);
140    }
141 }
142
143 static void r_global_remove(void *data, struct wl_registry *r, uint32_t name) {}
144
145 static struct wl_registry_listener r_listener = {r_global, r_global_remove};
146
147 int main(int argc, char **argv) {
148    lognotice("WinMan ver. %s", WINMAN_VERSION_STRING);
149
150    if (!getenv("XDG_RUNTIME_DIR"))
151       fatal("Environment variable XDG_RUNTIME_DIR not set");
152
153    struct conn c = {};
154
155    c.d = wl_display_connect(NULL);
156    if (!c.d)
157       fatal("Could not connect to compositor");
158    c.r = wl_display_get_registry(c.d);
159    wl_registry_add_listener(c.r, &r_listener, &c);
160
161    // First level objects
162    wl_display_roundtrip(c.d);
163    // Second level objects
164    wl_display_roundtrip(c.d);
165
166    if (!c.c)
167       fatal("ivi_controller global not available");
168
169    // main loop
170
171    return 0;
172 }