Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

+34
View File
@@ -0,0 +1,34 @@
#
# Tool to easily & quickly configure customer X server screen positions
#
# $Id$
# $HeadURL$
# $Author$
#
# Created by Mike Wille, NLSE, 2018-02-02
#
IF(NOT WIN32)
SET(ConfigX_SRCS
main.cpp
configurator.h
configurator.cpp
guez2018/guez2018.h
guez2018/guez2018.cpp
)
SET(ConfigX_UICS
guez2018/guez2018.ui
)
QT5_ADD_RESOURCES(ConfigX_SRCS resources.qrc)
NGL_WRAP_UI(ConfigX_SRCS ${ConfigX_UICS})
NGL_ADD_EXECUTABLE(WS ConfigX NO_TRANSLATION ${ConfigX_SRCS} ${ConfigX_UICS})
NGL_TARGET_LINK_LIBRARIES(ConfigX
Qt5::Widgets
)
NGL_INSTALL_TARGET(ConfigX)
ENDIF(NOT WIN32)
+200
View File
@@ -0,0 +1,200 @@
#include "configurator.h"
#include "guez2018/guez2018.h"
#include <QApplication>
#include <QScreen>
#include <QPushButton>
#include <QMessageBox>
#include <QStyle>
#include <QDesktopWidget>
#include <QFile>
#include <QCheckBox>
#include <QProcess>
#include <QDebug>
Configurator::Configurator(const QString &filename)
: QWidget(nullptr)
, m_uiIfc(nullptr)
, m_currentScreen(nullptr)
, m_mainScreen(nullptr)
, m_filename(filename)
, m_cbMainScreen(nullptr)
{
int index = projectNames().indexOf(m_filename);
switch (index)
{
case 0: // guez2018
{
m_uiIfc = new Guez2018(this);
break;
}
default:
{
QMessageBox::critical(this, QString(), QStringLiteral("Ui implementation missing for this project - aborting."));
QCoreApplication::quit();
return;
}
}
m_cbMainScreen = findChild<QCheckBox *>(QStringLiteral("cbMainScreen"));
if (m_cbMainScreen == nullptr)
{
qWarning() << "Developer: there is no ui element 'cbMainScreen' !";
QCoreApplication::quit();
return;
}
m_screensToTest = QGuiApplication::screens();
QList<QPushButton *> screenButtons = findChildren<QPushButton *>();
for (auto i = screenButtons.constBegin(); i != screenButtons.constEnd(); ++i)
{
QPushButton *btn = *i;
btn->setStyleSheet(QStringLiteral("QPushButton:hover { padding: 4px; border: 1px solid; border-color: #009933; border-radius: 2px; background-color: #99ff99; outline: none; } "
"QPushButton { padding: 4px; border: 1px solid; border-color: #66ff66; border-radius: 2px; background-color: #ccffcc; outline: none; } "
"QPushButton:disabled { padding: 4px; border: 1px solid; border-color: #000000; border-radius: 2px; background-color: #b3b3b3; outline: none; }"));
connect(btn, &QPushButton::clicked,
this, &Configurator::slotScreenClicked);
}
slotGo();
}
Configurator::~Configurator()
{
delete m_uiIfc;
}
void Configurator::slotScreenClicked()
{
//QMap<QString, QPoint> m_config;
QPushButton *screenButton = qobject_cast<QPushButton *>(sender());
screenButton->setEnabled(false); // already selected now
if (m_cbMainScreen->isChecked())
{
m_mainScreen = m_currentScreen;
m_cbMainScreen->setEnabled(false); // cannot set more than one main screen :)
m_cbMainScreen->setChecked(false); // there is already the main screen
}
m_config.insert(m_currentScreen->name(),
QPoint(screenButton->property("screenX").toInt(),
screenButton->property("screenY").toInt()));
slotGo(); // next !
}
void Configurator::slotGo()
{
if (m_screensToTest.isEmpty())
{
done();
return;
}
m_currentScreen = m_screensToTest.takeFirst();
setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, size(), m_currentScreen->availableGeometry()));
}
void Configurator::done()
{
hide();
slotSave();
}
void Configurator::slotSave()
{
if (m_mainScreen == nullptr)
{
QMessageBox::critical(this, QString(), QStringLiteral("You did not specify the main screen - aborting."));
QCoreApplication::quit();
return;
}
QFile f(QStringLiteral(":/%1.conf").arg(m_filename));
if (!f.open(QFile::ReadOnly))
{
QMessageBox::critical(this, QString(), QStringLiteral("Cannot open project template file from resources - aborting."));
QCoreApplication::quit();
return;
}
QString config = QString::fromUtf8(f.readAll());
int index = projectNames().indexOf(m_filename);
switch (index)
{
case 0: // guez2018
{
QStringList metamodes;
for (auto i = m_config.constBegin(); i != m_config.constEnd(); ++i)
{
const QString &interfaceName = i.key();
const QPoint &screenPos = i.value();
metamodes.append(QStringLiteral("%1: nvidia-auto-select +%2+%3").arg(interfaceName).arg(screenPos.x()).arg(screenPos.y()));
}
config = config.arg(m_mainScreen->name(), metamodes.join(QStringLiteral(", ")));
break;
}
default:
{
QMessageBox::critical(this, QString(), QStringLiteral("Save implementation missing for this project - aborting."));
QCoreApplication::quit();
return;
}
}
QString configFileName(QStringLiteral("/etc/X11/xorg.conf.d/50-nvidia.conf"));
if (QFile::remove(QStringLiteral("/etc/X11/xorg.conf")))
qWarning() << "xorg.conf deleted as this file is non-sense..";
QFile configFile(configFileName);
if (!configFile.open(QFile::WriteOnly))
{
QMessageBox::critical(this, QString(), QStringLiteral("Cannot write to config file '%1'.\n%2.\nAborting.").arg(configFileName, configFile.errorString()));
QCoreApplication::quit();
return;
}
configFile.write(config.toUtf8());
if (QMessageBox::question(this, QString(),
QStringLiteral("Config file '%1' was successfully written.\nDo you want to restart the X server now?").arg(configFileName),
QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No) == QMessageBox::StandardButton::Yes)
{
QProcess::startDetached(QStringLiteral("systemctl restart display-manager"));
}
QCoreApplication::quit(); // done!
}
void Configurator::closeEvent(QCloseEvent */*event*/)
{
QCoreApplication::quit();
}
+49
View File
@@ -0,0 +1,49 @@
#pragma once
#include <QWidget>
#include <QMap>
namespace Ui
{
class Configurator;
}
class QCheckBox;
class UiInterface
{
public:
virtual ~UiInterface() = default;
};
class Configurator : public QWidget
{
Q_OBJECT
public:
Configurator(const QString &filename);
~Configurator();
bool init();
static const QStringList projectNames() { return { QStringLiteral("guez2018") }; }
private slots:
void slotSave();
void slotGo();
void slotScreenClicked();
private:
void closeEvent(QCloseEvent *event) override;
void done();
UiInterface *m_uiIfc;
QList<QScreen *> m_screensToTest;
QScreen *m_currentScreen;
QScreen *m_mainScreen;
QMap<QString, QPoint> m_config;
QString m_filename;
QCheckBox *m_cbMainScreen;
};
+48
View File
@@ -0,0 +1,48 @@
# Config created by Lts/Tools/ConfigX
# ConfigX created by Mike Wille, NLSE, 2018-02-02
# nvidia-settings version: version 384.69 (buildd@lgw01-amd64-056) Tue Oct 10 10:21:06 UTC 2017
# Guez 2018
# Machine: HP Z640
# Screens: 4x 1920x1080
Section "ServerLayout"
Identifier "Layout0"
Screen 0 "Screen0" 0 0
Option "Xinerama" "0"
EndSection
Section "Monitor"
# HorizSync source: edid, VertRefresh source: edid
Identifier "Monitor0"
VendorName "Unknown"
ModelName "FUS B24-8 TE Pro"
HorizSync 30.0 - 82.0
VertRefresh 48.0 - 76.0
Option "DPMS"
EndSection
Section "Device"
Identifier "Device0"
Driver "nvidia"
VendorName "NVIDIA Corporation"
BoardName "Quadro K1200"
EndSection
Section "Screen"
Identifier "Screen0"
Device "Device0"
Monitor "Monitor0"
DefaultDepth 24
Option "Stereo" "0"
Option "nvidiaXineramaInfoOrder" "%1"
Option "metamodes" "%2"
Option "SLI" "Off"
Option "MultiGPU" "Off"
Option "BaseMosaic" "off"
SubSection "Display"
Depth 24
EndSubSection
EndSection
+15
View File
@@ -0,0 +1,15 @@
#include "guez2018.h"
#include "ui_guez2018.h"
Guez2018::Guez2018(QWidget *setupUi)
: m_ui(new Ui::Configurator)
{
m_ui->setupUi(setupUi);
}
Guez2018::~Guez2018()
{
delete m_ui;
}
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include "configurator.h"
#include <QWidget>
namespace Ui
{
class Configurator;
}
class Guez2018 : public UiInterface
{
public:
Guez2018(QWidget *setupUi);
~Guez2018();
private:
Ui::Configurator *m_ui;
};
+145
View File
@@ -0,0 +1,145 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Configurator</class>
<widget class="QWidget" name="Configurator">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>226</width>
<height>278</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string notr="true">ConfigX</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Which Screen is this?</string>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QPushButton" name="screen2">
<property name="minimumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="screenX" stdset="0">
<number>0</number>
</property>
<property name="screenY" stdset="0">
<number>1080</number>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="screen0">
<property name="minimumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="screenX" stdset="0">
<number>0</number>
</property>
<property name="screenY" stdset="0">
<number>0</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="screen1">
<property name="minimumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="screenX" stdset="0">
<number>1920</number>
</property>
<property name="screenY" stdset="0">
<number>0</number>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="screen3">
<property name="minimumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="screenX" stdset="0">
<number>1920</number>
</property>
<property name="screenY" stdset="0">
<number>1080</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="cbMainScreen">
<property name="text">
<string>This is the main screen</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+53
View File
@@ -0,0 +1,53 @@
#include "configurator.h"
#include <unistd.h>
#include <QApplication>
#include <QMessageBox>
#include <QProcess>
#include <QDebug>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QStringList arguments = app.arguments();
if (arguments.count() < 2)
{
qWarning() << "usage:" << arguments.at(0)
<< "<project name (" << Configurator::projectNames().join(QStringLiteral(", ")) << ")>";
return -1;
}
QString projectName = arguments.at(1);
if (!Configurator::projectNames().contains(projectName))
{
QMessageBox::critical(nullptr, QString(),
QStringLiteral("Unknown project. Available project names: %1").arg(
Configurator::projectNames().join(QStringLiteral(", "))));
return -2;
}
bool isDebug = (arguments.count() > 2 && arguments.at(2) == QStringLiteral("debug"));
if (!isDebug)
{
// restart if not root
uid_t uid = getuid();
if (uid != 0) // root
{
QProcess::startDetached(QStringLiteral("xgd-su -c %1 %2").arg(arguments.at(0), projectName));
//qWarning() << "wrong uid" << uid;
return 0;
}
}
Configurator *c = new Configurator(projectName);
c->show();
return app.exec();
}
+5
View File
@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file alias="guez2018.conf">guez2018/guez2018.conf</file>
</qresource>
</RCC>