kde-extraapps/krdc/nx/nxview.cpp
2015-02-27 11:02:43 +00:00

278 lines
8.2 KiB
C++

/****************************************************************************
**
** Copyright (C) 2008 David Gross <gdavid.devel@gmail.com>
**
** This file is part of KDE.
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; see the file COPYING. If not, write to
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
** Boston, MA 02110-1301, USA.
**
****************************************************************************/
#include "nxview.h"
#include "settings.h"
#include <nxcl/nxdata.h>
#include <KInputDialog>
#include <KMessageBox>
#include <KPasswordDialog>
#include <QEvent>
#include <QMetaType>
NxView::NxView(QWidget *parent, const KUrl &url, KConfigGroup configGroup)
: RemoteView(parent),
m_quitFlag(false),
m_container(NULL),
m_hostPreferences(NULL)
{
m_url = url;
m_host = url.host();
m_port = url.port();
if (m_port <= 0 || m_port >= 65536)
m_port = TCP_PORT_NX;
m_container = new QX11EmbedContainer(this);
m_container->installEventFilter(this);
qRegisterMetaType<QList<nxcl::NXResumeData> >("QList<nxcl::NXResumeData>");
m_clientThread.setCallbacks(&m_callbacks);
connect(&m_clientThread, SIGNAL(hasXid(int)), this, SLOT(hasXid(int)));
connect(&m_callbacks, SIGNAL(progress(int,QString)), this, SLOT(handleProgress(int,QString)));
connect(&m_callbacks, SIGNAL(suspendedSessions(QList<nxcl::NXResumeData>)), this, SLOT(handleSuspendedSessions(QList<nxcl::NXResumeData>)));
connect(&m_callbacks, SIGNAL(noSessions()), this, SLOT(handleNoSessions()));
connect(&m_callbacks, SIGNAL(atCapacity()), this, SLOT(handleAtCapacity()));
connect(&m_resumeSessions, SIGNAL(newSession()), this, SLOT(handleNewSession()));
connect(&m_resumeSessions, SIGNAL(resumeSession(QString)), this, SLOT(handleResumeSession(QString)));
m_hostPreferences = new NxHostPreferences(configGroup, this);
}
NxView::~NxView()
{
}
// filter out key and mouse events to the container if we are view only
//FIXME: X11 events are passed to the app before getting caught in the Qt event processing
bool NxView::eventFilter(QObject *obj, QEvent *event)
{
if (m_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::MouseMove)
return true;
}
return RemoteView::eventFilter(obj, event);
}
void NxView::startQuitting()
{
kDebug(5013) << "about to quit";
const bool connected = status() == RemoteView::Connected;
setStatus(Disconnecting);
m_quitFlag = true;
if (connected)
m_clientThread.stop();
else
m_clientThread.quit();
m_clientThread.wait(500);
setStatus(Disconnected);
m_container->discardClient();
}
bool NxView::isQuitting()
{
return m_quitFlag;
}
bool NxView::start()
{
m_clientThread.setResolution(m_hostPreferences->width(), m_hostPreferences->height());
m_clientThread.setDesktopType(m_hostPreferences->desktopType());
m_clientThread.setKeyboardLayout(m_hostPreferences->keyboardLayout());
m_clientThread.setPrivateKey(m_hostPreferences->privateKey());
m_container->show();
if (m_hostPreferences->walletSupport()) {
if (m_url.userName().isEmpty()) {
QString userName;
bool ok = false;
userName = KInputDialog::getText(i18n("Enter Username"),
i18n("Please enter the username you would like to use for login."),
QString(), &ok, this);
if (ok)
m_url.setUserName(userName);
}
if (!m_url.userName().isEmpty()) {
QString walletPassword = readWalletPassword();
if (!walletPassword.isNull())
m_url.setPassword(walletPassword);
else {
KPasswordDialog dialog(this);
dialog.setPrompt(i18n("Access to the system requires a password."));
if (dialog.exec() == KPasswordDialog::Accepted) {
m_url.setPassword(dialog.password());
if (m_hostPreferences->walletSupport())
saveWalletPassword(dialog.password());
}
}
}
}
m_clientThread.setHost(m_host);
m_clientThread.setPort(m_port);
m_clientThread.setUserName(m_url.userName());
m_clientThread.setPassword(m_url.password());
m_clientThread.setResolution(m_hostPreferences->width(), m_hostPreferences->height());
setStatus(Connecting);
m_clientThread.start();
connect(m_container, SIGNAL(clientIsEmbedded()), SLOT(connectionOpened()));
connect(m_container, SIGNAL(clientClosed()), SLOT(connectionClosed()));
return true;
}
HostPreferences* NxView::hostPreferences()
{
return m_hostPreferences;
}
QSize NxView::framebufferSize()
{
return m_container->minimumSizeHint();
}
QSize NxView::sizeHint() const
{
return maximumSize();
}
void NxView::switchFullscreen(bool on)
{
setGrabAllKeys(on);
}
void NxView::setGrabAllKeys(bool grabAllKeys)
{
m_grabAllKeys = grabAllKeys;
if (grabAllKeys) {
m_keyboardIsGrabbed = true;
m_container->grabKeyboard();
} else if (m_keyboardIsGrabbed)
m_container->releaseKeyboard();
}
void NxView::hasXid(int xid)
{
m_container->embedClient(xid);
}
void NxView::handleProgress(int id, QString msg)
{
Q_UNUSED(msg);
switch (id) {
case NXCL_AUTH_FAILED:
KMessageBox::error(this, i18n("The authentication key is invalid."), i18n("Invalid authentication key"));
break;
case NXCL_LOGIN_FAILED:
KMessageBox::error(this, i18n("The username or password that you have entered is invalid."), i18n("Invalid username or password"));
break;
case NXCL_HOST_KEY_VERIFAILED:
KMessageBox::error(this, i18n("The host key verification has failed."), i18n("Host key verification failed"));
break;
case NXCL_PROCESS_ERROR:
KMessageBox::error(this, i18n("An error has occurred during the connection to the NX server."), i18n("Process error"));
break;
default:
break;
}
}
void NxView::handleSuspendedSessions(QList<nxcl::NXResumeData> sessions)
{
if (!m_resumeSessions.empty())
m_resumeSessions.clear();
m_resumeSessions.addSessions(sessions);
m_resumeSessions.show();
}
void NxView::handleNoSessions()
{
m_clientThread.setSuspended(false);
m_clientThread.startSession();
}
void NxView::handleAtCapacity()
{
KMessageBox::error(this, i18n("This NX server is running at capacity."), i18n("Server at capacity"));
}
void NxView::handleNewSession()
{
m_clientThread.setSuspended(false);
m_clientThread.startSession();
}
void NxView::handleResumeSession(QString id)
{
m_clientThread.setId(id);
m_clientThread.setSuspended(true);
m_clientThread.startSession();
}
void NxView::connectionOpened()
{
kDebug(5013) << "Connection opened";
QSize size(m_hostPreferences->width(), m_hostPreferences->height());
kDebug(5013) << "Size hint: " << size.width() << size.height();
setStatus(Connected);
setFixedSize(size);
resize(size);
m_container->setFixedSize(size);
emit framebufferSizeChanged(size.width(), size.height());
emit connected();
setFocus();
}
void NxView::connectionClosed()
{
emit disconnected();
setStatus(Disconnected);
m_quitFlag = true;
}
#include "moc_nxview.cpp"