main: set layer visibility in init_layout()
[staging/windowmanager.git] / src / main.cpp
1 #include "util.h"
2 #include "wayland.hpp"
3
4 #include <unistd.h>
5
6 #include <stdlib.h>
7
8 #include <sys/poll.h>
9
10 struct conn {
11    std::vector<std::unique_ptr<wl::output>> outputs;
12    std::unique_ptr<genivi::controller> c;
13 };
14
15 namespace {
16 //       _               _                            _        ____
17 //   ___| |__   ___  ___| | __    _____   _____ _ __ | |_ ___ / /\ \
18 //  / __| '_ \ / _ \/ __| |/ /   / _ \ \ / / _ \ '_ \| __/ __| |  | |
19 // | (__| | | |  __/ (__|   <   |  __/\ V /  __/ | | | |_\__ \ |  | |
20 //  \___|_| |_|\___|\___|_|\_\___\___| \_/ \___|_| |_|\__|___/ |  | |
21 //                          |_____|                           \_\/_/
22 int check_events(struct wl::display &d, struct conn &c, int fd) {
23    struct pollfd pfd[2] = {{.fd = d.get_fd(), .events = POLLIN, .revents = 0},
24                            {.fd = fd, .events = POLLIN, .revents = 0}};
25
26    d.flush();
27
28    if (poll(pfd, fd != -1 ? 2 : 1, -1) != -1 && errno != EINTR) {
29       int ret = 0;
30
31       if (pfd[0].revents & POLLIN) {
32          ret = d.dispatch();
33       }
34
35       if (ret == -1)
36          return ret;
37
38       if (fd != -1 && (pfd[1].revents & POLLIN)) {
39          char buf[256];
40
41          // read all there is ...
42          while (read(pfd[1].fd, buf, sizeof(buf)) == sizeof(buf))
43             ;
44
45          // Display current status
46          if (!c.c->surfaces.empty()) {
47             puts("Surfaces:");
48             for (auto const &i : c.c->surfaces) {
49                auto const &r = i.second->dst_rect;
50                auto const &s = i.second->size;
51                printf("%d [%ux%u] (%ux%u@%dx%d), ", i.first, s.w, s.h, r.w, r.h,
52                       r.x, r.y);
53             }
54             puts("\b\b ");
55          }
56
57          if (!c.c->layers.empty()) {
58             puts("Layers:");
59             for (auto const &i : c.c->layers) {
60                auto const &r = i.second->dst_rect;
61                auto const &s = i.second->size;
62                printf("%d [%ux%u] (%ux%u@%dx%d), ", i.first, s.w, s.h, r.w, r.h,
63                       r.x, r.y);
64             }
65             puts("\b\b ");
66          }
67       }
68    }
69
70    return 0;
71 }
72
73 //  _       _ _       _                         _    ____
74 // (_)_ __ (_) |_    | | __ _ _   _  ___  _   _| |_ / /\ \
75 // | | '_ \| | __|   | |/ _` | | | |/ _ \| | | | __| |  | |
76 // | | | | | | |_    | | (_| | |_| | (_) | |_| | |_| |  | |
77 // |_|_| |_|_|\__|___|_|\__,_|\__, |\___/ \__,_|\__| |  | |
78 //              |_____|       |___/                 \_\/_/
79 void init_layout(struct conn &c) {
80    auto &o = c.outputs.front();
81    auto &s = c.c->screens.begin()->second;
82    auto &layers = c.c->layers;
83
84    // XXX: Write output dimensions to ivi controller...
85    c.c->output_size = genivi::size{uint32_t(o->width), uint32_t(o->height)};
86
87    // Clear scene
88    layers.clear();
89
90    // Clear screen
91    s->clear();
92
93    // Setup our dummy scene...
94    c.c->layer_create(100, 0, 0);   // bottom layer, anything else
95    c.c->layer_create(1000, 0, 0);  // top layer, mandelbrot
96
97    auto &l100 = c.c->layers[100];
98    auto &l1k = c.c->layers[1000];
99
100    // Set layers fullscreen
101    l100->set_destination_rectangle(0, 0, o->width, o->height);
102    l1k->set_destination_rectangle(0, 0, o->width, o->height);
103    l100->set_visibility(1);
104    l1k->set_visibility(1);
105
106    // Add layers to screen
107    s->set_render_order({100, 1000});
108
109    c.c->commit_changes();
110    // Note: this does not flush the display!
111 }
112 }
113
114 //                  _        ____
115 //  _ __ ___   __ _(_)_ __  / /\ \
116 // | '_ ` _ \ / _` | | '_ \| |  | |
117 // | | | | | | (_| | | | | | |  | |
118 // |_| |_| |_|\__,_|_|_| |_| |  | |
119 //                          \_\/_/
120 int main(int argc, char **argv) {
121    lognotice("WinMan ver. %s", WINMAN_VERSION_STRING);
122
123    if (!getenv("XDG_RUNTIME_DIR"))
124       fatal("Environment variable XDG_RUNTIME_DIR not set");
125
126    struct wl::display d {};
127    if (!d.ok())
128       fatal("Could not connect to compositor");
129
130    struct conn c {};
131
132    d.r.add_global_handler(
133       "ivi_controller", [&c](wl_registry *r, uint32_t name, uint32_t v) {
134          c.c = std::make_unique<genivi::controller>(r, name, v);
135       });
136
137    d.r.add_global_handler(
138       "wl_output", [&c](wl_registry *r, uint32_t name, uint32_t v) {
139          c.outputs.emplace_back(std::make_unique<wl::output>(r, name, v));
140       });
141
142    // First level objects
143    d.roundtrip();
144    // Second level objects
145    d.roundtrip();
146    // Third level objects
147    d.roundtrip();
148
149    if (!c.c)
150       fatal("ivi_controller global not available");
151
152    if (c.outputs.empty())
153       fatal("no output was set up!");
154
155    init_layout(c);
156
157    while (check_events(d, c, STDIN_FILENO) != -1) {
158       c.c->execute_pending();
159       d.flush();
160    }
161
162    d.roundtrip();
163
164    return 0;
165 }