From cbb1ff209a6af588d15c4469d44af8166a558cc0 Mon Sep 17 00:00:00 2001 From: Guillaume BOEHM Date: Tue, 16 Apr 2024 11:24:59 +0200 Subject: [PATCH 1/2] Build fixes --- .gitignore | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitignore b/.gitignore index 259148f..22d8993 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,10 @@ *.exe *.out *.app + +# Generated files +src/i18n/* + +# Generated build files +compile_commands.json +build/ From 6648097be0e80f3673637c7013b8d3078de84046 Mon Sep 17 00:00:00 2001 From: Guillaume BOEHM Date: Tue, 16 Apr 2024 15:50:04 +0200 Subject: [PATCH 2/2] Add CLI Options - Only the CoolerBoost for now as a POC - Modified some lines that static analyzer was complaining about - Add Options class to handle arg parsing and different option values --- CMakeLists.txt | 2 ++ src/cli.cpp | 58 +++++++++++++++++++++++++++++++ src/cli.h | 33 ++++++++++++++++++ src/main.cpp | 40 ++++++++++++++++++++-- src/mainwindow.cpp | 18 ++++++---- src/mainwindow.h | 1 + src/options.cpp | 85 ++++++++++++++++++++++++++++++++++++++++++++++ src/options.h | 53 +++++++++++++++++++++++++++++ 8 files changed, 281 insertions(+), 9 deletions(-) create mode 100644 src/cli.cpp create mode 100644 src/cli.h create mode 100644 src/options.cpp create mode 100644 src/options.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9bfd002..804b2d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,9 +19,11 @@ set(PROJECT_SOURCES src/mainwindow.ui src/mainwindow.cpp src/mainwindow.h src/operate.cpp src/operate.h + src/cli.cpp src/cli.h src/helper.cpp src/helper.h src/msi-ec_helper.cpp src/msi-ec_helper.h src/settings.cpp src/settings.h + src/options.cpp src/options.h src/resources.qrc ) diff --git a/src/cli.cpp b/src/cli.cpp new file mode 100644 index 0000000..fd46be1 --- /dev/null +++ b/src/cli.cpp @@ -0,0 +1,58 @@ +/* Copyright (C) 2022 Dmitry Serov + * + * This file is part of MControlCenter. + * + * MControlCenter is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * MControlCenter is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with MControlCenter. If not, see . + */ + +#include "cli.h" +#include "operate.h" + +static Operate operate; + +CLI::CLI() { + if (!operate.isEcSysModuleLoaded() && !operate.loadEcSysModule()){ + fprintf(stderr, "Failed to load the ec_sys kernel module\n"); + exit(1); + } + + if(!operate.updateEcData() || operate.getEcVersion().empty()){ + fprintf(stderr, "Failed to update EC data\n"); + exit(1); + } + + if (!operate.doProbe()) { + fprintf(stderr, "Failed probing devices\n"); + exit(1); + } +} + +CLI::~CLI() { +} + +void CLI::setCoolerBoost(Options::State state){ + bool on = false; + if(state == Options::State::TOGGLE){ // TOGGLE + on = !operate.getCoolerBoostState(); + } + else{ + on = state; + } + + if(operate.getCoolerBoostState() != on){ + fprintf(stdout, "%s Cooler Boost\n", ( on ? "Enabling" : "Disabling" )); + operate.setCoolerBoostState(on); + operate.updateEcData(); + } +} diff --git a/src/cli.h b/src/cli.h new file mode 100644 index 0000000..6613afb --- /dev/null +++ b/src/cli.h @@ -0,0 +1,33 @@ +/* Copyright (C) 2022 Dmitry Serov + * + * This file is part of MControlCenter. + * + * MControlCenter is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * MControlCenter is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with MControlCenter. If not, see . + */ + +#ifndef CLI_H +#define CLI_H + +#include "options.h" + +class CLI { + +public: + CLI(); + ~CLI(); + + void setCoolerBoost(Options::State on); +}; + +#endif // CLI_H diff --git a/src/main.cpp b/src/main.cpp index 04faa86..b487037 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,6 +17,8 @@ */ #include "mainwindow.h" +#include "cli.h" +#include "options.h" #include #include @@ -25,11 +27,34 @@ int main(int argc, char *argv[]) { + + Options options; + options.process_args(argc, argv); + const QString serverName = "MControlCenter"; - auto *socket = new QLocalSocket(); + QLocalSocket* socket = new QLocalSocket(); socket->connectToServer(serverName); + + if(options.cli){ + fprintf(stderr, "Executing CLI commands...\n"); + CLI cli; + if(options.cooler_boost.has_value()){ + cli.setCoolerBoost(options.cooler_boost.value()); + } + + if (socket->isOpen()) { + socket->write("update"); + socket->flush(); + socket->close(); + } + socket->deleteLater(); + return 0; + } + if (socket->isOpen()) { fprintf(stderr, "Another instance of the application is already running\n"); + socket->write("show"); + socket->flush(); socket->close(); socket->deleteLater(); return 0; @@ -51,8 +76,17 @@ int main(int argc, char *argv[]) { MainWindow w; QLocalServer server; - QObject::connect(&server, &QLocalServer::newConnection, [&w]() { - w.show(); + QObject::connect(&server, &QLocalServer::newConnection, [&w, &server]() { + QLocalSocket* socket = server.nextPendingConnection(); + if(socket->waitForConnected() && socket->waitForReadyRead()){ + QByteArray data = socket->readAll(); + if(std::strcmp(data.data(), "show") == 0){ + w.show(); + } + else if(std::strcmp(data.data(), "update") == 0){ + w.externalUpdate(); + } + } }); bool serverListening = server.listen(serverName); if (!serverListening && (server.serverError() == QAbstractSocket::AddressInUseError)) { diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 37b4ddd..878ba1d 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -23,7 +23,7 @@ #include #include -Operate operate; +static Operate operate; bool isActive = false; bool isUpdateDataError = false; @@ -204,6 +204,11 @@ void MainWindow::realtimeUpdate() { updateData(); } +void MainWindow::externalUpdate() { + if(operate.updateEcData()) + updateData(); +} + void MainWindow::updateData() { if (!isUpdateDataError && !operate.getEcVersion().empty()) { if (!isActive) { @@ -221,6 +226,7 @@ void MainWindow::updateData() { updateFan2Speed(); updateKeyboardBrightness(); updateWebCamState(); + updateCoolerBoostState(); } else { setTabsEnabled(false); isActive = false; @@ -427,10 +433,10 @@ void MainWindow::updateFanMode() { void MainWindow::updateFanSpeedSettings() { ui->advancedFanControlCheckBox->setChecked(operate.getFanMode() == fan_mode::advanced_fan_mode); - QVector fan1SpeedSettings = operate.getFan1SpeedSettings(); - QVector fan1TempSettings = operate.getFan1TempSettings(); - QVector fan2SpeedSettings = operate.getFan2SpeedSettings(); - QVector fan2TempSettings = operate.getFan2TempSettings(); + QVector fan1SpeedSettings = operate.getFan1SpeedSettings(); + QVector fan1TempSettings = operate.getFan1TempSettings(); + QVector fan2SpeedSettings = operate.getFan2SpeedSettings(); + QVector fan2TempSettings = operate.getFan2TempSettings(); ui->fan1Speed1Slider->setValue(fan1SpeedSettings[0]); ui->fan1Speed2Slider->setValue(fan1SpeedSettings[1]); @@ -801,4 +807,4 @@ void MainWindow::createActions() { void MainWindow::saveStateRequest(QSessionManager &sessionManager) { sessionManager.setRestartHint(QSessionManager::RestartNever); -} \ No newline at end of file +} diff --git a/src/mainwindow.h b/src/mainwindow.h index 7707139..17893a9 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -35,6 +35,7 @@ Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); + void externalUpdate(); void updateData(); static void setUpdateDataError(bool error); diff --git a/src/options.cpp b/src/options.cpp new file mode 100644 index 0000000..727adf0 --- /dev/null +++ b/src/options.cpp @@ -0,0 +1,85 @@ +/* Copyright (C) 2022 Dmitry Serov + * + * This file is part of MControlCenter. + * + * MControlCenter is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * MControlCenter is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with MControlCenter. If not, see . + */ +#include "options.h" + +#include + +Options::Options() + :cli(false), cooler_boost(std::nullopt) +{} + +void Options::print_help(std::string program_name) +{ + fprintf(stdout, R"(Description +Syntax: %s [options] + + -B, --coolerboost STATE toggle fan cooler boost + -h show help + +Arguments: + STATE: can be 'ON', 'OFF' or 'TOGGLE' +)", program_name.c_str()); + exit(1); +} + +void Options::process_args(int argc, char** argv) +{ + int option_index; + while (true) + { + const auto opt = getopt_long(argc, argv, short_opts.data(), long_opts, &option_index); + + if (-1 == opt){ + break; + } + + switch (opt) + { + case 0: + cli = true; + // long option without short equivalent + break; + + case 'B': + cli = true; + + if(std::strcmp(optarg,"ON") == 0){ + cooler_boost = std::optional{Options::State::ON}; + } + else if(std::strcmp(optarg,"OFF") == 0) + { + cooler_boost = std::optional{Options::State::OFF}; + } + else if(std::strcmp(optarg,"TOGGLE") == 0) + { + cooler_boost = std::optional{Options::State::TOGGLE}; + } + else{ + fprintf(stderr, "Wrong TOGGLE value for coolerboost option.\n"); + print_help(argv[0]); + } + break; + + case 'h': // -h or --help + case '?': // Unrecognized option + default: + print_help(argv[0]); + break; + } + } +} diff --git a/src/options.h b/src/options.h new file mode 100644 index 0000000..27644dc --- /dev/null +++ b/src/options.h @@ -0,0 +1,53 @@ +/* Copyright (C) 2022 Dmitry Serov + * + * This file is part of MControlCenter. + * + * MControlCenter is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * MControlCenter is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with MControlCenter. If not, see . + */ + +#ifndef OPTIONS_H +#define OPTIONS_H + +#include +#include +#include + +class Options{ +public: + Options(); + ~Options() = default; + + enum State { + OFF = 0, + ON = 1, + TOGGLE = 2 + }; + + bool cli; + std::optional cooler_boost; + + void process_args(int argc, char** argv); + +private: + static constexpr std::string_view const short_opts = "B:h"; + static constexpr option long_opts[] = { + {"coolerboost", required_argument, nullptr, 'B'}, + {"help", no_argument, nullptr, 'h'}, + {nullptr, no_argument, nullptr, 0} + }; + + void print_help(std::string program_name); +}; + +#endif // OPTIONS_H