From 1a5709501f94014d41987b956338bb6424b9f90c Mon Sep 17 00:00:00 2001 From: sr Date: Mon, 4 Feb 2013 19:50:31 +0100 Subject: Initial commit --- src/client/vnc/vncwindow.cpp | 277 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 src/client/vnc/vncwindow.cpp (limited to 'src/client/vnc/vncwindow.cpp') 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(event)); + return true; + break; + case QEvent::MouseButtonDblClick: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseMove: + mouseEventHandler(static_cast(event)); + return true; + break; + case QEvent::Wheel: + wheelEventHandler(static_cast(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 keys = _modkeys.keys(); + QList::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); +} -- cgit v1.2.3-55-g7522