main: reorganize and simplify
authorMarcus Fritzsch <marcus_fritzsch@mentor.com>
Thu, 6 Jul 2017 07:16:01 +0000 (09:16 +0200)
committerMarcus Fritzsch <marcus_fritzsch@mentor.com>
Tue, 8 Aug 2017 15:24:00 +0000 (17:24 +0200)
Signed-off-by: Marcus Fritzsch <marcus_fritzsch@mentor.com>
src/main.cpp

index f5d33c7..03aa202 100644 (file)
@@ -13,24 +13,53 @@ extern "C" {
 
 #include <json.hpp>
 
-using json = nlohmann::json;
-
 namespace {
 struct wayland {
    std::unique_ptr<wl::display> display;
    std::unique_ptr<genivi::controller> controller;
    std::vector<std::unique_ptr<wl::output>> outputs;
-   sd_event_source *event_source;
 
-   wayland()
-      : display(new wl::display),
-        controller(nullptr),
-        outputs(),
-        event_source{} {}
+   wayland() : display(new wl::display), controller(nullptr), outputs() {}
+
+   int init();
 };
 
 struct wayland *g_wayland;
 
+int wayland::init() {
+   if (!this->display->ok()) {
+      return -1;
+   }
+
+   this->display->r.add_global_handler("wl_output", [](wl_registry *r,
+                                                       uint32_t name,
+                                                       uint32_t v) {
+      g_wayland->outputs.emplace_back(std::make_unique<wl::output>(r, name, v));
+   });
+
+   this->display->r.add_global_handler(
+      "ivi_controller", [](wl_registry *r, uint32_t name, uint32_t v) {
+         g_wayland->controller =
+            std::make_unique<genivi::controller>(r, name, v);
+
+         // XXX: This protocol needs the output, so lets just add our mapping
+         // here...
+         g_wayland->controller->add_proxy_to_id_mapping(
+            g_wayland->outputs.back()->proxy.get(),
+            wl_proxy_get_id(reinterpret_cast<struct wl_proxy *>(
+               g_wayland->outputs.back()->proxy.get())));
+      });
+
+   // First level objects
+   this->display->roundtrip();
+   // Second level objects
+   this->display->roundtrip();
+   // Third level objects
+   this->display->roundtrip();
+
+   return 0;
+}
+
 //  _       _ _       _                         _    ____
 // (_)_ __ (_) |_    | | __ _ _   _  ___  _   _| |_ / /\ \
 // | | '_ \| | __|   | |/ _` | | | |/ _ \| | | | __| |  | |
@@ -84,6 +113,36 @@ char const *init_layout() {
    return nullptr;
 }
 
+int display_event_callback(sd_event_source *evs, int fd, uint32_t events,
+                           void *data) {
+   if ((events & EPOLLHUP) != 0) {
+      AFB_ERROR("The compositor hung up, dying now.");
+      delete g_wayland;
+      g_wayland = nullptr;
+      goto error;
+   }
+
+   if (events & EPOLLIN) {
+      int ret = g_wayland->display->dispatch();
+      if (ret == -1) {
+         AFB_ERROR("wl_display_dipatch() returned error %d",
+                   g_wayland->display->get_error());
+         goto error;
+      }
+      g_wayland->display->flush();
+
+      // execute pending tasks, that is layout changes etc.
+      g_wayland->controller->execute_pending();
+      g_wayland->display->roundtrip();
+   }
+
+   return 0;
+
+error:
+   sd_event_source_unref(evs);
+   return -1;
+}
+
 //  _     _           _ _                 _       _ _    ____
 // | |__ (_)_ __   __| (_)_ __   __ _    (_)_ __ (_) |_ / /\ \
 // | '_ \| | '_ \ / _` | | '_ \ / _` |   | | '_ \| | __| |  | |
@@ -104,66 +163,20 @@ int binding_init_() {
    }
 
    g_wayland = new wayland;
-   if (!g_wayland->display->ok()) {
+   if (g_wayland->init() == -1) {
       AFB_ERROR("Could not connect to compositor");
+      delete g_wayland;
       return -1;
    }
 
-   auto &d = g_wayland->display;
-   d->r.add_global_handler("wl_output", [](wl_registry *r, uint32_t name,
-                                           uint32_t v) {
-      g_wayland->outputs.emplace_back(std::make_unique<wl::output>(r, name, v));
-   });
-
-   d->r.add_global_handler("ivi_controller", [](wl_registry *r, uint32_t name,
-                                                uint32_t v) {
-      g_wayland->controller = std::make_unique<genivi::controller>(r, name, v);
-
-      // XXX: This protocol needs the output, so lets just add our mapping
-      // here...
-      g_wayland->controller->add_proxy_to_id_mapping(
-         g_wayland->outputs.back()->proxy.get(),
-         wl_proxy_get_id(reinterpret_cast<struct wl_proxy *>(
-            g_wayland->outputs.back()->proxy.get())));
-   });
-
-   // First level objects
-   d->roundtrip();
-   // Second level objects
-   d->roundtrip();
-   // Third level objects
-   d->roundtrip();
-
    if (char const *e = init_layout()) {
       AFB_ERROR("Could not init layout: %s", e);
       return -1;
    }
 
-   sd_event *ev = afb_daemon_get_event_loop();
-   sd_event_add_io(
-      ev, &g_wayland->event_source, g_wayland->display->get_fd(),
-      EPOLLIN | EPOLLHUP,
-      [](sd_event_source *evs, int fd, uint32_t events, void *data) {
-         if ((events & EPOLLHUP) != 0) {
-            sd_event_source_unref(evs);
-            delete g_wayland;
-            g_wayland = nullptr;
-            return 1;
-         }
-
-         if (events & EPOLLIN) {
-            int ret = g_wayland->display->dispatch();
-            g_wayland->display->flush();
-
-            // execute pending tasks, that is layout changes etc.
-            g_wayland->controller->execute_pending();
-            g_wayland->display->roundtrip();
-            return ret == -1 ? -1 : 0;
-         }
-
-         return 0;
-      },
-      g_wayland);
+   sd_event_add_io(afb_daemon_get_event_loop(), nullptr,
+                   g_wayland->display->get_fd(), EPOLLIN,
+                   display_event_callback, g_wayland);
 
    atexit([] { delete g_wayland; });
 
@@ -201,30 +214,32 @@ void debug_status(struct afb_req req) noexcept {
    CHECK_WAYLAND();
 
    try {
+      using json = nlohmann::json;
+
       json j;
 
       if (!g_wayland->controller->surfaces.empty()) {
-         auto js = json::array();
+         auto a = json::array();
          for (auto const &i : g_wayland->controller->surfaces) {
             auto const &r = i.second->dst_rect;
             auto const &s = i.second->size;
-            js.push_back({{"id", i.first},
-                          {"size", {s.w, s.h}},
-                          {"dst_rect", {r.w, r.h, r.x, r.y}}});
+            a.push_back({{"id", i.first},
+                         {"size", {s.w, s.h}},
+                         {"dst_rect", {r.w, r.h, r.x, r.y}}});
          }
-         j["surfaces"] = js;
+         j["surfaces"] = a;
       }
 
       if (!g_wayland->controller->layers.empty()) {
-         auto js = json::array();
+         auto a = json::array();
          for (auto const &i : g_wayland->controller->layers) {
             auto const &r = i.second->dst_rect;
             auto const &s = i.second->size;
-            js.push_back({{"id", i.first},
+            a.push_back({{"id", i.first},
                           {"size", {s.w, s.h}},
                           {"dst_rect", {r.w, r.h, r.x, r.y}}});
          }
-         j["layers"] = js;
+         j["layers"] = a;
       }
 
       afb_req_success(req, json_tokener_parse(j.dump().c_str()), "status");