diff options
author | sr | 2013-02-04 19:50:31 +0100 |
---|---|---|
committer | sr | 2013-02-04 19:50:31 +0100 |
commit | 1a5709501f94014d41987b956338bb6424b9f90c (patch) | |
tree | d3b93fe8dc406bca56aff147ef5cc4cbf9ed6be0 /src/client/vnc/vncserver.cpp | |
parent | Test (diff) | |
download | pvs2-1a5709501f94014d41987b956338bb6424b9f90c.tar.gz pvs2-1a5709501f94014d41987b956338bb6424b9f90c.tar.xz pvs2-1a5709501f94014d41987b956338bb6424b9f90c.zip |
Initial commit
Diffstat (limited to 'src/client/vnc/vncserver.cpp')
-rw-r--r-- | src/client/vnc/vncserver.cpp | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/src/client/vnc/vncserver.cpp b/src/client/vnc/vncserver.cpp new file mode 100644 index 0000000..2b49b8e --- /dev/null +++ b/src/client/vnc/vncserver.cpp @@ -0,0 +1,191 @@ +/* + * vncserver.cpp + * + * Created on: 24.01.2013 + * Author: sr + */ + +#include <QProcess> +#include "vncserver.h" +#include "../util/util.h" + +/******************************************* + * STATIC + *******************************************/ + +VncServer* VncServer::me = NULL; + +VncServer* VncServer::instance() +{ + if (me == NULL) + me = new VncServer(); + return me; +} + +// +static QString makePassword(int len = 10) +{ + char pass[len]; + for (int i = 0; i < len; ++i) + pass[i] = 43 + qrand() % 80; + return QString::fromUtf8(pass, len); +} + +// Ugly hack to get an el-cheapo platform independent sleep +struct Sleeper : public QThread +{ +static void msleep(unsigned long msecs) { QThread::msleep(msecs); } +}; + +/******************************************* + * INSTANCE + *******************************************/ + +VncServer::VncServer() : + _process(NULL), _port(0), _timerId(0) +{ + // TODO Auto-generated constructor stub +} + +VncServer::~VncServer() +{ + // TODO Auto-generated destructor stub +} + +void VncServer::start() +{ + // Keep things clean + if (_process != NULL) + { + disconnect(_process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(onError(QProcess::ProcessError))); + disconnect(_process, SIGNAL(finished(int)), this, SLOT(onFinished(int))); + } + this->stop(); + // Generate passwords + _rwpass = makePassword(); + _ropass = makePassword(); + // Create new password file + QDir path = Util::settingsDir(); + QString pwfile(path.absoluteFilePath("vncpass")); + QFile pwhandle(pwfile); + if (pwhandle.exists()) + pwhandle.remove(); + if (!pwhandle.open(QIODevice::WriteOnly)) + { + qDebug() << "Could not open " << pwfile << " for writing"; + emit started(0, _ropass, _rwpass); + return; + } + pwhandle.setPermissions(QFile::ReadOwner | QFile::WriteOwner); + pwhandle.write(_rwpass.toUtf8().constData()); + pwhandle.write("\n"); + pwhandle.write(_ropass.toUtf8().constData()); + pwhandle.write("\n"); + pwhandle.close(); + // Create new process + _process = new QProcess(this); + connect(_process, SIGNAL(readyReadStandardOutput()), this, SLOT(onStdOut())); + connect(_process, SIGNAL(readyReadStandardError()), this, SLOT(onStdErr())); + connect(_process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(onError(QProcess::ProcessError))); + connect(_process, SIGNAL(finished(int)), this, SLOT(onFinished(int))); + _timerId = startTimer(4000); + QStringList args; + args << "-forever"; + args << "-display" << ":0"; + args << "-passwdfile" << (QString("rm:" + pwfile)); + args << "-shared"; + args << "-autoport" << QString::number(54112); + qDebug() << "Arguments are: " << args; + _process->start("x11vnc", + args, + QIODevice::ReadOnly); +} + +void VncServer::stop() +{ + if (_timerId != 0) + { + killTimer(_timerId); + _timerId = 0; + } + if (_process == NULL) + return; + qDebug("Stopping old VNC server."); + disconnect(_process, SIGNAL(readyReadStandardOutput()), this, SLOT(onStdOut())); + disconnect(_process, SIGNAL(readyReadStandardError()), this, SLOT(onStdErr())); + QProcess *process = _process; + _process = NULL; + _port = 0; + process->terminate(); + for (int i = 0; i < 10 && process->state() != QProcess::NotRunning; ++i) + Sleeper::msleep(10); + if (process->state() == QProcess::Running) + process->kill(); + for (int i = 0; i < 10 && process->state() != QProcess::NotRunning; ++i) + Sleeper::msleep(10); + process->deleteLater(); +} + +/** + * Overrides + */ + +void VncServer::timerEvent(QTimerEvent *event) +{ + // Error timeout (3s), tell server that vnc setup failed + this->stop(); + emit started(0, _ropass, _rwpass); +} + +/** + * Slots + */ + +void VncServer::onStdOut() +{ + if (_process == NULL) + { + qDebug("VncServer::onStdOut() called in bad state."); + return; + } + QByteArray data(_process->readAllStandardOutput()); + qDebug() << "x11vnc: " << data; + if (_port <= 0) + { + const int pos = data.indexOf("PORT=", 0); + if (pos != -1) + { + _port = atoi(data.constData() + pos + 5); + qDebug() << "Got VNC port " << _port << ", ro " << _ropass << ", rw " << _rwpass; + emit started(_port, _ropass, _rwpass); + // Kill error timer, but only if port seemed valid + if (_timerId != 0 && _port > 0) + { + killTimer(_timerId); + _timerId = 0; + } + } + } +} + +void VncServer::onStdErr() +{ + if (_process == NULL) + { + qDebug("VncServer::onStdErr() called in bad state."); + return; + } + QByteArray data(_process->readAllStandardError()); +} + +void VncServer::onError(QProcess::ProcessError error) +{ + this->stop(); + emit started(0, _ropass, _rwpass); +} + +void VncServer::onFinished(int exitCode) +{ + this->stop(); + emit started(0, _ropass, _rwpass); +} |