summaryrefslogtreecommitdiffstats
path: root/src/client/vnc/vncwindow.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/vncwindow.cpp
parentTest (diff)
downloadpvs2-1a5709501f94014d41987b956338bb6424b9f90c.tar.gz
pvs2-1a5709501f94014d41987b956338bb6424b9f90c.tar.xz
pvs2-1a5709501f94014d41987b956338bb6424b9f90c.zip
Initial commit
Diffstat (limited to 'src/client/vnc/vncwindow.cpp')
-rw-r--r--src/client/vnc/vncwindow.cpp277
1 files changed, 277 insertions, 0 deletions
diff --git a/src/client/vnc/vncwindow.cpp b/src/client/vnc/vncwindow.cpp
new file mode 100644
index 0000000..d4f6d40
--- /dev/null
+++ b/src/client/vnc/vncwindow.cpp
@@ -0,0 +1,277 @@
+/*
+ # 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 "vncwindow.h"
+#include "vncthread.h"
+
+VncWindow::VncWindow(QWidget *parent) :
+ QDialog(parent), _vncWorker(NULL), _viewOnly(true), _buttonMask(0), _clientId(0)
+{
+ //
+}
+
+VncWindow::~VncWindow()
+{
+ close();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Public
+
+void VncWindow::open(const QString& host, int port, const QString& passwd, bool ro, bool fullscreen, const QString& caption, const int clientId)
+{
+ // start thread for vnc-updates
+ this->onThreadFinished();
+ _clientId = clientId;
+ _vncWorker = new VncThread(host, port, passwd, 1);
+ connect(_vncWorker, SIGNAL(finished()), this, SLOT(onThreadFinished()), Qt::QueuedConnection);
+ connect(_vncWorker, SIGNAL(projectionStarted()), this, SLOT(onProjectionStarted()), Qt::QueuedConnection);
+ _vncWorker->start(QThread::LowPriority);
+ //_rfbclient = _thread->getRfbClient();
+ //installEventFilter(this);
+ setMouseTracking(true); // get mouse events even when there is no mousebutton pressed
+ setFocusPolicy(Qt::WheelFocus); //needed?!?
+
+ setWindowTitle(caption);
+
+ setAttribute(Qt::WA_OpaquePaintEvent);
+
+ if (fullscreen)
+ {
+ setWindowFlags(Qt::WindowStaysOnTopHint);
+ showFullScreen();
+ activateWindow();
+ raise();
+ }
+ else
+ {
+ resize(800, 600);
+ showNormal();
+ }
+
+ this->show();
+ _vncWorker->setTargetSize(this->size());
+
+ connect(_vncWorker, SIGNAL(imageUpdated(const int, const int, const int, const int)), this,
+ SLOT(onUpdateImage(const int, const int, const int, const int)),
+ Qt::QueuedConnection);
+}
+
+void VncWindow::closeEvent(QCloseEvent *e)
+{
+ e->ignore();
+ qDebug("Closing VNC viewer window.");
+ this->setVisible(false);
+ this->onThreadFinished();
+ emit running(false, _clientId);
+}
+
+void VncWindow::onUpdateImage(const int x, const int y, const int w, const int h)
+{
+ this->repaint(x, y, w, h);
+}
+
+/**
+ * Thread finished, clean up and close window
+ */
+void VncWindow::onThreadFinished()
+{
+ if (_vncWorker)
+ {
+ disconnect(_vncWorker, SIGNAL(imageUpdated(const int, const int, const int, const int)), this,
+ SLOT(onUpdateImage(const int, const int, const int, const int)));
+ disconnect(_vncWorker, SIGNAL(finished()), this, SLOT(onThreadFinished()));
+ _vncWorker->stop();
+ delete _vncWorker;
+ _vncWorker = NULL;
+ this->close();
+ }
+}
+
+/**
+ * VNC Thread successfully connected to remote end - projection will start
+ */
+void VncWindow::onProjectionStarted()
+{
+ emit running(true, _clientId);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Protected
+
+void VncWindow::paintEvent(QPaintEvent *event)
+{
+ const QRect &r = event->rect();
+ this->draw(r.left(), r.top(), r.width(), r.height());
+ event->accept();
+}
+
+void VncWindow::resizeEvent(QResizeEvent* event)
+{
+ _vncWorker->setTargetSize(event->size());
+}
+
+void VncWindow::draw(const int x, const int y, const int w, const int h)
+{
+ if (_vncWorker == NULL)
+ return;
+ QPainter painter(this);
+ painter.drawImage(x, y, _vncWorker->getImage(), x, y, w, h);
+ //painter.drawRect(x,y,w,h); // for debugging updated area
+}
+
+//returns true if event was processed
+/*bool VncWindow::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 VncWindow::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;
+ }
+ }
+ _vncWorker->mouseEvent(e->x(), e->y(), _buttonMask);
+}
+
+//handles mousewheel
+void VncWindow::wheelEventHandler(QWheelEvent *event)
+{
+ int eb = 0;
+ if (event->delta() < 0)
+ eb |= 0x10;
+ else
+ eb |= 0x8;
+
+ const int x = event->x();
+ const int y = event->y();
+
+ _vncWorker->mouseEvent(x, y, eb | _buttonMask);
+ _vncWorker->mouseEvent(x, y, _buttonMask);
+}
+
+//Handles keypress
+void VncWindow::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)
+ {
+ _vncWorker->keyEvent(k, pressed);
+ }
+}
+
+void VncWindow::keyPressEvent(QKeyEvent* event)
+{
+ if (event->key() == Qt::Key_Escape)
+ this->close();
+}
+
+//removes modifier keys which have been pressed
+void VncWindow::unpressModifiers()
+{
+ const QList<unsigned int> keys = _modkeys.keys();
+ QList<unsigned int>::const_iterator it = keys.constBegin();
+ while (it != keys.end())
+ {
+ _vncWorker->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 VncWindow::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);
+}