Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Common/LtsProjectionWorkstation/vnc_server_manager.cpp
T
torstenandCopilot 7a6be7474e Qt6 migration: Fix BUILD_RTI=OFF build errors in TrainingAreaBase
- training_area_telegrams.cpp: Fixed QJsonObject initializer syntax (Qt6 requires {{}} not ({}))
- training_area_telegrams.cpp: Fixed fromJson() methods to access m_* members directly
- training_area_telegrams.cpp: Fixed brace mismatches in multiple toJson() methods
- training_area_telegrams.h: Changed Header struct to public members for consistency
- tx_mixin.cpp: Fixed getEquipmentNumber() template for direct member access
- lts_coordinate.cpp: Added missing #include <iomanip>
- MIGRATION_STATUS.md: Added migration progress tracking document

C++17 constraint enforced due to RTI Connext DDS 7.7.0 incompatibility with C++20+

Build status: BUILD_RTI=OFF successful (0 errors, warnings only)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-08-23 20:49:23 +02:00

180 lines
5.3 KiB
C++

#include "vnc_server_manager.h"
#include <QtCore/QDir>
#include <QtCore/QRegularExpression>
#include <QtGui/QScreen>
#include <utility>
namespace LtsProjectionWorkstation
{
VncServerManager::VncServerManager(LOGGER_T& logger, QObject* parent) : QObject(parent), m_logger(logger) {}
VncServerManager::~VncServerManager()
{
stopScreens();
}
QList<QScreen*> sortScreen(const QList<QScreen*>& screens)
{
auto ret(screens);
auto doSortScreens = [](const QScreen* s1, const QScreen* s2) -> bool {
const auto tl1 = s1->geometry().topLeft();
const auto tl2 = s2->geometry().topLeft();
if (tl1.y() > tl2.y())
return true;
if (tl1.y() < tl2.y())
return false;
return tl1.x() < tl2.x();
};
std::sort(ret.begin(), ret.end(), doSortScreens);
return ret;
}
bool VncServerManager::init(const QList<QScreen*>& screens)
{
killScreens();
createPwdFile();
const auto sortedScreens = sortScreen(screens);
DEBUG_LOG(m_logger) << "Setup VNCScreens with " << screens.size() << " screens";
int count = 1;
static constexpr char VNC_START_ARGS[] =
"-rfbauth,%1/.vnc/passwd,-clip,%2x%3+%4+%5,-loop100,-forever,-display,:0,-threads,-noxdamage";
for (QScreen* screen : sortedScreens)
{
VncScreen vncScreen;
vncScreen.geometry = screen->geometry();
vncScreen.name = QStringLiteral("Display%1").arg(count);
vncScreen.proc = new QProcess(this);
QString startArgs = QString::fromLatin1(VNC_START_ARGS)
.arg(QDir::home().absolutePath())
.arg(screen->geometry().width())
.arg(screen->geometry().height())
.arg(screen->geometry().x())
.arg(screen->geometry().y());
vncScreen.proc->setProgram(QStringLiteral("x11vnc"));
vncScreen.proc->setArguments(startArgs.split(QLatin1Char(',')));
NOTICE_LOG(m_logger) << "Started VNC for Screen " << count << " with geometry " << screen->geometry().width()
<< "," << screen->geometry().height() << "+" << screen->geometry().x() << "+"
<< screen->geometry().y();
m_vncScreens.push_back(vncScreen);
count++;
}
DEBUG_LOG(m_logger) << m_vncScreens.size() << " VNCScreen(s) created - Setup completed.";
return true;
}
void VncServerManager::startScreens()
{
DEBUG_LOG(m_logger) << "Starting " << m_vncScreens.size() << " VNCScreen(s) ... ";
for (const VncScreen& s : std::as_const(m_vncScreens))
{
connect(s.proc, &QProcess::readyReadStandardOutput, this, &VncServerManager::slotReadStandardOutput,
Qt::UniqueConnection);
connect(s.proc, &QProcess::errorOccurred, this, &VncServerManager::slotErrorOccured, Qt::UniqueConnection);
s.proc->start();
}
for (const VncScreen& s : std::as_const(m_vncScreens))
{
if (!s.proc->waitForStarted(2000))
ERROR_LOG(m_logger) << "Can not start process '" << s.proc->program() << "': " << s.proc->errorString();
}
DEBUG_LOG(m_logger) << "Done";
}
void VncServerManager::stopScreens()
{
DEBUG_LOG(m_logger) << "Stopping " << m_vncScreens.size() << " VNCScreen(s) ...";
for (const VncScreen& s : std::as_const(m_vncScreens))
{
s.proc->disconnect(this);
s.proc->terminate();
}
for (const VncScreen& s : std::as_const(m_vncScreens))
{
if (!s.proc->waitForFinished(2000))
s.proc->kill();
}
DEBUG_LOG(m_logger) << "Done";
}
void VncServerManager::killScreens()
{
DEBUG_LOG(m_logger) << "Killing all exisiting x11vnc processes ...";
SingleShotProcess ssp(QStringLiteral("killall x11vnc"));
ssp.execute();
DEBUG_LOG(m_logger) << "Done";
}
void VncServerManager::createPwdFile()
{
DEBUG_LOG(m_logger) << "(Re)creating x11vnc password-file ...";
SingleShotProcess ssp(
QStringLiteral("x11vnc -storepasswd ctc11de %1/.vnc/passwd").arg(QDir::home().absolutePath()));
ssp.execute();
DEBUG_LOG(m_logger) << "Done";
}
void VncServerManager::slotReadStandardOutput()
{
QProcess* p = qobject_cast<QProcess*>(QObject::sender());
if (!p)
return;
QString stdOut = QString::fromLocal8Bit(p->readAllStandardOutput());
QRegularExpressionMatch match = QRegularExpression(QStringLiteral("PORT=(.*?)\\s")).match(stdOut);
if (!match.hasMatch())
{
WARNING_LOG(m_logger) << "Could not retrieve port information from stdout of " << p->program();
return;
}
const quint16 port = match.captured(1).toInt();
if (port == 0)
return;
for (VncScreen& screen : m_vncScreens)
{
if (screen.proc != p)
continue;
screen.port = port;
disconnect(screen.proc, &QProcess::readyReadStandardOutput, nullptr, nullptr);
break;
}
}
void VncServerManager::slotErrorOccured()
{
QProcess* p = qobject_cast<QProcess*>(QObject::sender());
if (p)
ERROR_LOG(m_logger) << p->errorString();
}
SingleShotProcess::SingleShotProcess(const QString& cmd, bool startImmediatly) : m_cmd(cmd)
{
if (startImmediatly)
execute();
}
bool SingleShotProcess::execute()
{
m_process.start(m_cmd);
return m_process.waitForFinished();
}
} // namespace LtsProjectionWorkstation