summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--layers.json2
-rw-r--r--src/app.cpp24
-rw-r--r--src/config.cpp5
-rw-r--r--src/layers.cpp5
-rw-r--r--src/layers.hpp3
-rw-r--r--src/util.cpp27
-rw-r--r--src/util.hpp18
7 files changed, 79 insertions, 5 deletions
diff --git a/layers.json b/layers.json
index cf7ed34..230da55 100644
--- a/layers.json
+++ b/layers.json
@@ -3,6 +3,8 @@
"main_surface": {
"surface_role": "HomeScreen",
+ "width": 1080,
+ "height": 1920,
"comment": "This surface should never be made invisible (The HomeScreen)"
},
diff --git a/src/app.cpp b/src/app.cpp
index e9d79f5..575ab85 100644
--- a/src/app.cpp
+++ b/src/app.cpp
@@ -58,7 +58,6 @@ const char kKeyHeightPixel[] = "height_pixel";
const char kKeyWidthMm[] = "width_mm";
const char kKeyHeightMm[] = "height_mm";
-
namespace {
using nlohmann::json;
@@ -114,6 +113,10 @@ App::App(wl::display *d)
} else {
HMI_ERROR("wm", "%s", l.err().value());
}
+
+ if (this->config.get_string("scaling_ignore_aspect")) {
+ this->layers.scaling_keep_aspect =false;
+ }
}
} catch (std::exception &e) {
HMI_ERROR("wm", "Loading of configuration failed: %s", e.what());
@@ -237,11 +240,22 @@ int App::init_layers() {
// Clear screen
s->clear();
+ int width = this->layers.main_surface_width;
+ int height = this->layers.main_surface_height;
+
+ rectangle rect(width, height); // 1080x1920 by default
+ rect.scale(o->width, o->height, this->layers.scaling_keep_aspect);
+ rect.center(o->width, o->height);
+
+ HMI_DEBUG("wm", "Main surface (0,0),%dx%d to (%d,%d),%dx%d",
+ width, height, rect.left(), rect.top(), rect.width(), rect.height());
+
// Quick and dirty setup of layers
for (auto const &i : this->layers.mapping) {
- c->layer_create(i.second.layer_id, o->width, o->height);
+ c->layer_create(i.second.layer_id, rect.width(), rect.height());
auto &l = layers[i.second.layer_id];
- l->set_destination_rectangle(0, 0, o->width, o->height);
+ l->set_source_rectangle(0, 0, width, height);
+ l->set_destination_rectangle(rect.left(), rect.top(), rect.width(), rect.height());
l->set_visibility(1);
HMI_DEBUG("wm", "Setting up layer %s (%d) for surface role match \"%s\"",
i.second.name.c_str(), i.second.layer_id, i.second.role.c_str());
@@ -282,10 +296,10 @@ void App::surface_set_layout(int surface_id, optional<int> sub_surface_id) {
// less-than-0 values refer to MAX + 1 - $VALUE
// e.g. MAX is either screen width or height
if (w < 0) {
- w = this->controller->output_size.w + 1 + w;
+ w = this->layers.main_surface_width + 1 + w;
}
if (h < 0) {
- h = this->controller->output_size.h + 1 + h;
+ h = this->layers.main_surface_height + 1 + h;
}
if (sub_surface_id) {
diff --git a/src/config.cpp b/src/config.cpp
index c7e4ddb..cee9e91 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -29,6 +29,11 @@ config::config() : cfg() {
else {
this->cfg["layers.json"] = std::string(path_layers_json) + std::string("/etc/layers.json");
}
+
+ const char *ignore_aspect = getenv("HMI_SCALING_IGNORE_ASPECT");
+ if (ignore_aspect) {
+ this->cfg["scaling_ignore_aspect"] = std::string(ignore_aspect);
+ }
}
} // namespace wm
diff --git a/src/layers.cpp b/src/layers.cpp
index 04f944d..8698e83 100644
--- a/src/layers.cpp
+++ b/src/layers.cpp
@@ -24,6 +24,9 @@
namespace wm {
+const int default_main_width = 1080;
+const int default_main_height = 1920;
+
using json = nlohmann::json;
layer::layer(nlohmann::json const &j) {
@@ -104,6 +107,8 @@ struct result<struct layer_map> to_layer_map(nlohmann::json const &j) {
auto msi = j.find("main_surface");
if (msi != j.end()) {
stl.main_surface_name = msi->value("surface_role", "");
+ stl.main_surface_width = msi->value("width", default_main_width);
+ stl.main_surface_height = msi->value("height", default_main_height);
stl.main_surface = -1;
}
diff --git a/src/layers.hpp b/src/layers.hpp
index 1942229..fd0072b 100644
--- a/src/layers.hpp
+++ b/src/layers.hpp
@@ -77,6 +77,9 @@ struct layer_map {
layers_type layers; // the actual layer IDs we have
int main_surface;
std::string main_surface_name;
+ int main_surface_width;
+ int main_surface_height;
+ bool scaling_keep_aspect = true;
role_to_layer_map roles;
addsurf_layer_map surfaces; // additional surfaces on layers
diff --git a/src/util.cpp b/src/util.cpp
index 2ae856f..1fb6ac8 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -37,3 +37,30 @@ unique_fd::~unique_fd() {
close(this->fd);
}
}
+
+void rectangle::scale(int to_w, int to_h, bool keep_aspect)
+{
+ if (!keep_aspect) {
+ w = to_w;
+ h = to_h;
+ return;
+ }
+
+ int64_t resized_w = int64_t(to_h) * int64_t(w) / int64_t(h);
+
+ if (resized_w <= to_w) {
+ /* use aspect by height */
+ w = resized_w;
+ h = to_h;
+ } else {
+ /* use aspect by width */
+ w = to_h;
+ h = int64_t(to_w) * int64_t(h) / int64_t(w);
+ }
+}
+
+void rectangle::center(int outer_w, int outer_h)
+{
+ x = (outer_w - w) / 2;
+ y = (outer_h - h) / 2;
+}
diff --git a/src/util.hpp b/src/util.hpp
index f4e6e5f..6c6d0b9 100644
--- a/src/util.hpp
+++ b/src/util.hpp
@@ -103,4 +103,22 @@ struct unique_fd {
}
};
+class rectangle
+{
+public:
+ explicit rectangle(int wd, int ht) : w(wd), h(ht) {};
+ void scale(int to_w, int to_h, bool keep_aspect);
+ void center(int outer_w, int outer_h);
+ int left() { return x; };
+ int top() { return y; };
+ int width() { return w; };
+ int height() { return h; };
+
+private:
+ int x = 0;
+ int y = 0;
+ int w;
+ int h;
+};
+
#endif // !WM_UTIL_HPP