8 #include <sys/signalfd.h>
13 std::vector<std::unique_ptr<wl::output>> outputs;
14 std::unique_ptr<genivi::controller> c;
18 // ___| |_ _ __ _ _ ___| |_ | _ \ ___ | | | ___ _ __
19 // / __| __| '__| | | |/ __| __| | |_) / _ \| | |/ _ \ '__|
20 // \__ \ |_| | | |_| | (__| |_ | __/ (_) | | | __/ |
21 // |___/\__|_| \__,_|\___|\__| |_| \___/|_|_|\___|_|
24 std::vector<std::function<int(int)>> handlers;
25 std::vector<struct pollfd> pfds;
28 void add_fd(int fd, std::function<int(int)> handler);
32 void Poller::add_fd(int fd, std::function<int(int)> handler) {
33 pfds.emplace_back(pollfd{.fd = fd, .events = POLLIN, .revents = 0});
34 handlers.emplace_back(std::move(handler));
37 int Poller::check_events() {
39 if ((ret = poll(this->pfds.data(), this->pfds.size(), -1)) != -1 &&
41 for (unsigned i = 0; i < pfds.size(); i++) {
42 if (pfds[i].revents & POLLIN) {
43 if (handlers[i](pfds[i].fd) == -1) {
47 pfds[i].events = POLLIN;
56 unique_fd() = default;
57 explicit unique_fd(int f) : fd{f} {}
58 operator int() const { return fd; }
63 unique_fd(unique_fd const &) = delete;
64 unique_fd &operator=(unique_fd const &) = delete;
65 unique_fd(unique_fd &&o) : fd(o.fd) { o.fd = -1; }
66 unique_fd &operator=(unique_fd &&o) {
67 std::swap(this->fd, o.fd);
75 // (_)_ __ (_) |_ | | __ _ _ _ ___ _ _| |_ / /\ \
76 // | | '_ \| | __| | |/ _` | | | |/ _ \| | | | __| | | |
77 // | | | | | | |_ | | (_| | |_| | (_) | |_| | |_| | | |
78 // |_|_| |_|_|\__|___|_|\__,_|\__, |\___/ \__,_|\__| | | |
79 // |_____| |___/ \_\/_/
80 char const *init_layout(struct connection &c) {
82 return "ivi_controller global not available";
85 if (c.outputs.empty()) {
86 return "no output was set up!";
89 auto &o = c.outputs.front();
90 auto &s = c.c->screens.begin()->second;
91 auto &layers = c.c->layers;
93 // XXX: Write output dimensions to ivi controller...
94 c.c->output_size = genivi::size{uint32_t(o->width), uint32_t(o->height)};
102 // Setup our dummy scene...
103 c.c->layer_create(100, 0, 0); // bottom layer, anything else
104 c.c->layer_create(1000, 0, 0); // top layer, mandelbrot
106 auto &l100 = c.c->layers[100];
107 auto &l1k = c.c->layers[1000];
109 // Set layers fullscreen
110 l100->set_destination_rectangle(0, 0, o->width, o->height);
111 l1k->set_destination_rectangle(0, 0, o->width, o->height);
112 l100->set_visibility(1);
113 l1k->set_visibility(1);
115 // Add layers to screen
116 s->set_render_order({100, 1000});
118 c.c->commit_changes();
119 // Note: this does not flush the display!
126 // _ __ ___ __ _(_)_ __ / /\ \
127 // | '_ ` _ \ / _` | | '_ \| | | |
128 // | | | | | | (_| | | | | | | | |
129 // |_| |_| |_|\__,_|_|_| |_| | | |
131 int main(int /*argc*/, char ** /*argv*/) {
132 lognotice("WinMan ver. %s", WINMAN_VERSION_STRING);
134 if (getenv("XDG_RUNTIME_DIR") == nullptr) {
135 fatal("Environment variable XDG_RUNTIME_DIR not set");
138 struct wl::display d {};
140 fatal("Could not connect to compositor");
143 struct connection c {};
145 d.r.add_global_handler(
146 "wl_output", [&c](wl_registry *r, uint32_t name, uint32_t v) {
147 c.outputs.emplace_back(std::make_unique<wl::output>(r, name, v));
150 d.r.add_global_handler(
151 "ivi_controller", [&c](wl_registry *r, uint32_t name, uint32_t v) {
152 c.c = std::make_unique<genivi::controller>(r, name, v);
154 // XXX: This protocol needs the output, so lets just add our mapping here...
155 c.c->add_proxy_to_id_mapping(c.outputs.back()->proxy.get(),
157 reinterpret_cast<struct wl_proxy *>(
158 c.outputs.back()->proxy.get())));
161 // First level objects
163 // Second level objects
165 // Third level objects
168 if (char const *e = init_layout(c)) {
169 fatal("Could not init layout: %s", e);
173 p.add_fd(STDIN_FILENO, [&c](int fd) {
176 ret = read(fd, &buf, sizeof(buf));
177 c.c->debug_dump_current_status();
178 return ret == 0 ? -1 : 0;
181 p.add_fd(d.get_fd(), [&d](int fd) {
187 sigaddset(&sset, SIGINT);
188 sigaddset(&sset, SIGTERM);
190 auto sfd = unique_fd(signalfd(-1, &sset, SFD_NONBLOCK | SFD_CLOEXEC));
191 sigprocmask(SIG_BLOCK, &sset, NULL);
192 p.add_fd(sfd.fd, [](int fd) {
193 struct signalfd_siginfo si;
194 while (read(fd, &si, sizeof(si)) == sizeof(si)) {
195 lognotice("Received signal %u", si.ssi_signo);
200 while ((d.flush(), p.check_events()) != -1) {
201 c.c->execute_pending();
204 c.c->commit_changes();