summaryrefslogtreecommitdiffstats
path: root/src/gui/clientVNCViewer.cpp
diff options
context:
space:
mode:
authorSebastian2010-05-12 19:42:27 +0200
committerSebastian2010-05-12 19:42:27 +0200
commitce3329047d378a14006ce74ec273ac59e3375303 (patch)
tree782430f270b4c7aca1b35d5b7813518e3797c555 /src/gui/clientVNCViewer.cpp
downloadpvs-ce3329047d378a14006ce74ec273ac59e3375303.tar.gz
pvs-ce3329047d378a14006ce74ec273ac59e3375303.tar.xz
pvs-ce3329047d378a14006ce74ec273ac59e3375303.zip
initial import of latest svn version
Diffstat (limited to 'src/gui/clientVNCViewer.cpp')
-rw-r--r--src/gui/clientVNCViewer.cpp273
1 files changed, 273 insertions, 0 deletions
diff --git a/src/gui/clientVNCViewer.cpp b/src/gui/clientVNCViewer.cpp
new file mode 100644
index 0000000..d6a218b
--- /dev/null
+++ b/src/gui/clientVNCViewer.cpp
@@ -0,0 +1,273 @@
+/*
+ # 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/
+ # -----------------------------------------------------------------------------
+ # clientVNCViewer.cpp
+ # - connetct to vnc server and show remote screen (window/full)
+ # -----------------------------------------------------------------------------
+ */
+
+#include "clientVNCViewer.h"
+
+ClientVNCViewer::ClientVNCViewer(QWidget *parent) :
+ QDialog(parent), _thread(0), _viewOnly(true), _buttonMask(0)
+{
+ // connect to D-Bus and get interface
+ QDBusConnection dbus = QDBusConnection::sessionBus();
+ dbus.registerObject("/vnc", this);
+ dbus.registerService("org.openslx.pvsgui");
+ _ifaceDBus = new OrgOpenslxPvsInterface("org.openslx.pvs", "/", dbus, this);
+ connect(_ifaceDBus, SIGNAL(project(QString, int, QString, bool, bool, int)),
+ this, SLOT(open(QString, int, QString, bool, bool, int)));
+ connect(_ifaceDBus, SIGNAL(unproject()), this, SLOT(close()));
+}
+
+ClientVNCViewer::~ClientVNCViewer()
+{
+ close();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Public
+
+void ClientVNCViewer::open(QString host, int port, QString passwd, bool fs,
+ bool mode, int quality)
+{
+ // start thread for vnc-updates
+ _thread = new VNCClientThread(host, port, passwd, quality);
+ _thread->start();
+ //_rfbclient = _thread->getRfbClient();
+ //installEventFilter(this);
+ setMouseTracking(true); // get mouse events even when there is no mousebutton pressed
+ setFocusPolicy(Qt::WheelFocus); //needed?!?
+
+ setAttribute(Qt::WA_OpaquePaintEvent);
+
+ // smooth transformation?
+ if (mode)
+ _mode = Qt::SmoothTransformation;
+ else
+ _mode = Qt::FastTransformation;
+
+ // fullscreen?
+ if (fs)
+ {
+ setWindowFlags(Qt::WindowStaysOnTopHint);
+ showFullScreen();
+ activateWindow();
+ raise();
+ }
+ else
+ showNormal();
+
+ connect(this, SIGNAL(rejected()), this, SLOT(close()));
+ connect(_thread, SIGNAL(imageUpdated(int,int,int,int)), this,
+ SLOT(updateImage(int,int,int,int)), Qt::BlockingQueuedConnection);
+}
+
+void ClientVNCViewer::close()
+{
+ setVisible(false);
+ if (_thread)
+ {
+ disconnect(_thread, SIGNAL(imageUpdated(int,int,int,int)), this,
+ SLOT(updateImage(int,int,int,int)));
+
+ _thread->terminate = true;
+ _thread->wait(1000);
+ delete _thread;
+ _thread = NULL;
+ }
+ disconnect(this, SIGNAL(rejected()), this, SLOT(close()));
+}
+
+void ClientVNCViewer::updateImage(int x, int y, int w, int h)
+{
+ if (_thread->getSize() != size()) // scaling needed?
+ {
+ // grow the update rectangle to avoid artifacts
+ x -= 1;
+ y -= 1;
+ w += 2;
+ h += 2;
+
+ _img = _thread->getImage().copy(x, y, w, h);
+
+ qreal sx = qreal(width()) / qreal(_thread->getSize().width());
+ qreal sy = qreal(height()) / qreal(_thread->getSize().height());
+
+ x = qRound(qreal(x) * sx);
+ y = qRound(qreal(y) * sy);
+ w = qRound(qreal(w) * sx);
+ h = qRound(qreal(h) * sy);
+ }
+ else
+ {
+ _img = _thread->getImage().copy(x, y, w, h);
+ }
+
+ repaint(x, y, w, h);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Protected
+
+void ClientVNCViewer::paintEvent(QPaintEvent *event)
+{
+ if (_img.isNull())
+ return;
+
+ QPainter painter(this);
+ QRect r = event->rect();
+
+ if (r == rect())
+ _img = _thread->getImage(); // redraw complete image (e.g. on resize)
+
+ if (_thread->getSize() == size())
+ {
+ painter.drawImage(r.topLeft(), _img); // don't scale
+ }
+ else
+ {
+ QImage i = _img.scaled(r.size(), Qt::IgnoreAspectRatio, _mode);
+ painter.drawImage(r.topLeft(), i);
+ }
+ event->accept();
+}
+//returns true if event was processed
+/*bool ClientVNCViewer::event(QEvent *event)
+{
+ switch (event->type()) {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+
+ keyEventHandler(static_cast<QKeyEvent*>(event));
+ return true;
+ break;
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseMove:
+ mouseEventHandler(static_cast<QMouseEvent*>(event));
+ return true;
+ break;
+ case QEvent::Wheel:
+ wheelEventHandler(static_cast<QWheelEvent*>(event));
+ return true;
+ break;
+ default:
+ return false;
+ }
+}*/
+
+//handles mouseevents
+void ClientVNCViewer::mouseEventHandler(QMouseEvent *e)
+{
+ if (e->type() != QEvent::MouseMove) {
+ if ((e->type() == QEvent::MouseButtonPress) ||
+ (e->type() == QEvent::MouseButtonDblClick)) {
+ if (e->button() & Qt::LeftButton)
+ _buttonMask |= 0x01;
+ if (e->button() & Qt::MidButton)
+ _buttonMask |= 0x02;
+ if (e->button() & Qt::RightButton)
+ _buttonMask |= 0x04;
+ } else if (e->type() == QEvent::MouseButtonRelease) {
+ if (e->button() & Qt::LeftButton)
+ _buttonMask &= 0xfe;
+ if (e->button() & Qt::MidButton)
+ _buttonMask &= 0xfd;
+ if (e->button() & Qt::RightButton)
+ _buttonMask &= 0xfb;
+ }
+ }
+ qreal sx = qreal(width()) / qreal(_thread->getSize().width());
+ qreal sy = qreal(height()) / qreal(_thread->getSize().height());
+ _thread->mouseEvent(qRound(e->x() / sx), qRound(e->y() / sy), _buttonMask);
+}
+
+//handles mousewheel
+void ClientVNCViewer::wheelEventHandler(QWheelEvent *event)
+{
+ int eb = 0;
+ if (event->delta() < 0)
+ eb |= 0x10;
+ else
+ eb |= 0x8;
+
+ qreal sx = qreal(width()) / qreal(_thread->getSize().width());
+ qreal sy = qreal(height()) / qreal(_thread->getSize().height());
+ const int x = qRound(event->x() / sx);
+ const int y = qRound(event->y() / sy);
+
+ _thread->mouseEvent(x, y, eb | _buttonMask);
+ _thread->mouseEvent(x, y, _buttonMask);
+}
+
+//Handles keypress
+void ClientVNCViewer::keyEventHandler(QKeyEvent *e)
+{
+ rfbKeySym k = e->nativeVirtualKey();
+
+ // do not handle Key_Backtab separately because the Shift-modifier
+ // is already enabled
+ if (e->key() == Qt::Key_Backtab) {
+ k = XK_Tab;
+ }
+
+ const bool pressed = (e->type() == QEvent::KeyPress);
+
+ // handle modifiers
+ if (k == XK_Shift_L || k == XK_Control_L || k == XK_Meta_L || k == XK_Alt_L) {
+ if (pressed) {
+ _modkeys[k] = true;
+ } else if (_modkeys.contains(k)) {
+ _modkeys.remove(k);
+ } else {
+ unpressModifiers();
+ }
+ }
+
+ if (k) {
+ _thread->keyEvent(k, pressed);
+ }
+}
+
+//removes modifier keys which have been pressed
+void ClientVNCViewer::unpressModifiers()
+{
+ const QList<unsigned int> keys = _modkeys.keys();
+ QList<unsigned int>::const_iterator it = keys.constBegin();
+ while (it != keys.end()) {
+ _thread->keyEvent(*it, false);
+ it++;
+ }
+ _modkeys.clear();
+}
+
+//(QT Function) Filters events, if _viewOnly is set, true is returned and the event is ignored
+//TODO use this function when implementing viewonly switch
+bool ClientVNCViewer::eventFilter(QObject *obj, QEvent *event)
+{
+ if (_viewOnly) {
+ if (event->type() == QEvent::KeyPress ||
+ event->type() == QEvent::KeyRelease ||
+ event->type() == QEvent::MouseButtonDblClick ||
+ event->type() == QEvent::MouseButtonPress ||
+ event->type() == QEvent::MouseButtonRelease ||
+ event->type() == QEvent::Wheel ||
+ event->type() == QEvent::MouseMove)
+ return true;
+ }
+
+ return false;
+ //return RemoteView::eventFilter(obj, event);
+}