summaryrefslogtreecommitdiffstats
path: root/src/client/vnc/vncwindow.cpp
diff options
context:
space:
mode:
authorSimon Rettberg2014-04-23 20:30:48 +0200
committerSimon Rettberg2014-04-23 20:30:48 +0200
commit4a30aa26b608238eea90e7ecb97adc3b34d68f86 (patch)
treebf3242347a1d2d688021b1a0467306a9b1fea8f5 /src/client/vnc/vncwindow.cpp
parentMerge branch 'master' of git.openslx.org:pvs2 (diff)
downloadpvs2-4a30aa26b608238eea90e7ecb97adc3b34d68f86.tar.gz
pvs2-4a30aa26b608238eea90e7ecb97adc3b34d68f86.tar.xz
pvs2-4a30aa26b608238eea90e7ecb97adc3b34d68f86.zip
Doxygen comments, removed incomplete unused event handling for VNC RW access, introduced terminateVnc method in VncWindow
Diffstat (limited to 'src/client/vnc/vncwindow.cpp')
-rw-r--r--src/client/vnc/vncwindow.cpp333
1 files changed, 144 insertions, 189 deletions
diff --git a/src/client/vnc/vncwindow.cpp b/src/client/vnc/vncwindow.cpp
index 2f2b427..581d503 100644
--- a/src/client/vnc/vncwindow.cpp
+++ b/src/client/vnc/vncwindow.cpp
@@ -19,7 +19,7 @@
#include "vncthread.h"
VncWindow::VncWindow(QWidget *parent) :
- QDialog(parent), _vncWorker(NULL), _viewOnly(true), _buttonMask(0), _clientId(0), _redrawTimer(0)
+ QDialog(parent), _vncWorker(NULL), _viewOnly(true), _clientId(0), _redrawTimer(0), _tcpTimeoutTimer(0)
{
//
}
@@ -30,23 +30,79 @@ VncWindow::~VncWindow()
}
////////////////////////////////////////////////////////////////////////////////
+// Private
+
+/**
+ * Terminates the vnc worker thread and stops all related timers.
+ * The thread will be signalled to stop, but we don't wait for it
+ * to actually terminate. All signaled of the thread are blocked, and we NULL
+ * our reference to it. It will finish running in a detached state and finally
+ * delete itself upon completion.
+ */
+void VncWindow::terminateVncThread()
+{
+ if(_vncWorker == NULL)
+ return;
+
+ _vncWorker->blockSignals(true);
+ _vncWorker->stop();
+ _vncWorker = NULL;
+ if(_redrawTimer != 0)
+ {
+ killTimer(_redrawTimer);
+ _redrawTimer = 0;
+ }
+ if(_tcpTimeoutTimer != 0)
+ {
+ killTimer(_tcpTimeoutTimer);
+ _tcpTimeoutTimer = 0;
+ }
+}
+
+/**
+ * Draws given part of the current VNC frame buffer to the window.
+ * Gets the image from the _vncWorker thread in an unsafe way. :(
+ *
+ * @param x X offset of the region to draw
+ * @param y Y offset of the region to draw
+ * @param w width of the region to draw
+ * @param h height of the region to draw
+ */
+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
+}
+
+////////////////////////////////////////////////////////////////////////////////
// Public
+/**
+ * Show the VNC client window and connect to the given VNC server.
+ * Any currently active VNC client connection is signaled to terminate,
+ * and a new VNC client worker thread is created for the new connection.
+ *
+ * @param host IP address of VNC server to connect to
+ * @param port Port of VNC server to connect to
+ * @param passwd (view only) password of VNC server to connect to
+ * @param ro currently unused
+ * @param fullscreen display VNC image in fullscreen mode
+ * @param caption caption of window (only visible if not running in fullscreen mode)
+ * @param clientId the ID of the client we're connecting to (echoed back to server, not used locally)
+ */
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->onProjectionStopped();
+ this->terminateVncThread();
_clientId = clientId;
_vncWorker = new VncThread(host, port, passwd, 1);
connect(_vncWorker, SIGNAL(projectionStopped()), this, SLOT(onProjectionStopped()), Qt::QueuedConnection);
connect(_vncWorker, SIGNAL(projectionStarted()), this, SLOT(onProjectionStarted()), Qt::QueuedConnection);
-
- _tcpTimeoutTimer = startTimer(4000);
- _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?!?
+ 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);
setWindowTitle(caption);
@@ -68,27 +124,49 @@ void VncWindow::open(const QString& host, int port, const QString& passwd, bool
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);
+ _tcpTimeoutTimer = startTimer(4000);
+ _vncWorker->start(QThread::LowPriority);
}
+/**
+ * Called by Qt if the window is requested to be closed. This can either happen
+ * through code (this->close()), or a keypress (Alt-F4, Esc). We'll ignore the
+ * request and simply hide the window.
+ *
+ * @param e close event data
+ */
void VncWindow::closeEvent(QCloseEvent *e)
{
e->ignore();
qDebug("Closing VNC viewer window.");
this->setVisible(false);
- this->onProjectionStopped();
+ this->terminateVncThread();
emit running(false, _clientId);
}
+////////////////////////////////////////////////////////////////////////////////
+// Slots
+
+/**
+ * Triggered by imageUpdate signal from the _vncWorker thread telling
+ * that the given region of the image changed. Simply repaints the
+ * given area of the window. Coordinates have already been scaled
+ * accordingly.
+ *
+ * @param x X offset of the region to update
+ * @param y Y offset of the region to update
+ * @param w width of the region to update
+ * @param h height of the region to update
+ */
void VncWindow::onUpdateImage(const int x, const int y, const int w, const int h)
{
this->repaint(x, y, w, h);
}
/**
- * VNC Thread successfully connected to remote end - projection will start
+ * Triggered by _vncWorker after successfully connecting to the VNC server.
+ * This emits a signal that will eventually lead to the ServerConnection
+ * telling the server that we're now watching another client.
*/
void VncWindow::onProjectionStarted()
{
@@ -96,51 +174,77 @@ void VncWindow::onProjectionStarted()
_redrawTimer = startTimer(5000);
}
+/**
+ * Triggered by _vncWorker when the connection to the VNC server is lost.
+ * We'll terminate the thread (detached) and close the window. A signal
+ * telling the server that we're not watching a VNC stream anymore will
+ * eventually be emited by the closeEvent.
+ */
void VncWindow::onProjectionStopped()
{
- if(_vncWorker == NULL)
- return;
-
- _vncWorker->blockSignals(true);
- _vncWorker->stop();
- _vncWorker = NULL;
- if(_redrawTimer != 0)
- {
- killTimer(_redrawTimer);
- _redrawTimer = 0;
- }
- this->close();
-
+ this->terminateVncThread();
+ this->close();
}
////////////////////////////////////////////////////////////////////////////////
// Protected
-void VncWindow::close()
+
+/**
+ * Request to close the window. Overriden from QDialog/QWidget.
+ * If the window is already hidden, this just emits a signal that
+ * will tell the server that we're not watching a VNC stream
+ * currently. Otherwise it will just call the implementation of
+ * the super class.
+ *
+ * @return false
+ */
+bool VncWindow::close()
{
if (this->isVisible())
- QDialog::close();
- else
- emit running(false, _clientId);
-
+ return QDialog::close();
+ emit running(false, _clientId);
+ return false;
}
+
+/**
+ * Called when a Qt timer fires.
+ *
+ * redrawTimer: Redraw whole viewer window.
+ *
+ * tcpTimeoutTimer: Check if we're connected, close window if not.
+ *
+ * @param event the timer event
+ */
void VncWindow::timerEvent(QTimerEvent *event)
{
if (event->timerId() == _redrawTimer)
{
+ killTimer(_redrawTimer);
+ _redrawTimer = 0;
if (this->isVisible())
this->repaint();
}
else if (event->timerId() == _tcpTimeoutTimer)
{
killTimer(_tcpTimeoutTimer);
- if (_vncWorker != NULL && !_vncWorker->isConnected()){
- this->onProjectionStopped();
+ _tcpTimeoutTimer = 0;
+ if (_vncWorker != NULL && !_vncWorker->isConnected())
+ {
+ this->close();
}
}
else
killTimer(event->timerId());
}
+/**
+ * Called by Qt when a part of the window should be redrawn. This can either
+ * be caused by Qt (or the underlying graphical subsystem), or by
+ * an explicit call to QWidget::repaint()
+ *
+ * @param event the paint event, containing data like location and
+ * size area that should be repainted
+ */
void VncWindow::paintEvent(QPaintEvent *event)
{
const QRect &r = event->rect();
@@ -148,161 +252,12 @@ void VncWindow::paintEvent(QPaintEvent *event)
event->accept();
}
+/**
+ * Called by Qt if the window is being resized.
+ *
+ * @param event the resize event
+ */
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)
- {
- _clientId = 0;
- 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);
-}