summaryrefslogtreecommitdiffstats
path: root/src/util
diff options
context:
space:
mode:
authorSebastian2010-05-12 19:42:27 +0200
committerSebastian2010-05-12 19:42:27 +0200
commitce3329047d378a14006ce74ec273ac59e3375303 (patch)
tree782430f270b4c7aca1b35d5b7813518e3797c555 /src/util
downloadpvs-ce3329047d378a14006ce74ec273ac59e3375303.tar.gz
pvs-ce3329047d378a14006ce74ec273ac59e3375303.tar.xz
pvs-ce3329047d378a14006ce74ec273ac59e3375303.zip
initial import of latest svn version
Diffstat (limited to 'src/util')
-rw-r--r--src/util/CertManager.cpp87
-rw-r--r--src/util/CertManager.h30
-rw-r--r--src/util/TextFile.cpp39
-rw-r--r--src/util/TextFile.h26
-rw-r--r--src/util/clientGUIUtils.cpp144
-rw-r--r--src/util/clientGUIUtils.h39
-rw-r--r--src/util/consoleLogger.cpp355
-rw-r--r--src/util/consoleLogger.h273
-rw-r--r--src/util/dispatcher.h210
-rw-r--r--src/util/pvsSettingsManager.cpp185
-rw-r--r--src/util/pvsSettingsManager.h50
-rw-r--r--src/util/serviceDiscoveryUtil.cpp65
-rw-r--r--src/util/serviceDiscoveryUtil.h19
-rw-r--r--src/util/timeUtil.cpp42
-rw-r--r--src/util/timeUtil.h34
-rw-r--r--src/util/util.cpp416
-rw-r--r--src/util/util.h59
-rw-r--r--src/util/vncClientThread.cpp249
-rw-r--r--src/util/vncClientThread.h114
19 files changed, 2436 insertions, 0 deletions
diff --git a/src/util/CertManager.cpp b/src/util/CertManager.cpp
new file mode 100644
index 0000000..99d2438
--- /dev/null
+++ b/src/util/CertManager.cpp
@@ -0,0 +1,87 @@
+/*
+# Copyright (c) 2009 - OpenSLX Project, Computer Center University of Freiburg
+#
+# This program is free software distributed under the GPL version 2.
+# See http://openslx.org/COPYING
+#
+# If you have any feedback please consult http://openslx.org/feedback and
+# send your suggestions, praise, or complaints to feedback@openslx.org
+#
+# General information about OpenSLX can be found at http://openslx.org/
+# -----------------------------------------------------------------------------
+# src/util/CertManager.cpp
+# - Manage SSL certificates
+# - provide access by name
+# -----------------------------------------------------------------------------
+*/
+
+#include "CertManager.h"
+#include "util.h"
+#include <QMap>
+#include <QFileInfo>
+#include <cstdlib>
+
+namespace CertManager
+{
+ static QMap<QString, QSslCertificate> _certs;
+ static QMap<QString, QSslKey> _keys;
+
+ void generateFiles(QString key, QString cert);
+
+ QSslKey getPrivateKey(QString name) {
+ if (_keys.contains(name)) return _keys[name];
+ QString cert = getPolicyFilePath(name);
+ QString key = cert;
+ key.append(".rsa");
+ cert.append(".crt");
+ //
+ QFileInfo keyfile(key);
+ QFileInfo certfile(cert);
+ if (keyfile.exists() && certfile.exists())
+ { // It wouldn't make sense to have one without the other
+ if (getCertificate(name).isNull()) return QSslKey();
+ QFile f(key);
+ f.open(QFile::ReadOnly);
+ QSslKey k = QSslKey(&f, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
+ _keys.insert(name, k);
+ return k;
+ }
+ generateFiles(key, cert);
+ keyfile = QFileInfo(key);
+ if (!keyfile.exists() || getCertificate(name).isNull()) return QSslKey();
+ QFile f(key);
+ f.open(QFile::ReadOnly);
+ QSslKey k = QSslKey(&f, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
+ if (!k.isNull()) _keys.insert(name, k);
+ return k;
+ }
+
+ QSslCertificate getCertificate(QString name) {
+ if (_certs.contains(name)) return _certs[name];
+ QString cert = getPolicyFilePath(name);
+ cert.append(".crt");
+ //
+ QFileInfo certfile(cert);
+ if (certfile.exists())
+ {
+ QList<QSslCertificate> certlist = QSslCertificate::fromPath(cert);
+ if (certlist.empty()) return QSslCertificate();
+ QSslCertificate c = certlist.first();
+ if (!c.isNull()) _certs.insert(name, c);
+ return c;
+ }
+ return QSslCertificate();
+ }
+
+ void generateFiles(QString key, QString cert)
+ {
+ char tmp[1000];
+ unlink(key.toLocal8Bit().data());
+ unlink(cert.toLocal8Bit().data());
+ snprintf(tmp, 1000, "openssl req -x509 -nodes -days 3650 -newkey rsa:1024 -subj '/C=DE/ST=BaWue/L=Freiburg/CN=openslx.org' -keyout \"%s\" -out \"%s\"",
+ key.toLocal8Bit().data(), cert.toLocal8Bit().data());
+ system(tmp);
+ snprintf(tmp, 1000, "chmod 0600 \"%s\" \"%s\"", key.toLocal8Bit().data(), cert.toLocal8Bit().data());
+ system(tmp);
+ }
+}
diff --git a/src/util/CertManager.h b/src/util/CertManager.h
new file mode 100644
index 0000000..8caab8b
--- /dev/null
+++ b/src/util/CertManager.h
@@ -0,0 +1,30 @@
+/*
+# Copyright (c) 2009 - OpenSLX Project, Computer Center University of Freiburg
+#
+# This program is free software distributed under the GPL version 2.
+# See http://openslx.org/COPYING
+#
+# If you have any feedback please consult http://openslx.org/feedback and
+# send your suggestions, praise, or complaints to feedback@openslx.org
+#
+# General information about OpenSLX can be found at http://openslx.org/
+# -----------------------------------------------------------------------------
+# src/util/CertManager.cpp
+# - Manage SSL certificates
+# - provide access by name
+# -----------------------------------------------------------------------------
+*/
+
+#ifndef CERTMANAGER_H_
+#define CERTMANAGER_H_
+
+#include <QtNetwork/QSslCertificate>
+#include <QtNetwork/QSslKey>
+
+namespace CertManager
+{
+ QSslKey getPrivateKey(QString name);
+ QSslCertificate getCertificate(QString name);
+}
+
+#endif /* CERTMANAGER_H_ */
diff --git a/src/util/TextFile.cpp b/src/util/TextFile.cpp
new file mode 100644
index 0000000..0d04e47
--- /dev/null
+++ b/src/util/TextFile.cpp
@@ -0,0 +1,39 @@
+/*
+ * TextFile.cpp
+ *
+ * Created on: 13.02.2010
+ * Author: Zahl
+ */
+
+#include "TextFile.h"
+
+TextFile::TextFile(QString filename) : QTextStream()
+{
+ _file = new QFile(filename);
+ if (_file->open(QIODevice::ReadOnly))
+ {
+ this->setDevice(_file);
+ _good = true;
+ }
+ else
+ {
+ _good = false;
+ }
+}
+
+bool TextFile::good()
+{
+ return _good;
+}
+
+bool TextFile::eof()
+{
+ if (!_good || this->atEnd()) return true;
+ return false;
+}
+
+TextFile::~TextFile()
+{
+ _file->close();
+ delete _file;
+}
diff --git a/src/util/TextFile.h b/src/util/TextFile.h
new file mode 100644
index 0000000..49932fa
--- /dev/null
+++ b/src/util/TextFile.h
@@ -0,0 +1,26 @@
+/*
+ * TextFile.h
+ *
+ * Created on: 13.02.2010
+ * Author: Zahl
+ */
+
+#ifndef TEXTFILE_H_
+#define TEXTFILE_H_
+
+#include <QtCore/QFile>
+#include <QtCore/QTextStream>
+
+class TextFile : public QTextStream
+{
+public:
+ TextFile(QString filename);
+ virtual ~TextFile();
+ bool good();
+ bool eof();
+protected:
+ QFile *_file;
+ bool _good;
+};
+
+#endif /* TEXTFILE_H_ */
diff --git a/src/util/clientGUIUtils.cpp b/src/util/clientGUIUtils.cpp
new file mode 100644
index 0000000..4d4cc0d
--- /dev/null
+++ b/src/util/clientGUIUtils.cpp
@@ -0,0 +1,144 @@
+#include "clientGUIUtils.h"
+
+BlankScreen::BlankScreen()
+{
+ dpy = XOpenDisplay(NULL);
+ scr = DefaultScreen(dpy);
+ assert(dpy);
+ blackColor = BlackPixel(dpy, DefaultScreen(dpy));
+ whiteColor = WhitePixel(dpy, DefaultScreen(dpy));
+// win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 200, 100, 0, blackColor, whiteColor);
+ win = XCreateSimpleWindow(dpy, RootWindow(dpy, scr), 10, 10, 200, 200, 1, WhitePixel(dpy, scr), BlackPixel(dpy, scr));
+
+ XSelectInput(dpy, win, ExposureMask | KeyPressMask);
+ locked = false;
+ offX = offY = 0;
+}
+
+void BlankScreen::draw(bool force)
+{
+ if (locked)// no need to draw if we're not showing the window
+ {
+ XWindowAttributes xwa;
+ XGetWindowAttributes(dpy, DefaultRootWindow(dpy), &xwa);
+ int hx = (xwa.width)>>2, hy = (xwa.height)>>2;
+
+ if (XCheckTypedEvent(dpy, Expose, &ev) || force )
+ {
+ hx += offX;
+ hy += offY;
+
+ GC gcc = XCreateGC(dpy, win, 0, NULL);
+ XSetForeground(dpy, gcc, whiteColor);
+// XClearArea(dpy, win, 0, 0, xwa.width, xwa.height, false);
+ if (lockMsg.size() > 0)
+ {
+ char *msg = const_cast<char*>(lockMsg.toUtf8().data());
+ XDrawString(dpy, win, gcc/*DefaultGC(dpy, scr)*/, hx, hy, msg, strlen(msg));
+ }
+ else
+ {
+ }
+ }
+ }
+}
+
+bool BlankScreen::lock()
+{
+#define lock_test
+
+ if (locked)
+ return locked;
+
+ // We want to get MapNotify events
+ XSelectInput(dpy, win, StructureNotifyMask);
+
+ // "Map" the window (that is, make it appear on the screen)
+ XMapWindow(dpy, win);
+
+ // Create a "Graphics Context"
+ //GC gc = XCreateGC(dpy, win, 0, NULL);
+
+ XEvent xev;
+ Atom wm_state = XInternAtom(dpy, "_NET_WM_STATE", False);
+ Atom fullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
+ memset(&xev, 0, sizeof(xev));
+ xev.type = ClientMessage;
+ xev.xclient.window = win;
+ xev.xclient.message_type = wm_state;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = 1;
+ xev.xclient.data.l[1] = fullscreen;
+ xev.xclient.data.l[2] = 0;
+
+ XSendEvent(dpy, DefaultRootWindow(dpy), False,
+ SubstructureNotifyMask, &xev);
+
+
+
+
+ // Wait for the MapNotify event
+ for (;;)
+ {
+ XEvent e;
+ XNextEvent(dpy, &e);
+ if (e.type == MapNotify)
+ break;
+ }
+ //Flush it!
+ //XFlush(dpy);
+
+#ifndef lock_test
+ // load the locked cursor, so people dont think they can click anything
+ // TODO: Use some kind of invisible cursor instead of the wait-cursor
+ Cursor locked_cur = XCreateFontCursor(dpy, XC_watch);
+ XDefineCursor(dpy, DefaultRootWindow(dpy),locked_cur);
+#endif
+
+ // grabbing of keyboard and mouse and hide the cursor
+ XGrabKeyboard(dpy, DefaultRootWindow(dpy), false, GrabModeAsync, GrabModeAsync, CurrentTime);
+ XGrabPointer(dpy, DefaultRootWindow(dpy), false, 0, GrabModeAsync, GrabModeAsync, None, NULL, CurrentTime);
+
+ if (!locked)
+ ConsoleLog writeLine(QString("Locked"));
+
+ // see header for more information on this switch
+ return locked = true;
+}
+
+bool BlankScreen::lock_inputs()
+{
+ // grabbing of keyboard and mouse and hide the cursor
+ XGrabKeyboard(dpy, DefaultRootWindow(dpy), false, GrabModeAsync, GrabModeAsync, CurrentTime);
+ XGrabPointer(dpy, DefaultRootWindow(dpy), false, 0, GrabModeAsync, GrabModeAsync, None, NULL, CurrentTime);
+ return true;
+}
+
+bool BlankScreen::unlock()
+{
+
+ if (dpy)
+ {
+
+ int retval = -1;
+
+ //reset cursor to arrow (no *real* default here...)
+ Cursor normal_cur = XCreateFontCursor(dpy, XC_arrow);
+ XDefineCursor(dpy, DefaultRootWindow(dpy), normal_cur);
+
+ // ungrabbing of keyboard and mouse
+ XUngrabPointer(dpy, CurrentTime);
+ XUngrabKeyboard(dpy, CurrentTime);
+
+
+ retval = XUnmapWindow(dpy,win);
+ if (retval == BadWindow)
+ ConsoleLog writeError(QString("Bad window while unmapping. Badwindow: ").append(int2String(retval)));
+ XFlush(dpy);
+ }
+ if (locked)
+ ConsoleLog writeLine(QString("Unlocked"));
+
+ lockMsg.clear();
+ return !(locked = false);
+}
diff --git a/src/util/clientGUIUtils.h b/src/util/clientGUIUtils.h
new file mode 100644
index 0000000..28b05cc
--- /dev/null
+++ b/src/util/clientGUIUtils.h
@@ -0,0 +1,39 @@
+#include "src/util/consoleLogger.h"
+#include <X11/Xlib.h> // Every Xlib program must include this
+#include <X11/cursorfont.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdio.h>
+
+
+
+#define REFRESH_RATE 0.15
+
+#ifndef _BLANKSCREEN_H_
+#define _BLANKSCREEN_H_
+
+class BlankScreen
+{
+public:
+ BlankScreen();
+ void draw(bool force = false);
+ bool lock();
+ bool unlock();
+ void setLogMsg(QString msg);
+ bool lock_inputs();
+
+private:
+ Display *dpy;
+ Window win;
+ XEvent ev;
+ int scr;
+
+ bool locked;
+
+
+ QString lockMsg;
+ int blackColor, whiteColor;
+ int offX, offY;
+};
+
+#endif
diff --git a/src/util/consoleLogger.cpp b/src/util/consoleLogger.cpp
new file mode 100644
index 0000000..b523b40
--- /dev/null
+++ b/src/util/consoleLogger.cpp
@@ -0,0 +1,355 @@
+/*
+ # Copyright (c) 2009, 2010 - OpenSLX Project, Computer Center University of
+ # Freiburg
+ #
+ # This program is free software distributed under the GPL version 2.
+ # See http://openslx.org/COPYING
+ #
+ # If you have any feedback please consult http://openslx.org/feedback and
+ # send your suggestions, praise, or complaints to feedback@openslx.org
+ #
+ # General information about OpenSLX can be found at http://openslx.org/
+ # -----------------------------------------------------------------------------
+ # consoleLogger.cpp
+ # - ???.
+ # -----------------------------------------------------------------------------
+ */
+
+#include "consoleLogger.h"
+
+#ifdef never
+template<class T>
+void ConsoleLogger::addListener(T* who, void (T :: *func)(QString))
+{
+ LogNotify<T> *test = new LogNotify<T>(who, func);
+ _CBLog.push_back(dynamic_cast<LogNotifyEntry*>(test));
+}
+
+template<class T>
+void ConsoleLogger::removeListener(T* who, void (T :: *func)(QString))
+{
+ if (_CBLog.size())
+ {
+ for (std::list<LogNotifyEntry*>::iterator it = _CBLog.begin(); it != _CBLog.end(); it++)
+ {
+ LogNotify<T> *probe = dynamic_cast<LogNotify<T>*>((*it));
+ if (probe)
+ {
+ if (probe->getCallee() == who && probe->getCB() == func)
+ {
+ _CBLog.remove((*it));
+ }
+ }
+ }
+ }
+// LogNotify<T> *test = new LogNotify<T>(who, func);
+ // _CBLog.push_back(dynamic_cast<LogNotifyEntry*>(test));
+}
+
+#endif
+int ConsoleLogger::writeLine(QString message, LOG_LEVEL level)
+{
+ if (message.size() == 0)
+ return -1;
+
+ ConsoleEntry consoleEntry(_getTimeStamp(), message, level);
+ _announceWrite(consoleEntry); // tell the listeners!
+ _writeLine2File(consoleEntry.getLine());
+ _log.push_back(consoleEntry);
+
+ return _log.size();
+}
+
+int ConsoleLogger::writeline(const char* message, LOG_LEVEL level)
+{
+ if (message)
+ {
+ if (strlen(message) > 0)
+ return writeLine(QString(message), level);
+ }
+ return -1;
+}
+
+int ConsoleLogger::writeError(QString error)
+{
+ return writeLine(error, LOG_ERROR);
+}
+
+int ConsoleLogger::writeError(const char* error)
+{
+ return writeLine(error, LOG_ERROR);
+}
+
+int ConsoleLogger::writeTerminal(QString terminal)
+{
+ // printing the line on the console happens further down the line!
+ return writeLine(terminal, LOG_TERMINAL);
+}
+
+int ConsoleLogger::writeTerminal(const char* terminal)
+{
+ if (terminal)
+ if (strlen(terminal) > 0)
+ return writeTerminal(QString(terminal));
+
+ terminal = NULL;
+ return -1;
+}
+
+int ConsoleLogger::writeNetwork(QString network)
+{
+ // printing the line on the console happens further down the line!
+ return writeLine(network, LOG_NETWORK);
+}
+
+int ConsoleLogger::writeNetwork(const char* network)
+{
+ if (network)
+ if (strlen(network) > 0)
+ return writeNetwork(QString(network));
+
+ network = NULL;
+ return -1;
+}
+
+int ConsoleLogger::writeChat(QString chat)
+{
+ return writeLine(chat, LOG_CHAT);
+}
+
+int ConsoleLogger::writeChat(const char* chat)
+{
+ if (chat)
+ if (strlen(chat) > 0)
+ return writeChat(QString(chat));
+
+ chat = NULL;
+ return -1;
+}
+
+void ConsoleLogger::getLine(int lineNum, char* line)
+{
+ QString tmp;
+ getLine(lineNum, &tmp);
+ if (tmp.size() > 0)
+ {
+ line = new char[_log[lineNum].getLine().size()+1];
+ if (line)
+ {
+ memcpy(line, _log[lineNum].getLine().toUtf8().data(), _log[lineNum].getLine().size());
+ if (strlen(line) > 0)
+ return;
+ }
+ }
+ line = NULL;
+
+}
+
+void ConsoleLogger::getLine(int lineNum, QString* line)
+{
+ if (lineNum <= int(_log.size()))
+ {
+ if (lineNum > 0)
+ lineNum--;
+ else if (lineNum < 0)
+ {
+ line = NULL;
+ return;
+ }
+ }
+ else
+ {
+ line->clear();
+ line = NULL;
+ }
+}
+
+void ConsoleLogger::setLogPath(QString logPath)
+{
+ getLogger()->_logPath = logPath;
+ getLogger()->_prepareLog();
+}
+
+void ConsoleLogger::setLogName(QString logName)
+{
+ getLogger()->_logName = logName;
+ getLogger()->_prepareLog();
+}
+
+void ConsoleLogger::dumpLog(DUMP_MODE mode)
+{
+ if (mode == DUMP_FILE || (DUMP_FILE_CONCAT && !_fileRead))
+ getLogger()->_writeLog();
+ if (mode == DUMP_FILE_CONCAT && _fileRead)
+ getLogger()->_writeLog(true);
+ if (mode == DUMP_ALL_LISTENERS)
+ {
+ for (int i = 0; i <int(_log.size()); i++)
+ {
+ _announceWrite(_log[i]);
+ }
+ }
+}
+
+int ConsoleLogger::count = 0;
+
+ConsoleLogger* ConsoleLogger::_logger;
+
+ConsoleLogger* ConsoleLogger::getLogger()
+{
+ if (!_logger)
+ {
+ return ConsoleLogger::_logger = new ConsoleLogger();
+ }
+ else
+ return ConsoleLogger::_logger;
+}
+
+ConsoleLogger::ConsoleLogger()
+ : _logName(""),
+ _logPath(getPolicyFilePath(QString(""))),
+ _fileRead(false),
+ entryDispatcher()
+{
+// _prepareLog();
+}
+
+ConsoleLogger::~ConsoleLogger()
+{
+ // doesnt work!?
+ _writeLog();
+}
+
+void ConsoleLogger::_prepareLog()
+{
+ _logFile.close();
+ _logFileGood = false;
+ _readLog();
+
+ mkdir(getPolicyFilePath(QString()).toUtf8().data(), 0777);
+ QString fullpath;
+ fullpath.append(_logPath);
+ //TODO: handle wether path/ or path were entered?
+ fullpath.append(_logName);
+ _logFile.open(fullpath.toUtf8().data(), std::ofstream::out | std::ofstream::app);
+ if (_logFile.good())
+ {
+ _logFileGood = true;
+ writeTerminal(QString("LogPath/Name changed to: ").append(fullpath));
+ }
+ else
+ {
+ printf("ERROR: Logfile ( %s ) not accessible/found. Logs will not be available.\n", _logPath.toUtf8().data());
+ }
+ _logFile.close();
+}
+
+void ConsoleLogger::_writeLine2File(QString line)
+{
+ if (_logFileGood)
+ {
+ QString fullpath;
+ fullpath.append(_logPath);
+ //TODO: handle wether path/ or path were entered?
+ fullpath.append(_logName);
+ _logFile.open(fullpath.toUtf8().data(), std::ofstream::out | std::ofstream::app);
+
+ if (_logFile.good()) // one can never be too sure
+ {
+ _logFile.write(line.toUtf8().data(), line.size());
+ }
+
+ _logFile.close();
+ }
+
+}
+
+// overwrites the file and dumps the complete log archive of this session
+void ConsoleLogger::_writeLog(bool concat)
+{
+ if (_logFileGood)
+ {
+ QString fullpath;
+ fullpath.append(_logPath);
+ //TODO: handle wether path/ or path were entered?
+ fullpath.append(_logName);
+
+ std::vector<ConsoleEntry> *tmpLog = NULL;
+
+ if (concat)
+ {
+ std::vector<ConsoleEntry> newLog = _prev_log;
+ newLog.insert(newLog.end(), _log.begin(), _log.end());
+ tmpLog = &newLog;
+ }
+ else
+ {
+ tmpLog = &_log;
+ }
+ _logFile.open(fullpath.toUtf8().data(), std::ofstream::out | std::ofstream::trunc);
+
+ if (_logFile.good()) // one can never be too sure
+ {
+ for (int i = 0; i < int(tmpLog->size()); i++)
+ {
+ _logFile.write(tmpLog->at(i).getLine().toUtf8().data(), tmpLog->at(i).getLine().size());
+ }
+ }
+
+ _logFile.close();
+ }
+}
+
+void ConsoleLogger::_announceWrite(ConsoleEntry consoleEntry)
+{
+
+ entryDispatcher.fire(consoleEntry);
+}
+
+void ConsoleLogger::_readLog(QString path)
+{
+ // todo, read the file, filter the entries and recombine them if possible etc..
+ // then save it all to _log_prev.
+ // then set _readFile to true, so the dump will concat our current log to the old and THEN overwrite the whole file
+ _prev_log.clear();
+ _fileRead = false;
+}
+
+QString ConsoleLogger::_getTimeStamp()
+{
+ time_t rawtime;
+ tm * ptm;
+ time ( &rawtime );
+
+ //ptm = gmtime ( &rawtime );
+ ptm = localtime ( &rawtime );
+
+ QString tmpStr;
+ if (ptm->tm_mday < 10)
+ tmpStr.append(QString("0"));
+ tmpStr.append(int2String(ptm->tm_mday));
+ tmpStr.push_back('.');
+ if (ptm->tm_mon < 10)
+ tmpStr.append(QString("0"));
+ tmpStr.append(int2String(int(ptm->tm_mon) +1));
+ tmpStr.push_back('.');
+ int year = (ptm->tm_year % 100);
+ if (year < 10)
+ tmpStr.append(QString("0"));
+ tmpStr.append(int2String(year));
+ tmpStr.push_back(' ');
+ if (ptm->tm_hour < 10)
+ tmpStr.append(QString("0"));
+ tmpStr.append(int2String(ptm->tm_hour));
+ tmpStr.push_back(':');
+ if (ptm->tm_min < 10)
+ tmpStr.append(QString("0"));
+ tmpStr.append(int2String(ptm->tm_min));
+ tmpStr.push_back(':');
+ if (ptm->tm_sec < 10)
+ tmpStr.append(QString("0"));
+ tmpStr.append(int2String(ptm->tm_sec));
+
+ return tmpStr;
+}
+
diff --git a/src/util/consoleLogger.h b/src/util/consoleLogger.h
new file mode 100644
index 0000000..3a0950d
--- /dev/null
+++ b/src/util/consoleLogger.h
@@ -0,0 +1,273 @@
+
+#include "util.h"
+#include "dispatcher.h"
+#include <vector>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <list>
+
+
+//#define as_daemon
+#ifndef _CONSOLELOGGER_H_
+#define _CONSOLELOGGER_H_
+
+/**********************************************************************************************************************/
+// Console-, and Message Dispatching / Logging (With timestamping!)
+/**********************************************************************************************************************/
+//
+// :: Usage ::
+//
+#define ConsoleLog ConsoleLogger::getLogger()-> //ease of acces!
+//
+//
+// *Logging:
+//
+// ConsoleLog writeLine(<string/char*>); // sends out a message with "normal" loglevel
+// ConsoleLog writeLine(<string/char*>, <loglevel>); // sends out a message with the chosen loglevel --> enum LOG_LEVEL
+// ConsoleLog writeError(<string/char*>); // sends out a message with "Error" loglevel
+// ConsoleLog writeTerminal(<string/char*>); // sends out a message with "Terminal" loglevel, which means it is
+// // also printed on stdout
+// ConsoleLog writeNetwork(<string/char*>); // sends out a message with "network" loglevel
+// ConsoleLog writeChat(<string/char*>); // sends out a message with "Chat" loglevel
+//
+// *un/subscribing to the LogDispatcher
+//
+// ConsoleLog addListener(<pointer-to-object-of-Type-myClass>, &myClass::myMethod);
+// callback signature --> typedef void (T::*callback)(ConsoleEntry); // with <U, T> as template // for more on ConsoleEntry, see later
+// ConsoleLog removeListener(<pointer-to-object-of-Type-myClass>, &myClass::myMethod);
+//
+// *Misc
+//
+// ConsoleLog setLogPath(<string-path-to-log-directory>); // set the log directory (with a final /, the logfilename is appended.)
+// ConsoleLog setLogName(<string-name>); // like the above, but for the filename.
+// ConsoleLog dumpLog(DUMP_MODE);
+//
+// DUMP_FILE ::>> Dumps the whole log since the logger was started into the specified logfile. the file content gets overwritten
+// DUMP_FILE_CONCAT ::>> The Same as above, but it will just append itself to the previously (if implemented) log which got \**
+// ***\ read from the logfile which was present at logger start. if no log is found or logfile was not read, behaves as DUMP_FILE
+// DUMP_TERMINAL ::>> Dumps the whole log into the terminal
+// DUMP_ALL_LISTENERS ::>> Dumps the whole log to all listeners
+//
+// Alternatively, you can request a dump to a certain listener:
+// ConsoleLog dump2Listener(<pointer-to-object-of-Type-myClass>, &myClass::myMethod); // it expects the same information as when subscribing
+// // the PVS-Server console makes heavy use of this feature to implement its filters
+//
+//
+// :: using the ConsoleEntry class ::
+//
+// *methods and members
+//
+//
+// LOG_LEVEL getLevel() // returns the loglevel as LOG_LEVEL Enum-type
+// QString getLine() // returns the complete line as shown in the logfile, with timestamp, loglevel prefix etc
+// QString getMessage() // returns the message body, no gimmicks attached
+// QString getPrefix() // returns the loglevel as string-represenation
+// QString getTimeStamp() // returns the timestamp which was set at the creation of the object
+//
+//
+//
+//
+//
+//
+/**********************************************************************************************************************/
+
+
+
+
+
+
+// Typdef at bottom of file :
+// typedef ConsoleLogger::ConsoleEntry LogEntry;
+
+
+class ConsoleLogger
+{
+public:
+
+ enum LOG_LEVEL { LOG_NORMAL,
+ LOG_ERROR,
+ LOG_CHAT,
+ LOG_TERMINAL,
+ LOG_NETWORK
+ };
+ enum DUMP_MODE { DUMP_FILE,
+ DUMP_FILE_CONCAT,
+ DUMP_TERMINAL,
+ DUMP_ALL_LISTENERS,
+ };
+ class ConsoleEntry
+ {
+ public:
+ ConsoleEntry(QString timeStamp, QString message, LOG_LEVEL level)
+ {
+ setLine(timeStamp, message, level);
+ };
+ void setLine(QString timeStamp, QString message, LOG_LEVEL level)
+ {
+ _message = message;
+ _prefix = _prefixLine(level);
+ _timeStamp = timeStamp;
+ _line.append(QString("[ ").append(timeStamp));
+ _line.append(QString(" ] ").append(_prefix));
+ _line.append(QString(": ").append(message));
+ _level = level;
+ if ('\n' != _line[_line.size()-1] && '\n' != _line[_line.size()])
+ _line.push_back('\n'); // add an explicit newline char, so it looks better in the logfile
+ //#ifndef as_daemon
+ if (_level == LOG_TERMINAL) // may look strange here, but its quite central :-)
+ printf("%s\n", _line.toUtf8().data());
+ //#endif
+ };
+ LOG_LEVEL getLevel()
+ {
+ return _level;
+ };
+ QString getLine()
+ {
+ return _line;
+ };
+ QString getMessage()
+ {
+ return _message;
+ };
+ QString getPrefix()
+ {
+ return _prefix;
+ };
+ QString getTimeStamp()
+ {
+ return _timeStamp;
+ };
+
+ private:
+ QString _prefixLine(LOG_LEVEL level)
+ {
+ // switch anyone?
+ if (level == LOG_NORMAL)
+ return QString("PVS");
+ if (level == LOG_ERROR)
+ return QString("PVS ERROR");
+ if (level == LOG_TERMINAL)
+ return QString("PVS Terminal");
+ if (level == LOG_CHAT)
+ return QString("PVS Chat");
+ if (level == LOG_NETWORK)
+ return QString("PVS Network");
+ return QString("UNDEFINED");
+ };
+ QString _line; // the complete line with timestamp and everything
+ QString _message; // the message itself
+ QString _prefix; // just the prefix
+ QString _timeStamp; // just the timestamp
+ LOG_LEVEL _level;
+ };
+
+ class LogNotifyEntry
+ {
+ public:
+ virtual void fire(ConsoleEntry consoleEntry) {};
+ LogNotifyEntry() {};
+ };
+
+#ifdef never
+private:
+ template<class T>
+ class LogNotify : public LogNotifyEntry
+ {
+ public:
+ typedef void (T::*callback)(ConsoleEntry);
+ LogNotify(T* who, callback func )//void (T :: *func)(QString))
+ {
+ callee = who;
+ //callback = func;
+ myCB = func;
+ };
+ virtual void fire(ConsoleEntry consoleEntry)
+ {
+ if (callee)
+ (callee->*myCB)(consoleEntry);
+ };
+ T* getCallee()
+ {
+ return callee;
+ };
+ callback getCB()
+ {
+ return myCB;
+ };
+
+ private:
+ T *callee;
+ callback myCB;
+ };
+
+public:
+#endif
+ // interfaces for the dispatcher for easy of access ( --> ConsoleLog Makro)
+ template<class T> void addListener(T* who, void (T :: *func)(ConsoleEntry))
+ {
+ entryDispatcher.addListener(who, func);
+ };
+ template<class T> void removeListener(T* who, void (T :: *func)(ConsoleEntry))
+ {
+ entryDispatcher.removeListener(who, func);
+ };
+ template<class T> void dump2Listener(T* who, void (T :: *func)(ConsoleEntry))
+ {
+ for (int i = 0; i < int(_log.size()) ; i++)
+ (who->*func)(_log[i]);
+ };
+
+ int writeLine(QString message, LOG_LEVEL = LOG_NORMAL);
+ int writeline(const char* message, LOG_LEVEL = LOG_NORMAL);
+ int writeError(QString error);
+ int writeError(const char* error);
+ int writeTerminal(QString terminal);
+ int writeTerminal(const char* terminal);
+ int writeNetwork(QString network);
+ int writeNetwork(const char* network);
+ int writeChat(QString chat);
+ int writeChat(const char* chat);
+ void getLine(int lineNum, char* line);
+ void getLine(int lineNum, QString* line);
+ void setLogPath(QString logPath);
+ void setLogName(QString logName);
+ void dumpLog(DUMP_MODE mode = DUMP_FILE);
+ static ConsoleLogger* getLogger();
+ static int count;
+private:
+
+
+ std::vector<ConsoleEntry>* _getLog()
+ {
+ return &_log;
+ };
+ static ConsoleLogger* _logger;
+ void _prepareLog();
+ void _writeLine2File(QString line);
+ void _writeLog(bool concat = false);
+ void _announceWrite(ConsoleEntry consoleEntry);
+ void _readLog(QString path = QString(""));
+ QString _getTimeStamp();
+ void _prefixLine(QString* line, LOG_LEVEL level = LOG_NORMAL);
+
+
+
+ ConsoleLogger();
+ ~ConsoleLogger();
+
+ QString _logName;
+ QString _logPath;
+
+ bool _logFileGood, _fileRead;
+// std::list<LogNotifyEntry*> _CBLog;
+ EventDispatcher<ConsoleEntry> entryDispatcher;
+ std::vector<ConsoleEntry> _log;
+ std::vector<ConsoleEntry> _prev_log;
+ std::ofstream _logFile;
+};
+
+typedef ConsoleLogger::ConsoleEntry LogEntry;
+
+#endif
diff --git a/src/util/dispatcher.h b/src/util/dispatcher.h
new file mode 100644
index 0000000..490a3be
--- /dev/null
+++ b/src/util/dispatcher.h
@@ -0,0 +1,210 @@
+#ifndef _DISPATCHER_H_
+#define _DISPATCHER_H_
+#include <list>
+#include <QString>
+#include <iostream>
+#include <map>
+
+
+//****************************************************************************************************/
+// EventDispatcher && EventIdentDispatcher //
+/***************************************************************************************************/
+// This handy class(es) act as very simple signals/events.
+// Its OOP-only, so dont even try to add static functions
+// or C-like methods!
+//
+// :: Return Types ::
+//
+// at the moment only callbacks for void methods with a parameter
+// count of one ( whos type is the primary template parameter)
+//
+// :: callback signature ::
+//
+// typedef void (T::*callback)(U); // with <U, T> as template
+//
+// :: Usage Example ::
+//
+// *creating a Dispatcher
+//
+// -- EventDispatcher<Type A>* nameYourDispatcher = new EventDispatcher<Type A>; // simple Dispatcher
+// -- EventIdentDispatcher<Type A>* nameYourIdentDispatcher = new EventIdentDispatcher<Type A>; // ident dispatcher
+//
+// *difference between simple and ident
+//
+// a simple dispatcher features only one type of signal, so you can only call all
+// attached listeners at once or none at all
+//
+// an ident dispatcher uses an ident string to hold and fire more than one event type at once
+// but is limited to the one defined parameter type for its methods
+//
+// *subscribung to a dispatcher
+//
+// -- nameYourDispatcher->addListener(<pointer-to-object-of-Type-myClass>, &myClass::myMethod); // simple Dispatcher
+// -- nameYourIdentDispatcher->addListener(<string-as-ident>, <pointer-to-object-of-Type-myClass>, &myClass::myMethod); // ident dispatcher//
+//
+// you can add the same method/instance to different dispatchers oder differnt ident-distinguished dispatchers in a identdispatcher.
+// you can also add the same method/instance to the same dispatchers all over again, which is not recommended
+//
+//
+// *firing a dispatcher
+//
+// -- nameYourDispatcher->fire(Type_A Object); // simple Dispatcher
+// -- nameYourIdentDispatcher->fire(<string-as-ident>, Type_A Object); // ident dispatcher//
+//
+// All respective attached callbacks are called in the order they were added
+//
+//
+// *unsubscribing
+//
+// -- nameYourDispatcher->removeListener(<pointer-to-object-of-Type-myClass>, &myClass::myMethod); // simple Dispatcher
+// -- nameYourIdentDispatcher->removeListener(<string-as-ident>, <pointer-to-object-of-Type-myClass>, &myClass::myMethod); // ident dispatcher//
+//
+// just the reverse of addListener. currently no removeAll() available
+//
+//
+//
+/***************************************************************************************************/
+class CallbackHandle
+{
+};
+
+template<class U>
+class CallbackBase : public CallbackHandle
+{
+public:
+ virtual void fire(U u) {};
+
+private:
+};
+
+template<class T, class U>
+class Callback : public CallbackBase<U>
+{
+public:
+
+ virtual void fire(U u)
+ {
+ if (cbVU)
+ (callee->*cbVU)(u);
+ };
+
+ typedef void (T::*callbackVU)(U);
+
+ Callback(T* who, callbackVU cb)
+ {
+ cbVU = cb;
+ callee = who;
+ };
+
+ T* getCallee()
+ {
+ return callee;
+ };
+ callbackVU getCBVU()
+ {
+ return cbVU;
+ };
+
+private:
+ callbackVU cbVU;
+ T* callee;
+
+};
+
+template<class U>
+class EventDispatcher
+{
+public:
+ template<class T> void addListener(T *who, void (T :: *func)(U))
+ {
+ Callback<T, U> *tmp = new Callback<T, U>(who, func);
+ _listener.push_back(dynamic_cast<CallbackBase<U>*>(tmp));
+ };
+ void fire(U u)
+ {
+ for (typename std::list<CallbackBase<U>*>::iterator it = _listener.begin(); it != _listener.end(); it++)
+ {
+ if (*it)
+ {
+ (*it)->fire(u);
+ }
+ }
+ };
+
+ template<class T> void removeListener(T* who, void (T :: *func)(U))
+ {
+ if (_listener.size())
+ {
+ for (typename std::list<CallbackBase<U>*>::iterator it = _listener.begin(); it != _listener.end(); it++)
+ {
+ CallbackBase<U>* pro = (*it);
+ Callback<T, U> *probe = dynamic_cast<Callback<T,U>*>(pro);
+ if (probe)
+ {
+ if (probe->getCallee() == who && probe->getCBVU() == func )
+ {
+ delete (probe);
+ _listener.remove((*it));
+ return;
+ }
+ }
+ }
+ }
+ };
+
+private:
+
+ std::list<CallbackBase<U>*> _listener;
+};
+
+template<class U>
+class EventIdentDispatcher
+{
+public:
+ template<class T> void addListener(QString ident, T* who, void (T :: *func)(U))
+ {
+ Callback<T, U>* tmp = new Callback<T, U>(who, func);
+ _listener.push_back(std::pair<QString, CallbackBase<U>*>(ident, dynamic_cast<CallbackBase<U>*>(tmp)));
+ };
+
+ void fire(QString ident, U u)
+ {
+ for ( typename std::list<std::pair<QString, CallbackBase<U>* > >::iterator it = _listener.begin(); it != _listener.end(); it++)
+ {
+ if ((*it).first.compare(ident) == 0 || QString("*").compare((*it).first) == 0)
+ {
+ if ((*it).second)
+ {
+ (*it).second->fire(u);
+ }
+ }
+ }
+ };
+ template<class T> void removeListener(QString ident, T* who, void (T :: *func)(U))
+ {
+ if (_listener.size())
+ {
+ for (std::list<std::pair <QString, CallbackHandle*> >::iterator it = _listener.begin(); it != _listener.end(); it++)
+ {
+ if ((*it).first.compare(ident) == 0)
+ {
+ CallbackBase<U>* pro = (*it).second;
+ Callback<T, U> *probe = dynamic_cast<Callback<T,U>*>(pro);
+ if (probe)
+ {
+ if (probe->getCallee() == who && probe->getVoidCB == func)
+ {
+ delete (*it).second;
+ _listener.remove((*it));
+ return;
+ }
+ }
+ }
+ }
+ }
+ };
+private:
+ std::list<std::pair<QString, CallbackBase<U>* > > _listener;
+};
+
+#endif
diff --git a/src/util/pvsSettingsManager.cpp b/src/util/pvsSettingsManager.cpp
new file mode 100644
index 0000000..a6a742b
--- /dev/null
+++ b/src/util/pvsSettingsManager.cpp
@@ -0,0 +1,185 @@
+#include "pvsSettingsManager.h"
+#include "TextFile.h"
+
+PVSSettingsManager* PVSSettingsManager::getManager()
+{
+ if (myself)
+ return myself;
+ else
+ return myself = new PVSSettingsManager;
+}
+
+void PVSSettingsManager::setConfigFile(QString path)
+{
+ if (path.size() && fileExists(path))
+ {
+ _path = path;
+ _parseFile(_path);
+
+ }
+ else
+ ConsoleLog writeError(QString("Can't open config file \"").append(QString(path).append("\"")));
+}
+
+bool PVSSettingsManager::hasEntry(QString name)
+{
+ for (SettingsIter it = settingsList.begin(); it != settingsList.end(); it++)
+ {
+ if ((*it).first.compare(name) == 0)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+QString PVSSettingsManager::getEntryString(QString name)
+{
+ for (SettingsIter it = settingsList.begin(); it != settingsList.end(); it++)
+ {
+ if ((*it).first.compare(name) == 0)
+ {
+ return (*it).second;
+ }
+ }
+ return QString();
+}
+
+void PVSSettingsManager::writeEntry(QString name, QString value)
+{
+ if (name.size() && value.size())
+ return;
+ bool unique = true;
+ for (SettingsIter it = settingsList.begin(); it != settingsList.end(); it++)
+ {
+ if ((*it).first.compare(name) == 0)
+ {
+ unique = false;
+ (*it).second = value;
+ break;
+ }
+ }
+ if (unique)
+ {
+ SettingsEntry tmp(name, value);
+ settingsList.push_back(tmp);
+ }
+}
+
+
+PVSSettingsManager* PVSSettingsManager::myself = NULL;
+
+PVSSettingsManager::PVSSettingsManager()
+{
+
+}
+
+void PVSSettingsManager::setConfigs()
+{
+ //default settings
+ _configs.setValue("Chat/chatstate", "on");
+ _configs.setValue("Chat/chatmode", "bossmode");
+ _configs.setValue("Room/roomId", "0");
+ _configs.setValue("VNC/permit", "off");
+ _configs.setValue("VNC/quality", "high");
+ _configs.sync();
+}
+void PVSSettingsManager::reWriteConfigs(QString set, QString val)
+{
+ _configs.setValue(set, val);
+ _configs.sync();
+}
+
+void PVSSettingsManager::readConfigs(QString sett, QString vall)
+{
+ //TODO: read the config file..
+ _configs.value("Chat/chatstate").toBool();
+ _configs.value("Chat/chatmode").toString();
+ _configs.value("Room/room").toInt();
+ _configs.value("VNC/permit").toBool();
+ _configs.value("VNC/quality").toString();
+}
+
+void PVSSettingsManager::_parseFile(QString path)
+{
+ QString line;
+ TextFile file(path);
+
+ SettingsList tmpList;
+
+ if (file.good())
+ {
+ while (!file.eof())
+ {
+ line = file.readLine();
+ if (!(line.length() <=1)) // ignore blank
+ {
+ if (!(line[0] == '#' || line[0] == '/' || line[0] == '[')) // ignore comments and section headers
+ {
+ SettingsEntry tmp = _parseLine(line);
+ if (tmp.first.size() && tmp.second.size())
+ {
+ bool unique = true;
+ for (SettingsIter it = tmpList.begin(); it != tmpList.end(); it++)
+ {
+ if ((*it).first.compare(tmp.first) == 0)
+ {
+ unique = false;
+ break;
+ }
+ }
+ if (unique)
+ tmpList.push_back(tmp);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ ConsoleLog writeError(QString("No configfile \"").append(QString(path).append("\" found or file corrupt.")));
+ }
+
+ if (tmpList.size())
+ settingsList = tmpList;
+}
+#ifdef verbose
+ConsoleLog writeLine(QString("Dumping Config Content of ").append(QString(path).append(" : ")));
+for (SettingsIter it = settingsList.begin(); it != settingsList.end(); it++)
+{
+ ConsoleLog writeLine(QString("Option: ").append(QString((*it).first).append(QString(" | Value: ").append((*it).second))));
+}
+ConsoleLog writeLine(QString("End of ").append(QString(path).append(".")));
+#endif
+
+SettingsEntry PVSSettingsManager::_parseLine(QString line)
+{
+ QString name;
+ QString value;
+
+ name = lineSplitter(line, "=\n\t", true);
+ value = lineSplitter(line, "=\n\t", false);
+
+ if (!(name.size() && value.size()))
+ return SettingsEntry("","");
+
+
+ // remove whitespaces in front of option name
+ for (int i = 0; i < name.size(); i++)
+ {
+ if (name[i] == '\t' || name[i] == ' ')
+ {
+ name.remove(i, 1);
+ i--;
+ }
+ else
+ break;
+ }
+ // whitespaces after the value are trimmed by the lineSplitter
+
+ SettingsEntry tmp(name, value);
+ return tmp;
+}
+
+
+
diff --git a/src/util/pvsSettingsManager.h b/src/util/pvsSettingsManager.h
new file mode 100644
index 0000000..78607eb
--- /dev/null
+++ b/src/util/pvsSettingsManager.h
@@ -0,0 +1,50 @@
+/// documentation test 1
+/// line 2
+/// line 3
+#ifndef _PVSSETTINGSMANGER_H_
+#define _PVSSETTINGSMANGER_H_
+
+#include <list>
+#include <map>
+#include <src/util/util.h>
+#include <src/util/consoleLogger.h>
+#include <QSettings>
+
+
+/// documentation test 1.1
+/// line 2.1
+/// line 3.1
+
+typedef std::pair<QString, QString> SettingsEntry; ///< first = option name, second = option value
+typedef std::list<SettingsEntry> SettingsList; ///< obvious
+typedef std::list<SettingsEntry>::iterator SettingsIter;
+
+
+class PVSSettingsManager;
+/// documentation test 1.2
+/// line 2.2
+/// line 3.2
+class PVSSettingsManager
+{
+public:
+ static PVSSettingsManager* getManager();
+ void setConfigFile(QString path);
+ bool hasEntry(QString name);
+ QString getEntryString(QString name);
+ void writeEntry(QString name, QString value);
+ void setConfigs();
+ void reWriteConfigs(QString set, QString val);
+ void readConfigs(QString sett, QString vall);
+private:
+ static PVSSettingsManager* myself;
+ PVSSettingsManager();
+ void _parseFile(QString path);
+ SettingsEntry _parseLine(QString line);
+ QString _path;
+ SettingsList settingsList;
+ QSettings _configs;
+
+};
+
+
+#endif
diff --git a/src/util/serviceDiscoveryUtil.cpp b/src/util/serviceDiscoveryUtil.cpp
new file mode 100644
index 0000000..32aa0fc
--- /dev/null
+++ b/src/util/serviceDiscoveryUtil.cpp
@@ -0,0 +1,65 @@
+#include "serviceDiscoveryUtil.h"
+#include <cassert>
+
+void appendSdField(QByteArray* target, const char* id, QString data)
+{
+ assert(strlen(id) == 3);
+ target->append(id);
+ QByteArray tmp = data.toUtf8();
+ if (tmp.size() > 100) tmp.truncate(100);
+ target->append((char)tmp.size());
+ target->append(tmp);
+}
+
+SdFields parseSdFields(unsigned char* data, int len)
+{
+ SdFields fields;
+ for (;;)
+ {
+ //printf("%d bytes left: %s\n", len, (char*)data);
+ if (len < 4 || len < 4 + data[3]) break; // end of data
+ QString key = QString::fromUtf8((char*)data, 3);
+ QString val = QString::fromUtf8((char*)data+4, data[3]);
+ //printf("Key: %s, Val: %s\n", key.toUtf8().data(), val.toUtf8().data());
+ fields.insert(key, val);
+ len -= (4 + data[3]);
+ data += (4 + data[3]);
+ }
+ return fields;
+}
+
+QString sha1ToReadable(QByteArray input)
+{
+ unsigned char *ptr = (unsigned char *)input.data();
+ QString retval;
+ for (int i = (input.length() < 10 ? input.length() : 10); i; --i)
+ {
+ switch(*ptr++ % 0xD)
+ {
+ case 0x0: retval.append('S'); break;
+ case 0x1: retval.append('F'); break;
+ case 0x2: retval.append('M'); break;
+ case 0x3: retval.append('K'); break;
+ case 0x4: retval.append('H'); break;
+ case 0x5: retval.append('T'); break;
+ case 0x6: retval.append('P'); break;
+ case 0x7: retval.append('D'); break;
+ case 0x8: retval.append('Y'); break;
+ case 0x9: retval.append('W'); break;
+ case 0xA: retval.append('G'); break;
+ case 0xB: retval.append('L'); break;
+ case 0xC: retval.append('B'); break;
+ }
+ if (--i == 0) break;
+ switch((*ptr >> 2) % 5)
+ {
+ case 0: retval.append('a'); break;
+ case 1: retval.append('i'); break;
+ case 2: retval.append('u'); break;
+ case 3: retval.append('e'); break;
+ case 4: retval.append('o'); break;
+ }
+ if ((*ptr++ & 3) == 0) retval.append('n');
+ }
+ return retval;
+}
diff --git a/src/util/serviceDiscoveryUtil.h b/src/util/serviceDiscoveryUtil.h
new file mode 100644
index 0000000..537daeb
--- /dev/null
+++ b/src/util/serviceDiscoveryUtil.h
@@ -0,0 +1,19 @@
+#ifndef SERVICEDISCOVERYUTIL_H_
+#define SERVICEDISCOVERYUTIL_H_
+
+#include <QtCore/QString>
+#include <QtCore/QHash>
+
+typedef QHash<QString, QString> SdFields;
+
+// These two functions build/parse the message format used in SD broadcasts
+// It is some kind of key-value pairs, encoded as follows:
+// <3 chars/bytes, key><1 byte, value length in bytes><up to 100 chars/bytes, value>
+void appendSdField(QByteArray* target, const char* id, QString data);
+SdFields parseSdFields(unsigned char* data, int len);
+
+// This algorithm is supposed to generate a readable and maybe pronouncable
+// string from the fingerprint of the servers certificate
+QString sha1ToReadable(QByteArray input);
+
+#endif /* SERVICEDISCOVERYUTIL_H_ */
diff --git a/src/util/timeUtil.cpp b/src/util/timeUtil.cpp
new file mode 100644
index 0000000..6f8e93d
--- /dev/null
+++ b/src/util/timeUtil.cpp
@@ -0,0 +1,42 @@
+/*
+ # Copyright (c) 2009, 2010 - OpenSLX Project, Computer Center University of
+ # Freiburg
+ #
+ # This program is free software distributed under the GPL version 2.
+ # See http://openslx.org/COPYING
+ #
+ # If you have any feedback please consult http://openslx.org/feedback and
+ # send your suggestions, praise, or complaints to feedback@openslx.org
+ #
+ # General information about OpenSLX can be found at http://openslx.org/
+ # -----------------------------------------------------------------------------
+ # timeUtil.cpp
+ # - ???.
+ # -----------------------------------------------------------------------------
+ */
+
+#include "timeUtil.h"
+
+TimeUtil::TimeUtil()
+{
+ seconds = useconds = mtime = 0;
+}
+
+void TimeUtil::start()
+{
+ gettimeofday(&Begin, NULL);
+}
+
+void TimeUtil::stop()
+{
+ gettimeofday(&End, NULL);
+ seconds = End.tv_sec - Begin.tv_sec;
+ useconds = End.tv_usec - Begin.tv_usec;
+ mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5;
+}
+
+long TimeUtil::getMS()
+{
+ return mtime;
+}
+
diff --git a/src/util/timeUtil.h b/src/util/timeUtil.h
new file mode 100644
index 0000000..90d647d
--- /dev/null
+++ b/src/util/timeUtil.h
@@ -0,0 +1,34 @@
+#ifndef TIME_UTIL
+#define TIME_UTIL
+
+#include <sys/time.h>
+#include <stdio.h>
+#include <unistd.h>
+
+
+#ifdef PROFILE
+#define startTime(aaa) TimeUtil aaa ## Time = TimeUtil(); aaa ## Time.start();
+#define endTime(aaa) aaa ## Time.stop(); printf("Time to execute " #aaa " : %ld\n", aaa ## Time.getMS());
+#endif
+
+#ifndef PROFILE
+#define startTime(aaa)
+#define endTime(aaa)
+#endif
+
+
+
+class TimeUtil
+{
+
+public:
+ TimeUtil();
+ void start();
+ void stop();
+ long getMS();
+private:
+ long mtime, seconds, useconds;
+ struct timeval Begin, End; //initialize Begin and End for the timer
+};
+
+#endif
diff --git a/src/util/util.cpp b/src/util/util.cpp
new file mode 100644
index 0000000..c2d06a0
--- /dev/null
+++ b/src/util/util.cpp
@@ -0,0 +1,416 @@
+#include "util.h"
+#include <QtGui/QDesktopServices>
+#include "consoleLogger.h"
+#include "TextFile.h"
+#include <ctime>
+#include <cstdlib>
+#include <QStringList>
+#include <iostream>
+
+
+PVSServerEntry::PVSServerEntry(QString name)
+{
+ name_ = name;
+}
+void PVSServerEntry::addClient(QString client)
+{
+ clientList_.push_back(client);
+}
+bool PVSServerEntry::hasClient(QString client)
+{
+ for (std::list<QString>::iterator it = clientList_.begin(); it != clientList_.end(); it++)
+ {
+ if ((*it).compare(client) == 0)
+ return true;
+ }
+ return false;
+}
+QString PVSServerEntry::getName()
+{
+ return name_;
+}
+
+int PVSServerEntry::getSize()
+{
+ return clientList_.size();
+}
+
+
+//namespace util
+//{
+
+int getRandom(int min, int max)
+{
+ static bool init = true;
+ if (init)
+ {
+ init = false;
+ srand ( time(NULL) + getpid() );
+ }
+ if (min >= max) return rand();
+ return rand() % (max-min+1) + min;
+}
+
+std::list<PVSServerEntry> getPVSServerEntryList(QString fileName)
+{
+ QString line;
+ TextFile file(fileName);
+ std::list<PVSServerEntry> entryList;
+
+ if (file.good())
+ {
+// std::cout << "reading table file \"" << fileName <<"\"" << std::endl;
+ PVSServerEntry* tmpEntry = NULL;
+ while (!file.eof())
+ {
+ line = file.readLine();
+
+ if (!(line.length() <=1)) // ignore blank
+ if (!(line[0] == '#' || line[0] == '/')) // ignore comments
+ {
+ if (line.mid(0, 5).compare(QString("start")) == 0)
+ {
+ if (tmpEntry != NULL)
+ {
+ // unclean file... but no reason to break down
+ //PVSServerEntry tmpEntry2 = *tmpEntry;
+ entryList.push_back(*tmpEntry);
+ delete tmpEntry;
+ tmpEntry = NULL;
+ }
+ QString tmpName(colonSplitter(line, false));
+ if (tmpName.size()<1)
+ tmpName = QString("localhost");
+
+ tmpEntry = new PVSServerEntry(tmpName);
+ continue;
+ }
+ if (line.mid(0, 3).compare(QString("end")) == 0)
+ {
+ if (tmpEntry!=NULL)
+ {
+ entryList.push_back(*tmpEntry);
+ delete tmpEntry;
+ tmpEntry = NULL;
+ }
+ else
+ ;// ignore
+
+ continue;
+ }
+ if (tmpEntry != NULL)
+ {
+ tmpEntry->addClient(line);
+ }
+ }
+ }
+ if (tmpEntry != NULL)
+ {
+ delete tmpEntry;
+ tmpEntry = NULL;
+ }
+
+ return entryList;
+ }
+ else
+ {
+ std::cout << "ERROR: no file \"" << fileName.toStdString() <<"\" found or file corrupt" << std::endl;
+ }
+ return std::list<PVSServerEntry>();
+}
+QString getFilenameFromPath(QString line)
+{
+ int lastSlash = 0;
+ for (int i = 0; i < line.length(); i++)
+ {
+ if (line.at(i) == '/')
+ {
+ lastSlash = i;
+ }
+ }
+ QString result;
+ if (lastSlash != 0 && lastSlash != line.length() -1)
+ {
+ result = line.mid(lastSlash+1, line.length()-(lastSlash+1));
+ }
+ return result;
+}
+
+QString lineSplitter(QString line, const char* signs, bool first)
+{
+ char *pch;
+ char* cLine = new char[line.length()+1];
+ strcpy(cLine, line.toUtf8().data());
+ pch = strtok (cLine,signs);
+ if (first)
+ {
+ QString tmp(pch);
+ delete cLine;
+ return tmp;
+ }
+ else
+ {
+ QString tmp;
+ char* tmpp = strtok(NULL, ";,\t\n");
+ if (tmpp)
+ tmp = QString(tmpp);
+ delete cLine;
+ return tmp;
+ }
+}
+
+QString colonSplitter(QString line, bool first)
+{
+ char *pch;
+ char* cLine = new char[line.length()+1];
+ strcpy(cLine, line.toUtf8().data());
+ pch = strtok (cLine," :\t\n");
+ if (first)
+ {
+ QString tmp(pch);
+ delete[] cLine;
+ return tmp;
+ }
+ else
+ {
+ QString tmp;
+ char* tmpp = strtok(NULL, " ;,\t\n");
+ if (tmpp)
+ tmp = QString(tmpp);
+ delete[] cLine;
+ return tmp;
+ }
+}
+
+QString getUserName()
+{
+ struct passwd* passUser = getpwuid(getuid());
+ QString username;
+ if (passUser)
+ {
+ username = QString(passUser->pw_name);
+ }
+ if (username.isEmpty())
+ {
+ printf("USERNAME COULDNT BE RETRIEVED!\n");
+ username = QString("USERNAMEERROR");
+ }
+ return username;
+}
+
+// Get full username.
+QString getFullUsername()
+{
+ QString fullname = getUserName();
+ struct passwd *pd;
+
+ if (NULL == (pd = getpwuid(getuid())))
+ {ConsoleLog writeError("getpwuid() error.");}
+ else
+ {
+ QString tmp = pd->pw_gecos;
+ QStringList userData = tmp.split(",");
+ if(userData[0].length() > 0 )
+ {
+ fullname = userData[0];
+ }
+ }
+ return fullname;
+}
+
+bool fileExists(QString fileName)
+{
+ std::ifstream file(fileName.toLocal8Bit().data());
+ if (file.good())
+ {
+#ifdef verbose
+ printf("fileExists(): file good.\n");
+#endif
+ file.close();
+ return true;
+ }
+ return false;
+
+}
+
+QString getHomeDir()
+{
+ return QDesktopServices::storageLocation(QDesktopServices::HomeLocation);
+}
+
+QString getPolicyDir()
+{
+ QString policyDir = getHomeDir();
+ QString subPath("/.pvs/");
+ policyDir.append(subPath);
+ return policyDir;
+}
+
+QString getPolicyFilePath(QString fileName)
+{
+
+ QString fullPath = getPolicyDir();
+ fullPath.append(fileName);
+ return fullPath;
+}
+bool policyFileExists(QString fileName)
+{
+ std::ifstream file(getPolicyFilePath(fileName).toUtf8().data());
+ if (file.good())
+ {
+ file.close();
+ return true;
+ }
+ return false;
+}
+
+void createPolicyDir()
+{
+ mkdir(getPolicyDir().toUtf8().data(), 0777);
+}
+
+void createPolicyFiles()
+{
+ if (!policyFileExists(QString(".allow")))
+ {
+ std::ofstream file(getPolicyFilePath(QString(".allow")).toUtf8().data());
+ file.close();
+ }
+#ifdef old_method
+ if (!policyFileExists(QString(".pass")))
+ {
+ std::ofstream file(getPolicyFilePath(QString(".pass")).toUtf8().data());
+ file.close();
+ }
+#endif
+}
+
+QString readPassFromPassFile()
+{
+ TextFile file(getPolicyFilePath(".pass"));
+ if (file.good()) // should have been checked via exists before, but better be safe
+ {
+ QString pass;
+ pass = file.readLine(); // we expect a password in correct format. otherwise their fault
+ return pass;
+ }
+ else
+ return QString();
+}
+bool getAllowed()
+{
+ printf("Checking %s\n", getPolicyFilePath(QString(".allow")).toUtf8().data());
+ TextFile file(getPolicyFilePath(".allow"));
+ if (file.good()) // should have been checked via exists before, but better be safe
+ {
+ QString allowed;
+ allowed = file.readLine();
+ if ( (allowed.compare(QString("1")) == 0) ||
+ (allowed.compare(QString("true")) == 0) ||
+ (allowed.compare(QString("t")) == 0) ||
+ (allowed.compare(QString("T")) == 0) ||
+ (allowed.compare(QString("true")) == 0) ||
+ (allowed.compare(QString("allow")) == 0) ||
+ (allowed.compare(QString("TRUE")) == 0) )
+ return true;
+ }
+ printf("...negative\n");
+ return false;
+}
+
+QString int2String(int intInt)
+{
+ char tmp[50];
+ snprintf(tmp, 49, "%d", intInt);
+ return QString(tmp);
+}
+
+int string2Int(QString string)
+{
+ return atoi(string.toUtf8().data());
+}
+
+//}//end namespace util
+
+
+#ifdef neverever
+std::list<VNCConnectInfo*> readFile(char* fileName)
+{
+ QString line;
+ std::ifstream file(fileName);
+ std::list<VNCConnectInfo*> infoList;
+
+ if (file.good())
+ {
+// std::cout << "reading clients file \"" << fileName <<"\"" << std::endl;
+ while (!file.eof())
+ {
+ getline(file, line);
+
+ if (!(line.length() <=1)) // ignore blank
+ if (!(line[0] == '#' || line[0] == '/')) // ignore comments
+ infoList.push_back(getConInfo(line));
+ }
+ }
+ else
+ {
+ std::cout << "ERROR: no file \"" << fileName <<"\" found or file corrupt" << std::endl;
+ }
+ return infoList;
+}
+
+VNCConnectInfo* getConInfo(QString line)
+{
+ char** arguments = new char*[100];
+ char* cLine = new char[line.length()+1];
+ strcpy(cLine, line.toUtf8().data());
+ int count;
+ makeArgs(cLine , &count , arguments);
+ std::cout << "found " << count << " arguments" << std::endl;
+ if (count > 2) // assume that a password would be the second argument in the line, therefore the third argument in the argv
+ {
+ QString pass = QString(arguments[2]);
+ std::cout << "think i found a password" << std::endl;
+ count--;
+ delete arguments[2];
+ // no changes to the arguments though, since the vnc-lib will ignore most of it anyway
+ return new VNCConnectInfo(count, arguments, pass);
+ }
+
+ return new VNCConnectInfo(count, arguments);
+}
+
+void makeArgs(char* line, int* count, char** arguments)
+{
+ (*count) = 1;
+
+ arguments[(*count)-1] = new char[strlen("dummy")+1]; // get program name from somewhere
+ strcpy(arguments[(*count)-1], "dummy");
+
+ /*// include encodings
+ arguments[(*count)++] = new char[strlen("-encodings")+1];
+ strcpy(arguments[(*count)], "-encodings");
+ (*count)++;
+ arguments[(*count)++] = new char[strlen("tight")+1];
+ strcpy(arguments[(*count)], "tight");
+ (*count)++;
+ */
+
+
+ if (line[strlen(line)-1] == '\n' || line[strlen(line)-1] == '\r')
+ line[strlen(line)-1] = '\0'; // remove newline
+
+ char *pch;
+ pch = strtok (line," ,\t");
+ while (pch != NULL && (*count) <= 3)
+ {
+ (*count)++; // count args
+ arguments[(*count)-1] = new char[strlen(pch)+1];
+ strcpy(arguments[(*count)-1], pch);
+ pch = strtok (NULL, " ,\t");
+ }
+}
+
+
+#endif
+
diff --git a/src/util/util.h b/src/util/util.h
new file mode 100644
index 0000000..37565cb
--- /dev/null
+++ b/src/util/util.h
@@ -0,0 +1,59 @@
+#include <QString>
+#include <cstdio>
+//#include <cstring>
+#include <list>
+#include <fstream>
+#include <iostream>
+#include <pwd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+
+
+#ifndef _PVSSERVERENTRY_H_
+#define _PVSSERVERENTRY_H_
+class PVSServerEntry
+{
+public:
+ PVSServerEntry(QString name);
+ void addClient(QString client);
+ bool hasClient(QString client);
+ QString getName();
+ int getSize();
+private:
+ QString name_;
+ std::list<QString> clientList_;
+};
+#endif
+
+//namespace util
+//{
+int getRandom(int min, int max);
+std::list<PVSServerEntry> getPVSServerEntryList(QString fileName);
+QString getFilenameFromPath(QString line);
+QString lineSplitter(QString line, const char* signs, bool first);
+QString colonSplitter(QString line, bool first);
+QString getUserName();
+QString getFullUsername();
+bool fileExists(QString fileName);
+QString getHomeDir();
+QString getPolicyDir();
+QString getPolicyFilePath(QString fileName);
+bool policyFileExists(QString fileName);
+void createPolicyFiles();
+void createPolicyDir();
+QString readPassFromPassFile();
+bool getAllowed();
+
+QString int2String(int intInt);
+int string2Int(QString string);
+int string2Int(QString string);
+//} // end namespace util
+
+//std::list<VNCConnectInfo*> readFile(char* fileName);
+//void makeArgs(char* line, int* count, char** arguments);
+//VNCConnectInfo* getConInfo(QString line);
+
+
+
+
diff --git a/src/util/vncClientThread.cpp b/src/util/vncClientThread.cpp
new file mode 100644
index 0000000..bb1d457
--- /dev/null
+++ b/src/util/vncClientThread.cpp
@@ -0,0 +1,249 @@
+/*
+ # Copyright (c) 2009, 2010 - OpenSLX Project, Computer Center University of
+ # Freiburg
+ #
+ # This program is free software distributed under the GPL version 2.
+ # See http://openslx.org/COPYING
+ #
+ # If you have any feedback please consult http://openslx.org/feedback and
+ # send your suggestions, praise, or complaints to feedback@openslx.org
+ #
+ # General information about OpenSLX can be found at http://openslx.org/
+ # -----------------------------------------------------------------------------
+ # vncClientThread.cpp
+ # - Connection to remove vnc server
+ # - Emits Qt signal on framebuffer updates
+ # -----------------------------------------------------------------------------
+ */
+
+#include "vncClientThread.h"
+
+VNCClientThread::VNCClientThread(QString host, int port, QString passwd,
+ int quality, int updatefreq) :
+ QThread(), _frameBuffer(0)
+{
+ _host = host;
+ _port = port;
+ _passwd = passwd;
+ _quality = quality;
+ _updatefreq = updatefreq;
+ terminate = false;
+ _client = NULL;
+ _connected = false;
+}
+
+VNCClientThread::~VNCClientThread()
+{
+ if (this->isRunning()) this->wait(2000);
+ if (_frameBuffer) delete[] _frameBuffer;
+ _frameBuffer = NULL;
+ if (_client != NULL)
+ {
+ ::close(_client->sock);
+ _client->frameBuffer = NULL;
+ rfbClientCleanup(_client);
+ _client = NULL;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Public
+
+void VNCClientThread::run()
+{
+ qDebug("[%s] VNC client started.", metaObject()->className());
+ qDebug("[%s] Host: '%s' Port: %i Passwd: '%s' Quality: %i",
+ metaObject()->className(), qPrintable(_host), _port,
+ qPrintable(_passwd), _quality);
+
+ // setup network
+ _client = rfbGetClient(8, 3, 4);
+ _client->MallocFrameBuffer = frameBufferHandler;
+ _client->canHandleNewFBSize = true;
+ _client->serverHost = strdup(_host.toUtf8().constData());
+ _client->desktopName = NULL;
+ _client->serverPort = _port;
+ _client->GetPassword = passwdHandler;
+ _client->GotFrameBufferUpdate = updateImage;
+ _client->frameBuffer = NULL;
+
+ // save this instance in vnc-struct for callbacks
+ rfbClientSetClientData(_client, 0, this);
+
+ // start client
+ if (!rfbInitClient(_client, NULL, NULL))
+ {
+ _client = NULL; // !!! <- if you don't do this you will get a segfault
+ return; // later when you try to clean up _client, as rfbInitClient already did so
+ }
+
+ qDebug("[%s] Connection successful!", metaObject()->className());
+
+ // Main VNC event loop
+ while (!terminate)
+ {
+ _connected = true;
+ const int i = WaitForMessage(_client, 500); // its usec, not msec
+ if (i < 0)
+ break;
+ if (i) if (!HandleRFBServerMessage(_client))
+ break;
+
+ /*
+ //work yourself through event queue and fire every event...
+ while (!_eventQueue.isEmpty()) {
+ SomeEvent* event = _eventQueue.dequeue();
+ event->fire(_client);
+ delete event;
+ }*/
+
+ this->msleep(_updatefreq);
+ }
+
+ // cleanup
+ ::close(_client->sock);
+
+ qDebug("[%s] VNC client stopped.", metaObject()->className());
+ _connected = false;
+}
+
+QImage VNCClientThread::getImage()
+{
+ return _img;
+}
+
+QSize VNCClientThread::getSize()
+{
+ return _clientSize;
+}
+
+int VNCClientThread::getUpdatefreq()
+{
+ if (_updatefreq > 0)
+ return _updatefreq;
+ return 500;
+}
+
+void VNCClientThread::setUpdatefreq(int updatefreq)
+{
+ _updatefreq = updatefreq;
+}
+
+QString VNCClientThread::getDesktopName()
+{
+ if (_client == NULL || _client->desktopName == NULL) return QString();
+ return QString(_client->desktopName);
+}
+
+char* VNCClientThread::passwdHandler(rfbClient *client)
+{
+ VNCClientThread* t = (VNCClientThread*) rfbClientGetClientData(client, 0);
+ return strdup(t->_passwd.toLocal8Bit());
+}
+
+rfbBool VNCClientThread::frameBufferHandler(rfbClient *client)
+{
+ VNCClientThread *t = (VNCClientThread*) rfbClientGetClientData(client, 0);
+ const int width = client->width, height = client->height, depth =
+ client->format.bitsPerPixel;
+ const int size = width * height * (depth / 8);
+ qDebug("[%s] Remote desktop: %ix%ix%i", t->metaObject()->className(),
+ width, height, depth);
+
+ if (t->_frameBuffer)
+ delete[] t->_frameBuffer;
+
+ t->_frameBuffer = new uint8_t[size];
+ client->frameBuffer = t->_frameBuffer;
+ memset(client->frameBuffer, '\0', size);
+ client->format.bitsPerPixel = 32;
+ client->format.redShift = 16;
+ client->format.greenShift = 8;
+ client->format.blueShift = 0;
+ client->format.redMax = 0xff;
+ client->format.greenMax = 0xff;
+ client->format.blueMax = 0xff;
+
+ const int quality = t->_quality;
+ switch (quality)
+ {
+ case VNCClientThread::HIGH:
+ client->appData.useBGR233 = 0;
+ client->appData.encodingsString = "copyrect hextile raw";
+ client->appData.compressLevel = 0;
+ client->appData.qualityLevel = 9;
+ client->appData.scaleSetting = 10; // FIXME: Doesn't work
+ break;
+ case VNCClientThread::MEDIUM:
+ client->appData.useBGR233 = 0;
+ client->appData.encodingsString
+ = "tight zrle ultra copyrect hextile zlib corre rre raw";
+ client->appData.compressLevel = 5;
+ client->appData.qualityLevel = 7;
+ client->appData.scaleSetting = 10;
+ break;
+ case VNCClientThread::LOW:
+ default:
+ client->appData.useBGR233 = 1;
+ client->appData.encodingsString
+ = "tight zrle ultra copyrect hextile zlib corre rre raw";
+ client->appData.compressLevel = 9;
+ client->appData.qualityLevel = 1;
+ client->appData.scaleSetting = 10;
+ break;
+ }
+ SetFormatAndEncodings(client);
+
+ t->_clientSize = QSize(width, height);
+
+ // If something stops working with VNC images/updates, move these two
+ // commands back tp updateImage
+ const QImage img = QImage(client->frameBuffer, client->width,
+ client->height, QImage::Format_RGB32);
+ t->_img = img;
+ // <>
+
+ return true;
+}
+
+void VNCClientThread::updateImage(rfbClient* client, int x, int y, int w, int h)
+{
+ VNCClientThread* t = (VNCClientThread*) rfbClientGetClientData(client, 0);
+ emit t->imageUpdated(x, y, w, h);
+}
+
+/* rfbClient* VNCClientThread::getRfbClient(){
+ return _client;
+}*/
+
+SomeEvent::~SomeEvent()
+{
+}
+
+void PointerEvent::fire(rfbClient* cl)
+{
+ SendPointerEvent(cl, _x, _y, _buttonMask);
+}
+
+void KeyEvent::fire(rfbClient* cl)
+{
+ SendKeyEvent(cl, _key, _pressed);
+}
+
+void VNCClientThread::mouseEvent(int x, int y, int buttonMask)
+{
+ //QMutexLocker lock(&mutex);
+ if (terminate)
+ return;
+
+ _eventQueue.enqueue(new PointerEvent(x, y, buttonMask));
+}
+
+void VNCClientThread::keyEvent(int key, bool pressed)
+{
+ //QMutexLocker lock(&mutex);
+ if (terminate)
+ return;
+
+ _eventQueue.enqueue(new KeyEvent(key, pressed));
+}
diff --git a/src/util/vncClientThread.h b/src/util/vncClientThread.h
new file mode 100644
index 0000000..10980b8
--- /dev/null
+++ b/src/util/vncClientThread.h
@@ -0,0 +1,114 @@
+/*
+ # Copyright (c) 2009, 2010 - OpenSLX Project, Computer Center University of
+ # Freiburg
+ #
+ # This program is free software distributed under the GPL version 2.
+ # See http://openslx.org/COPYING
+ #
+ # If you have any feedback please consult http://openslx.org/feedback and
+ # send your suggestions, praise, or complaints to feedback@openslx.org
+ #
+ # General information about OpenSLX can be found at http://openslx.org/
+ */
+
+#ifndef VNCCLIENTTHREAD_H_
+#define VNCCLIENTTHREAD_H_
+
+#include <QtCore>
+#include <QtGui/QImage>
+
+extern "C"
+{
+#include <rfb/rfbclient.h>
+}
+
+class SomeEvent
+{
+public:
+ virtual ~SomeEvent();
+
+ virtual void fire(rfbClient*) = 0;
+};
+
+class KeyEvent : public SomeEvent
+{
+public:
+ KeyEvent(int key, int pressed)
+ : _key(key), _pressed(pressed) {}
+
+ void fire(rfbClient*);
+
+private:
+ int _key;
+ int _pressed;
+};
+
+class PointerEvent : public SomeEvent
+{
+public:
+ PointerEvent(int x, int y, int buttonMask)
+ : _x(x), _y(y), _buttonMask(buttonMask) {}
+
+ void fire(rfbClient*);
+
+private:
+ int _x;
+ int _y;
+ int _buttonMask;
+};
+
+class VNCClientThread: public QThread
+{
+ Q_OBJECT
+
+public:
+ VNCClientThread(QString host, int port, QString passwd, int quality, int updatefreq = 0);
+ ~VNCClientThread();
+
+ void run();
+ QImage getImage();
+ QSize getSize();
+ int getUpdatefreq();
+ void setUpdatefreq(int updatefreq);
+ QString getDesktopName();
+ void mouseEvent(int x, int y, int buttonMask);
+ void keyEvent(int key, bool pressed);
+ bool isConnected()
+ {
+ return _connected;
+ }
+
+
+ static void updateImage(rfbClient *client, int x, int y, int w, int h);
+ static char* passwdHandler(rfbClient *client);
+ static rfbBool frameBufferHandler(rfbClient *client);
+ //rfbClient* getRfbClient();
+
+ bool terminate;
+
+ int const static HIGH = 0;
+ int const static MEDIUM = 1;
+ int const static LOW = 2;
+
+Q_SIGNALS:
+ void imageUpdated(int x, int y, int w, int h);
+
+private:
+ rfbClient *_client;
+ uint8_t *_frameBuffer;
+
+ QString _host;
+ int _port;
+ QString _passwd;
+ int _quality;
+ int _updatefreq;
+ QQueue<SomeEvent* > _eventQueue;
+
+ QImage _img;
+ QSize _clientSize;
+
+ bool _connected;
+
+};
+
+#endif /* VNCCLIENTTHREAD_H_ */