app: implement configured surface areas from ids.json
authorMarcus Fritzsch <marcus_fritzsch@mentor.com>
Tue, 1 Aug 2017 09:48:13 +0000 (11:48 +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>
ids.json
src/app.cpp
src/layers.cpp
src/layers.hpp

index 8914111..f7cdfe5 100644 (file)
--- a/ids.json
+++ b/ids.json
@@ -6,6 +6,7 @@
          "surface_id": "1000",
          "name": "HomeScreen",
          "layer_id": "1000",
+         "area": { "type": "full" },
          "comment": "Single layer map for the HomeScreen, XXX: type is redundant, could also check existence of id/first_id+last_id"
       },
       {
@@ -14,7 +15,8 @@
          "last_surface_id": "2999",
          "name": "apps",
          "layer_id": "1001",
-         "comment": "Range of IDs that will always be placed on layer 1001"
+         "area": { "type": "rect", "rect": { "x": "0", "y": "100", "width": "-1", "height": "-201" } },
+         "comment": "Range of IDs that will always be placed on layer 1001, negative rect values are interpreted as output_size.dimension - $value"
       },
       {
          "type": "range",
@@ -22,6 +24,7 @@
          "last_surface_id": "3999",
          "name": "popups",
          "layer_id": "9999",
+         "area": { "type": "rect", "rect": { "x": "0", "y": "100", "width": "-1", "height": "-201" } },
          "comment": "Range of IDs that will always be placed on the popup layer, that gets a very high 'dummy' id of 9999"
       }
    ],
index c9abd2d..5ddcb8c 100644 (file)
@@ -227,23 +227,29 @@ void App::surface_created(uint32_t surface_id) {
       logerror("Surface %d (0x%x) is not part of any layer!", surface_id,
                surface_id);
    } else {
+      auto rect = this->surface2layer.get_rect_for_surface(surface_id).value();
       this->controller->add_task(
          "fullscreen surface",
-         [layer_id, surface_id](struct genivi::controller *c) {
+         [layer_id, surface_id, rect](struct genivi::controller *c) {
             auto &s = c->surfaces[surface_id];
-            // s->set_destination_rectangle(0, 0, c->output_size.w, c->output_size.h);
-            // s->set_source_rectangle(0, 100, c->output_size.w, c->output_size.h - 200);
-            if (layer_id != 1000) {
-               // s->set_source_rectangle(0, 0, c->output_size.w, c->output_size.h - 200);
-               s->set_configuration(c->output_size.w, c->output_size.h - 200);
-               s->set_destination_rectangle(0, 100, c->output_size.w,
-                                            c->output_size.h - 200);
-            } else {
-               // s->set_source_rectangle(0, 0, c->output_size.w, c->output_size.h);
-               s->set_configuration(c->output_size.w, c->output_size.h);
-               s->set_destination_rectangle(0, 0, c->output_size.w,
-                                            c->output_size.h);
+
+            int x = rect.x;
+            int y = rect.y;
+            int w = rect.w;
+            int h = rect.h;
+
+            if (w < 0) {
+               w = c->output_size.w + 1 + w;
+            }
+            if (h < 0) {
+               h = c->output_size.h + 1 + h;
             }
+            logdebug("Computed rect={ %d, %d, %d, %d }", x,  y, w, h);
+
+            s->set_configuration(w, h);
+            s->set_source_rectangle(0, 0, w, h);
+            s->set_destination_rectangle(x, y, w, h);
+
             s->set_visibility(1);
             c->layers[layer_id]->add_surface(s.get());
             logdebug("Surface %u now on layer %u", surface_id,
index 5e7256e..013c16a 100644 (file)
@@ -13,7 +13,7 @@ namespace wm {
 using json = nlohmann::json;
 
 surface_id_to_layer::surface_id_to_layer(nlohmann::json const &j) {
-   // DB(j);
+   DB(j);
    if (j["type"] == "range") {
       this->id_min = get<int>(j["first_surface_id"]);
       this->id_max = get<int>(j["last_surface_id"]);
@@ -22,6 +22,16 @@ surface_id_to_layer::surface_id_to_layer(nlohmann::json const &j) {
    }
    this->name = j["name"].get<std::string>();
    this->layer_id = get<int>(j["layer_id"]);
+   this->rect = genivi::rect{-1, -1, 0, 0};
+   if (j["area"]["type"] == "rect") {
+      auto jr = j["area"]["rect"];
+      this->rect = genivi::rect{
+              get<int32_t>(jr["width"]),
+              get<int32_t>(jr["height"]),
+              get<int32_t>(jr["x"]),
+              get<int32_t>(jr["y"]),
+      };
+   }
 }
 
 struct result<struct surface_id_to_layer_map> to_surface_id_to_layer_map(
@@ -87,19 +97,31 @@ inline bool
    return a.id_max < b;
 }
 
-optional<int> surface_id_to_layer_map::get_layer_for_surface(int surface_id) {
-   auto i = std::lower_bound(std::cbegin(this->mapping),
-                             std::cend(this->mapping), surface_id);
+namespace {
+optional<surface_id_to_layer> get_surface_id_to_layer(struct surface_id_to_layer_map const *s2l, int surface_id) {
+   auto i = std::lower_bound(std::cbegin(s2l->mapping),
+                             std::cend(s2l->mapping), surface_id);
 
-   if (i != this->mapping.end()) {
+   if (i != s2l->mapping.end()) {
       // std::less only checks for surface_id_to_layer::id_max, so check
       // that we are actually inside of an interval here.
       if (i->id_min <= surface_id) {
-         return optional<int>(i->layer_id);
+         return optional<surface_id_to_layer>(*i);
       }
    }
 
    return nullopt;
 }
+}
+
+optional<int> surface_id_to_layer_map::get_layer_for_surface(int surface_id) {
+   auto e = get_surface_id_to_layer(this, surface_id);
+   return e ? optional<int>(e->layer_id) : nullopt;
+}
+
+optional<genivi::rect> surface_id_to_layer_map::get_rect_for_surface(int surface_id) {
+   auto e = get_surface_id_to_layer(this, surface_id);
+   return e ? optional<genivi::rect>(e->rect) : nullopt;
+}
 
 }  // namespace wm
index aed39c8..a827928 100644 (file)
@@ -9,6 +9,7 @@
 #include <set>
 #include <string>
 
+#include "wayland.hpp"
 #include "result.hpp"
 
 namespace wm {
@@ -18,6 +19,7 @@ struct surface_id_to_layer {
    int id_max = -1;
    std::string name = "";
    int layer_id = -1;
+   genivi::rect rect;
 
    explicit surface_id_to_layer(nlohmann::json const &j);
 
@@ -36,6 +38,7 @@ struct surface_id_to_layer_map {
    layers_type layers;
 
    optional<int> get_layer_for_surface(int surface_id);
+   optional<genivi::rect> get_rect_for_surface(int surface_id);
    layers_type::size_type get_layers_count() const {
       return this->layers.size();
    }