summaryrefslogtreecommitdiffstats
path: root/src/client/vnc/vncserver.cpp
diff options
context:
space:
mode:
authorsr2013-02-04 19:50:31 +0100
committersr2013-02-04 19:50:31 +0100
commit1a5709501f94014d41987b956338bb6424b9f90c (patch)
treed3b93fe8dc406bca56aff147ef5cc4cbf9ed6be0 /src/client/vnc/vncserver.cpp
parentTest (diff)
downloadpvs2-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.cpp191
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);
+}