diff -up kdenetwork-4.10.5/krdc/CMakeLists.txt.freerdp kdenetwork-4.10.5/krdc/CMakeLists.txt --- kdenetwork-4.10.5/krdc/CMakeLists.txt.freerdp 2013-07-04 21:52:45.864029571 +0200 +++ kdenetwork-4.10.5/krdc/CMakeLists.txt 2013-07-04 22:05:59.950275124 +0200 @@ -29,7 +29,13 @@ endif(NOT INSIDE_KDENETWORK) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH}) macro_optional_find_package(LibVNCServer) -macro_log_feature(LIBVNCSERVER_FOUND "libvncserver" "VNC Server library" "http://libvncserver.sourceforge.net/" FALSE "0.9" "Needed to build Krfb and VNC support in Krdc") +macro_log_feature(LIBVNCSERVER_FOUND "libvncserver" "VNC Server library" "http://libvncserver.sourceforge.net/" FALSE "0.9" "Needed to build Krfb and VNC support in KRDC") + +FIND_PROGRAM(FREERDP_EXECUTABLE xfreerdp) +if(FREERDP_EXECUTABLE) + set(FREERDP_EXECUTABLE_FOUND true) +endif(FREERDP_EXECUTABLE) +macro_log_feature(FREERDP_EXECUTABLE_FOUND "freerdp" "A free Remote Desktop Protocol (RDP) Implementation" "http://www.freerdp.com" FALSE "1.0.2" "Needed for RDP support in KRDC (at runtime)") # NX support is not ready for KDE 4.2; disabled (uwolfer) # macro_optional_find_package(LibNXCL) diff -up kdenetwork-4.10.5/krdc/core/krdc.kcfg.freerdp kdenetwork-4.10.5/krdc/core/krdc.kcfg --- kdenetwork-4.10.5/krdc/core/krdc.kcfg.freerdp 2013-06-28 20:08:57.390483848 +0200 +++ kdenetwork-4.10.5/krdc/core/krdc.kcfg 2013-07-04 21:52:45.865029569 +0200 @@ -83,7 +83,7 @@ 7 - 0 + 2 0 @@ -100,6 +100,15 @@ true + + true + + + 2 + + + /media + diff -up kdenetwork-4.10.5/krdc/rdp/CMakeLists.txt.freerdp kdenetwork-4.10.5/krdc/rdp/CMakeLists.txt --- kdenetwork-4.10.5/krdc/rdp/CMakeLists.txt.freerdp 2013-06-28 20:08:57.392483928 +0200 +++ kdenetwork-4.10.5/krdc/rdp/CMakeLists.txt 2013-07-04 21:52:45.865029569 +0200 @@ -1,9 +1,9 @@ if(Q_WS_X11) - set(HAVE_RDESKTOP true) # TODO: implement cmake check? + set(HAVE_XFREERDP true) endif(Q_WS_X11) -if(HAVE_RDESKTOP) +if(HAVE_XFREERDP) add_definitions(-DKDE_DEFAULT_DEBUG_AREA=5012) include_directories( @@ -49,4 +49,4 @@ if(HAVE_RDESKTOP) install(FILES rdp.protocol DESTINATION ${SERVICES_INSTALL_DIR}) install(FILES smb2rdc.desktop DESTINATION ${SERVICES_INSTALL_DIR}/ServiceMenus) -endif(HAVE_RDESKTOP) +endif(HAVE_XFREERDP) diff -up kdenetwork-4.10.5/krdc/rdp/rdphostpreferences.cpp.freerdp kdenetwork-4.10.5/krdc/rdp/rdphostpreferences.cpp --- kdenetwork-4.10.5/krdc/rdp/rdphostpreferences.cpp.freerdp 2013-06-28 20:08:57.392483928 +0200 +++ kdenetwork-4.10.5/krdc/rdp/rdphostpreferences.cpp 2013-07-04 21:52:45.865029569 +0200 @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2007 Urs Wolfer +** Copyright (C) 2007 - 2012 Urs Wolfer +** Copyright (C) 2012 AceLan Kao ** ** This file is part of KDE. ** @@ -108,6 +109,9 @@ QWidget* RdpHostPreferences::createProto rdpUi.kcfg_Sound->setCurrentIndex(sound()); rdpUi.kcfg_Console->setChecked(console()); rdpUi.kcfg_ExtraOptions->setText(extraOptions()); + rdpUi.kcfg_RemoteFX->setChecked(remoteFX()); + rdpUi.kcfg_Performance->setCurrentIndex(performance()); + rdpUi.kcfg_ShareMedia->setText(shareMedia()); connect(rdpUi.resolutionComboBox, SIGNAL(currentIndexChanged(int)), SLOT(updateWidthHeight(int))); @@ -172,6 +176,9 @@ void RdpHostPreferences::acceptConfig() setSound(rdpUi.kcfg_Sound->currentIndex()); setConsole(rdpUi.kcfg_Console->isChecked()); setExtraOptions(rdpUi.kcfg_ExtraOptions->text()); + setRemoteFX(rdpUi.kcfg_RemoteFX->isChecked()); + setPerformance(rdpUi.kcfg_Performance->currentIndex()); + setShareMedia(rdpUi.kcfg_ShareMedia->text()); } void RdpHostPreferences::setColorDepth(int colorDepth) @@ -228,4 +235,36 @@ QString RdpHostPreferences::extraOptions return m_configGroup.readEntry("extraOptions", Settings::extraOptions()); } +void RdpHostPreferences::setRemoteFX(bool remoteFX) +{ + m_configGroup.writeEntry("remoteFX", remoteFX); +} + +bool RdpHostPreferences::remoteFX() const +{ + return m_configGroup.readEntry("remoteFX", Settings::remoteFX()); +} + +void RdpHostPreferences::setPerformance(int performance) +{ + if (performance >= 0) + m_configGroup.writeEntry("performance", performance); +} + +int RdpHostPreferences::performance() const +{ + return m_configGroup.readEntry("performance", Settings::performance()); +} + +void RdpHostPreferences::setShareMedia(const QString &shareMedia) +{ + if (!shareMedia.isNull()) + m_configGroup.writeEntry("shareMedia", shareMedia); +} + +QString RdpHostPreferences::shareMedia() const +{ + return m_configGroup.readEntry("shareMedia", Settings::shareMedia()); +} + #include "rdphostpreferences.moc" diff -up kdenetwork-4.10.5/krdc/rdp/rdphostpreferences.h.freerdp kdenetwork-4.10.5/krdc/rdp/rdphostpreferences.h --- kdenetwork-4.10.5/krdc/rdp/rdphostpreferences.h.freerdp 2013-06-28 20:08:57.392483928 +0200 +++ kdenetwork-4.10.5/krdc/rdp/rdphostpreferences.h 2013-07-04 21:52:45.866029567 +0200 @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2007 Urs Wolfer +** Copyright (C) 2007 - 2012 Urs Wolfer +** Copyright (C) 2012 AceLan Kao ** ** This file is part of KDE. ** @@ -45,6 +46,12 @@ public: bool console() const; void setExtraOptions(const QString &extraOptions); QString extraOptions() const; + void setRemoteFX(bool remoteFX); + bool remoteFX() const; + void setPerformance(int performance); + int performance() const; + void setShareMedia(const QString &shareMedia); + QString shareMedia() const; protected: QWidget* createProtocolSpecificConfigPage(); diff -up kdenetwork-4.10.5/krdc/rdp/rdppreferences.ui.freerdp kdenetwork-4.10.5/krdc/rdp/rdppreferences.ui --- kdenetwork-4.10.5/krdc/rdp/rdppreferences.ui.freerdp 2013-06-28 20:08:57.392483928 +0200 +++ kdenetwork-4.10.5/krdc/rdp/rdppreferences.ui 2013-07-04 21:52:45.866029567 +0200 @@ -7,7 +7,7 @@ 0 0 484 - 406 + 452 @@ -415,6 +415,12 @@ + + + 280 + 0 + + On This Computer @@ -432,6 +438,87 @@ + + + + Performance: + + + kcfg_Performance + + + + + + + + 280 + 0 + + + + + Modem + + + + + Broadband + + + + + LAN + + + + + + + + RemoteFX: + + + kcfg_RemoteFX + + + + + + + Enable RemoteFX + + + RemoteFX covers a set of technologies that enhance visual experience of the Remote Desktop Protocol. + + + + + + + Share Media: + + + kcfg_ShareMedia + + + + + + + + 280 + 0 + + + + Share a local media directory with the remote host. + + + true + + + @@ -541,15 +628,15 @@ - KLineEdit - QLineEdit -
klineedit.h
-
- KComboBox QComboBox
kcombobox.h
+ + KLineEdit + QLineEdit +
klineedit.h
+
resolutionComboBox @@ -558,6 +645,9 @@ kcfg_ColorDepth kcfg_KeyboardLayout kcfg_Sound + kcfg_Performance + kcfg_RemoteFX + kcfg_ShareMedia kcfg_Console kcfg_ExtraOptions kcfg_DefaultRdpUserName diff -up kdenetwork-4.10.5/krdc/rdp/rdpview.cpp.freerdp kdenetwork-4.10.5/krdc/rdp/rdpview.cpp --- kdenetwork-4.10.5/krdc/rdp/rdpview.cpp.freerdp 2013-06-28 20:08:57.392483928 +0200 +++ kdenetwork-4.10.5/krdc/rdp/rdpview.cpp 2013-07-04 21:52:45.866029567 +0200 @@ -1,7 +1,8 @@ /**************************************************************************** ** ** Copyright (C) 2002 Arend van Beelen jr. -** Copyright (C) 2007 Urs Wolfer +** Copyright (C) 2007 - 2012 Urs Wolfer +** Copyright (C) 2012 AceLan Kao ** ** This file is part of KDE. ** @@ -167,39 +168,72 @@ bool RdpView::start() arguments << "-X" << QString::number(m_container->winId()); arguments << "-a" << QString::number((m_hostPreferences->colorDepth() + 1) * 8); - QString sound; switch (m_hostPreferences->sound()) { + case 1: + arguments << "-o"; + break; + case 0: + arguments << "--plugin" << "rdpsnd"; + break; + case 2: + default: + break; + } + + if (!m_hostPreferences->shareMedia().isEmpty()) { + QStringList shareMedia; + shareMedia << "--plugin" << "rdpdr" << "--data" << "disk:media:" + m_hostPreferences->shareMedia() << "--"; + arguments += shareMedia; + } + + QString performance; + switch (m_hostPreferences->performance()) { case 0: - sound = "local"; + performance = "m"; break; case 1: - sound = "remote"; + performance = "b"; break; case 2: + performance = "l"; + break; default: - sound = "off"; + break; } - arguments << "-r" << "sound:" + sound; + + arguments << "-x" << performance; if (m_hostPreferences->console()) { arguments << "-0"; } + if (m_hostPreferences->remoteFX()) { + arguments << "--rfx"; + } + if (!m_hostPreferences->extraOptions().isEmpty()) { const QStringList additionalArguments = KShell::splitArgs(m_hostPreferences->extraOptions()); arguments += additionalArguments; } + // krdc has no support for certificate management yet; it would not be possbile to connect to any host: + // "The host key for example.com has changed" ... + // "Add correct host key in ~/.freerdp/known_hosts to get rid of this message." + arguments << "--ignore-certificate"; + arguments << (m_host + ':' + QString::number(m_port)); + kDebug(5012) << "Starting xfreerdp with arguments:" << arguments; + setStatus(Connecting); connect(m_process, SIGNAL(error(QProcess::ProcessError)), SLOT(processError(QProcess::ProcessError))); connect(m_process, SIGNAL(readyReadStandardError()), SLOT(receivedStandardError())); + connect(m_process, SIGNAL(readyReadStandardOutput()), SLOT(receivedStandardOutput())); connect(m_container, SIGNAL(clientClosed()), SLOT(connectionClosed())); connect(m_container, SIGNAL(clientIsEmbedded()), SLOT(connectionOpened())); - m_process->start("rdesktop", arguments); + m_process->start("xfreerdp", arguments); return true; } @@ -242,45 +276,85 @@ void RdpView::connectionClosed() m_quitFlag = true; } +void RdpView::connectionError() +{ + emit disconnectedError(); + connectionClosed(); +} + void RdpView::processError(QProcess::ProcessError error) { + kDebug(5012) << "processError:" << error; if (m_quitFlag) // do not try to show error messages while quitting (prevent crashes) return; if (m_status == Connecting) { - setStatus(Disconnected); - if (error == QProcess::FailedToStart) { - KMessageBox::error(0, i18n("Could not start \"rdesktop\"; make sure rdesktop is properly installed."), + KMessageBox::error(0, i18n("Could not start \"xfreerdp\"; make sure xfreerdp is properly installed."), i18n("RDP Failure")); + connectionError(); return; } + } +} - if (m_clientVersion.isEmpty()) { - KMessageBox::error(0, i18n("Connection attempt to host failed."), - i18n("Connection Failure")); - } else { - KMessageBox::error(0, i18n("The version of \"rdesktop\" you are using (%1) is too old:\n" - "rdesktop 1.3.2 or greater is required.", m_clientVersion), +void RdpView::receivedStandardError() +{ + const QString output(m_process->readAllStandardError()); + kDebug(5012) << "receivedStandardError:" << output; + QString line; + int i = 0; + while (!(line = output.section('\n', i, i)).isEmpty()) { + + // the following error is issued by freerdp because of a bug in freerdp 1.0.1 and below; + // see: https://github.com/FreeRDP/FreeRDP/pull/576 + //"X Error of failed request: BadWindow (invalid Window parameter) + // Major opcode of failed request: 7 (X_ReparentWindow) + // Resource id in failed request: 0x71303348 + // Serial number of failed request: 36 + // Current serial number in output stream: 36" + if (line.contains(QLatin1String("X_ReparentWindow"))) { + KMessageBox::error(0, i18n("The version of \"xfreerdp\" you are using is too old.\n" + "xfreerdp 1.0.2 or greater is required."), i18n("RDP Failure")); + connectionError(); + return; } - emit disconnectedError(); + i++; } } -void RdpView::receivedStandardError() +void RdpView::receivedStandardOutput() { - const QString output(m_process->readAllStandardError()); + const QString output(m_process->readAllStandardOutput()); + kDebug(5012) << "receivedStandardOutput:" << output; QString line; int i = 0; while (!(line = output.section('\n', i, i)).isEmpty()) { - if (line.startsWith(QLatin1String("Version "))) { - m_clientVersion = line.section(' ', 1, 1); - m_clientVersion = m_clientVersion.left(m_clientVersion.length() - 1); + + // full xfreerdp message: "transport_connect: getaddrinfo (Name or service not known)" + if (line.contains(QLatin1String("Name or service not known"))) { + KMessageBox::error(0, i18n("Name or service not known."), + i18n("Connection Failure")); + connectionError(); + return; + + // full xfreerdp message: "unable to connect to example.com:3389" + } else if (line.contains(QLatin1String("unable to connect to"))) { + KMessageBox::error(0, i18n("Connection attempt to host failed."), + i18n("Connection Failure")); + connectionError(); + return; + + // looks like some generic xfreerdp error message, handle it if nothing was handled: + // "Error: protocol security negotiation failure" + } else if (line.contains(QLatin1String("Error: protocol security negotiation failure"))) { + KMessageBox::error(0, i18n("Connection attempt to host failed."), + i18n("Connection Failure")); + connectionError(); return; - } else { - kDebug(5012) << "Process error output: " << line; } + i++; } } diff -up kdenetwork-4.10.5/krdc/rdp/rdpviewfactory.cpp.freerdp kdenetwork-4.10.5/krdc/rdp/rdpviewfactory.cpp --- kdenetwork-4.10.5/krdc/rdp/rdpviewfactory.cpp.freerdp 2013-06-28 20:08:57.393483968 +0200 +++ kdenetwork-4.10.5/krdc/rdp/rdpviewfactory.cpp 2013-07-04 21:52:45.867029564 +0200 @@ -37,7 +37,7 @@ RdpViewFactory::RdpViewFactory(QObject * m_connectToolTipString = i18n("Connect to a Windows Remote Desktop (RDP)"); - QMetaObject::invokeMethod(this, "checkRdektopAvailability", Qt::DirectConnection); + QMetaObject::invokeMethod(this, "checkFreerdpAvailability", Qt::DirectConnection); } RdpViewFactory::~RdpViewFactory() @@ -80,10 +80,10 @@ QString RdpViewFactory::connectToolTipTe "Example: rdpserver:3389 (host:port)"); } -void RdpViewFactory::checkRdektopAvailability() +void RdpViewFactory::checkFreerdpAvailability() { - if (KStandardDirs::findExe("rdesktop").isEmpty()) { - m_connectToolTipString += '\n' + i18n("The application \"rdesktop\" cannot be found on your system; make sure it is properly installed " + if (KStandardDirs::findExe("xfreerdp").isEmpty()) { + m_connectToolTipString += '\n' + i18n("The application \"xfreerdp\" cannot be found on your system; make sure it is properly installed " "if you need RDP support."); } } diff -up kdenetwork-4.10.5/krdc/rdp/rdpviewfactory.h.freerdp kdenetwork-4.10.5/krdc/rdp/rdpviewfactory.h --- kdenetwork-4.10.5/krdc/rdp/rdpviewfactory.h.freerdp 2013-06-28 20:08:57.393483968 +0200 +++ kdenetwork-4.10.5/krdc/rdp/rdpviewfactory.h 2013-07-04 21:52:45.867029564 +0200 @@ -53,7 +53,7 @@ public: virtual QString connectToolTipText() const; private Q_SLOTS: - void checkRdektopAvailability(); + void checkFreerdpAvailability(); private: QString m_connectToolTipString; diff -up kdenetwork-4.10.5/krdc/rdp/rdpview.h.freerdp kdenetwork-4.10.5/krdc/rdp/rdpview.h --- kdenetwork-4.10.5/krdc/rdp/rdpview.h.freerdp 2013-06-28 20:08:57.392483928 +0200 +++ kdenetwork-4.10.5/krdc/rdp/rdpview.h 2013-07-04 21:52:45.867029564 +0200 @@ -84,17 +84,18 @@ private: // other properties bool m_quitFlag; // if set: die - QString m_clientVersion; // version number returned by rdesktop - QX11EmbedContainer *m_container; // container for the rdesktop window - QProcess *m_process; // rdesktop process + QX11EmbedContainer *m_container; // container for the xfreerdp window + QProcess *m_process; // xfreerdp process RdpHostPreferences *m_hostPreferences; private slots: - void connectionOpened(); // called if rdesktop started - void connectionClosed(); // called if rdesktop quits - void processError(QProcess::ProcessError error); // called if rdesktop dies - void receivedStandardError(); // catches rdesktop debug output + void connectionOpened(); // called if xfreerdp started + void connectionClosed(); // called if xfreerdp quits + void connectionError(); // called if xfreerdp quits with error + void processError(QProcess::ProcessError error); // called if xfreerdp dies + void receivedStandardError(); // catches xfreerdp debug output + void receivedStandardOutput(); // catches xfreerdp output }; #endif