Lomiri
DisplayConfigurationStorage.cpp
1/*
2 * Copyright (C) 2017 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "DisplayConfigurationStorage.h"
18
19#include <QFile>
20#include <QStandardPaths>
21#include <QJsonObject>
22#include <QJsonDocument>
23
24namespace {
25
26inline QString stringFromEdid(const miroil::Edid& edid)
27{
28 QString str;
29 str += QString::fromStdString(edid.vendor);
30 str += QString("%1%2").arg(edid.product_code).arg(edid.serial_number);
31
32 for (int i = 0; i < 4; i++) {
33 str += QString::fromStdString(edid.descriptors[i].string_value());
34 }
35 return str;
36}
37
38}
39
40DisplayConfigurationStorage::DisplayConfigurationStorage()
41{
42}
43
44void DisplayConfigurationStorage::save(const miroil::DisplayId &displayId, const miroil::DisplayConfigurationOptions &options)
45{
46 const QString dbPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QStringLiteral("/lomiri/");
47 QFile f(dbPath + stringFromEdid(displayId.edid) + ".edid");
48
49 QJsonObject json;
50 if (options.used.is_set()) json.insert("used", options.used.value());
51 if (options.clone_output_index.is_set()) json.insert("clone_output_index", static_cast<int>(options.clone_output_index.value()));
52 if (options.mode.is_set()) {
53 auto const& mode = options.mode.value();
54
55 QString sz(QString("%1x%2").arg(mode.size.width.as_int()).arg(mode.size.height.as_int()));
56 QJsonObject jsonMode({
57 {"size", sz},
58 {"refresh_rate", mode.refresh_rate }
59 });
60 json.insert("mode", jsonMode);
61 }
62 if (options.orientation.is_set()) json.insert("orientation", static_cast<int>(options.orientation.value()));
63 if (options.form_factor.is_set()) json.insert("form_factor", static_cast<int>(options.form_factor.value()));
64 if (options.scale.is_set()) json.insert("scale", options.scale.value());
65
66 if (f.open(QIODevice::WriteOnly)) {
67 QJsonDocument saveDoc(json);
68 f.write(saveDoc.toJson());
69 }
70}
71
72bool DisplayConfigurationStorage::load(const miroil::DisplayId &displayId, miroil::DisplayConfigurationOptions &options) const
73{
74 const QString dbPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QStringLiteral("/lomiri/");
75 QFile f(dbPath + stringFromEdid(displayId.edid) + ".edid");
76
77 if (f.open(QIODevice::ReadOnly)) {
78 QByteArray saveData = f.readAll();
79 QJsonDocument loadDoc(QJsonDocument::fromJson(saveData));
80
81 QJsonObject json(loadDoc.object());
82 if (json.contains("used")) options.used = json["used"].toBool();
83 if (json.contains("clone_output_index")) options.clone_output_index = json["clone_output_index"].toInt();
84 if (json.contains("mode")) {
85 QJsonObject jsonMode = json["mode"].toObject();
86
87 if (jsonMode.contains("size") && jsonMode.contains("refresh_rate")) {
88 QString sz(jsonMode["size"].toString());
89#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
90 QStringList geo = sz.split("x", Qt::SkipEmptyParts);
91#else
92 QStringList geo = sz.split("x", QString::SkipEmptyParts);
93#endif
94 if (geo.count() == 2) {
95 miroil::DisplayConfigurationOptions::DisplayMode mode;
96 mode.size = mir::geometry::Size(geo[0].toInt(), geo[1].toInt());
97 mode.refresh_rate = jsonMode["refresh_rate"].toDouble();
98 options.mode = mode;
99 }
100 }
101 }
102 if (json.contains("orientation")) options.orientation = static_cast<MirOrientation>(json["orientation"].toInt());
103 if (json.contains("form_factor")) options.form_factor = static_cast<MirFormFactor>(json["form_factor"].toInt());
104 if (json.contains("scale")) options.scale = json["form_factor"].toDouble();
105
106 return true;
107 }
108
109 return false;
110}