diff options
author | Sean Rhodes <sean@starlabs.systems> | 2021-11-12 08:54:50 +0000 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2022-01-27 16:16:23 +0000 |
commit | 9c89e3ada2dd30d683c44364e8eea5de757b74eb (patch) | |
tree | 30e29cf5094559f82589dd7583aeac89c5a95592 /util/coreboot-configurator/src | |
parent | aef6de34263694a62f42135be1a97075ec3a2b7a (diff) |
util: Add coreboot-configurator
A simple GUI to change settings in coreboot's CBFS, via the nvramtool utility.
Test on the StarBook Mk IV running coreboot 4.15 with:
* Ubuntu 20.04
* Ubuntu 21.10
* MX Linux 21
* elementary OS 6
* Manjaro 21
Signed-off-by: Sean Rhodes <sean@starlabs.systems>
Change-Id: I491922bf55ed87c2339897099634a38f8d055876
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59256
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Martin Roth <martinroth@google.com>
Diffstat (limited to 'util/coreboot-configurator/src')
29 files changed, 2633 insertions, 0 deletions
diff --git a/util/coreboot-configurator/src/README.md b/util/coreboot-configurator/src/README.md new file mode 100644 index 0000000000..e3386242a2 --- /dev/null +++ b/util/coreboot-configurator/src/README.md @@ -0,0 +1,31 @@ +# Categories ![alt text](images/StarLabs_Logo.png "Star Labs Systems") + +CMOS values should be added to [categories.yaml](src/application/categories.yaml]. + +This allows `coreboot-configurator` to display them in a relavant tab, with a nice +name and help text. Without this, they will still be visible in the **Raw** tab. + +An example entry is below: +``` +processor: + displayName: Processor + me_state: + displayName: Intel Management Engine + type: bool + help: Enable or disable the Intel Management Engine +``` + +To explain the options: +``` +**tabgroup**: <- This is the reference to the tab group + displayName: **Hello World** <- This is the name of the group that the user + will see + **setting_1**: <- This is the value that should match the CMOS + option. + displayName: **Hi World** <- This is the name of the option that the user + will see. + type: **bool** <- Valid type are: bool (checkbox) and enum + <- (dropdown). + help: **Greet the World** <- Help text that is displayed when hovering on the + option. +``` diff --git a/util/coreboot-configurator/src/application/AboutDialog.cpp b/util/coreboot-configurator/src/application/AboutDialog.cpp new file mode 100644 index 0000000000..8282e0c063 --- /dev/null +++ b/util/coreboot-configurator/src/application/AboutDialog.cpp @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include "AboutDialog.h" +#include "NvramToolCli.h" +#include "ui_AboutDialog.h" + +AboutDialog::AboutDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::AboutDialog) +{ + ui->setupUi(this); + + ui->logoLabel->setPixmap(QPixmap(":/images/star.svg")); + + ui->versionLabel->setText("<tt>"+NvramToolCli::version()+"</tt>"); +} + +AboutDialog::~AboutDialog() +{ + delete ui; +} diff --git a/util/coreboot-configurator/src/application/AboutDialog.h b/util/coreboot-configurator/src/application/AboutDialog.h new file mode 100644 index 0000000000..7a3123335d --- /dev/null +++ b/util/coreboot-configurator/src/application/AboutDialog.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#pragma once + +#include <QDialog> + +namespace Ui { +class AboutDialog; +} + +class AboutDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AboutDialog(QWidget *parent = nullptr); + ~AboutDialog(); + +private: + Ui::AboutDialog *ui; +}; diff --git a/util/coreboot-configurator/src/application/AboutDialog.ui b/util/coreboot-configurator/src/application/AboutDialog.ui new file mode 100644 index 0000000000..009acc24b9 --- /dev/null +++ b/util/coreboot-configurator/src/application/AboutDialog.ui @@ -0,0 +1,141 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>AboutDialog</class> + <widget class="QDialog" name="AboutDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>412</width> + <height>273</height> + </rect> + </property> + <property name="windowTitle"> + <string>About</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string notr="true"><html><head/><body><p><span style=" font-size:16pt; font-weight:600;">coreboot configurator</span></p></body></html></string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="logoLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string notr="true"/> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="aboutDescriptionLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string><html><head/><body><p>A simple GUI to change settings in coreboot's CBFS, via the nvramtool utility.</p></body></html></string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="versionLabel"> + <property name="text"> + <string notr="true"/> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="emailLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string notr="true"><html><head/><body><p><a href="https://support.starlabs.systems"><span style=" text-decoration: underline; color:#0000ff;">starlabs.systems</span></a></p></body></html></string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Ok</set> + </property> + <property name="centerButtons"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>AboutDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>AboutDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/util/coreboot-configurator/src/application/Configuration.cpp b/util/coreboot-configurator/src/application/Configuration.cpp new file mode 100644 index 0000000000..9f383f83e2 --- /dev/null +++ b/util/coreboot-configurator/src/application/Configuration.cpp @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <QFile> +#include <QString> +#include <QTextStream> + +#include "Configuration.h" +#include "Util.h" + +QMap<QString, QString> Configuration::fromFile(const QString &curr_path) +{ + QFile curr_file(curr_path); + + if ( !curr_file.open(QFile::ReadOnly) + || !curr_file.isReadable() + || curr_file.atEnd()) { + return {}; + } + + auto result = Util::parseParameters(curr_file); + + curr_file.close(); + return result; +} + + +bool Configuration::toFile(const QString &curr_path, const Parameters ¶ms) +{ + QFile output(curr_path); + + if(!output.open(QFile::WriteOnly|QFile::Truncate)){ + return false; + } + QTextStream outStream(&output); + for(auto it = params.begin(); it != params.end(); ++it){ + outStream << it.key() << " = " << it.value() << "\n"; + } + + output.close(); + return true; +} diff --git a/util/coreboot-configurator/src/application/Configuration.h b/util/coreboot-configurator/src/application/Configuration.h new file mode 100644 index 0000000000..b2559d4960 --- /dev/null +++ b/util/coreboot-configurator/src/application/Configuration.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#pragma once + +#include <QFile> +#include <QMap> +#include <QObject> +#include <QString> + + +namespace Configuration { + +using Parameters = QMap<QString,QString>; + +Parameters fromFile(const QString& curr_path); +bool toFile(const QString& curr_path, const Parameters& params); + +} diff --git a/util/coreboot-configurator/src/application/MainWindow.cpp b/util/coreboot-configurator/src/application/MainWindow.cpp new file mode 100644 index 0000000000..d51937d161 --- /dev/null +++ b/util/coreboot-configurator/src/application/MainWindow.cpp @@ -0,0 +1,388 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <QFileDialog> +#include <QHeaderView> +#include <QLabel> +#include <QMessageBox> +#include <QShortcut> +#include <QtGui> + +#include "AboutDialog.h" +#include "Configuration.h" +#include "MainWindow.h" +#include "NvramToolCli.h" +#include "ToggleSwitch.h" +#include "ui_MainWindow.h" + +static auto s_errorWindowTitle = MainWindow::tr("Error Occured"); +static auto s_nvramErrorMessage = MainWindow::tr("Nvramtool was not able to access cmos settings. Look at documentation for possible causes of errors."); + +QString makeNvramErrorMessage(const QString& error){ + if(!error.trimmed().isEmpty()){ + return QString(MainWindow::tr("%1<br><br>Error message:<br><tt>%2</tt>")).arg(s_nvramErrorMessage, + Qt::convertFromPlainText(error)); + } + return s_nvramErrorMessage; +} + +namespace YAML { +template <> +struct convert<QString>{ + static Node encode(const QString& rhs) { return Node(rhs.toUtf8().data()); } + + static bool decode(const Node& node, QString& rhs) { + if (!node.IsScalar()) + return false; + rhs = QString::fromStdString(node.Scalar()); + return true; + } +}; +} + +static auto s_metadataErrorMessage = MainWindow::tr("Can't load categories metadata file. Check your installation."); +static constexpr char s_sudoProg[] = "/usr/bin/pkexec"; + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) +{ + ui->setupUi(this); + + connect(ui->actionAbout, &QAction::triggered, this, [](){ + AboutDialog().exec(); + }); + +#if MOCK + this->setWindowTitle("coreboot configurator "+tr("[MOCKED DATA]")); +#else + this->setWindowTitle("coreboot configurator"); +#endif + this->setWindowIcon(QIcon::fromTheme("coreboot_configurator")); + + QFile catFile(":/config/categories.yaml"); + + if(!catFile.open(QFile::ReadOnly)){ + QMessageBox::critical(this, s_errorWindowTitle, s_metadataErrorMessage); + this->close(); + return; + } + + m_categories = YAML::Load(catFile.readAll()); + + if(m_categories.IsNull() || !m_categories.IsDefined()){ + QMessageBox::critical(this, s_errorWindowTitle, s_metadataErrorMessage); + this->close(); + return; + } + + QShortcut* returnAction = new QShortcut(QKeySequence("Ctrl+Return"), this); + connect(returnAction, &QShortcut::activated, this, &MainWindow::on_saveButton_clicked); + + generateUi(); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::pullSettings() +{ + QString error; + m_parameters = NvramToolCli::readParameters(&error); + + if(m_parameters.isEmpty()){ + QMessageBox::critical(this, s_errorWindowTitle, makeNvramErrorMessage(error)); + + /* we need delayed close as initialization error happened before event loop start so we can't stop application properly */ + QTimer::singleShot(0, this, &MainWindow::close); + } +} + +void MainWindow::pushSettings() +{ + QString error; + if(!NvramToolCli::writeParameters(m_parameters, &error)){ + QMessageBox::critical(this, s_errorWindowTitle, makeNvramErrorMessage(error)); + } +} + + +QComboBox* MainWindow::createComboBox(const QString& key) { + auto box = new QComboBox(this); + + auto opts = NvramToolCli::readOptions(key); + + box->addItems(opts); + box->setCurrentText(m_parameters[key]); + + connect(ui->advancedModeCheckBox, &QCheckBox::clicked, this, [box](bool clicked){ + box->setEditable(clicked); + }); + + connect(this, &MainWindow::updateValue, this, [box, this, key](const QString& name){ + if(key!=name || m_parameters[name]==box->currentText()){ + return; + } + box->setCurrentText(m_parameters[name]); + }); + + connect(box, &QComboBox::currentTextChanged, this, [key, this](const QString& value){ + if(value==m_parameters[key]){ + return; + } + m_parameters[key] = value; + emit updateValue(key); + }); + + return box; +} +QString boolToString(bool value){ + return value?QStringLiteral("Enable"):QStringLiteral("Disable"); +} +bool stringToBool(const QString& str){ + return str==QStringLiteral("Enable"); +} +QCheckBox* MainWindow::createCheckBox(const QString& key) { + auto box = new ToggleSwitch(this); + + box->setChecked(stringToBool(m_parameters[key])); + + connect(this, &MainWindow::updateValue, this, [box, this, key](const QString& name){ + + if(key!=name || m_parameters[name]==boolToString(box->isChecked())){ + return; + } + auto newValue = stringToBool(m_parameters[name]); + + box->setChecked(newValue); + }); + + connect(box, &QCheckBox::clicked, this, [key, this](bool checked){ + auto value = boolToString(checked); + if(value==m_parameters[key]){ + return; + } + m_parameters[key] = value; + emit updateValue(key); + }); + + return box; +} + + +QTableWidget *MainWindow::createRawTable() +{ + /* Create Raw values table */ + auto table = new QTableWidget(m_parameters.size(), 2); + table->setHorizontalHeaderLabels({tr("Key"), tr("Value")}); + table->horizontalHeader()->setSectionResizeMode(0,QHeaderView::Stretch); + table->verticalHeader()->hide(); + table->setSelectionBehavior(QTableWidget::SelectRows); + + connect(table, &QTableWidget::cellChanged, this, [table, this](int row, int column){ + if(column != 1 || row >= table->rowCount() || row < 0 ){ + /* Weird state when changed cell is not a value cell */ + return; + } + auto keyItem = table->item(row, 0); + auto valueItem = table->item(row, 1); + + if(keyItem == nullptr || valueItem == nullptr){ + /* Invalid cells */ + return; + } + + if(valueItem->text()==m_parameters[keyItem->text()]){ + return; + } + + m_parameters[keyItem->text()] = valueItem->text(); + emit updateValue(keyItem->text()); + }); + + auto it = m_parameters.begin(); + for(int i = 0; i<m_parameters.size(); i++, ++it){ + + auto item = new QTableWidgetItem(it.key()); + item->setFlags(item->flags() ^ Qt::ItemIsEditable); + table->setItem(i,0,item); + + item = new QTableWidgetItem(it.value()); + connect(this, &MainWindow::updateValue, this, [item, it, this](const QString& name){ + if(it.key()!=name || m_parameters[name]==item->text()){ + return; + } + item->setText(m_parameters[name]); + }); + + table->setItem(i,1,item); + } + return table; +} + +void MainWindow::generateUi() +{ + pullSettings(); + + if(!m_categories.IsMap()){ + return; + } + for(const auto& category : m_categories){ + if(!category.second.IsMap()){ + continue; + } + auto name = category.second["displayName"].as<QString>(); + + auto layout = new QVBoxLayout; + + auto tabPage = new QWidget(this); + tabPage->setLayout(layout); + + ui->centralTabWidget->addTab(tabPage, name); + + for(const auto& value : category.second){ + if(!value.second.IsMap() || !m_parameters.contains(value.first.as<QString>())){ + continue; + } + auto displayName = value.second["displayName"]; + if(!displayName.IsDefined()){ + continue; + } + auto type = value.second["type"]; + if(!type.IsDefined()){ + continue; + } + + auto controlLayout = new QHBoxLayout(); + + auto help = value.second["help"]; + + if(help.IsDefined()){ + auto labelWithTooltip = new QWidget; + labelWithTooltip->setToolTip(help.as<QString>()); + labelWithTooltip->setCursor({Qt::WhatsThisCursor}); + labelWithTooltip->setLayout(new QHBoxLayout); + + auto helpButton = new QLabel(); + helpButton->setPixmap(QIcon::fromTheme("help-hint").pixmap(16,16)); + + { + auto layout = qobject_cast<QHBoxLayout*>(labelWithTooltip->layout()); + layout->addWidget(new QLabel(displayName.as<QString>())); + layout->addWidget(helpButton,1); + } + controlLayout->addWidget(labelWithTooltip, 0); + } else { + controlLayout->addWidget(new QLabel(displayName.as<QString>()), 0); + } + + controlLayout->addStretch(1); + + QWidget* res = nullptr; + + if(type.as<QString>() == QStringLiteral("bool")){ + res = createCheckBox(value.first.as<QString>()); + } else if (type.as<QString>() == QStringLiteral("enum")){ + res = createComboBox(value.first.as<QString>()); + } else { + controlLayout->deleteLater(); + continue; + } + res->setObjectName(value.first.as<QString>()); + + controlLayout->addWidget(res, 0); + + layout->addLayout(controlLayout); + } + } + + auto table = createRawTable(); + + connect(ui->advancedModeCheckBox, &QCheckBox::clicked, this, [table,this](bool clicked){ + if(clicked && ui->centralTabWidget->widget(ui->centralTabWidget->count()-1) != table){ + ui->centralTabWidget->addTab(table, tr("Raw")); + } else if(!clicked && ui->centralTabWidget->widget(ui->centralTabWidget->count()-1) == table) { + ui->centralTabWidget->removeTab(ui->centralTabWidget->count()-1); + } + }); +} + +void MainWindow::askForReboot() +{ + QMessageBox rebootDialog(QMessageBox::Question, + tr("Reboot"), + tr("Changes are saved. Do you want to reboot to apply changes?")); + + auto nowButton = rebootDialog.addButton(tr("Reboot now"), QMessageBox::AcceptRole); + rebootDialog.addButton(tr("Reboot later"), QMessageBox::RejectRole); + + rebootDialog.exec(); + if(rebootDialog.clickedButton()==nowButton){ + QProcess::startDetached(s_sudoProg, {"/usr/bin/systemctl", "reboot"}); + this->close(); + } +} + +void MainWindow::readSettings(const QString &fileName) +{ + if(fileName.isEmpty()){ + return; + } + + auto configValues = Configuration::fromFile(fileName); + + for(auto it = configValues.begin(); it != configValues.end(); ++it){ + if(!m_parameters.contains(it.key())){ + continue; + } + m_parameters[it.key()]=it.value(); + emit updateValue(it.key()); + } +} + +void MainWindow::writeSettings(const QString &fileName) +{ + if(fileName.isEmpty()){ + return; + } + if(!Configuration::toFile(fileName, m_parameters)){ + QMessageBox::critical(this, tr("Error Occured"), tr("Can't open file to write")); + this->close(); + } +} + + +void MainWindow::on_actionSave_triggered() +{ + auto filename = QFileDialog::getSaveFileName(this, + tr("Select File To Save"), + QDir::homePath(), + tr("Coreboot Configuration Files")+"(*.cfg)"); + writeSettings(filename); +} + + +void MainWindow::on_actionLoad_triggered() +{ + auto filename = QFileDialog::getOpenFileName(this, + tr("Select File To Load"), + QDir::homePath(), + tr("Coreboot Configuration Files")+"(*.cfg)"); + + readSettings(filename); +} + + +void MainWindow::on_saveButton_clicked() +{ + ui->centralwidget->setEnabled(false); + ui->menubar->setEnabled(false); + + pushSettings(); + + askForReboot(); + + ui->centralwidget->setEnabled(true); + ui->menubar->setEnabled(true); +} diff --git a/util/coreboot-configurator/src/application/MainWindow.h b/util/coreboot-configurator/src/application/MainWindow.h new file mode 100644 index 0000000000..bf317a814f --- /dev/null +++ b/util/coreboot-configurator/src/application/MainWindow.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#pragma once + +#include <Configuration.h> +#include <QCheckBox> +#include <QComboBox> +#include <QMainWindow> +#include <QString> +#include <QTableWidget> +#include <yaml-cpp/yaml.h> + +QT_BEGIN_NAMESPACE +namespace Ui { class MainWindow; } +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +signals: + void updateValue(const QString& key); + +private slots: + void on_actionSave_triggered(void); + + void on_actionLoad_triggered(void); + + void on_saveButton_clicked(void); + +private: + void pullSettings(void); + void pushSettings(void); + + void generateUi(void); + void askForReboot(void); + + void readSettings(const QString& fileName); + void writeSettings(const QString& fileName); + + Configuration::Parameters m_parameters; + YAML::Node m_categories; + + Ui::MainWindow *ui; + + QComboBox *createComboBox(const QString &key); + QCheckBox *createCheckBox(const QString &key); + + QTableWidget *createRawTable(); +}; diff --git a/util/coreboot-configurator/src/application/MainWindow.ui b/util/coreboot-configurator/src/application/MainWindow.ui new file mode 100644 index 0000000000..0f59d80585 --- /dev/null +++ b/util/coreboot-configurator/src/application/MainWindow.ui @@ -0,0 +1,118 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>400</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>600</width> + <height>400</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>600</width> + <height>400</height> + </size> + </property> + <property name="windowTitle"> + <string>coreboot configurator</string> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTabWidget" name="centralTabWidget"/> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QCheckBox" name="advancedModeCheckBox"> + <property name="text"> + <string>Advanced mode</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="saveButton"> + <property name="text"> + <string>Save</string> + </property> + <property name="icon"> + <iconset theme="document-save-symbolic"/> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <widget class="QMenuBar" name="menubar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>25</height> + </rect> + </property> + <widget class="QMenu" name="menuFile"> + <property name="title"> + <string>File</string> + </property> + <addaction name="actionSave"/> + <addaction name="actionLoad"/> + </widget> + <widget class="QMenu" name="menuHelp"> + <property name="title"> + <string>Help</string> + </property> + <addaction name="actionAbout"/> + </widget> + <addaction name="menuFile"/> + <addaction name="menuHelp"/> + </widget> + <action name="actionSave"> + <property name="text"> + <string>Save to File...</string> + </property> + </action> + <action name="actionLoad"> + <property name="text"> + <string>Load from File...</string> + </property> + </action> + <action name="actionAbout"> + <property name="text"> + <string>About...</string> + </property> + </action> + </widget> + <resources/> + <connections/> +</ui> diff --git a/util/coreboot-configurator/src/application/NvramToolCli.cpp b/util/coreboot-configurator/src/application/NvramToolCli.cpp new file mode 100644 index 0000000000..da844a043b --- /dev/null +++ b/util/coreboot-configurator/src/application/NvramToolCli.cpp @@ -0,0 +1,120 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <QProcess> +#include <QTextStream> + +#include "NvramToolCli.h" +#include "Util.h" + +static constexpr char s_sudoProg[] = "/usr/bin/pkexec"; +static constexpr char s_nvramToolProg[] = "/usr/sbin/nvramtool"; + +#if MOCK + +QMap<QString, QString> NvramToolCli::readParameters(QString *error) { + return QMap<QString,QString>({ + {"boot_option","Normal"}, + {"reboot_counter","0x0"}, + {"debug_level","Spew"}, + {"vtd","Enable"}, + {"power_profile","Performance"}, + {"wireless","Enable"}, + {"webcam","Enable"}, + {"microphone","Enable"}, + {"legacy_8254_timer","Enable"}, + {"usb_always_on","Disable"}, + {"kbl_timeout","Never"}, + {"fn_ctrl_swap","Enable"}, + {"max_charge","100%"}, + {"power_on_after_fail","Disable"}, + {"fn_lock_state","0x2"}, + {"trackpad_state","0x40"}, + {"kbl_brightness","0xc4"}, + {"kbl_state","0x22"} + }); +} + +QStringList NvramToolCli::readOptions(const QString ¶meter, QString *error){ + return (parameter=="power_profile")? + QStringList{ + "Power Saver","Balanced","Performance" + } : QStringList{}; +} + +#else + +QMap<QString, QString> NvramToolCli::readParameters(QString *error) +{ + QProcess nvramtoolProcess; + nvramtoolProcess.start(s_sudoProg, {s_nvramToolProg, "-a"}); + + nvramtoolProcess.waitForFinished(); + + if(error) *error = nvramtoolProcess.readAllStandardError(); + + if(nvramtoolProcess.exitCode() != 0){ + return {}; + } + + return Util::parseParameters(nvramtoolProcess); +} + +QStringList NvramToolCli::readOptions(const QString ¶meter, QString *error) +{ + QStringList result; + + QProcess nvramtoolProcess; + nvramtoolProcess.start(s_sudoProg, {s_nvramToolProg, "-e", parameter}); + nvramtoolProcess.waitForFinished(); + + if(error) *error = nvramtoolProcess.readAllStandardError(); + + while (nvramtoolProcess.canReadLine()) { + result.append(nvramtoolProcess.readLine().trimmed()); + } + + return result; +} +#endif + +bool NvramToolCli::writeParameters(const QMap<QString, QString> ¶meters, QString *error) +{ + +#if MOCK + QTextStream outStream(stdout); +#else + QProcess nvramtoolProcess; + nvramtoolProcess.start(s_sudoProg, {s_nvramToolProg, "-i"}); + nvramtoolProcess.waitForStarted(); + QTextStream outStream(&nvramtoolProcess); +#endif + for(auto it = parameters.begin(); it != parameters.end(); ++it){ + outStream << it.key() << " = " << it.value() << "\n"; + } + + outStream.flush(); +#if MOCK + return true; +#else + nvramtoolProcess.closeWriteChannel(); + nvramtoolProcess.waitForFinished(); + + if(error){ + *error = nvramtoolProcess.readAllStandardError(); + } + + return nvramtoolProcess.exitCode()==0; +#endif +} + + + +QString NvramToolCli::version() +{ + QProcess nvramtoolProcess; + nvramtoolProcess.start(s_nvramToolProg, {"-v"}); + + nvramtoolProcess.waitForFinished(); + + return nvramtoolProcess.readAll(); +} diff --git a/util/coreboot-configurator/src/application/NvramToolCli.h b/util/coreboot-configurator/src/application/NvramToolCli.h new file mode 100644 index 0000000000..3bb5d0a6ea --- /dev/null +++ b/util/coreboot-configurator/src/application/NvramToolCli.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#pragma once + +#include <QList> +#include <QMap> +#include <QString> + +#include "Configuration.h" + +/* + * Namespace for convinient functions to work with nvramtool CLI utility + */ +namespace NvramToolCli { + +Configuration::Parameters readParameters(QString* error = nullptr); +QStringList readOptions(const QString& parameter, QString* error = nullptr); +bool writeParameters(const Configuration::Parameters& parameters, QString* error = nullptr); +QString version(); + +} diff --git a/util/coreboot-configurator/src/application/ToggleSwitch.cpp b/util/coreboot-configurator/src/application/ToggleSwitch.cpp new file mode 100644 index 0000000000..b0a399e01c --- /dev/null +++ b/util/coreboot-configurator/src/application/ToggleSwitch.cpp @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <QEvent> +#include <QGuiApplication> +#include <QPainter> +#include <QPalette> +#include <QTimer> + +#include "ToggleSwitch.h" +#include "ToggleSwitch.svg.h" + +const QByteArray ToggleSwitch::s_toggleOffSvgContent = ToggleSwitchSVG::s_toggledOffContent; +const QByteArray ToggleSwitch::s_toggleOnSvgContent = ToggleSwitchSVG::s_toggledOnContent; +const int ToggleSwitch::s_colorPosInToggleOn = ToggleSwitch::s_toggleOnSvgContent.indexOf("#1a73e8"); + +ToggleSwitch::ToggleSwitch(QWidget *parent) : QCheckBox(parent){ + + setFixedWidth(50); + setFixedHeight(width()/2); + + m_toggleOnSvgContentColored = s_toggleOnSvgContent; +} + +void ToggleSwitch::paintEvent(QPaintEvent *event){ + QPainter p(this); + + if(isChecked()){ + auto accent = palette().highlight().color(); + m_toggleOnSvgContentColored = m_toggleOnSvgContentColored.replace(s_colorPosInToggleOn, 7, accent.name().toLatin1()); + + m_svgr.load(m_toggleOnSvgContentColored); + } else { + m_svgr.load(s_toggleOffSvgContent); + } + + m_svgr.render(&p, this->rect()); + p.end(); +} diff --git a/util/coreboot-configurator/src/application/ToggleSwitch.h b/util/coreboot-configurator/src/application/ToggleSwitch.h new file mode 100644 index 0000000000..191dc5ef96 --- /dev/null +++ b/util/coreboot-configurator/src/application/ToggleSwitch.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#pragma once + +#include <QCheckBox> +#include <QFile> +#include <QObject> +#include <QSvgRenderer> + + +/* + * The ToggleSwitch class represents Toggle Switch widget based on QCheckBox and toggles svg with colorscheme support + */ +class ToggleSwitch : public QCheckBox { + Q_OBJECT +public: + explicit ToggleSwitch(QWidget* parent = nullptr); + +private: + QSvgRenderer m_svgr; + + static const QByteArray s_toggleOnSvgContent; + static const QByteArray s_toggleOffSvgContent; + static const int s_colorPosInToggleOn; + + QByteArray m_toggleOnSvgContentColored; + + /* QWidget interface */ +protected: + void paintEvent(QPaintEvent *event) override; + + /* QAbstractButton interface */ +protected: + bool hitButton(const QPoint &pos) const override + { + /* needs to be clickable on */ + return rect().contains(pos); + } +}; diff --git a/util/coreboot-configurator/src/application/ToggleSwitch.svg.h b/util/coreboot-configurator/src/application/ToggleSwitch.svg.h new file mode 100644 index 0000000000..4aeb12b122 --- /dev/null +++ b/util/coreboot-configurator/src/application/ToggleSwitch.svg.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#pragma once + +/* Embed SVG files into code as debian packages does weird things when svgs are included as qrc */ +namespace ToggleSwitchSVG { +static constexpr char s_toggledOnContent[] = + "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" + "<svg\n" + " xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" + " xmlns:cc=\"http://creativecommons.org/ns#\"\n" + " xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" + " xmlns:svg=\"http://www.w3.org/2000/svg\"\n" + " xmlns=\"http://www.w3.org/2000/svg\"\n" + " xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n" + " xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n" + " inkscape:version=\"1.0rc1 (1.0rc1+100)\"\n" + " sodipodi:docname=\"toggle-on.svg\"\n" + " id=\"svg6\"\n" + " version=\"1.1\"\n" + " viewBox=\"0 0 40 20\"\n" + " height=\"20\"\n" + " width=\"40\">\n" + " <metadata\n" + " id=\"metadata12\">\n" + " <rdf:RDF>\n" + " <cc:Work\n" + " rdf:about=\"\">\n" + " <dc:format>image/svg+xml</dc:format>\n" + " <dc:type\n" + " rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" />\n" + " </cc:Work>\n" + " </rdf:RDF>\n" + " </metadata>\n" + " <defs\n" + " id=\"defs10\" />\n" + " <sodipodi:namedview\n" + " inkscape:current-layer=\"svg6\"\n" + " inkscape:window-maximized=\"1\"\n" + " inkscape:window-y=\"28\"\n" + " inkscape:window-x=\"65\"\n" + " inkscape:cy=\"10\"\n" + " inkscape:cx=\"20.062112\"\n" + " inkscape:zoom=\"32.2\"\n" + " showgrid=\"false\"\n" + " id=\"namedview8\"\n" + " inkscape:window-height=\"1020\"\n" + " inkscape:window-width=\"1855\"\n" + " inkscape:pageshadow=\"2\"\n" + " inkscape:pageopacity=\"0\"\n" + " guidetolerance=\"10\"\n" + " gridtolerance=\"10\"\n" + " objecttolerance=\"10\"\n" + " borderopacity=\"1\"\n" + " bordercolor=\"#666666\"\n" + " pagecolor=\"#ffffff\" />\n" + " <rect\n" + " style=\"fill:#0068bf;fill-opacity:1\"\n" + " id=\"rect2\"\n" + " fill=\"#1a73e8\"\n" + " ry=\"8\"\n" + " height=\"16\"\n" + " width=\"36\"\n" + " y=\"2\"\n" + " x=\"2\" />\n" + " <circle\n" + " id=\"circle4\"\n" + " fill=\"#ffffff\"\n" + " r=\"6\"\n" + " cy=\"10\"\n" + " cx=\"30\" />\n" + "</svg>\n"; +static constexpr char s_toggledOffContent[] = + "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"20\" viewBox=\"0 0 40 20\">\n" + " <rect x=\"2\" y=\"2\" width=\"36\" height=\"16\" ry=\"8\" fill=\"#000000\" fill-opacity=\".26\"/>\n" + " <circle cx=\"10\" cy=\"10\" r=\"6\" fill=\"#ffffff\"/>\n" + "</svg>"; +} diff --git a/util/coreboot-configurator/src/application/Util.h b/util/coreboot-configurator/src/application/Util.h new file mode 100644 index 0000000000..55553f2981 --- /dev/null +++ b/util/coreboot-configurator/src/application/Util.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#pragma once + +#include <QIODevice> +#include <QMap> +#include <QString> + +namespace Util { + inline QMap<QString,QString> parseParameters(QIODevice& dev){ + QString curr_line; + QMap<QString, QString> result; + + while (!dev.atEnd()) { + curr_line = dev.readLine().trimmed(); + + auto split = curr_line.split('='); + if(split.size()!=2){ + continue; + } + + result.insert(split[0].trimmed(), split[1].trimmed()); + } + return result; + } +} diff --git a/util/coreboot-configurator/src/application/lang.qrc b/util/coreboot-configurator/src/application/lang.qrc new file mode 100644 index 0000000000..e25d9df240 --- /dev/null +++ b/util/coreboot-configurator/src/application/lang.qrc @@ -0,0 +1,3 @@ +<RCC> + <qresource prefix="/lang"/> +</RCC> diff --git a/util/coreboot-configurator/src/application/main.cpp b/util/coreboot-configurator/src/application/main.cpp new file mode 100644 index 0000000000..94b10d9fff --- /dev/null +++ b/util/coreboot-configurator/src/application/main.cpp @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <QApplication> +#include <QTranslator> + +#include "MainWindow.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + QTranslator translator; + if (translator.load(QLocale(), QLatin1String("corebootconfigurator"), QLatin1String("_"), QLatin1String(":/lang/i18n"))){ + a.installTranslator(&translator); + } + + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/util/coreboot-configurator/src/application/meson.build b/util/coreboot-configurator/src/application/meson.build new file mode 100644 index 0000000000..cb9b50e8d1 --- /dev/null +++ b/util/coreboot-configurator/src/application/meson.build @@ -0,0 +1,35 @@ +## SPDX-License-Identifier: GPL-2.0-only + +# Documentation: https://mesonbuild.com/Qt5-module.html +qt5 = import('qt5') +qt5_dep = dependency('qt5', modules : ['Core', 'Widgets', 'Svg']) +yamlcpp_dep = dependency('yaml-cpp', version: '>= 0.5.1', required: true) + +# TODO: Translations +# lang_cpp = qt5.compile_translations(qresource: 'lang.qrc') + +generated_files = qt5.preprocess( + moc_headers : ['MainWindow.h', 'AboutDialog.h', 'ToggleSwitch.h'], + ui_files : ['MainWindow.ui', 'AboutDialog.ui'], + dependencies : [qt5_dep], + qresources : ['resources.qrc'], +) + +mock = get_option('mock') + +if mock + add_project_arguments('-DMOCK', language : 'cpp') +endif + +executable('coreboot-configurator', + 'main.cpp', + 'MainWindow.cpp', + 'AboutDialog.cpp', + 'Configuration.cpp', + 'ToggleSwitch.cpp', + 'NvramToolCli.cpp', +# lang_cpp, + generated_files, + dependencies : [qt5_dep, yamlcpp_dep], + install : true +) diff --git a/util/coreboot-configurator/src/application/qrc/categories.yaml b/util/coreboot-configurator/src/application/qrc/categories.yaml new file mode 100644 index 0000000000..21419511fe --- /dev/null +++ b/util/coreboot-configurator/src/application/qrc/categories.yaml @@ -0,0 +1,119 @@ + processor: + displayName: Processor + hyper_threading: + displayName: Hyper-Threading + type: bool + help: Enable or disable Hyper-Threading + vtd: + displayName: Intel VT-d + type: bool + help: Enable or disable Intel VT-d (virtualisation) + power_profile: + displayName: Power Profile + type: enum + help: Select whether to maximise performance, battery life or both + me_state: + displayName: Intel Management Engine + type: bool + help: Enable or disable the Intel Management Engine + + devices: + displayName: Devices + wireless: + displayName: Wireless + type: bool + help: Enable or disable the built-in wireless card + wlan: + displayName: Wireless + type: bool + help: Enable or disable the built-in wireless card + bluetooth: + displayName: Bluetooth + type: bool + help: Enable or disable the built-in bluetooth + wwan: + displayName: Mobile Network + type: bool + help: Enable or disable the built-in mobile network + ethernet1: + displayName: Ethernet 1 + type: bool + help: Enable or disable the built-in Ethernet Port 1 + ethernet2: + displayName: Ethernet 2 + type: bool + help: Enable or disable the built-in Ethernet Port 2 + ethernet3: + displayName: Ethernet 3 + type: bool + help: Enable or disable the built-in Ethernet Port 3 + webcam: + displayName: Webcam + type: bool + help: Enable or disable the built-in webcam + microphone: + displayName: Microphone + type: bool + help: Enable or disable the built-in microphone + legacy_8254_timer: + displayName: Clock Gating + type: bool + help: Enable or disable the legacy 8254 timer. Reduces power consumption when enabled but must be disabled for certain distributions such as Qubes + usb_always_on: + displayName: USB Always On + type: bool + help: Allow the USB ports to provide power to connected devices when the computer is suspended + touchpad: + displayName: Touchpad + type: bool + help: Enable or disable the built-in touchpad + trackpoint: + displayName: Trackpoint + type: bool + help: Enable or disable the built-in trackpoint + sata_mode: + displayName: SATA Mode + type: enum + help: Set the mode of the SATA controller from AHCI or Compatible + thunderbolt: + displayName: Thunderbolt + type: bool + help: Enable or disable Thunderbolt functionality + + system: + displayName: System + kbl_timeout: + displayName: Keyboard Backlight Timeout + type: enum + help: Adjust the amout of time before the keyboard backlight turns off when un-used + fn_ctrl_swap: + displayName: Fn Ctrl Reverse + type: bool + help: Swap the functions of the [Fn] and [Ctrl] keys + max_charge: + displayName: Max Charge + type: enum + help: Set the maximum level the battery will charge to + fan_mode: + displayName: Fan Mode + type: enum + help: Adjust the fan curve to priotise performance or noise levels + f1_to_f12_as_primary: + displayName: Function Lock + type: bool + help: Make the F-keys behave as if you are holding down the Fn key + + advanced: + displayName: Advanced + boot_option: + displayName: Boot Options + type: enum + help: Change the boot device in the event of a failed boot + debug_level: + displayName: Debug Level + type: enum + help: Set the verbosity of the debug output + power_on_after_fail: + displayName: Power on Behaviour + type: enum + help: Select whether to power on in the event of a power failure diff --git a/util/coreboot-configurator/src/application/qrc/star.svg b/util/coreboot-configurator/src/application/qrc/star.svg new file mode 100644 index 0000000000..3bb9802ff5 --- /dev/null +++ b/util/coreboot-configurator/src/application/qrc/star.svg @@ -0,0 +1,391 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + width="100" + height="100" + viewBox="0 0 26.458334 26.458334" + version="1.1" + id="svg5517" + inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)" + sodipodi:docname="star.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <sodipodi:namedview + id="namedview5519" + pagecolor="#505050" + bordercolor="#eeeeee" + borderopacity="1" + inkscape:pageshadow="0" + inkscape:pageopacity="0" + inkscape:pagecheckerboard="0" + inkscape:document-units="mm" + showgrid="false" + inkscape:zoom="0.73406285" + inkscape:cx="396.42382" + inkscape:cy="207.06674" + inkscape:window-width="1854" + inkscape:window-height="1020" + inkscape:window-x="66" + inkscape:window-y="28" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + units="px" /> + <defs + id="defs5514"> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient10558" + id="linearGradient10560" + x1="3.9647901" + y1="311.93555" + x2="25.1075" + y2="299.72879" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0744218,0,0,1.0744218,-38.534669,-244.51634)" /> + <linearGradient + inkscape:collect="always" + id="linearGradient10558"> + <stop + style="stop-color:#86868a;stop-opacity:1" + offset="0" + id="stop10554" /> + <stop + style="stop-color:#3d3d40;stop-opacity:1" + offset="1" + id="stop10556" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient10622" + id="linearGradient10624" + x1="3.9647901" + y1="311.93555" + x2="25.107491" + y2="299.72879" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0744218,0,0,1.0744218,-38.534669,-244.51634)" /> + <linearGradient + inkscape:collect="always" + id="linearGradient10622"> + <stop + style="stop-color:#444447;stop-opacity:1" + offset="0" + id="stop10618" /> + <stop + style="stop-color:#757579;stop-opacity:1" + offset="1" + id="stop10620" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient10630" + id="linearGradient10632" + x1="35.217491" + y1="299.72879" + x2="56.360199" + y2="311.93555" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0744218,0,0,1.0744218,-38.534669,-244.51634)" /> + <linearGradient + inkscape:collect="always" + id="linearGradient10630"> + <stop + style="stop-color:#4f4f52;stop-opacity:1" + offset="0" + id="stop10626" /> + <stop + style="stop-color:#525255;stop-opacity:1" + offset="1" + id="stop10628" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient10566" + id="linearGradient10568" + x1="35.217491" + y1="299.72879" + x2="56.360199" + y2="311.93555" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0744218,0,0,1.0744218,-38.534669,-244.51634)" /> + <linearGradient + inkscape:collect="always" + id="linearGradient10566"> + <stop + style="stop-color:#404043;stop-opacity:1" + offset="0" + id="stop10562" /> + <stop + style="stop-color:#7c7c80;stop-opacity:1" + offset="1" + id="stop10564" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient10646" + id="linearGradient10648" + x1="30.1625" + y1="266.55981" + x2="30.1625" + y2="290.97327" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0744218,0,0,1.0744218,-38.534669,-244.51634)" /> + <linearGradient + inkscape:collect="always" + id="linearGradient10646"> + <stop + style="stop-color:#4f4f52;stop-opacity:1" + offset="0" + id="stop10642" /> + <stop + style="stop-color:#737376;stop-opacity:1" + offset="1" + id="stop10644" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient10638" + id="linearGradient10640" + x1="30.1625" + y1="266.55981" + x2="30.1625" + y2="290.9733" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0744218,0,0,1.0744218,-38.534669,-244.51634)" /> + <linearGradient + inkscape:collect="always" + id="linearGradient10638"> + <stop + style="stop-color:#76767a;stop-opacity:1" + offset="0" + id="stop10634" /> + <stop + style="stop-color:#505053;stop-opacity:1" + offset="1" + id="stop10636" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient10598" + id="linearGradient10600" + x1="30.1625" + y1="296.8103" + x2="56.360199" + y2="311.93555" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0744218,0,0,1.0744218,-38.534669,-244.51634)" /> + <linearGradient + inkscape:collect="always" + id="linearGradient10598"> + <stop + style="stop-color:#0165ba;stop-opacity:1" + offset="0" + id="stop10594" /> + <stop + style="stop-color:#001425;stop-opacity:1" + offset="1" + id="stop10596" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient10606" + id="linearGradient10608" + x1="30.1625" + y1="296.8103" + x2="30.1625" + y2="323.45831" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0744218,0,0,1.0744218,-38.534669,-244.51634)" /> + <linearGradient + inkscape:collect="always" + id="linearGradient10606"> + <stop + style="stop-color:#0084f3;stop-opacity:1" + offset="0" + id="stop10602" /> + <stop + style="stop-color:#003766;stop-opacity:1" + offset="1" + id="stop10604" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient10574" + id="linearGradient10576" + x1="30.1625" + y1="296.8103" + x2="30.1625" + y2="266.55981" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0744218,0,0,1.0744218,-38.534669,-244.51634)" /> + <linearGradient + inkscape:collect="always" + id="linearGradient10574"> + <stop + style="stop-color:#0063b5;stop-opacity:1" + offset="0" + id="stop10570" /> + <stop + style="stop-color:#000f1c;stop-opacity:1" + offset="1" + id="stop10572" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient10590" + id="linearGradient10592" + x1="30.1625" + y1="296.8103" + x2="56.360199" + y2="311.93555" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0744218,0,0,1.0744218,-38.534669,-244.51634)" /> + <linearGradient + inkscape:collect="always" + id="linearGradient10590"> + <stop + style="stop-color:#015dab;stop-opacity:1" + offset="0" + id="stop10586" /> + <stop + style="stop-color:#007ce5;stop-opacity:1" + offset="1" + id="stop10588" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient10614" + id="linearGradient10616" + x1="7.08464" + y1="283.4863" + x2="30.1625" + y2="296.8103" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0744218,0,0,1.0744218,-38.534669,-244.51634)" /> + <linearGradient + inkscape:collect="always" + id="linearGradient10614"> + <stop + style="stop-color:#003563;stop-opacity:1" + offset="0" + id="stop10610" /> + <stop + style="stop-color:#0080ec;stop-opacity:1" + offset="1" + id="stop10612" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient10582" + id="linearGradient10584" + x1="30.1625" + y1="266.55981" + x2="30.1625" + y2="296.8103" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0744218,0,0,1.0744218,-38.534669,-244.51634)" /> + <linearGradient + inkscape:collect="always" + id="linearGradient10582"> + <stop + style="stop-color:#001424;stop-opacity:1" + offset="0" + id="stop10578" /> + <stop + style="stop-color:#0065b9;stop-opacity:1" + offset="1" + id="stop10580" /> + </linearGradient> + </defs> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <g + id="g5791" + transform="matrix(0.43279952,0,0,0.43279952,15.881114,-18.126215)"> + <path + id="path10367" + style="fill:url(#linearGradient10560);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.158757" + d="m -34.274812,90.63402 24.045828,-7.35759 -1.32964,-5.75761 z" /> + <path + id="path10369" + style="fill:url(#linearGradient10624);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.158757" + d="m -34.274812,90.634 18.394778,-17.1455 4.321399,4.03031 z" /> + <path + id="path10373" + style="fill:url(#linearGradient10632);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.158757" + d="M 22.019958,90.634 3.62518,73.4885 -0.69623,77.51881 Z" /> + <path + id="path10375" + style="fill:url(#linearGradient10568);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.158757" + d="M 22.019958,90.634 -2.02587,83.27642 -0.69623,77.51881 Z" /> + <path + id="path10379" + style="fill:url(#linearGradient10648);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.158757" + d="m -6.127422,41.88132 -5.651061,24.50309 5.651061,1.7273 z" /> + <path + id="path10381" + style="fill:url(#linearGradient10640);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.158757" + d="m -6.127422,41.88132 5.651051,24.50309 -5.651051,1.7273 z" /> + <path + d="m -6.127422,74.38311 5.431192,3.1357 -5.431192,25.49551 V 74.38311" + style="fill:url(#linearGradient10600);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.158757" + id="path10385" + inkscape:connector-curvature="0" + inkscape:export-filename="/home/sean/Insync/Shared/Technical/Logo/coreboot-gif/green-star.png" + inkscape:export-xdpi="166.19583" + inkscape:export-ydpi="166.19583" + sodipodi:nodetypes="cccc" /> + <path + d="m -6.127422,74.38311 -5.431191,3.1357 5.431191,25.49551 V 74.38311" + style="fill:url(#linearGradient10608);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.158757" + id="path10387" + inkscape:connector-curvature="0" + inkscape:export-filename="/home/sean/Insync/Shared/Technical/Logo/coreboot-gif/green-star.png" + inkscape:export-xdpi="166.19583" + inkscape:export-ydpi="166.19583" + sodipodi:nodetypes="cccc" /> + <path + d="M -6.127422,74.38311 V 68.1117 L 18.667945,60.0675 -6.127422,74.38311" + style="fill:url(#linearGradient10576);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.158757" + id="path10391" + inkscape:connector-curvature="0" + inkscape:export-filename="/home/sean/Insync/Shared/Technical/Logo/coreboot-gif/green-star.png" + inkscape:export-xdpi="166.19583" + inkscape:export-ydpi="166.19583" + sodipodi:nodetypes="cccc" /> + <path + d="M -6.127422,74.38311 -0.69623,77.51881 18.667934,60.06749 -6.127422,74.38311" + style="fill:url(#linearGradient10592);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.158757" + id="path10393" + inkscape:connector-curvature="0" + inkscape:export-filename="/home/sean/Insync/Shared/Technical/Logo/coreboot-gif/green-star.png" + inkscape:export-xdpi="166.19583" + inkscape:export-ydpi="166.19583" + sodipodi:nodetypes="cccc" /> + <path + d="m -6.127422,74.38312 -5.431191,3.1357 -19.364164,-17.45132 24.795355,14.31562" + style="fill:url(#linearGradient10616);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.158757" + id="path10397" + inkscape:connector-curvature="0" + inkscape:export-filename="/home/sean/Insync/Shared/Technical/Logo/coreboot-gif/green-star.png" + inkscape:export-xdpi="166.19583" + inkscape:export-ydpi="166.19583" + sodipodi:nodetypes="cccc" /> + <path + d="m -6.127422,74.38312 v -6.27141 l -24.795355,-8.0442 24.795355,14.31561" + style="fill:url(#linearGradient10584);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.158757" + id="path10399" + inkscape:connector-curvature="0" + inkscape:export-filename="/home/sean/Insync/Shared/Technical/Logo/coreboot-gif/green-star.png" + inkscape:export-xdpi="166.19583" + inkscape:export-ydpi="166.19583" + sodipodi:nodetypes="cccc" /> + </g> + </g> +</svg> diff --git a/util/coreboot-configurator/src/application/qrc/toggle-off.svg b/util/coreboot-configurator/src/application/qrc/toggle-off.svg new file mode 100644 index 0000000000..504ea58c5f --- /dev/null +++ b/util/coreboot-configurator/src/application/qrc/toggle-off.svg @@ -0,0 +1,4 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="40" height="20" viewBox="0 0 40 20"> + <rect x="2" y="2" width="36" height="16" ry="8" fill="#000000" fill-opacity=".26"/> + <circle cx="10" cy="10" r="6" fill="#ffffff"/> +</svg> diff --git a/util/coreboot-configurator/src/application/qrc/toggle-on.svg b/util/coreboot-configurator/src/application/qrc/toggle-on.svg new file mode 100644 index 0000000000..0b8e61848c --- /dev/null +++ b/util/coreboot-configurator/src/application/qrc/toggle-on.svg @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + inkscape:version="1.0rc1 (1.0rc1+100)" + sodipodi:docname="toggle-on.svg" + id="svg6" + version="1.1" + viewBox="0 0 40 20" + height="20" + width="40"> + <metadata + id="metadata12"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs10" /> + <sodipodi:namedview + inkscape:current-layer="svg6" + inkscape:window-maximized="1" + inkscape:window-y="28" + inkscape:window-x="65" + inkscape:cy="10" + inkscape:cx="20.062112" + inkscape:zoom="32.2" + showgrid="false" + id="namedview8" + inkscape:window-height="1020" + inkscape:window-width="1855" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + bordercolor="#666666" + pagecolor="#ffffff" /> + <rect + style="fill:#0068bf;fill-opacity:1" + id="rect2" + fill="#1a73e8" + ry="8" + height="16" + width="36" + y="2" + x="2" /> + <circle + id="circle4" + fill="#ffffff" + r="6" + cy="10" + cx="30" /> +</svg> diff --git a/util/coreboot-configurator/src/application/resources.qrc b/util/coreboot-configurator/src/application/resources.qrc new file mode 100644 index 0000000000..06264d63d1 --- /dev/null +++ b/util/coreboot-configurator/src/application/resources.qrc @@ -0,0 +1,12 @@ +<RCC> + <qresource prefix="/toggle"> + <file alias="toggle-off.svg">qrc/toggle-off.svg</file> + <file alias="toggle-on.svg">qrc/toggle-on.svg</file> + </qresource> + <qresource prefix="/config"> + <file alias="categories.yaml">qrc/categories.yaml</file> + </qresource> + <qresource prefix="/images"> + <file alias="star.svg">qrc/star.svg</file> + </qresource> +</RCC> diff --git a/util/coreboot-configurator/src/meson.build b/util/coreboot-configurator/src/meson.build new file mode 100644 index 0000000000..cb73f0818b --- /dev/null +++ b/util/coreboot-configurator/src/meson.build @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +subdir('application') +subdir('resources') diff --git a/util/coreboot-configurator/src/resources/coreboot-configurator.desktop b/util/coreboot-configurator/src/resources/coreboot-configurator.desktop new file mode 100644 index 0000000000..5f17d000e4 --- /dev/null +++ b/util/coreboot-configurator/src/resources/coreboot-configurator.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Name=coreboot configurator +StartupWMCLass=coreboot_configurator +Exec=/usr/bin/coreboot-configurator +Icon=coreboot-configurator.png +Type=Application +Categories=Settings;System +Comment=A graphical interface to set options on devices with coreboot firmware. +Keywords=coreboot;BIOS;Firmware;uefi; diff --git a/util/coreboot-configurator/src/resources/coreboot_configurator.svg b/util/coreboot-configurator/src/resources/coreboot_configurator.svg new file mode 100644 index 0000000000..33a7229891 --- /dev/null +++ b/util/coreboot-configurator/src/resources/coreboot_configurator.svg @@ -0,0 +1,748 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="512" + height="512" + viewBox="0 0 135.46667 135.46667" + version="1.1" + id="svg8" + inkscape:version="1.0.2 (1.0.2+r75+1)" + sodipodi:docname="corevantage.svg" + inkscape:export-filename="/home/sean/Documents/corevantage-x200-1.2/icon/16x16png.png" + inkscape:export-xdpi="3" + inkscape:export-ydpi="3"> + <defs + id="defs2"> + <linearGradient + inkscape:collect="always" + id="linearGradient1476"> + <stop + style="stop-color:#27f7d0;stop-opacity:1;" + offset="0" + id="stop1472" /> + <stop + style="stop-color:#2195f2;stop-opacity:1" + offset="1" + id="stop1474" /> + </linearGradient> + <filter + style="color-interpolation-filters:sRGB" + inkscape:label="Drop Shadow" + id="filter570"> + <feColorMatrix + type="hueRotate" + values="180" + result="color1" + id="feColorMatrix566" /> + <feColorMatrix + values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 2 0 " + result="fbSourceGraphic" + id="feColorMatrix568" /> + <feColorMatrix + result="fbSourceGraphicAlpha" + in="fbSourceGraphic" + values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0" + id="feColorMatrix572" /> + <feColorMatrix + id="feColorMatrix574" + type="hueRotate" + values="180" + result="color1" + in="fbSourceGraphic" /> + <feColorMatrix + id="feColorMatrix576" + values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 2 0 " + result="fbSourceGraphic" /> + <feColorMatrix + result="fbSourceGraphicAlpha" + in="fbSourceGraphic" + values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0" + id="feColorMatrix578" /> + <feColorMatrix + id="feColorMatrix580" + type="hueRotate" + values="180" + result="color1" + in="fbSourceGraphic" /> + <feColorMatrix + id="feColorMatrix582" + values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 2 0 " + result="fbSourceGraphic" /> + <feColorMatrix + result="fbSourceGraphicAlpha" + in="fbSourceGraphic" + values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0" + id="feColorMatrix12032" /> + <feFlood + id="feFlood12034" + flood-opacity="0.698039" + flood-color="rgb(0,0,0)" + result="flood" + in="fbSourceGraphic" /> + <feComposite + in2="fbSourceGraphic" + id="feComposite12036" + in="flood" + operator="out" + result="composite1" /> + <feGaussianBlur + id="feGaussianBlur12038" + in="composite1" + stdDeviation="1.26667" + result="blur" /> + <feOffset + id="feOffset12040" + dx="0.9" + dy="1" + result="offset" /> + <feComposite + in2="fbSourceGraphic" + id="feComposite12042" + in="offset" + operator="atop" + result="composite2" /> + </filter> + <filter + style="color-interpolation-filters:sRGB" + inkscape:label="Bump" + id="filter10278"> + <feGaussianBlur + in="SourceGraphic" + stdDeviation="1.81244" + result="blur1" + id="feGaussianBlur10256" /> + <feColorMatrix + in="blur1" + values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 " + result="colormatrix1" + id="feColorMatrix10258" /> + <feColorMatrix + in="colormatrix1" + type="luminanceToAlpha" + result="colormatrix2" + id="feColorMatrix10260" /> + <feComposite + in2="blur1" + operator="arithmetic" + k2="1" + k3="0" + result="composite1" + id="feComposite10262" + k1="0" + k4="0" /> + <feGaussianBlur + in="composite1" + stdDeviation="2.99163" + result="blur2" + id="feGaussianBlur10264" /> + <feSpecularLighting + lighting-color="#ffffff" + surfaceScale="10.0614996" + specularConstant="0.72376299" + specularExponent="17" + result="lighting" + id="feSpecularLighting10268"> + <feDistantLight + azimuth="225" + elevation="45" + id="feDistantLight10266" /> + </feSpecularLighting> + <feFlood + flood-color="rgb(197,41,41)" + flood-opacity="1" + result="flood" + id="feFlood10270" /> + <feComposite + in="lighting" + in2="blur1" + operator="arithmetic" + k3="1" + k2="1" + result="composite2" + id="feComposite10272" + k1="0" + k4="0" /> + <feBlend + in2="SourceGraphic" + mode="normal" + result="blend" + id="feBlend10274" /> + <feComposite + in="blend" + in2="SourceGraphic" + operator="in" + result="fbSourceGraphic" + id="feComposite10276" /> + <feColorMatrix + result="fbSourceGraphicAlpha" + in="fbSourceGraphic" + values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0" + id="feColorMatrix14324" /> + <feGaussianBlur + id="feGaussianBlur14326" + in="fbSourceGraphic" + stdDeviation="0.276667" + result="blur1" /> + <feColorMatrix + id="feColorMatrix14328" + in="blur1" + values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 " + result="colormatrix1" /> + <feColorMatrix + id="feColorMatrix14330" + in="colormatrix1" + type="luminanceToAlpha" + result="colormatrix2" /> + <feComposite + in2="blur1" + id="feComposite14332" + operator="arithmetic" + k2="1" + k3="-49.8667" + result="composite1" + k1="0" + k4="0" /> + <feGaussianBlur + id="feGaussianBlur14334" + in="composite1" + stdDeviation="1.27667" + result="blur2" /> + <feSpecularLighting + id="feSpecularLighting14336" + lighting-color="#ffffff" + surfaceScale="10.0614996" + specularConstant="0.72376299" + specularExponent="17" + result="lighting"> + <feDistantLight + id="feDistantLight14338" + azimuth="225" + elevation="45" /> + </feSpecularLighting> + <feFlood + id="feFlood14340" + flood-color="rgb(197,41,41)" + flood-opacity="1" + result="flood" /> + <feComposite + in2="blur1" + id="feComposite14342" + in="lighting" + operator="arithmetic" + k3="1" + k2="1" + result="composite2" + k1="0" + k4="0" /> + <feBlend + in2="fbSourceGraphic" + id="feBlend14344" + mode="normal" + result="blend" /> + <feComposite + in2="fbSourceGraphic" + id="feComposite14346" + in="blend" + operator="in" + result="composite3" /> + </filter> + <clipPath + id="b-7-9"> + <path + id="path106-2-2" + d="m 18,102 h 86 v 16 H 18 Z m 0,0" + inkscape:connector-curvature="0" /> + </clipPath> + <clipPath + id="c-5-0"> + <path + id="path121-1-2" + d="m 16.496,28.445 h 96.176 c 4.418,0 8,3.575 8,7.989 v 73.578 c 0,4.414 -3.582,7.988 -8,7.988 H 16.496 c -4.418,0 -8,-3.574 -8,-7.988 V 36.434 c 0,-4.414 3.582,-7.989 8,-7.989 z m 0,0" + inkscape:connector-curvature="0" /> + </clipPath> + <linearGradient + gradientTransform="matrix(0.25,0,0,0.2496,0.495,57.398)" + y2="234.21899" + x2="94.021004" + y1="194.21899" + x1="94.021004" + gradientUnits="userSpaceOnUse" + id="d-3"> + <stop + id="stop37" + stop-color="#f9f06b" + offset="0" /> + <stop + id="stop39" + stop-color="#fcf7ac" + offset=".512" /> + <stop + id="stop41" + stop-color="#f9f06b" + offset="1" /> + </linearGradient> + <clipPath + id="e-5-9"> + <path + id="path118-6-2" + d="m 18,116 h 76 v 2 H 18 Z m 0,0" + inkscape:connector-curvature="0" /> + </clipPath> + <clipPath + id="f-62-2"> + <path + id="path115-3-8" + d="m 16.496,28.445 h 96.176 c 4.418,0 8,3.575 8,7.989 v 73.578 c 0,4.414 -3.582,7.988 -8,7.988 H 16.496 c -4.418,0 -8,-3.574 -8,-7.988 V 36.434 c 0,-4.414 3.582,-7.989 8,-7.989 z m 0,0" + inkscape:connector-curvature="0" /> + </clipPath> + <linearGradient + gradientTransform="matrix(0.25,0,0,0.2496,0.495,57.398)" + y2="234.78101" + x2="202.021" + y1="242.79401" + x1="202.021" + gradientUnits="userSpaceOnUse" + id="g-9"> + <stop + id="stop62" + stop-color="#c09608" + offset="0" /> + <stop + id="stop64" + stop-color="#f6ca30" + offset="1" /> + </linearGradient> + <clipPath + id="h-36"> + <path + id="path112-0-1" + d="m 98,115 h 6 v 3 h -6 z m 0,0" + inkscape:connector-curvature="0" /> + </clipPath> + <clipPath + id="i-12-2"> + <path + id="path109-2-9" + d="m 16.496,28.445 h 96.176 c 4.418,0 8,3.575 8,7.989 v 73.578 c 0,4.414 -3.582,7.988 -8,7.988 H 16.496 c -4.418,0 -8,-3.574 -8,-7.988 V 36.434 c 0,-4.414 3.582,-7.989 8,-7.989 z m 0,0" + inkscape:connector-curvature="0" /> + </clipPath> + <linearGradient + inkscape:collect="always" + xlink:href="#j-7" + id="linearGradient5088" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(3.2066783,0,0,3.2066783,432.07192,-765.09973)" + x1="37" + y1="249" + x2="37" + y2="254" /> + <linearGradient + gradientTransform="matrix(1.4285714,0,0,1.4285714,65.142859,-261.28571)" + y2="254" + x2="37" + y1="249" + x1="37" + gradientUnits="userSpaceOnUse" + id="j-7"> + <stop + id="stop2-6" + stop-color="#d5d1cc" + offset="0" /> + <stop + id="stop4-1-0" + stop-color="#f6f5f4" + offset=".183" /> + <stop + id="stop6-5" + stop-color="#fff" + offset=".395" /> + <stop + id="stop8-6" + stop-color="#d7d3ce" + offset=".784" /> + <stop + id="stop10-0" + stop-color="#c8c2bb" + offset="1" /> + </linearGradient> + <linearGradient + gradientTransform="matrix(1.4285714,0,0,1.4285714,36.571431,-224.85714)" + y2="259" + x2="18.608" + y1="253" + x1="17" + gradientUnits="userSpaceOnUse" + id="k-2"> + <stop + id="stop88" + stop-color="#f9f06b" + offset="0" /> + <stop + id="stop90" + stop-color="#fcf7ac" + offset=".512" /> + <stop + id="stop92" + stop-color="#f9f06b" + offset="1" /> + </linearGradient> + <linearGradient + gradientTransform="matrix(1.4285714,0,0,0.4761857,36.571431,11.332859)" + y2="259" + x2="18.608" + y1="253" + x1="17" + gradientUnits="userSpaceOnUse" + id="l-936"> + <stop + id="stop81-6" + stop-color="#f9f06b" + offset="0" /> + <stop + id="stop83" + stop-color="#fcf7ac" + offset=".512" /> + <stop + id="stop85" + stop-color="#f9f06b" + offset="1" /> + </linearGradient> + <linearGradient + gradientTransform="matrix(1.4285714,0,0,0.4761857,48.000002,-5.8099974)" + y2="259" + x2="18.608" + y1="253" + x1="17" + gradientUnits="userSpaceOnUse" + id="m-06"> + <stop + id="stop74" + stop-color="#f9f06b" + offset="0" /> + <stop + id="stop76" + stop-color="#fcf7ac" + offset=".512" /> + <stop + id="stop78" + stop-color="#f9f06b" + offset="1" /> + </linearGradient> + <linearGradient + gradientTransform="matrix(1.4285714,0,0,1.4285714,48.000002,-259.14285)" + y2="259" + x2="18.608" + y1="253" + x1="17" + gradientUnits="userSpaceOnUse" + id="n-2-6"> + <stop + id="stop67-5" + stop-color="#f9f06b" + offset="0" /> + <stop + id="stop69-0" + stop-color="#fcf7ac" + offset=".512" /> + <stop + id="stop71" + stop-color="#f9f06b" + offset="1" /> + </linearGradient> + <linearGradient + gradientTransform="matrix(1.4285714,0,0,0.4761857,48.000002,-22.952854)" + y2="259" + x2="18.608" + y1="253" + x1="17" + gradientUnits="userSpaceOnUse" + id="o-1"> + <stop + id="stop55" + stop-color="#f9f06b" + offset="0" /> + <stop + id="stop57" + stop-color="#fcf7ac" + offset=".512" /> + <stop + id="stop59" + stop-color="#f9f06b" + offset="1" /> + </linearGradient> + <linearGradient + gradientTransform="matrix(1.4285714,0,0,1.4285714,93.714287,-234.85714)" + y2="254" + x2="37" + y1="249" + x1="37" + gradientUnits="userSpaceOnUse" + id="p-61"> + <stop + id="stop44-8" + stop-color="#d5d1cc" + offset="0" /> + <stop + id="stop46" + stop-color="#f6f5f4" + offset=".183" /> + <stop + id="stop48" + stop-color="#fff" + offset=".395" /> + <stop + id="stop50" + stop-color="#d7d3ce" + offset=".784" /> + <stop + id="stop52" + stop-color="#c8c2bb" + offset="1" /> + </linearGradient> + <linearGradient + gradientTransform="matrix(1.4285714,0,0,-1.4285714,93.714287,465.14285)" + y2="254" + x2="37" + y1="249" + x1="37" + gradientUnits="userSpaceOnUse" + id="q-79"> + <stop + id="stop26" + stop-color="#d5d1cc" + offset="0" /> + <stop + id="stop28-8" + stop-color="#f6f5f4" + offset=".183" /> + <stop + id="stop30-7" + stop-color="#fff" + offset=".395" /> + <stop + id="stop32" + stop-color="#d7d3ce" + offset=".784" /> + <stop + id="stop34" + stop-color="#c8c2bb" + offset="1" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#r-2" + id="linearGradient5104" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(3.2066783,0,0,3.2066783,367.93856,-676.916)" + x1="37" + y1="249" + x2="37" + y2="254" /> + <linearGradient + gradientTransform="matrix(1.4285714,0,0,1.4285714,36.571431,-221.99999)" + y2="254" + x2="37" + y1="249" + x1="37" + gradientUnits="userSpaceOnUse" + id="r-2"> + <stop + id="stop95" + stop-color="#d5d1cc" + offset="0" /> + <stop + id="stop97" + stop-color="#f6f5f4" + offset=".183" /> + <stop + id="stop99" + stop-color="#fff" + offset=".395" /> + <stop + id="stop101-0" + stop-color="#d7d3ce" + offset=".784" /> + <stop + id="stop103-23" + stop-color="#c8c2bb" + offset="1" /> + </linearGradient> + <filter + inkscape:collect="always" + style="color-interpolation-filters:sRGB" + id="filter1525-3" + x="-0.012" + width="1.024" + y="-0.012" + height="1.024"> + <feGaussianBlur + inkscape:collect="always" + stdDeviation="0.063499999" + id="feGaussianBlur1527-6" /> + </filter> + <clipPath + id="clipPath24907" + clipPathUnits="userSpaceOnUse"> + <rect + inkscape:label="Square-Background" + style="fill:#319395;fill-opacity:1;stroke-width:0.315296" + id="rect24909" + width="12.170834" + height="12.170922" + x="-204.80406" + y="195.97275" + rx="2.2374113" /> + </clipPath> + <clipPath + id="clipPath24901" + clipPathUnits="userSpaceOnUse"> + <path + inkscape:connector-curvature="0" + d="M 52.848788,9.1555002 H 203.13314 c 24.20496,0 43.69115,19.4861378 43.69115,43.6911478 V 203.13271 c 0,24.2048 -19.48619,43.6912 -43.69115,43.6912 H 52.848788 c -24.204958,0 -43.6911479,-19.4864 -43.6911479,-43.6912 V 52.846648 c 0,-24.20501 19.4861899,-43.6911478 43.6911479,-43.6911478 z" + inkscape:label="Square-Background" + style="fill:#319395;fill-opacity:1;stroke-width:6.15696" + id="path24903" /> + </clipPath> + <linearGradient + inkscape:collect="always" + xlink:href="#p-61" + id="linearGradient1470" + x1="32.241405" + y1="52.764114" + x2="164.33501" + y2="52.764114" + gradientUnits="userSpaceOnUse" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient1476" + id="radialGradient1478" + cx="518.65234" + cy="84.663773" + fx="518.65234" + fy="84.663773" + r="64.910637" + gradientTransform="matrix(2.9098159,0.04997269,-0.04502878,2.6219419,-986.71822,-163.23817)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + xlink:href="#p-61" + id="linearGradient1500" + gradientUnits="userSpaceOnUse" + x1="32.241405" + y1="52.764114" + x2="164.33501" + y2="52.764114" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.3160391" + inkscape:cx="144.17386" + inkscape:cy="37.998289" + inkscape:document-units="mm" + inkscape:current-layer="layer2" + inkscape:document-rotation="0" + showgrid="false" + units="px" + inkscape:window-width="928" + inkscape:window-height="1020" + inkscape:window-x="992" + inkscape:window-y="28" + inkscape:window-maximized="0" /> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" /> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="Layer 2"> + <g + id="g1498" + transform="translate(-450.91873,-16.930479)"> + <rect + style="display:inline;opacity:0.2;fill:#000000;fill-opacity:1;stroke-width:0.329004;filter:url(#filter1525-3)" + id="rect24836" + width="12.7" + height="12.7" + x="0.11910726" + y="-0.044058971" + rx="2.3346901" + transform="matrix(10.416591,0,0,10.416666,451.26602,18.976929)" + inkscape:label="Square-Shadow" /> + <rect + rx="23.865547" + y="19.752666" + x="453.7417" + height="129.82222" + width="129.82127" + id="rect24838" + style="display:inline;fill:url(#radialGradient1478);fill-opacity:1;stroke-width:3.36314" + inkscape:label="Square-Background" /> + <path + style="fill:url(#linearGradient5088);stroke-width:3.20667" + inkscape:connector-curvature="0" + id="path4986" + d="m 486.58552,31.747108 c -1.77909,0 -3.20679,1.427114 -3.20679,3.206817 v 12.839519 h 6.41328 V 34.953925 c 0,-1.779673 -1.42683,-3.206817 -3.20679,-3.206817 z m 12.82685,0 c -1.77909,0 -3.2068,1.427114 -3.2068,3.206817 v 12.839519 h 6.41328 V 34.953925 c 0,-1.779673 -1.4268,-3.206817 -3.20679,-3.206817 z m 12.82656,0 c -1.77909,0 -3.2068,1.427114 -3.2068,3.206817 v 12.839519 h 6.41357 V 34.953925 c 0,-1.779673 -1.42681,-3.206817 -3.20708,-3.206817 z m 12.82684,0 c -1.77909,0 -3.20679,1.427114 -3.20679,3.206817 v 12.839519 h 6.41328 V 34.953925 c 0,-1.779673 -1.42681,-3.206817 -3.20679,-3.206817 z m 12.82656,0 c -1.77909,0 -3.20679,1.427114 -3.20679,3.206817 v 12.839519 h 6.41356 V 34.953925 c 0,-1.779673 -1.4268,-3.206817 -3.20708,-3.206817 z m 12.82684,0 c -1.77909,0 -3.20679,1.427114 -3.20679,3.206817 v 12.839519 h 6.41328 V 34.953925 c 0,-1.779673 -1.4268,-3.206817 -3.20679,-3.206817 z m 0,0" /> + <path + style="fill:url(#linearGradient5104);stroke-width:3.20667" + inkscape:connector-curvature="0" + id="path5078" + d="m 483.37904,121.54693 v 12.8267 c 0,1.77967 1.4268,3.20681 3.20677,3.20681 1.77909,0 3.20679,-1.42681 3.20679,-3.20681 v -12.8267 z m 12.82653,0 v 12.8267 c 0,1.77967 1.42683,3.20681 3.2068,3.20681 1.77909,0 3.20679,-1.42681 3.20679,-3.20681 v -12.8267 z m 12.82687,0 v 12.8267 c 0,1.77967 1.42681,3.20681 3.20677,3.20681 1.77909,0 3.20679,-1.42681 3.20679,-3.20681 v -12.8267 z m 12.82654,0 v 12.8267 c 0,1.77967 1.42683,3.20681 3.20679,3.20681 1.77909,0 3.20679,-1.42681 3.20679,-3.20681 v -12.8267 z m 12.82686,0 v 12.8267 c 0,1.77967 1.42681,3.20681 3.20678,3.20681 1.77909,0 3.20679,-1.42681 3.20679,-3.20681 v -12.8267 z m 12.82654,0 v 12.8267 c 0,1.77967 1.42683,3.20681 3.20708,3.20681 1.77909,0 3.20679,-1.42681 3.20679,-3.20681 v -12.8267 z m 0,0" /> + <path + style="fill:#3d3846;stroke-width:3.20667" + inkscape:connector-curvature="0" + id="path4980" + d="m 480.17224,50.999964 h 76.96021 a 9.6200357,9.6200357 0 0 1 9.62006,9.620094 v 54.513502 a 9.6200357,9.6200357 0 0 1 -9.62006,9.62006 h -76.96021 a 9.6200357,9.6200357 0 0 1 -9.62007,-9.62006 V 60.620058 a 9.6200357,9.6200357 0 0 1 9.62007,-9.620094 z m 0,0" /> + <path + style="fill:#262e36;fill-opacity:1;stroke-width:3.20667" + inkscape:connector-curvature="0" + id="path4988" + d="m 480.17224,41.379989 h 76.96021 a 9.6200357,9.6200357 0 0 1 9.62006,9.619975 v 57.720266 a 9.6200357,9.6200357 0 0 1 -9.62006,9.62003 h -76.96021 a 9.6200357,9.6200357 0 0 1 -9.62007,-9.62003 V 50.999964 a 9.6200357,9.6200357 0 0 1 9.62007,-9.619975 z m 0,0" /> + <path + d="m 453.74142,45.031249 v -1.41652 c 0,-13.22156 10.646,-23.86202 23.86745,-23.86202 h 82.08634 c 13.22156,0 23.86745,10.64046 23.86745,23.86202 v 1.41652 c 0,-13.22145 -10.64589,-23.86745 -23.86745,-23.86745 h -82.08634 c -13.22145,0 -23.86745,10.646 -23.86745,23.86745 z" + inkscape:label="Square-Top-Highlight" + style="display:inline;opacity:0.2;fill:#ffffff;fill-opacity:1;stroke-width:3.36313" + id="path24842" + inkscape:connector-curvature="0" /> + <path + id="path24840" + style="display:inline;opacity:0.2;fill:#000000;fill-opacity:1;stroke-width:3.36313" + inkscape:label="Square-Bottom-Highlight" + d="m 453.74142,124.29638 v 1.41663 c 0,13.22156 10.646,23.86191 23.86745,23.86191 h 82.08634 c 13.22156,0 23.86745,-10.64035 23.86745,-23.86191 v -1.41663 c 0,13.22156 -10.64589,23.86745 -23.86745,23.86745 h -82.08634 c -13.22145,0 -23.86745,-10.64589 -23.86745,-23.86745 z" + inkscape:connector-curvature="0" /> + <g + id="g237" + transform="matrix(0.50144561,0,0,0.50144561,469.36615,53.401791)" + style="fill:#d9d5d1;fill-opacity:1;stroke:url(#linearGradient1470)"> + <path + d="M 148.419,40.725 C 137.843,34.44 134.762,36.625 125.266,29.054 110.441,17.237 92.488,3.794 74.861,0 c 0,0 4.307,3.492 12.283,9.822 0.559,0.465 0.705,0.684 0.595,0.867 -0.169,0.287 -0.928,-0.046 -0.928,-0.046 -6.163,-2.345 -13.123,-3.675 -17.839,-3.37 -1.561,0.1 -2.061,0.352 -2.283,0.797 -0.104,0.209 -0.119,0.772 0.405,1.469 2.061,2.725 7.024,8.064 15.281,13.132 8.486,5.206 23.472,12.592 36.726,18.489 5.932,2.638 10.207,6.164 8.846,10.232 -1.52,4.533 -7.387,5.15 -12.074,3.275 C 112.065,53.144 108.506,48.37 102.725,41.966 92.709,30.868 87.956,26.441 71.335,29.825 63.003,31.522 55.141,38.341 48.853,45.538 44.657,50.83 42.64,55.232 42.032,60.54 c 0,0 -1.146,-2.105 -0.008,-7.49 1.989,-9.407 -2.341,-13.447 -2.341,-13.447 -21.925,31.092 9.261,59.202 33.301,32.281 0,0 -7.865,17.467 -7.21,22.906 -3.355,1.1 -4.845,4.186 0.176,7.91 5.486,4.068 18.961,3.716 29.59,-0.852 19.845,-8.529 32.213,-24.423 38.344,-34.516 1.432,-2.36 2.947,-3.508 3.996,-3.883 1.591,-0.574 12.537,0.086 17.662,-2.824 0.713,0.347 1.621,0.533 2.817,0.442 3.714,-0.282 5.976,-4.727 5.976,-4.727 0,0 -4.687,-8.941 -15.916,-15.615 z m -41.142,44.652 c -10.166,7.24 -21.192,9.26 -28.008,6.262 10.782,-7.818 30.624,-27.373 30.624,-27.373 0,0 -3.302,-8.318 -9.257,-3.225 -5.76,4.925 -11.081,11.078 -13.184,13.043 -1.301,1.213 -3.508,3.506 -4.812,2.52 -1.587,-1.199 3.137,-11.825 6.749,-20.631 4.928,-12.01 -0.742,-15.762 -7.379,-15.429 -5.947,0.299 -14.071,3.903 -19.891,7.462 -1.648,1.009 -2.773,1.629 -3.189,1.244 -0.364,-0.339 0.021,-0.977 1.102,-1.89 15.471,-13.108 37.549,-12.767 39.523,-3.175 1.571,7.65 -14.771,26.914 -13.697,27.223 0.104,0.029 0.338,-0.088 0.68,-0.322 5.364,-7.021 15.521,-17.801 19.331,-17.384 6.827,0.746 9.183,9.794 9.183,9.794 L 92.291,84.034 c 4.701,1.277 9.842,1.738 14.986,1.343 z" + id="path235" + style="fill:#d9d5d1;fill-opacity:1;stroke:url(#linearGradient1500)" /> + </g> + </g> + </g> +</svg> diff --git a/util/coreboot-configurator/src/resources/meson.build b/util/coreboot-configurator/src/resources/meson.build new file mode 100644 index 0000000000..12270ab14e --- /dev/null +++ b/util/coreboot-configurator/src/resources/meson.build @@ -0,0 +1,43 @@ +## SPDX-License-Identifier: GPL-2.0-only + +# Polkit Files +polkit_dir = join_paths(get_option('datadir'), 'polkit-1', 'actions') +polkit_sources = [ + 'org.coreboot.nvramtool.policy', + 'org.coreboot.reboot.policy', +] + +install_data(polkit_sources, + install_dir: polkit_dir) + +# Desktop Entry +desktop_dir = join_paths(get_option('datadir'), 'applications') +desktop_sources = [ + 'coreboot-configurator.desktop', +] + +install_data(desktop_sources, + install_dir: desktop_dir) + +# Icon +inkscape = find_program('inkscape') +icon_dir = join_paths(get_option('datadir'),'icons', 'hicolor') +foreach size: get_option('sizes') + target_temp_name = '@0@'.format(size) + dpi=size.to_int() * 2 + png = configure_file( + input: 'coreboot_configurator.svg', + output: target_temp_name + '.png', + command: [ + inkscape, + '--export-height=@0@'.format(size), + '--export-width=@0@'.format(size), + '--export-png=@OUTPUT@', + '@INPUT@', + ] + ) + + install_data(png, + rename: meson.project_name() + '.png', + install_dir: join_paths(icon_dir, '@0@x@1@'.format(size, size), 'apps')) +endforeach diff --git a/util/coreboot-configurator/src/resources/org.coreboot.nvramtool.policy b/util/coreboot-configurator/src/resources/org.coreboot.nvramtool.policy new file mode 100644 index 0000000000..c95bc8b9a3 --- /dev/null +++ b/util/coreboot-configurator/src/resources/org.coreboot.nvramtool.policy @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE policyconfig PUBLIC + "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" + "http://www.freedesktop.org/software/polkit/policyconfig-1.dtd"> +<policyconfig> + <action id="org.coreboot.nvramtool"> + <message>Authentication is required to read and write to coreboot settings.</message> + <defaults> + <allow_active>auth_admin_keep</allow_active> + </defaults> + <annotate key="org.freedesktop.policykit.exec.path">/usr/sbin/nvramtool</annotate> + </action> +</policyconfig> diff --git a/util/coreboot-configurator/src/resources/org.coreboot.reboot.policy b/util/coreboot-configurator/src/resources/org.coreboot.reboot.policy new file mode 100644 index 0000000000..5364c8c22c --- /dev/null +++ b/util/coreboot-configurator/src/resources/org.coreboot.reboot.policy @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE policyconfig PUBLIC + "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" + "http://www.freedesktop.org/software/polkit/policyconfig-1.dtd"> +<policyconfig> + <action id="org.coreboot.reboot"> + <defaults> + <allow_active>yes</allow_active> + </defaults> + <annotate key="org.freedesktop.policykit.exec.path">/usr/sbin/reboot</annotate> + </action> +</policyconfig> |