diff options
-rw-r--r-- | layers.json | 2 | ||||
-rw-r--r-- | src/app.cpp | 24 | ||||
-rw-r--r-- | src/config.cpp | 5 | ||||
-rw-r--r-- | src/layers.cpp | 5 | ||||
-rw-r--r-- | src/layers.hpp | 3 | ||||
-rw-r--r-- | src/util.cpp | 27 | ||||
-rw-r--r-- | src/util.hpp | 18 |
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 |