* major layout fixes (size, stacked widget, ...)
[kdenetwork.git] / krdc / rdp / rdpview.cpp
blob8d54f9a3c4d5101ff1f768ef8fb7b8b21a5e8e64
1 /****************************************************************************
2 **
3 ** Copyright (C) 2002 Arend van Beelen jr. <arend@auton.nl>
4 ** Copyright (C) 2007 Urs Wolfer <uwolfer @ kde.org>
5 **
6 ** This file is part of KDE.
7 **
8 ** This program is free software; you can redistribute it and/or modify
9 ** it under the terms of the GNU General Public License as published by
10 ** the Free Software Foundation; either version 2 of the License, or
11 ** (at your option) any later version.
13 ** This program is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ** GNU General Public License for more details.
18 ** You should have received a copy of the GNU General Public License
19 ** along with this program; see the file COPYING. If not, write to
20 ** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 ** Boston, MA 02110-1301, USA.
23 ****************************************************************************/
25 #include "rdpview.h"
27 #include "settings.h"
29 #include <KInputDialog>
30 #include <KMessageBox>
31 #include <KPasswordDialog>
33 #include <QX11EmbedContainer>
34 #include <QEvent>
36 RdpView::RdpView(QWidget *parent,
37 const KUrl &url,
38 const QString &user, const QString &password,
39 int flags, const QString &domain,
40 const QString &shell, const QString &directory)
41 : RemoteView(parent),
42 m_user(user),
43 m_password(password),
44 m_flags(flags),
45 m_domain(domain),
46 m_shell(shell),
47 m_directory(directory),
48 m_quitFlag(false),
49 m_process(NULL)
51 m_url = url;
52 m_host = url.host();
53 m_port = url.port();
55 if (m_port <= 0) {
56 m_port = TCP_PORT_RDP;
59 m_container = new QX11EmbedContainer(this);
60 m_container->installEventFilter(this);
63 RdpView::~RdpView()
65 startQuitting();
68 // filter out key and mouse events to the container if we are view only
69 //FIXME: X11 events are passed to the app before getting caught in the Qt event processing
70 bool RdpView::eventFilter(QObject *obj, QEvent *event)
72 if (m_viewOnly) {
73 if (event->type() == QEvent::KeyPress ||
74 event->type() == QEvent::KeyRelease ||
75 event->type() == QEvent::MouseButtonDblClick ||
76 event->type() == QEvent::MouseButtonPress ||
77 event->type() == QEvent::MouseButtonRelease ||
78 event->type() == QEvent::MouseMove)
79 return true;
81 return RemoteView::eventFilter(obj, event);
84 QSize RdpView::framebufferSize()
86 return m_container->minimumSizeHint();
89 QSize RdpView::sizeHint() const
91 return maximumSize();
94 void RdpView::startQuitting()
96 kDebug(5012) << "About to quit";
97 m_quitFlag = true;
98 if (m_process) {
99 m_process->terminate();
100 m_process->waitForFinished(1000);
101 m_container->discardClient();
105 bool RdpView::isQuitting()
107 return m_quitFlag;
110 bool RdpView::start()
112 m_hostPreferences = new RdpHostPreferences(m_url.prettyUrl(KUrl::RemoveTrailingSlash), false, this);
114 m_container->show();
116 if (m_hostPreferences->walletSupport()) {
117 if (m_url.userName().isEmpty()) {
118 QString userName;
119 bool ok = true;
121 userName = KInputDialog::getText(i18n("Enter Username"),
122 i18n("Please enter the username you would like to use for login."),
123 QString(), &ok, this);
125 if (ok)
126 m_url.setUserName(userName);
129 if (!m_url.userName().isEmpty()) {
130 QString walletPassword = readWalletPassword();
132 if (!walletPassword.isNull())
133 m_url.setPassword(walletPassword);
134 else {
135 KPasswordDialog dialog(this);
136 dialog.setPrompt(i18n("Access to the system requires a password."));
137 if (dialog.exec() == KPasswordDialog::Accepted) {
138 m_url.setPassword(dialog.password());
140 if (m_hostPreferences->walletSupport())
141 saveWalletPassword(dialog.password());
147 m_process = new QProcess(m_container);
149 QStringList arguments;
150 arguments << "-g" << (QString::number(m_hostPreferences->width()) + 'x' +
151 QString::number(m_hostPreferences->height()));
152 arguments << "-k" << m_hostPreferences->keyboardLayout();
154 if (!m_url.userName().isEmpty())
155 arguments << "-u" << m_url.userName();
156 else if (!Settings::sendCurrentUserName())
157 arguments << "-u" << "";
159 if (!m_url.password().isNull())
160 arguments << "-p" << m_url.password();
162 arguments << "-X" << QString::number(m_container->winId());
163 arguments << "-a" << QString::number((m_hostPreferences->colorDepth() + 1) * 8);
165 QString sound;
166 switch (m_hostPreferences->sound()) {
167 case 0:
168 sound = "local";
169 break;
170 case 1:
171 sound = "remote";
172 break;
173 case 2:
174 default:
175 sound = "off";
177 arguments << "-r" << "sound:" + sound;
179 if (!m_hostPreferences->extraOptions().isEmpty()) {
180 QStringList additionalArguments = m_hostPreferences->extraOptions().split(' ');
181 arguments += additionalArguments;
184 arguments << (m_host + ':' + QString::number(m_port));
186 kDebug(5012) << arguments;
188 setStatus(Connecting);
190 connect(m_process, SIGNAL(error(QProcess::ProcessError)), SLOT(processError(QProcess::ProcessError)));
191 connect(m_process, SIGNAL(readyReadStandardError()), SLOT(receivedStandardError()));
192 connect(m_container, SIGNAL(clientClosed()), SLOT(connectionClosed()));
193 connect(m_container, SIGNAL(clientIsEmbedded()), SLOT(connectionOpened()));
195 m_process->start("rdesktop", arguments);
197 return true;
200 void RdpView::switchFullscreen(bool on)
202 if (on == true) {
203 m_container->grabKeyboard();
207 void RdpView::connectionOpened()
209 kDebug(5012) << "Connection opened";
210 QSize size = m_container->minimumSizeHint();
211 kDebug(5012) << "Size hint: " << size.width() << " " << size.height();
212 setStatus(Connected);
213 setFixedSize(size);
214 resize(size);
215 m_container->setFixedSize(size);
216 emit changeSize(size.width(), size.height());
217 emit connected();
218 setFocus();
221 void RdpView::connectionClosed()
223 emit disconnected();
224 setStatus(Disconnected);
225 m_quitFlag = true;
228 void RdpView::processError(QProcess::ProcessError error)
230 if (m_status == Connecting) {
231 setStatus(Disconnected);
233 if (error == QProcess::FailedToStart) {
234 KMessageBox::error(0, i18n("Could not start rdesktop; make sure rdesktop is properly installed."),
235 i18n("rdesktop Failure"));
236 return;
239 if (m_clientVersion.isEmpty()) {
240 KMessageBox::error(0, i18n("Connection attempt to host failed."),
241 i18n("Connection Failure"));
242 } else {
243 KMessageBox::error(0, i18n("The version of rdesktop you are using (%1) is too old:\n"
244 "rdesktop 1.3.2 or greater is required.", m_clientVersion),
245 i18n("rdesktop Failure"));
247 emit disconnectedError();
251 void RdpView::receivedStandardError()
253 QString output(m_process->readAllStandardError());
254 QString line;
255 int i = 0;
256 while (!(line = output.section('\n', i, i)).isEmpty()) {
257 if (line.startsWith("Version ")) {
258 m_clientVersion = line.section(' ', 1, 1);
259 m_clientVersion = m_clientVersion.left(m_clientVersion.length() - 1);
260 return;
261 } else {
262 kDebug(5012) << "Process error output: " << line;
264 i++;
268 #include "rdpview.moc"