-// _ _ _ _
-// ___| | __ _ ___ ___ / \ _ __ _ __ (_)_ __ ___ _ __ | |
-// / __| |/ _` / __/ __| / _ \ | '_ \| '_ \ | | '_ ` _ \| '_ \| |
-// | (__| | (_| \__ \__ \ / ___ \| |_) | |_) | | | | | | | | |_) | |
-// \___|_|\__,_|___/___/ /_/ \_\ .__/| .__/ |_|_| |_| |_| .__/|_|
-// |_| |_| |_|
-App::App(wl::display *d)
- : api{this},
- chooks{this},
- display{d},
- controller{},
- outputs(),
- config(),
- layers(),
- id_alloc{},
- pending_events(false),
- policy{} {
- try {
- {
- auto l = load_layer_map(
- this->config.get_string("layers.json").value().c_str());
- if (l.is_ok()) {
- this->layers = l.unwrap();
- } else {
- logerror("%s", l.err().value());
- }
- }
- } catch (std::exception &e) {
- logerror("Loading of configuration failed: %s", e.what());
- }
-}
-
-int App::init() {
- if (!this->display->ok()) {
- return -1;
- }
-
- if (this->layers.mapping.empty()) {
- logerror("No surface -> layer mapping loaded");
- return -1;
- }
-
- this->display->add_global_handler(
- "wl_output", [this](wl_registry *r, uint32_t name, uint32_t v) {
- this->outputs.emplace_back(std::make_unique<wl::output>(r, name, v));
- });
-
- this->display->add_global_handler(
- "ivi_controller", [this](wl_registry *r, uint32_t name, uint32_t v) {
- this->controller =
- std::make_unique<struct genivi::controller>(r, name, v);
-
- // Init controller hooks
- this->controller->chooks = &this->chooks;
-
- // XXX: This protocol needs the output, so lets just add our mapping
- // here...
- this->controller->add_proxy_to_id_mapping(
- this->outputs.back()->proxy.get(),
- wl_proxy_get_id(reinterpret_cast<struct wl_proxy *>(
- this->outputs.back()->proxy.get())));
- });
-
- // First level objects
- this->display->roundtrip();
- // Second level objects
- this->display->roundtrip();
- // Third level objects
- this->display->roundtrip();
-
- return init_layers();
-}
-
-int App::dispatch_events() {
- if (this->dispatch_events() == 0) {
- return 0;
- }
-
- int ret = this->display->dispatch();
- if (ret == -1) {
- logerror("wl_display_dipatch() returned error %d",
- this->display->get_error());
- return -1;
- }
- this->display->flush();
-
- return 0;
-}
-
-int App::dispatch_pending_events() {
- if (this->pop_pending_events()) {
- this->display->dispatch_pending();
- return 0;
-}
- return -1;
-}
-
-bool App::pop_pending_events() {
- bool x{true};
- return this->pending_events.compare_exchange_strong(
- x, false, std::memory_order_consume);
-}
-
-void App::set_pending_events() {
- this->pending_events.store(true, std::memory_order_release);
-}
-
-optional<int> App::lookup_id(char const *name) {
- return this->id_alloc.lookup(std::string(name));
-}
-optional<std::string> App::lookup_name(int id) {
- return this->id_alloc.lookup(id);
-}
-
-// _ _ _ _ _ ____
-// (_)_ __ (_) |_ | | __ _ _ _ ___ _ _| |_ / /\ \
-// | | '_ \| | __| | |/ _` | | | |/ _ \| | | | __| | | |
-// | | | | | | |_ | | (_| | |_| | (_) | |_| | |_| | | |
-// |_|_| |_|_|\__|___|_|\__,_|\__, |\___/ \__,_|\__| | | |
-// |_____| |___/ \_\/_/
-int App::init_layers() {
- if (!this->controller) {
- logerror("ivi_controller global not available");
- return -1;
- }
-
- if (this->outputs.empty()) {
- logerror("no output was set up!");
- return -1;
- }
-
- auto &c = this->controller;
-
- auto &o = this->outputs.front();
- auto &s = c->screens.begin()->second;
- auto &layers = c->layers;
-
- // XXX: Write output dimensions to ivi controller...
- c->output_size = genivi::size{uint32_t(o->width), uint32_t(o->height)};
-
- // Clear scene
- layers.clear();
-
- // Clear screen
- s->clear();