9 std::vector<std::unique_ptr<wl::output>> outputs;
10 std::unique_ptr<genivi::controller> c;
14 // ___| |_ _ __ _ _ ___| |_ | _ \ ___ | | | ___ _ __
15 // / __| __| '__| | | |/ __| __| | |_) / _ \| | |/ _ \ '__|
16 // \__ \ |_| | | |_| | (__| |_ | __/ (_) | | | __/ |
17 // |___/\__|_| \__,_|\___|\__| |_| \___/|_|_|\___|_|
20 std::vector<std::function<int(int)>> handlers;
21 std::vector<struct pollfd> pfds;
24 void add_fd(int fd, std::function<int(int)> handler);
28 void Poller::add_fd(int fd, std::function<int(int)> handler) {
29 pfds.emplace_back(pollfd{ .fd = fd, .events = POLLIN, .revents = 0 });
30 handlers.emplace_back(std::move(handler));
33 int Poller::check_events() {
35 if ((ret = poll(this->pfds.data(), this->pfds.size(), -1)) != -1 && errno != EINTR) {
36 for (unsigned i = 0; i < pfds.size(); i++) {
37 if (pfds[i].revents & POLLIN) {
38 if (handlers[i](pfds[i].fd) == -1) {
42 pfds[i].events = POLLIN;
51 // (_)_ __ (_) |_ | | __ _ _ _ ___ _ _| |_ / /\ \
52 // | | '_ \| | __| | |/ _` | | | |/ _ \| | | | __| | | |
53 // | | | | | | |_ | | (_| | |_| | (_) | |_| | |_| | | |
54 // |_|_| |_|_|\__|___|_|\__,_|\__, |\___/ \__,_|\__| | | |
55 // |_____| |___/ \_\/_/
56 char const *init_layout(struct connection &c) {
58 return "ivi_controller global not available";
61 if (c.outputs.empty()) {
62 return "no output was set up!";
65 auto &o = c.outputs.front();
66 auto &s = c.c->screens.begin()->second;
67 auto &layers = c.c->layers;
69 // XXX: Write output dimensions to ivi controller...
70 c.c->output_size = genivi::size{uint32_t(o->width), uint32_t(o->height)};
78 // Setup our dummy scene...
79 c.c->layer_create(100, 0, 0); // bottom layer, anything else
80 c.c->layer_create(1000, 0, 0); // top layer, mandelbrot
82 auto &l100 = c.c->layers[100];
83 auto &l1k = c.c->layers[1000];
85 // Set layers fullscreen
86 l100->set_destination_rectangle(0, 0, o->width, o->height);
87 l1k->set_destination_rectangle(0, 0, o->width, o->height);
88 l100->set_visibility(1);
89 l1k->set_visibility(1);
91 // Add layers to screen
92 s->set_render_order({100, 1000});
94 c.c->commit_changes();
95 // Note: this does not flush the display!
102 // _ __ ___ __ _(_)_ __ / /\ \
103 // | '_ ` _ \ / _` | | '_ \| | | |
104 // | | | | | | (_| | | | | | | | |
105 // |_| |_| |_|\__,_|_|_| |_| | | |
107 int main(int /*argc*/, char ** /*argv*/) {
108 lognotice("WinMan ver. %s", WINMAN_VERSION_STRING);
110 if (getenv("XDG_RUNTIME_DIR") == nullptr) {
111 fatal("Environment variable XDG_RUNTIME_DIR not set");
114 struct wl::display d {};
116 fatal("Could not connect to compositor");
119 struct connection c {};
121 d.r.add_global_handler(
122 "wl_output", [&c](wl_registry *r, uint32_t name, uint32_t v) {
123 c.outputs.emplace_back(std::make_unique<wl::output>(r, name, v));
126 d.r.add_global_handler(
127 "ivi_controller", [&c](wl_registry *r, uint32_t name, uint32_t v) {
128 c.c = std::make_unique<genivi::controller>(r, name, v);
130 // XXX: This protocol needs the output, so lets just add our mapping here...
131 c.c->add_proxy_to_id_mapping(c.outputs.back()->proxy.get(),
133 reinterpret_cast<struct wl_proxy *>(
134 c.outputs.back()->proxy.get())));
137 // First level objects
139 // Second level objects
141 // Third level objects
144 if (char const *e = init_layout(c)) {
145 fatal("Could not init layout: %s", e);
149 p.add_fd(STDIN_FILENO, [&c](int fd) {
152 while ((ret = read(fd, &buf, sizeof(buf))) == sizeof(buf)) {
155 c.c->debug_dump_current_status();
156 return ret == 0 ? -1 : 0;
159 p.add_fd(d.get_fd(), [&d](int fd) {
163 while ((d.flush(), p.check_events()) != -1) {
164 c.c->execute_pending();