summaryrefslogtreecommitdiffstats
path: root/krfb/krfb
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitbcb704366cb5e333a626c18c308c7e0448a8e69f (patch)
treef0d6ab7d78ecdd9207cf46536376b44b91a1ca71 /krfb/krfb
downloadtdenetwork-bcb704366cb5e333a626c18c308c7e0448a8e69f.tar.gz
tdenetwork-bcb704366cb5e333a626c18c308c7e0448a8e69f.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdenetwork@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'krfb/krfb')
-rw-r--r--krfb/krfb/Makefile.am34
-rw-r--r--krfb/krfb/configuration.cc474
-rw-r--r--krfb/krfb/configuration.h139
-rw-r--r--krfb/krfb/connection-side-image.pngbin0 -> 53735 bytes
-rw-r--r--krfb/krfb/connectiondialog.cc63
-rw-r--r--krfb/krfb/connectiondialog.h44
-rw-r--r--krfb/krfb/connectionwidget.ui208
-rw-r--r--krfb/krfb/cr16-app-krfb.pngbin0 -> 931 bytes
-rw-r--r--krfb/krfb/cr32-app-krfb.pngbin0 -> 2551 bytes
-rw-r--r--krfb/krfb/cr48-app-krfb.pngbin0 -> 5508 bytes
-rw-r--r--krfb/krfb/eventsrc1219
-rw-r--r--krfb/krfb/eyes-closed24.pngbin0 -> 1485 bytes
-rw-r--r--krfb/krfb/eyes-open.pngbin0 -> 2551 bytes
-rw-r--r--krfb/krfb/eyes-open24.pngbin0 -> 1734 bytes
-rw-r--r--krfb/krfb/invitation.cc125
-rw-r--r--krfb/krfb/invitation.h57
-rw-r--r--krfb/krfb/invitedialog.cc65
-rw-r--r--krfb/krfb/invitedialog.h54
-rw-r--r--krfb/krfb/invitewidget.ui197
-rw-r--r--krfb/krfb/kinetd_krfb.desktop150
-rw-r--r--krfb/krfb/krfb.desktop64
-rw-r--r--krfb/krfb/krfbiface.h24
-rw-r--r--krfb/krfb/krfbifaceimpl.cc27
-rw-r--r--krfb/krfb/krfbifaceimpl.h22
-rw-r--r--krfb/krfb/lo16-app-krfb.pngbin0 -> 305 bytes
-rw-r--r--krfb/krfb/lo32-app-krfb.pngbin0 -> 505 bytes
-rw-r--r--krfb/krfb/main.cpp191
-rw-r--r--krfb/krfb/manageinvitations.ui216
-rw-r--r--krfb/krfb/manageinvitations.ui.h15
-rw-r--r--krfb/krfb/personalinvitedialog.cc54
-rw-r--r--krfb/krfb/personalinvitedialog.h44
-rw-r--r--krfb/krfb/personalinvitewidget.ui241
-rw-r--r--krfb/krfb/rfbcontroller.cc902
-rw-r--r--krfb/krfb/rfbcontroller.h221
-rw-r--r--krfb/krfb/templates/cpp_template16
-rw-r--r--krfb/krfb/templates/header_template16
-rw-r--r--krfb/krfb/trayicon.cpp138
-rw-r--r--krfb/krfb/trayicon.h90
-rw-r--r--krfb/krfb/xupdatescanner.cc481
-rw-r--r--krfb/krfb/xupdatescanner.h112
40 files changed, 5703 insertions, 0 deletions
diff --git a/krfb/krfb/Makefile.am b/krfb/krfb/Makefile.am
new file mode 100644
index 00000000..31feb286
--- /dev/null
+++ b/krfb/krfb/Makefile.am
@@ -0,0 +1,34 @@
+KDE_CXXFLAGS = $(USE_THREADS)
+
+METASOURCES = AUTO
+
+noinst_LTLIBRARIES = libkrfbconfig.la
+libkrfbconfig_la_SOURCES = configuration.cc configuration.skel invitedialog.cc invitation.cc \
+ manageinvitations.ui personalinvitewidget.ui \
+ invitewidget.ui personalinvitedialog.cc
+libkrfbconfig_la_LIBADD = ../srvloc/libsrvloc.la $(LIB_KDEUI)
+
+bin_PROGRAMS = krfb
+krfb_SOURCES = rfbcontroller.cc xupdatescanner.cc main.cpp \
+ connectionwidget.ui krfbifaceimpl.cc krfbiface.skel \
+ trayicon.cpp connectiondialog.cc
+krfb_LDADD = libkrfbconfig.la ../libvncserver/libvncserver.la ../srvloc/libsrvloc.la -lXtst $(LIB_KDEUI) $(LIBJPEG) -lkio
+krfb_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+
+appdatadir = $(kde_datadir)/krfb/pics
+appdata_DATA = eyes-open24.png eyes-closed24.png connection-side-image.png
+
+kde_services_DATA = kinetd_krfb.desktop
+
+xdg_apps_DATA = krfb.desktop
+
+appdir = $(kde_datadir)/krfb
+app_DATA = eventsrc
+
+KDE_ICON = krfb
+
+INCLUDES= -I$(top_srcdir)/krfb/libvncserver -I$(top_srcdir)/krfb/srvloc \
+ $(all_includes)
+
+messages: rc.cpp
+ $(XGETTEXT) rc.cpp *.cpp *.cc -o $(podir)/krfb.pot
diff --git a/krfb/krfb/configuration.cc b/krfb/krfb/configuration.cc
new file mode 100644
index 00000000..75f8c31d
--- /dev/null
+++ b/krfb/krfb/configuration.cc
@@ -0,0 +1,474 @@
+/***************************************************************************
+ configuration.cpp
+ -------------------
+ begin : Tue Dec 11 2001
+ copyright : (C) 2001-2003 by Tim Jansen
+ email : tim@tjansen.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "configuration.h"
+#include "kinetinterface.h"
+
+#include <kglobal.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <kmessagebox.h>
+#include <kprocess.h>
+#include <ksockaddr.h>
+#include <kactivelabel.h>
+
+#include <qdatastream.h>
+#include <dcopclient.h>
+#include <dcopref.h>
+
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qlineedit.h>
+#include <qcheckbox.h>
+
+#include <krun.h>
+
+/**
+ * Note that this class is used and provides GUI in every mode:
+ * - for the invitation dialogs
+ * - for the kcontrol module
+ * - for the running krfb instance
+ */
+Configuration::Configuration(krfb_mode mode) :
+ m_mode(mode),
+ invMngDlg(0, 0, true),
+ invDlg(0, "InviteDialog"),
+ persInvDlg(0, "PersonalInviteDialog"),
+ portNum(-1),
+ kinetdRef("kded", "kinetd")
+{
+ kinetdRef.setDCOPClient(KApplication::dcopClient());
+ loadFromKConfig();
+ saveToDialogs();
+ doKinetdConf();
+
+ connectDCOPSignal( 0, "KRFB::ConfigChanged", "KRFB_ConfigChanged()",
+ "updateKConfig()", false );
+ connect(invMngDlg.newPersonalInvitationButton, SIGNAL(clicked()),
+ SLOT(showPersonalInvitationDialog()));
+ connect(invMngDlg.newEmailInvitationButton, SIGNAL(clicked()), SLOT(inviteEmail()));
+ connect(invMngDlg.deleteOneButton, SIGNAL(clicked()), SLOT(invMngDlgDeleteOnePressed()));
+ connect(invMngDlg.deleteAllButton, SIGNAL(clicked()), SLOT(invMngDlgDeleteAllPressed()));
+ invMngDlg.listView->setSelectionMode(QListView::Extended);
+ invMngDlg.listView->setMinimumSize(QSize(400, 100)); // QTs size is much to small
+
+ connect(&invDlg, SIGNAL(createInviteClicked()),
+ SLOT(showPersonalInvitationDialog()));
+ connect(&invDlg, SIGNAL(emailInviteClicked()),
+ SLOT(inviteEmail()));
+ connect(&invDlg, SIGNAL(manageInviteClicked()),
+ SLOT(showManageInvitationsDialog()));
+ connect(&invDlg, SIGNAL(configureClicked()),
+ SLOT(showConfigurationModule()));
+ connect(this, SIGNAL(invitationNumChanged(int)),
+ &invDlg, SLOT(setInviteCount(int)));
+ connect(this, SIGNAL(invitationNumChanged(int)),
+ &invMngDlg, SLOT(listSizeChanged(int)));
+ emit invitationNumChanged(invitationList.size());
+
+ connect(&refreshTimer, SIGNAL(timeout()), SLOT(refreshTimeout()));
+ refreshTimer.start(1000*60);
+}
+
+Configuration::~Configuration() {
+ save();
+}
+
+void Configuration::updateKConfig()
+{
+ loadFromKConfig();
+}
+
+void Configuration::setKInetdEnabled(bool enabled) {
+ kinetdRef.send("setEnabled", QString("krfb"), enabled);
+ kinetdRef.send("setEnabled", QString("krfb_httpd"), enabled);
+}
+
+void Configuration::setKInetdEnabled(const QDateTime &date) {
+ kinetdRef.send("setEnabled", QString("krfb"), date);
+ kinetdRef.send("setEnabled", QString("krfb_httpd"), date);
+}
+
+void Configuration::setKInetdServiceRegistrationEnabled(bool enabled) {
+ kinetdRef.send("setServiceRegistrationEnabled",
+ QString("krfb"), enabled);
+ kinetdRef.send("setServiceRegistrationEnabled",
+ QString("krfb_httpd"), enabled);
+}
+
+void Configuration::getPortFromKInetd() {
+ DCOPReply r = kinetdRef.call("port", QString("krfb"));
+ if (!r.isValid())
+ return; // nice error msg here?
+ r.get(portNum);
+}
+
+void Configuration::setKInetdPort(int p) {
+ DCOPReply r = kinetdRef.call("setPort",
+ QString("krfb"), p, 1);
+ // nice error msg here?
+}
+
+
+void Configuration::removeInvitation(QValueList<Invitation>::iterator it) {
+ invitationList.remove(it);
+ save();
+}
+
+void Configuration::doKinetdConf() {
+ setKInetdPort(preferredPortNum);
+
+ if (allowUninvitedFlag) {
+ setKInetdEnabled(true);
+ setKInetdServiceRegistrationEnabled(enableSLPFlag);
+ getPortFromKInetd();
+ return;
+ }
+
+ QDateTime lastExpiration;
+ QValueList<Invitation>::iterator it = invitationList.begin();
+ while (it != invitationList.end()) {
+ Invitation &ix = (*it);
+ QDateTime t = ix.expirationTime();
+ if (t > lastExpiration)
+ lastExpiration = t;
+ it++;
+ }
+ if (lastExpiration.isNull() || (lastExpiration < QDateTime::currentDateTime())) {
+ setKInetdEnabled(false);
+ portNum = -1;
+ }
+ else {
+ setKInetdServiceRegistrationEnabled(false);
+ setKInetdEnabled(lastExpiration);
+ getPortFromKInetd();
+ }
+}
+
+void Configuration::loadFromKConfig() {
+
+ KConfig c("krfbrc");
+ allowUninvitedFlag = c.readBoolEntry("allowUninvited", false);
+ enableSLPFlag = c.readBoolEntry("enableSLP", true);
+ askOnConnectFlag = c.readBoolEntry("confirmUninvitedConnection", true);
+ allowDesktopControlFlag = c.readBoolEntry("allowDesktopControl", false);
+ preferredPortNum = c.readNumEntry("preferredPort", -1);
+ disableBackgroundFlag = c.readBoolEntry("disableBackground", false);
+ disableXShmFlag = c.readBoolEntry("disableXShm", false);
+ if (c.hasKey("uninvitedPasswordCrypted"))
+ passwordString = cryptStr(c.readEntry("uninvitedPasswordCrypted", ""));
+ else
+ passwordString = c.readEntry("uninvitedPassword", "");
+
+ unsigned int invNum = invitationList.size();
+ invitationList.clear();
+ c.setGroup("invitations");
+ int num = c.readNumEntry("invitation_num", 0);
+ for (int i = 0; i < num; i++)
+ invitationList.push_back(Invitation(&c, i));
+
+ invalidateOldInvitations();
+ if (invNum != invitationList.size())
+ emit invitationNumChanged(invitationList.size());
+
+}
+
+void Configuration::saveToKConfig() {
+
+ KConfig c("krfbrc");
+ c.writeEntry("confirmUninvitedConnection", askOnConnectFlag);
+ c.writeEntry("allowDesktopControl", allowDesktopControlFlag);
+ c.writeEntry("allowUninvited", allowUninvitedFlag);
+ c.writeEntry("enableSLP", enableSLPFlag);
+ c.writeEntry("preferredPort", preferredPortNum);
+ c.writeEntry("disableBackground", disableBackgroundFlag);
+ c.writeEntry("disableXShm", disableXShmFlag);
+ c.writeEntry("uninvitedPasswordCrypted", cryptStr(passwordString));
+ c.deleteEntry("uninvitedPassword");
+
+ c.setGroup("invitations");
+ int num = invitationList.count();
+ c.writeEntry("invitation_num", num);
+ int i = 0;
+ while (i < num) {
+ invitationList[i].save(&c, i);
+ i++;
+ }
+
+}
+
+void Configuration::saveToDialogs() {
+ invalidateOldInvitations();
+ QValueList<Invitation>::iterator it = invitationList.begin();
+ while (it != invitationList.end()) {
+ Invitation &inv = *(it++);
+ if (!inv.getViewItem())
+ inv.setViewItem(new KListViewItem(invMngDlg.listView,
+ inv.creationTime().toString(Qt::LocalDate),
+ inv.expirationTime().toString(Qt::LocalDate)));
+ }
+ invMngDlg.adjustSize();
+}
+
+void Configuration::save() {
+ saveToKConfig();
+ saveToDialogs();
+ doKinetdConf();
+}
+
+void Configuration::update() {
+ loadFromKConfig();
+ saveToDialogs();
+}
+
+Invitation Configuration::createInvitation() {
+ Invitation inv;
+ invitationList.push_back(inv);
+ return inv;
+}
+
+void Configuration::invalidateOldInvitations() {
+ QValueList<Invitation>::iterator it = invitationList.begin();
+ while (it != invitationList.end()) {
+ if (!(*it).isValid())
+ it = invitationList.remove(it);
+ else
+ it++;
+ }
+}
+
+void Configuration::refreshTimeout() {
+ unsigned int invNum = invitationList.size();
+ loadFromKConfig();
+ saveToDialogs();
+ if (invNum != invitationList.size())
+ emit invitationNumChanged(invitationList.size());
+}
+
+QString Configuration::hostname() const
+{
+ KInetSocketAddress *a = KInetInterface::getPublicInetAddress();
+ QString hostName;
+ if (a) {
+ hostName = a->nodeName();
+ delete a;
+ }
+ else
+ hostName = "localhost";
+ return hostName;
+}
+
+///////// properties ///////////////////////////
+
+krfb_mode Configuration::mode() const {
+ return m_mode;
+}
+
+bool Configuration::askOnConnect() const {
+ return askOnConnectFlag;
+}
+
+bool Configuration::allowDesktopControl() const {
+ return allowDesktopControlFlag;
+}
+
+bool Configuration::allowUninvitedConnections() const {
+ return allowUninvitedFlag;
+}
+
+bool Configuration::enableSLP() const {
+ return enableSLPFlag;
+}
+
+QString Configuration::password() const {
+ return passwordString;
+}
+
+QValueList<Invitation> &Configuration::invitations() {
+ return invitationList;
+}
+
+bool Configuration::disableBackground() const {
+ return disableBackgroundFlag;
+}
+
+bool Configuration::disableXShm() const {
+ return disableXShmFlag;
+}
+
+void Configuration::setAllowUninvited(bool allowUninvited) {
+ allowUninvitedFlag = allowUninvited;
+}
+
+void Configuration::setEnableSLP(bool e) {
+ enableSLPFlag = e;
+}
+
+void Configuration::setAskOnConnect(bool askOnConnect)
+{
+ askOnConnectFlag = askOnConnect;
+}
+
+void Configuration::setAllowDesktopControl(bool allowDesktopControl)
+{
+ allowDesktopControlFlag = allowDesktopControl;
+}
+
+void Configuration::setPassword(QString password)
+{
+ passwordString = password;
+}
+
+int Configuration::port() const
+{
+ if ((portNum < 5900) || (portNum >= 6000))
+ return portNum;
+ else
+ return portNum - 5900;
+}
+
+// use p=-1 for defaults
+void Configuration::setPreferredPort(int p)
+{
+ preferredPortNum = p;
+}
+
+int Configuration::preferredPort() const
+{
+ return preferredPortNum;
+}
+
+void Configuration::setDisableBackground(bool disable) {
+ disableBackgroundFlag = disable;
+}
+
+void Configuration::setDisableXShm(bool disable) {
+ disableXShmFlag = disable;
+}
+
+////////////// invitation manage dialog //////////////////////////
+
+void Configuration::showManageInvitationsDialog() {
+ loadFromKConfig();
+ saveToDialogs();
+ invMngDlg.exec();
+}
+
+void Configuration::invMngDlgDeleteOnePressed() {
+ QValueList<Invitation>::iterator it = invitationList.begin();
+ while (it != invitationList.end()) {
+ Invitation &ix = (*it);
+ KListViewItem *iv = ix.getViewItem();
+ if (iv && iv->isSelected())
+ it = invitationList.remove(it);
+ else
+ it++;
+ }
+ saveToKConfig();
+ doKinetdConf();
+ emit invitationNumChanged(invitationList.size());
+}
+
+void Configuration::invMngDlgDeleteAllPressed() {
+ invitationList.clear();
+ saveToKConfig();
+ doKinetdConf();
+ emit invitationNumChanged(invitationList.size());
+}
+
+////////////// invitation dialog //////////////////////////
+
+void Configuration::showInvitationDialog() {
+ invDlg.exec();
+ emit invitationFinished();
+ saveToKConfig();
+}
+
+////////////// personal invitation dialog //////////////////////////
+
+void Configuration::showPersonalInvitationDialog() {
+ loadFromKConfig();
+ Invitation inv = createInvitation();
+ save();
+ emit invitationNumChanged(invitationList.size());
+
+ invDlg.enableInviteButton(false);
+ invMngDlg.newPersonalInvitationButton->setEnabled(false);
+
+ persInvDlg.setHost(hostname(), port());
+ persInvDlg.setPassword(inv.password());
+ persInvDlg.setExpiration(inv.expirationTime());
+
+ persInvDlg.exec();
+ invDlg.enableInviteButton(true);
+ invMngDlg.newPersonalInvitationButton->setEnabled(true);
+}
+
+////////////// invite email //////////////////////////
+
+void Configuration::inviteEmail() {
+ int r = KMessageBox::warningContinueCancel(0,
+ i18n("When sending an invitation by email, note that everybody who reads this email "
+ "will be able to connect to your computer for one hour, or until the first "
+ "successful connection took place, whichever comes first. \n"
+ "You should either encrypt the email or at least send it only in a "
+ "secure network, but not over the Internet."),
+ i18n("Send Invitation via Email"),
+ KStdGuiItem::cont(),
+ "showEmailInvitationWarning");
+ if (r == KMessageBox::Cancel)
+ return;
+
+ loadFromKConfig();
+ Invitation inv = createInvitation();
+ save();
+ emit invitationNumChanged(invitationList.size());
+
+ KApplication *app = KApplication::kApplication();
+ app->invokeMailer(QString::null, QString::null, QString::null,
+ i18n("Desktop Sharing (VNC) invitation"),
+ i18n("You have been invited to a VNC session. If you have the KDE Remote "
+ "Desktop Connection installed, just click on the link below.\n\n"
+ "vnc://invitation:%1@%2:%3\n\n"
+ "Otherwise you can use any VNC client with the following parameters:\n\n"
+ "Host: %4:%5\n"
+ "Password: %6\n\n"
+ "Alternatively you can click on the link below to start the VNC session\n"
+ "within your web browser.\n"
+ "\n"
+ " http://%7:%8/\n"
+ "\n"
+ "For security reasons this invitation will expire at %9.")
+ .arg(inv.password())
+ .arg(hostname())
+ .arg(port())
+ .arg(hostname())
+ .arg(port())
+ .arg(inv.password())
+ .arg(hostname())
+ .arg(5800) // determine with dcop ... later ...
+ .arg(KGlobal::locale()->formatDateTime(inv.expirationTime())));
+}
+
+////////////// invoke kcontrol module //////////////////////////
+
+void Configuration::showConfigurationModule() {
+ KRun::run( "kcmshell kcmkrfb", KURL::List() );
+}
+
+
+#include "configuration.moc"
diff --git a/krfb/krfb/configuration.h b/krfb/krfb/configuration.h
new file mode 100644
index 00000000..cec7a2ed
--- /dev/null
+++ b/krfb/krfb/configuration.h
@@ -0,0 +1,139 @@
+/***************************************************************************
+ configuration.h
+ -------------------
+ begin : Tue Dec 11 2001
+ copyright : (C) 2001-2003 by Tim Jansen
+ email : tim@tjansen.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef CONFIGURATION_H
+#define CONFIGURATION_H
+
+#include "invitation.h"
+
+#include "manageinvitations.h"
+#include "personalinvitedialog.h"
+#include "invitedialog.h"
+
+#include <dcopref.h>
+#include <kconfig.h>
+#include <qtimer.h>
+#include <qobject.h>
+#include <qvalidator.h>
+#include <qstring.h>
+
+#include <dcopobject.h>
+
+enum krfb_mode {
+ KRFB_UNKNOWN_MODE = 0,
+ KRFB_KINETD_MODE,
+ KRFB_INVITATION_MODE,
+ KRFB_CONFIGURATION_MODE
+};
+
+
+/**
+ * This class stores the app's configuration, manages the
+ * standalone-config-dialog and all the invitation dialogs
+ * @author Tim Jansen
+ */
+class Configuration : public QObject, public DCOPObject {
+ K_DCOP
+ Q_OBJECT
+public:
+ Configuration(krfb_mode mode);
+ virtual ~Configuration();
+
+ krfb_mode mode() const;
+ bool askOnConnect() const;
+ bool allowDesktopControl() const;
+ bool allowUninvitedConnections() const;
+ bool enableSLP() const;
+ QString password() const;
+ QString hostname() const;
+ int port() const;
+ int preferredPort() const;
+ bool disableBackground() const;
+ bool disableXShm() const;
+
+ void setAllowUninvited(bool allowUninvited);
+ void setEnableSLP(bool e);
+ void setAskOnConnect(bool askOnConnect);
+ void setPassword(QString password);
+ void setPreferredPort(int p);
+ void setDisableBackground(bool disable);
+ void setDisableXShm(bool disable);
+ void save();
+ void update();
+
+ QValueList<Invitation> &invitations();
+ void removeInvitation(QValueList<Invitation>::iterator it);
+signals:
+ void invitationFinished();
+ void invitationNumChanged(int num);
+
+public slots:
+ void setAllowDesktopControl(bool allowDesktopControl);
+ void showManageInvitationsDialog();
+ void showInvitationDialog();
+ void showPersonalInvitationDialog();
+ void showConfigurationModule();
+ void inviteEmail();
+
+private:
+ void loadFromKConfig();
+ void loadFromDialogs();
+ void saveToKConfig();
+ void saveToDialogs();
+ Invitation createInvitation();
+ void closeInvDlg();
+ void invalidateOldInvitations();
+ void setKInetdEnabled(const QDateTime &date);
+ void setKInetdEnabled(bool enabled);
+ void setKInetdServiceRegistrationEnabled(bool enabled);
+ void getPortFromKInetd();
+ void setKInetdPort(int port);
+ void doKinetdConf();
+
+ krfb_mode m_mode;
+
+ ManageInvitationsDialog invMngDlg;
+ InviteDialog invDlg;
+ PersonalInviteDialog persInvDlg;
+ QTimer refreshTimer;
+
+ bool askOnConnectFlag;
+ bool allowDesktopControlFlag;
+ bool allowUninvitedFlag;
+ bool enableSLPFlag;
+
+ int portNum, preferredPortNum;
+
+ DCOPRef kinetdRef;
+
+ QString passwordString;
+ QValueList<Invitation> invitationList;
+
+ bool disableBackgroundFlag;
+ bool disableXShmFlag;
+
+k_dcop:
+ // Connected to the DCOP signal
+ void updateKConfig();
+private slots:
+ void refreshTimeout();
+
+ void invMngDlgDeleteOnePressed();
+ void invMngDlgDeleteAllPressed();
+};
+
+#endif
diff --git a/krfb/krfb/connection-side-image.png b/krfb/krfb/connection-side-image.png
new file mode 100644
index 00000000..f3d9db67
--- /dev/null
+++ b/krfb/krfb/connection-side-image.png
Binary files differ
diff --git a/krfb/krfb/connectiondialog.cc b/krfb/krfb/connectiondialog.cc
new file mode 100644
index 00000000..eeb80479
--- /dev/null
+++ b/krfb/krfb/connectiondialog.cc
@@ -0,0 +1,63 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Nadeem Hasan <nhasan@kde.org>
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "connectiondialog.h"
+#include "connectionwidget.h"
+
+#include <qcheckbox.h>
+#include <qlabel.h>
+
+#include <kiconloader.h>
+#include <klocale.h>
+
+ConnectionDialog::ConnectionDialog( QWidget *parent, const char *name )
+ : KDialogBase( parent, name, true, i18n( "New Connection" ),
+ Ok|Cancel, Cancel, true )
+{
+ m_connectWidget = new ConnectionWidget( this, "ConnectWidget" );
+ m_connectWidget->pixmapLabel->setPixmap(
+ UserIcon( "connection-side-image.png" ) );
+
+ KGuiItem accept = KStdGuiItem::ok();
+ accept.setText( i18n( "Accept Connection" ) );
+ setButtonOK( accept );
+
+ KGuiItem refuse = KStdGuiItem::cancel();
+ refuse.setText( i18n( "Refuse Connection" ) );
+ setButtonCancel( refuse );
+
+ setMainWidget( m_connectWidget );
+}
+
+void ConnectionDialog::setRemoteHost( const QString &host )
+{
+ m_connectWidget->remoteHost->setText( host );
+}
+
+void ConnectionDialog::setAllowRemoteControl( bool b )
+{
+ m_connectWidget->cbAllowRemoteControl->setChecked( b );
+}
+
+bool ConnectionDialog::allowRemoteControl()
+{
+ return m_connectWidget->cbAllowRemoteControl->isChecked();
+}
+
+#include "connectiondialog.moc"
diff --git a/krfb/krfb/connectiondialog.h b/krfb/krfb/connectiondialog.h
new file mode 100644
index 00000000..35deae29
--- /dev/null
+++ b/krfb/krfb/connectiondialog.h
@@ -0,0 +1,44 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Nadeem Hasan <nhasan@kde.org>
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef CONNECTIONDIALOG_H
+#define CONNECTIONDIALOG_H
+
+#include <kdialogbase.h>
+
+class ConnectionWidget;
+
+class ConnectionDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ ConnectionDialog( QWidget *parent, const char *name );
+ ~ConnectionDialog() {};
+
+ void setRemoteHost( const QString &host );
+ void setAllowRemoteControl( bool b );
+ bool allowRemoteControl();
+
+ protected:
+ ConnectionWidget *m_connectWidget;
+};
+
+#endif // CONNECTIONDIALOG_H
+
diff --git a/krfb/krfb/connectionwidget.ui b/krfb/krfb/connectionwidget.ui
new file mode 100644
index 00000000..e053adf9
--- /dev/null
+++ b/krfb/krfb/connectionwidget.ui
@@ -0,0 +1,208 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>ConnectionWidget</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>NewConnectWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>521</width>
+ <height>328</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLabel" row="0" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>TextLabel5</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>13</pointsize>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Attention</string>
+ </property>
+ <property name="indent">
+ <number>0</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>mainTextLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="lineWidth">
+ <number>-1</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="midLineWidth">
+ <number>5</number>
+ </property>
+ <property name="text">
+ <string>Somebody is requesting a connection to your computer. Granting this will allow the remote user to watch your desktop. </string>
+ </property>
+ <property name="textFormat">
+ <enum>AutoText</enum>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter|AlignLeft</set>
+ </property>
+ <property name="indent">
+ <number>0</number>
+ </property>
+ <property name="wordwrap" stdset="0">
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="6" colspan="1">
+ <property name="name">
+ <cstring>pixmapLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>108</width>
+ <height>318</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>108</width>
+ <height>318</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>WinPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="lineWidth">
+ <number>0</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ <property name="indent">
+ <number>0</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="2">
+ <property name="name">
+ <cstring>remoteHost</cstring>
+ </property>
+ <property name="font">
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>123.234.123.234</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="5" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>cbAllowRemoteControl</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Allow remote user to &amp;control keyboard and mouse</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If you turn this option on, the remote user can enter keystrokes and use your mouse pointer. This gives them full control over your computer, so be careful. When the option is disabled the remote user can only watch your screen.</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="1">
+ <property name="name">
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property name="font">
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Remote system:</string>
+ </property>
+ </widget>
+ <spacer row="4" column="1">
+ <property name="name">
+ <cstring>spacer23</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Minimum</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>84</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="2" column="1">
+ <property name="name">
+ <cstring>spacer22</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Minimum</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>80</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/krfb/krfb/cr16-app-krfb.png b/krfb/krfb/cr16-app-krfb.png
new file mode 100644
index 00000000..9bbbe097
--- /dev/null
+++ b/krfb/krfb/cr16-app-krfb.png
Binary files differ
diff --git a/krfb/krfb/cr32-app-krfb.png b/krfb/krfb/cr32-app-krfb.png
new file mode 100644
index 00000000..b5a6328b
--- /dev/null
+++ b/krfb/krfb/cr32-app-krfb.png
Binary files differ
diff --git a/krfb/krfb/cr48-app-krfb.png b/krfb/krfb/cr48-app-krfb.png
new file mode 100644
index 00000000..19c31a71
--- /dev/null
+++ b/krfb/krfb/cr48-app-krfb.png
Binary files differ
diff --git a/krfb/krfb/eventsrc b/krfb/krfb/eventsrc
new file mode 100644
index 00000000..ba18c766
--- /dev/null
+++ b/krfb/krfb/eventsrc
@@ -0,0 +1,1219 @@
+[!Global!]
+IconName=krfb
+Comment=Desktop Sharing
+Comment[af]=Werkskerm Deeling
+Comment[ar]=مشاركة سطح المكتب
+Comment[be]=Агульнае выкарыстанне кампутара
+Comment[bg]=Споделяне на работното място
+Comment[bn]=ডেস্কটপ ভাগাভাগি
+Comment[br]=Rannañ ar vurev
+Comment[bs]=Dijeljenje desktopa
+Comment[ca]=Compartició de l'escriptori
+Comment[cs]=Sdílení pracovní plochy
+Comment[cy]=Rhannu Penbwrdd
+Comment[da]=Desktopdeling
+Comment[de]=Arbeitsfläche freigeben
+Comment[el]=Κοινή χρήση επιφάνειας εργασίας
+Comment[eo]=Tabula fordonado
+Comment[es]=Escritorio compartido
+Comment[et]=Töölaua jagamine
+Comment[eu]=Mahaigain partekatzea
+Comment[fa]=اشتراک رومیزی
+Comment[fi]=Työpöydän jakaminen
+Comment[fr]=Partage du bureau
+Comment[ga]=Roinnt Deisce
+Comment[gl]=Compartición do escritorio
+Comment[he]=שיתוף שולחנות עבודה
+Comment[hi]=डेस्कटॉप साझेदारी
+Comment[hr]=Dijeljenje radne površine
+Comment[hu]=Munkaasztal-megosztás
+Comment[is]=Skjáborðamiðlun
+Comment[it]=Condivisione desktop
+Comment[ja]=デスクトップ共有
+Comment[ka]=სამუშაო მაგიდის გაზიარება
+Comment[kk]=Үстелді ортақтастыру
+Comment[km]=ការ​ចែក​រំលែក​ផ្ទែ​តុ
+Comment[lt]=Dalinimasis darbastaliu
+Comment[mk]=Делење на работната површина
+Comment[mn]=Ажлын байрыг хамтран эзэмших
+Comment[ms]=Perkongsian Ruang Kerja
+Comment[mt]=Qsim tad-desktop
+Comment[nb]=Skrivebordsdeling
+Comment[nds]=Schriefdisch-Freegaav
+Comment[ne]=डेस्कटप साझेदारी
+Comment[nl]=Bureaublad delen
+Comment[nn]=Skrivebordsdeling
+Comment[nso]=Kabagano ya Desktop
+Comment[pa]=ਡੈਸਕਟਾਪ ਸਾਂਝ
+Comment[pl]=Współdzielenie pulpitu
+Comment[pt]=Partilha do Ecrã
+Comment[pt_BR]=Compartilhamento do Ambiente de Trabalho
+Comment[ro]=Partajare ecran
+Comment[ru]=Параметры общего рабочего стола
+Comment[se]=Čállinbeavdejuogadeapmi
+Comment[sk]=Zdieľanie pracovnej plochy
+Comment[sl]=Deljenje namizja
+Comment[sr]=Дељење радне површине
+Comment[sr@Latn]=Deljenje radne površine
+Comment[sv]=Dela ut skrivbord
+Comment[ta]=பணிமேடை பகிர்வு
+Comment[tg]=Истифодаи Муштараки Мизи Корӣ
+Comment[th]=ใช้งานพื้นที่ทำงานร่วมกัน
+Comment[tr]=Masaüstü Paylaşımı
+Comment[uk]=Спільні стільниці
+Comment[ven]=U kovhekana ha desikithopo
+Comment[xh]=Ulwahlulelano lwe Desktop
+Comment[zh_CN]=桌面共享
+Comment[zh_HK]=桌面分享
+Comment[zh_TW]=桌面分享
+Comment[zu]=Ukuhlukaniselana kwe-Desktop
+
+[UserAcceptsConnection]
+Name=UserAcceptsConnection
+Name[ar]=المستخدم قبل الاتصال
+Name[bg]=Приета е връзка от потребител
+Name[bn]=ব্যবহারকারী সংযোগ গ্রহণ করে
+Name[ca]=L'usuari accepta la connexió
+Name[cs]=Uživatel přijímá spojení
+Name[cy]=DefnyddiwrDerbynCysylltiad
+Name[da]=BrugerAcceptererForbindelse
+Name[de]=BenutzerBestätigtVerbindung
+Name[el]=Ο χρήστης αποδέχεται σύνδεση
+Name[eo]=UzantoAkceptasKonektojn
+Name[es]=El usuario acepta la conexión
+Name[et]=Kasutaja ühendusega nõus
+Name[eu]=Erabiltzaileak konexioa onartu du
+Name[fa]=پذیرش اتصال توسط کاربر
+Name[fr]=L'utilisateur accepte les connexions
+Name[ga]=GlacannÚsáideoirLeCeangal
+Name[gl]=O usuario acepta a conexión
+Name[he]=משתמש מקבל חיבור
+Name[hi]=उपयोक्ता-कनेक्शन-स्वीकारा
+Name[hr]=KorisnikPrihvaćaVezu
+Name[hu]=KapcsolatElfogadva
+Name[is]=NotandiSamþykkirTengingar
+Name[it]=L'utente accetta la connessione
+Name[ja]=ユーザが許可した接続
+Name[kk]=Пайдаланушы қосылымды қабылдайды
+Name[km]=អ្នក​ប្រើ​ទទួលយក​ការ​ត​ភ្ជាប់
+Name[lt]=Naudotojas priima kvietimą
+Name[mk]=Корисникот го прифаќа поврзувањето
+Name[mn]=Хэрэглэгч зөвшөөрсөн холболт
+Name[ms]=Pengguna Menerima Sambungan
+Name[mt]=UserJaċċettaKonnessjoni
+Name[nb]=Bruker tar i mot oppkobling
+Name[nds]=BrukerLettTokoppelnTo
+Name[ne]=प्रयोगकर्ताले जडान स्वीकार गर्दछ
+Name[nl]=Gebruiker accepteert verbinding
+Name[nn]=Brukar godtek samband
+Name[nso]=Modirisi o Amogela Kgokagano
+Name[pl]=Połączenie akceptowane przez użytkownika
+Name[pt_BR]=Aceita Conexões do Usuário
+Name[ro]=Conexiune acceptată de utilizator
+Name[ru]=Пользователь принимает соединения
+Name[se]=Geavaheaddji dohkkeha oktavuođa
+Name[sk]=Užívateľ akceptoval spojenie
+Name[sl]=Uporabnik sprejel povezavo
+Name[sr]=Корисник прихвата везе
+Name[sr@Latn]=Korisnik prihvata veze
+Name[sv]=Användare accepterar anslutning
+Name[ta]=பயனர் இணைப்பு ஏற்றுக்கொள்ளப்பட்டது
+Name[tg]=Корванд Пайвастшавиро Қабул мекунад
+Name[th]=ผู้ใช้ยอมรับการเชื่อมต่อ
+Name[tr]=Kullanıcı Kabul Eden Bağlantı
+Name[uk]=Користувач приймає з'єднання
+Name[ven]=Mushumisi o tanganedza vhukwamani
+Name[xh]=Umsebenzisi Wamkela Uxhulumaniso
+Name[zh_CN]=用户接受连接
+Name[zh_HK]=用戶接受連線
+Name[zh_TW]=使用者接受連線
+Name[zu]=UmsebenziUvumelaUkuxhumana
+Comment=User accepts connection
+Comment[af]=Gebruiker aanvaar verbinding
+Comment[ar]=المستخدم قبل الإتصال
+Comment[be]=Карыстальнік дазволіў злучэнне
+Comment[bg]=Приета е връзка от потребител
+Comment[bn]=ব্যবহারকারী সংযোগ গ্রহণ করে
+Comment[bs]=Korisnik prihvata konekciju
+Comment[ca]=L'usuari accepta la connexió
+Comment[cs]=Uživatel přijímá spojení
+Comment[cy]=Mae'r defnyddiwr yn derbyn y cysylltiad
+Comment[da]=Bruger accepterer forbindelse
+Comment[de]=Der Benutzer bestätigt die Verbindung
+Comment[el]=Ο χρήστης αποδέχεται σύνδεση
+Comment[eo]=Uzanto akceptas konektojn
+Comment[es]=El usuario acepta la conexión
+Comment[et]=Kasutaja nõustub ühendusega
+Comment[eu]=Erabiltzaileak konexioa onartu du
+Comment[fa]=کاربر اتصال را پذیرفت
+Comment[fi]=Käyttäjä hyväksyy yhteyden
+Comment[fr]=l'utilisateur accepte les connexions
+Comment[ga]=Glacann úsáideoir le ceangal
+Comment[gl]=O usuario aceptou a conexión
+Comment[he]=המשתמש מקבל את החיבור
+Comment[hi]=उपयोक्ता कनेक्शन स्वीकारा
+Comment[hr]=Korisnik prihvaća vezu
+Comment[hu]=A felhasználó elfogadja a csatlakozási kérést
+Comment[is]=Notandi samþykkir tengingu
+Comment[it]=L'utente accetta la connessione
+Comment[ja]=ユーザが接続を許可
+Comment[ka]=მომხმარებლმა მიიღო კავშირი
+Comment[kk]=Пайдаланушы қосылымды қабылдайды
+Comment[km]=អ្នក​ប្រើ​ទទួលយក​ការ​ត​ភ្ជាប់
+Comment[lt]=Naudotojas priima kvietimą
+Comment[mk]=Корисникот прифаќа поврзување
+Comment[mn]=Хэрэглэгч зөвшөөрсөн холболт
+Comment[ms]= Pengguna menerima sambungan
+Comment[mt]=User jaċċetta l-konnessjoni
+Comment[nb]=Bruker tar imot oppkobling
+Comment[nds]=Bruker nimmt Tokoppelanfraag an
+Comment[ne]=प्रयोगकर्ताले जडान स्वीकार गर्दछ
+Comment[nl]=Gebruiker accepteert verbinding
+Comment[nn]=Brukar godtek samband
+Comment[nso]=Modirisi o Amogela Kgokagano
+Comment[pl]=Użytkownik akceptuje połączenie
+Comment[pt]=O utilizador aceita a ligação
+Comment[pt_BR]=O usuário aceita a conexão
+Comment[ro]=Utilizatorul acceptă conexiunea
+Comment[ru]=Пользователь принимает соединения
+Comment[se]=Geavaheaddji dohkkeha oktavuođa
+Comment[sk]=Užívateľ akceptoval spojenie
+Comment[sl]=Uporabnik sprejel povezavo
+Comment[sr]=Корисник прихвата везу
+Comment[sr@Latn]=Korisnik prihvata vezu
+Comment[sv]=Användaren accepterar anslutning
+Comment[ta]=பயனர் இணைப்பு ஏற்றுக்கொள்ளப்பட்டது
+Comment[tg]=Корванд пайвастшавиро қабул мекунад
+Comment[th]=ผู้ใช้ยอมรับการเชื่อมต่อ
+Comment[tr]=Kullanıcı bağlantıyı kabul etti
+Comment[uk]=Користувач приймає з'єднання
+Comment[ven]=Mushumisi o tanganedza vhukwamani
+Comment[xh]=Umsebenzisi wamkela uxhulumaniso
+Comment[zh_CN]=用户接受连接
+Comment[zh_HK]=用戶接受連線
+Comment[zh_TW]=使用者接受的連線
+Comment[zu]=Umsebenzi uyakuvumela ukuxhumana
+default_presentation=4
+
+[UserRefusesConnection]
+Name=UserRefusesConnection
+Name[ar]=المستخدم رفض الاتصال
+Name[bg]=Отказана връзка от потребител
+Name[bn]=ব্যবহারকারী সংযোগ অস্বীকার করে
+Name[ca]=L'usuari refusa la connexió
+Name[cs]=Uživatel odmítá spojení
+Name[cy]=DefnyddiwrGwrthodCysylltiad
+Name[da]=BrugerAfslårForbindelse
+Name[de]=BenutzerLehntVerbindungAb
+Name[el]=Ο χρήστης απορρίπτει σύνδεση
+Name[eo]=UzantoRifuzasKonektojn
+Name[es]=El usuario rechaza la conexión
+Name[et]=Kasutaja keeldub ühendusest
+Name[eu]=Erabiltzaileak konexioa ukatu du
+Name[fa]=نپذیرفتن اتصال توسط کاربر
+Name[fr]=L'utilisateur refuse les connexions
+Name[ga]=DiúltíonnÚsáideoirLeCeangal
+Name[gl]=O usuario rexeita a conexión
+Name[he]=משתמש דוחה חיבור
+Name[hi]=उपयोक्ता-कनेक्शन-अस्वीकारा
+Name[hr]=KorisnikOdbijaVezu
+Name[hu]=KapcsolatVisszautasítva
+Name[is]=NotandiHafnarTengingum
+Name[it]=L'utente rifiuta la connessione
+Name[ja]=ユーザが拒否した接続
+Name[kk]=Пайдаланушы қосылымды қабылдамайды
+Name[km]=អ្នក​ប្រើ​បដិសេធ​ការ​ត​ភ្ជាប់
+Name[lt]=Naudotojas atmeta kvietimą
+Name[mk]=Корисникот го одбива поврзувањето
+Name[mn]=Хэрэглэгч зөвшөөрөөгүй холболт
+Name[ms]=Pengguna Menolak Sambungan
+Name[mt]=UserJirrifjutaKonnessjoni
+Name[nb]=Bruker avviser oppkobling
+Name[nds]=BrukerWiestTokoppelnAf
+Name[ne]=प्रयोगकर्ताले जडान अस्वीकार गर्दछ
+Name[nl]=Gebruiker weigert verbinding
+Name[nn]=Brukar nektar samband
+Name[nso]=Modirisi o Gana Kgokagano
+Name[pl]=Połączenie odrzucone przez użytkownika
+Name[pt_BR]=Rejeita Conexões do Usuário
+Name[ro]=Conexiune respinsă de utilizator
+Name[ru]=Пользователь не принимает соединения
+Name[se]=Geavaheaddji hilgo oktavuođa
+Name[sk]=Užívateľ zamietol spojenie
+Name[sl]=Uporabnik zavrnil povezavo
+Name[sr]=Корисник одбија везе
+Name[sr@Latn]=Korisnik odbija veze
+Name[sv]=Användaren vägrar anslutning
+Name[ta]=பயனர் இணைப்பு ஏற்கப்படவில்லை
+Name[tg]=Корванд Пайвастшавиро Рад мекунад
+Name[th]=ผู้ใช้ปฏิเสธการเชื่อมต่อ
+Name[tr]=Kullanıcı Bağlantıyı Reddetti
+Name[uk]=КористувачВідмовляєУЗ'єднанні
+Name[ven]=Mushumisi o hana Vhukwamani
+Name[xh]=Umsebenzisi Uyalwala Uxhulumaniso
+Name[zh_CN]=用户拒绝连接
+Name[zh_HK]=用戶拒絕連線
+Name[zh_TW]=使用者拒絕連線
+Name[zu]=UmsebenzisiWalaUxhumaniso
+Comment=User refuses connection
+Comment[af]=Gebruiker weier verbinding
+Comment[ar]=المستخدم رفض الاتصال
+Comment[be]=Карыстальнік адмовіў злучэнню
+Comment[bg]=Отказана връзка от потребител
+Comment[bn]=ব্যবহারকারী সংযোগ অস্বীকার করে
+Comment[bs]=Korisnik odbija konekciju
+Comment[ca]=L'usuari refusa la connexió
+Comment[cs]=Uživatel odmítá spojení
+Comment[cy]=Mae'r defnyddiwr yn gwrthod y cysylltiad
+Comment[da]=Bruger afslår forbindelse
+Comment[de]=Der Benutzer lehnt die Verbindung ab
+Comment[el]=Ο χρήστης απορρίπτει σύνδεση
+Comment[eo]=Uzanto rifuzas konektojn
+Comment[es]=El usuario rechaza la conexión
+Comment[et]=Kasutaja keeldub ühendusest
+Comment[eu]=Erabiltzaileak konexioa ukatu du
+Comment[fa]=کاربر اتصال را نپذیرفت
+Comment[fi]=Käyttäjä hylkää yhteyden
+Comment[fr]=L'utilisateur refuse les connexions
+Comment[ga]=Diúltaíonn úsáideoir ceangal
+Comment[gl]=O usuario rexeitou a conexión
+Comment[he]=המשתמש מסרב לחיבור
+Comment[hi]=उपयोक्ता कनेक्शन अस्वीकारा
+Comment[hr]=Korisnik odbija vezu
+Comment[hu]=A felhasználó visszautasítja a csatlakozási kérést
+Comment[is]=Notandi hafnar tengingu
+Comment[it]=L'utente rifiuta la connessione
+Comment[ja]=ユーザが接続を拒否
+Comment[ka]=მომხმარებელმა უარყო კავშირი
+Comment[kk]=Пайдаланушы қосылымды қабылдамайды
+Comment[km]=អ្នក​ប្រើ​បដិសេធ​ការ​ត​ភ្ជាប់
+Comment[lt]=Naudotojas atmeta kvietimą
+Comment[mk]=Корисникот одбива поврзување
+Comment[mn]=Хэрэглэгч зөвшөөрөөгүй холболт
+Comment[ms]=Pengguna menolak sambungan
+Comment[mt]=User jiċħad il-konnessjoni
+Comment[nb]=Bruker avviser oppkobling
+Comment[nds]=Bruker wiest Tokoppelanfraag af
+Comment[ne]=प्रयोगकर्ताले जडान अस्वीकार गर्दछ
+Comment[nl]=Gebruiker weigert verbinding
+Comment[nn]=Brukar nektar samband
+Comment[nso]=Modirisi o gana kgokagano
+Comment[pl]=Użytkownik odrzuca połączenie
+Comment[pt]=O utilizador recusa a ligação
+Comment[pt_BR]=O usuário rejeita a conexão
+Comment[ro]=Utilizatorul refuză conexiunea
+Comment[ru]=Пользователь не принимает соединения
+Comment[se]=Geavaheaddji hilgo oktavuođa
+Comment[sk]=Užívateľ odmietol spojenie
+Comment[sl]=Uporabnik zavrnil povezavo
+Comment[sr]=Корисник одбија везу
+Comment[sr@Latn]=Korisnik odbija vezu
+Comment[sv]=Användaren vägrar anslutning
+Comment[ta]=பயனர் இணைப்பு ஏற்க மறுக்கப்பட்டது
+Comment[tg]=Корванд пайвастшавиро рад мекунад
+Comment[th]=ผู้ใช้ปฏิเสธการเชื่อมต่อ
+Comment[tr]=Kullanıcı bağlantıyı iptal etti
+Comment[uk]=Користувач відмовляє у з'єднанні
+Comment[ven]=Mushumisi o hana vhukwamani
+Comment[xh]=Umsebenzisi wala uxhulumaniso
+Comment[zh_CN]=用户拒绝连接
+Comment[zh_HK]=用戶拒絕連線
+Comment[zh_TW]=使用者拒絕的連線
+Comment[zu]=Umsebenzi awukuvumeli ukuxhumana
+default_presentation=4
+
+[ConnectionClosed]
+Name=ConnectionClosed
+Name[ar]=اتصال مغلق
+Name[bg]=Връзката е прекъсната
+Name[bn]=সংযোগ বন্ধ করা হল
+Name[br]=Kevreadur serret
+Name[ca]=Connexió tancada
+Name[cs]=Spojení ukončeno
+Name[cy]=CysylltiadArGau
+Name[da]=ForbindelseLukket
+Name[de]=VerbindungGeschlossen
+Name[el]=Η σύνδεση έκλεισε
+Name[eo]=KonektoFermita
+Name[es]=Conexión cerrada
+Name[et]=Ühendus suletud
+Name[eu]=Konexioa itxi da
+Name[fa]=اتصال بسته
+Name[fr]=Connexion fermée
+Name[ga]=CeangalDúnta
+Name[gl]=Conexión pechada
+Name[he]=חיבור נסגר
+Name[hi]=कनेक्शन-बन्द
+Name[hr]=VezaPrekinuta
+Name[hu]=KapcsolatBezárva
+Name[is]=TenginguLokað
+Name[it]=Connessione chiusa
+Name[ja]=接続切断
+Name[kk]=Қосылым жабылды
+Name[km]=បាន​បិទ​ការ​ត​ភ្ជាប់
+Name[lt]=Ryšys baigtas
+Name[mk]=Поврзувањето е затворено
+Name[mn]=Холболт хаагдав
+Name[ms]=Sambungan Ditutup
+Name[mt]=KonnessjonijiMagħluqa
+Name[nb]=Kobling stengt
+Name[nds]=Afkoppelt
+Name[ne]=जडना बन्द भयो
+Name[nl]=Verbinding gesloten
+Name[nn]=Samband stengt
+Name[nso]=Kgokagano e Tswaletswe
+Name[pl]=Połączenia zakończone
+Name[pt_BR]=Conexão fechada
+Name[ro]=Conexiune închisă
+Name[ru]=Соединение закрыто
+Name[se]=Oktavuohta giddejuvui
+Name[sk]=Spojenie ukončené
+Name[sl]=Povezava zaprta
+Name[sr]=Веза је затворена
+Name[sr@Latn]=Veza je zatvorena
+Name[sv]=Anslutning stängd
+Name[ta]=இணைப்பு மூடப்பட்டது
+Name[tg]=Пайвастшавӣ Пӯшида шудааст
+Name[th]=การเชื่อมต่อยุติ
+Name[tr]=Bağlantı Kapatıldı
+Name[uk]=З'єднанняЗакрито
+Name[ven]=Vhukwamani ho valwa
+Name[xh]=Uxhulumaniso Luvaliwe
+Name[zh_CN]=连接关闭
+Name[zh_HK]=連線已關閉
+Name[zh_TW]=連線已關閉
+Name[zu]=UkuxhumanisaKuvaliwe
+Comment=Connection closed
+Comment[af]=Verbinding gesluit
+Comment[ar]=الاتصال قُطع
+Comment[be]=Злучэнне закрытае
+Comment[bg]=Връзката е прекъсната
+Comment[bn]=সংযোগ বন্ধ করা হল
+Comment[br]=Serret eo ar gevreadenn
+Comment[bs]=Konekcija prekinuta
+Comment[ca]=Connexió tancada
+Comment[cs]=Spojení ukončeno
+Comment[cy]=Mae'r cysylltiad ar gau
+Comment[da]=Forbindelse lukket
+Comment[de]=Verbindung geschlossen
+Comment[el]=Η σύνδεση έκλεισε
+Comment[eo]=Konekto fermita
+Comment[es]=Conexión rechazada
+Comment[et]=Ühendus suletud
+Comment[eu]=Konexioa itxi da
+Comment[fa]=اتصال بسته شد
+Comment[fi]=Yhteys suljettu
+Comment[fr]=Connexion coupée
+Comment[ga]=Ceangal dúnta
+Comment[gl]=Conexión pechada
+Comment[he]=החיבור נסגר
+Comment[hi]=कनेक्शन बन्द
+Comment[hr]=Veza prekinuta
+Comment[hu]=A kapcsolat bezárva
+Comment[is]=Tengingu lokað
+Comment[it]=Connessione chiusa
+Comment[ja]=接続が閉じられました
+Comment[ka]=კავშირი დაიხურა
+Comment[kk]=Қосылым жабылды
+Comment[km]=បាន​បិទ​ការ​ត​ភ្ជាប់
+Comment[lt]=Ryšys baigtas
+Comment[mk]=Поврзувањето е затворено
+Comment[mn]=Холболт хаагдав
+Comment[ms]=Sambungan ditutup
+Comment[mt]=Konnessjoni magħluqa
+Comment[nb]=Oppkobling stengt
+Comment[nds]=Afkoppelt
+Comment[ne]=जडान बन्द भयो
+Comment[nl]=Verbinding verbroken
+Comment[nn]=Samband stengt
+Comment[nso]=Kopantsho e tswaletswe
+Comment[pa]=ਕੁਨੈਕਸ਼ਨ ਬੰਦ ਕੀਤਾ
+Comment[pl]=Połączenie zakończone
+Comment[pt]=Ligação fechada
+Comment[pt_BR]=conexão encerrada
+Comment[ro]=Conexiune închisă
+Comment[ru]=Соединение закрыто
+Comment[se]=Oktavuohta giddejuvvui
+Comment[sk]=Spojenie ukončené
+Comment[sl]=Povezava zaprta
+Comment[sr]=Веза је затворена
+Comment[sr@Latn]=Veza je zatvorena
+Comment[sv]=Anslutning stängd
+Comment[ta]=இணைப்புகள் மூடப்பட்டது
+Comment[tg]=Пайвастшавӣ пӯшида аст
+Comment[th]=การเชื่อมต่อยุติ
+Comment[tr]=Bağlantı kesildi
+Comment[uk]=З'єднання закрито
+Comment[uz]=Aloqa uzildi
+Comment[uz@cyrillic]=Алоқа узилди
+Comment[ven]=Vhukwamani ho valwa
+Comment[xh]=Uxhulumaniso luvaliwe
+Comment[zh_CN]=连接关闭
+Comment[zh_HK]=連線已關閉
+Comment[zh_TW]=連線已關閉
+Comment[zu]=Ukuxhumana kuvaliwe
+default_presentation=4
+
+[InvalidPassword]
+Name=InvalidPassword
+Name[ar]=كلمة مرور غير صالحة
+Name[bg]=Невалидна парола
+Name[bn]=অবৈধ পাসওয়ার্ড
+Name[br]=N'eo ket mat an tremenger
+Name[ca]=Contrasenya no vàlida
+Name[cs]=Neplatné heslo
+Name[cy]=CyfrinairAnnilys
+Name[da]=UgyldigtKodeord
+Name[de]=UngültigesPasswort
+Name[el]=Μη έγκυρος κωδικός πρόσβασης
+Name[eo]=NevalidaPasvorto
+Name[es]=Contraseña errónea
+Name[et]=Vale parool
+Name[eu]=Baliogabeko pasahitza
+Name[fa]=اسم‌ رمز نامعتبر
+Name[fr]=Mots de passe non valable
+Name[ga]=FocalFaireNeamhbhailí
+Name[gl]=Contraseña inválida
+Name[he]=סיסמה שגויה
+Name[hi]=अवैध-पासवर्ड
+Name[hr]=NevažećaLozinka
+Name[hu]=ÉrvénytelenJelszó
+Name[is]=ÓgiltLykilorð
+Name[it]=Password non valida
+Name[ja]=不正なパスワード
+Name[kk]=Жарамсыз пароль
+Name[km]=ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ
+Name[lt]=Neteisingas slaptažodžis
+Name[mk]=Невалидна лозинка
+Name[mn]=Буруу нууц үг
+Name[ms]=Kata Laluan Tidak Sah
+Name[mt]=PasswordĦażin
+Name[nb]=Ugyldig passord
+Name[nds]=LeegPasswoort
+Name[ne]=अवैध पासवर्ड
+Name[nl]=Ongeldig wachtwoord
+Name[nn]=Ugyldig passord
+Name[nso]=Lentsuphetiso gase la Nnete
+Name[pa]=ਗਲਤ ਗੁਪਤ-ਕੋਡ
+Name[pl]=Błędne hasło
+Name[pt_BR]=Senha inválida
+Name[ro]=Parolă eronată
+Name[ru]=Неверный пароль
+Name[se]=Gustomeahttun beassansátni
+Name[sk]=Zlé heslo
+Name[sl]=Neveljavno geslo
+Name[sr]=Погрешна лозинка
+Name[sr@Latn]=Pogrešna lozinka
+Name[sv]=Ogiltigt lösenord
+Name[ta]=செல்லாத கடவுச்சொல்
+Name[tg]=Гузарвожаи Нодуруст
+Name[th]=รหัสผ่านไม่ถูกต้อง
+Name[tr]=Geçersiz Parola
+Name[uk]=НеправильнийПароль
+Name[ven]=Phasiwede asi yone
+Name[xh]=Igama lokugqitha Elingasebenziyo
+Name[zh_CN]=无效密码
+Name[zh_HK]=無效的密碼
+Name[zh_TW]=無效的密碼
+Name[zu]=IgamaEliyimfihloLokudlulaOkungasiyilona
+Comment=Invalid password
+Comment[af]=Ongeldige wagwoord
+Comment[ar]=كلمة مرور غير صالحة
+Comment[be]=Няправільны пароль
+Comment[bg]=Невалидна парола
+Comment[bn]=অবৈধ পাসওয়ার্ড
+Comment[br]=Tremenger siek
+Comment[bs]=Neispravna šifra
+Comment[ca]=Contrasenya no vàlida
+Comment[cs]=Neplatné heslo
+Comment[cy]=Cyfrinair annilys
+Comment[da]=Ugyldigt kodeord
+Comment[de]=Ungültiges Passwort
+Comment[el]=Μη έγκυρος κωδικός πρόσβασης
+Comment[eo]=nevalida pasvorto
+Comment[es]=Contraseña errónea
+Comment[et]=Vale parool
+Comment[eu]=Baliogabeko pasahitza
+Comment[fa]=اسم‌ رمز نامعتبر
+Comment[fi]=Virheellinen salasana
+Comment[fr]=Mot de passe non valable
+Comment[ga]=Focal faire neamhbhailí
+Comment[gl]=Contraseña errónea
+Comment[he]=הסיסמה שגויה
+Comment[hi]=अवैध पासवर्ड
+Comment[hr]=Nevažeća šifra
+Comment[hu]=Érvénytelen jelszó
+Comment[is]=Lykilorð ógilt
+Comment[it]=Password non valida
+Comment[ja]=不正なパスワード
+Comment[ka]=არასწორი პაროლი
+Comment[kk]=Жарамсыз пароль
+Comment[km]=ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ
+Comment[lt]=Neteisingas slaptažodis
+Comment[mk]=Невалидна лозинка
+Comment[mn]=Буруу нууц үг
+Comment[ms]=Kata laluan tidak sah
+Comment[mt]=Password ħażin
+Comment[nb]=Ugyldig passord
+Comment[nds]=Leeg Passwoort
+Comment[ne]=अवैध पासवर्ड
+Comment[nl]=Ongeldig wachtwoord
+Comment[nn]=Ugyldig passord
+Comment[nso]=Lentsuphetiso gase la nnete
+Comment[pa]=ਗਲਤ ਗੁਪਤ-ਕੋਡ
+Comment[pl]=Błędne hasło
+Comment[pt]=Senha inválida
+Comment[pt_BR]=senha inválida
+Comment[ro]=Parolă eronată
+Comment[ru]=Неверный пароль
+Comment[se]=Gustomeahttun beassansátni
+Comment[sk]=Zlé heslo
+Comment[sl]=Neveljavno geslo
+Comment[sr]=Погрешна лозинка
+Comment[sr@Latn]=Pogrešna lozinka
+Comment[sv]=Ogiltigt lösenord
+Comment[ta]=செல்லாத கடவுச்சொல்
+Comment[tg]=Гузарвожаи нодуруст
+Comment[th]=รหัสผ่านไม่ถูกต้อง
+Comment[tr]=Geçersiz parola
+Comment[uk]=Невірний пароль
+Comment[uz]=Maxfiy soʻz haqiqiy emas
+Comment[uz@cyrillic]=Махфий сўз ҳақиқий эмас
+Comment[ven]=Phasiwede isa shumi
+Comment[wa]=Sicret nén valide
+Comment[xh]=Igama lokugqitha elingasebenziyo
+Comment[zh_CN]=无效密码
+Comment[zh_HK]=無效的密碼
+Comment[zh_TW]=無效的密碼
+Comment[zu]=Igama elifihlikeli
+default_presentation=4
+
+[InvalidPasswordInvitations]
+Name=InvalidPasswordInvitations
+Name[ar]=دعوات كلمات مرور غير صالحة
+Name[bg]=Получи се покана с невалидна парола
+Name[bn]=অবৈধ পাসওয়ার্ড আমন্ত্রণ
+Name[ca]=Contrasenya convidats no vàlides
+Name[cs]=Neplatné hesla výzev
+Name[cy]=GwahoddiadauCyfrinairAnnilys
+Name[da]=UgyldigtKodeordInvitationer
+Name[de]=UngültigePasswortAnfragen
+Name[el]=Μη έγκυρες προσκλήσεις κωδικού πρόσβασης
+Name[eo]=NevalidaPasvortoInvito
+Name[es]=Invitación de contraseñas erróneas
+Name[et]=Vale parool kutsed
+Name[eu]=Baliogabeko pasahitz gonbidapena
+Name[fa]=دعوتهای اسم‌ رمز نامعتبر
+Name[fr]=Invitations de mot de passe non valable
+Name[gl]=Invitación de Contraseñas inválidas
+Name[he]=סיסמת הזמנות שגויה
+Name[hi]=अवैध-पासवर्ड-निमंत्रण
+Name[hr]=KrivePizovniceŠifri
+Name[hu]=ÉrvénytelenJelszóMeghívások
+Name[is]=ÓgildLykilorðsBoð
+Name[it]=Invito password non valida
+Name[ja]=不正なパスワードの招待
+Name[kk]=Жарамсыз сұралған пароль
+Name[km]=ពាក្យ​សម្ងាត់​អញ្ជើញ​មិន​ត្រឹមត្រូវ
+Name[lt]=Neteisingo slaptažodžio kvietimai
+Name[mk]=Невалидна лозинка на поканите
+Name[mn]=Буруу нууц үгээр орох
+Name[ms]=Jemputan Kata Laluan Tidak Sah
+Name[mt]=PasswordĦażinaStediniet
+Name[nb]=Ugyldig passord ved invitasjon
+Name[nds]=LeegPasswoortinladen
+Name[ne]=अवैध पासवर्ड निमन्त्रणा
+Name[nl]=Ongeldige wachtwoordaanvragen
+Name[nn]=Ugyldige passordinvitasjonar
+Name[nso]=Ditaletso tsa Mantsuphetiso tseo esego tsa Nnete
+Name[pl]=Informacja o błędnym haśle
+Name[pt_BR]=Aviso de senha inválida
+Name[ru]=Неверный запрос пароля
+Name[se]=Gustomeahttun beassansátnebovdehusat
+Name[sk]=Zlé heslo pozvánky
+Name[sl]=Povabila z neveljavnimi gesli
+Name[sr]=Погрешни позиви са лозинкама
+Name[sr@Latn]=Pogrešni pozivi sa lozinkama
+Name[sv]=Ogiltigt lösenord vid inbjudan
+Name[ta]=செல்லாத அழைப்பிதழ் கடவுச்சொல்
+Name[tg]=Дархости Нодурусти Гузарвожа
+Name[tr]=Geçersiz Parola İsteği
+Name[uk]=ЗапрошенняЗНевірнимПаролем
+Name[ven]=Mbidzo ya phasiwede isi yone
+Name[xh]=IzimemoZegamalokugqithaEzingasebebenziyo
+Name[zh_CN]=无效密码邀请
+Name[zh_HK]=無效的密碼邀請函
+Name[zh_TW]=無效的密碼邀請函
+Name[zu]=IsimemoSegamaEliyimfihloLokudlulaOkungasiyilona
+Comment=The invited party sent an invalid password. Connection refused.
+Comment[af]=Die uitgenooi party gestuur 'n ongeldige wagwoord. Verbinding geweier.
+Comment[ar]=الجهة المدعوة أرسلت كلمة مرور غير صالحة. الاتصال رُفض
+Comment[bg]=Получи се покана с невалидна парола
+Comment[bn]=আমন্ত্রিত দল একটি অবৈধ পাসওয়ার্ড পাঠাল। সংযোগ অস্বীকার করা হল।
+Comment[bs]=Pozvana strana je poslala neispravnu šifru. Konekcija je odbijena.
+Comment[ca]=La part invitada ha enviat una contrasenya no vàlida. Connexió refusada.
+Comment[cs]=Pozvaná strana poslala neplatné heslo. Spojení odmítnuto.
+Comment[cy]=Anfonodd y person gwahodd cyfrinair annilys. Gwrthodwyd y cysylltiad.
+Comment[da]=Den inviterede part sendte et ugyldigt kodeord. Forbindelse afslået.
+Comment[de]=Die eingeladene Partei hat ein ungültiges Passwort gesendet: Verbindung abgelehnt.
+Comment[el]=Η πλευρά που προσκλήθηκε έστειλε μη έγκυρο κωδικό πρόσβασης. Η σύνδεση απορρίφθηκε.
+Comment[eo]=La invitita kliento sendis nevalidan pasvorton. Konekto rifuzita.
+Comment[es]=La parte invitada envió una contraseña incorrecta. Conexión rechazada.
+Comment[et]=Kutsutu saatis vigase parooli. Ühendusest keelduti.
+Comment[eu]=Gonbidatutako parekoak baliogabeko pasahitza bidali du. Konexioa ukatu da.
+Comment[fa]=شخص دعوت‌شده اسم‌ رمز نامعتبری را ارسال کرد. اتصال پذیرفته نشد.
+Comment[fi]=Kutsuttu taho lähetti virheellisen salasanan. Yhteys hylättiin.
+Comment[fr]=La partie invitée a envoyé un mot de passe non valable. Connexion refusée.
+Comment[gl]=O invitado mandou unha contraseña inválida. A conexión foi rexeitada
+Comment[he]=הצד המוזמן שלח סיסמה שגויה. החיבור נדחה.
+Comment[hi]=निमंत्रित पार्टी ने अवैध पासवर्ड भेजा. कनेक्शन अस्वीकृत.
+Comment[hr]=Stranka koju ste pozvali je poslala nevažeću šifru. Veza odbijena.
+Comment[hu]=A meghívott fél érvénytelen jelszót küldött. A csatlakozás nem sikerült.
+Comment[is]=Boðinn aðili sendi ógilt lykilorð. Tengingu hafnað
+Comment[it]=La parte invitata ha inviato una password non valida. Connessione rifiutata.
+Comment[ja]=招待された人が不正なパスワードを送ってきました。接続を拒否しました。
+Comment[ka]=დაპატიჟებულმა არასწორი პაროლი გამოაგზავნა.
+Comment[kk]=Кірмек тұлға жарамсыз парольді келтірді. Қосылым болмады.
+Comment[km]=ភាគី​ដែល​បាន​អញ្ជើញ បាន​ផ្ញើ​ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ ។ ការ​តភ្ជាប់​ត្រូវ​បាន​បដិសេធ ។
+Comment[lt]=Pakviestoji pusė atsiuntė neteisingą slaptažodį. Ryšys nutrauktas.
+Comment[mk]=Поканетата страна испрати невалидна лозинка. Поврзувањето е одбиено.
+Comment[mn]=Буруу нууц үгийг уригдсан хэсэг илгээв. Холболт зөвшөөрөгдсөнгүй
+Comment[ms]=Pihak yang dijemput telah menghantar kata laluan yang salah. Sambungan ditolak.
+Comment[mt]=Il-persuna mistiedna bagħtet password ħażin. Konnessjoni miċħuda.
+Comment[nb]=Den inviterte parten sendte ugyldig passord. Oppkobling avvist.
+Comment[nds]=De inlaadt Deel hett en leeg Passwoort sendt. Verbinnen torüchwiest.
+Comment[ne]=निमन्त्रणा गरेको पार्टीले एउटा अवैध पासवर्ड पठायो । जडान अस्वीकार गरियो ।
+Comment[nl]=De uitgenodigde partij stuurde een ongeldig wachtwoord. Verbinding geweigerd.
+Comment[nn]=Den inviterte parten sende eit ugyldig passord. Sambandet vart nekta.
+Comment[nso]=Sehlopha seo se memilwego se romela lentsuphetiso leo esego la nnete. Kgokagano e gannwe.
+Comment[pl]=Z drugiej strony podano błędne hasło. Połączenie odrzucone.
+Comment[pt]=O convidado enviou uma senha inválida. A ligação foi recusada.
+Comment[pt_BR]=A parte "convidada" enviou uma senha inválida. Conexão recusada.
+Comment[ru]=Удалённый пользователь ввёл неверный пароль. В доступе отказано.
+Comment[se]=Bovdejuvvon bealli sáddii gustomeahttun beassansáni. Oktavuohta hilgojuvui.
+Comment[sk]=Pozvaný účastnik poslal zlé heslo. Spojenie zamietnuté.
+Comment[sl]=Povabljena stranka je poslala neveljavno geslo. Povezava zavrnjena.
+Comment[sr]=Позвана странка је послала погрешну лозинку. Веза је одбијена.
+Comment[sr@Latn]=Pozvana stranka je poslala pogrešnu lozinku. Veza je odbijena.
+Comment[sv]=Den inbjudna personen skickade ett ogiltigt lösenord. Anslutning vägrades.
+Comment[ta]=அழைத்த நபர் தவறான கடவுச்சொல்லை அனுப்பியுள்ளார். இணைப்பு நிராகரிக்கப்பட்டது.
+Comment[tg]=Корванди дурдаст гузарвожаи нодурустро фиристод. Пайвастшавӣ манъ шудааст.
+Comment[th]=ผู้เข้าร่วมการเชิญชวนส่งรหัสผ่านมาไม่ถูกต้อง ทำการปฏิเสธการเชื่อมต่อ
+Comment[tr]=Davet edilenden gönderilmiş geçersiz parola. Bağlantı rededildi.
+Comment[uk]=Запрошена сторона надіслала невірний пароль. У з'єднанні відмовлено.
+Comment[ven]=Murado o rambiwaho o rumela phasiwede isa shumi. Vhukwamani ho hanwa.
+Comment[xh]=Umhlangano omenyiweyo uthumele igama lokugqitha elisebenzayo. Uxhulumano lwa liwe.
+Comment[zh_CN]=受邀请方发送的密码不对。连接被拒绝。
+Comment[zh_HK]=被邀請的一方送出無效的密碼。已拒絕連線。
+Comment[zh_TW]=被邀請的一方送出無效的密碼。已拒絕連線。
+Comment[zu]=Ingxenye emenyiwe ithumele igama lokungena alivunyelwanga. Ukuxhumana kwaliwe.
+default_presentation=2
+
+[NewConnectionOnHold]
+Name=NewConnectionOnHold
+Name[ar]=اتصال جديد على الانتظار
+Name[bg]=Получи се нова заявка за връзка
+Name[bn]=নতুন সংযোগ ধরে রাখা
+Name[ca]=Nova connexió en espera
+Name[cs]=Nové spojení pozdrženo
+Name[cy]=CysylltiadNewyddArArfael
+Name[da]=NyForbindelseSatPåHold
+Name[de]=NeueVerbindungWartet
+Name[el]=Νέα σύνδεση σε αναμονή
+Name[eo]=NovaKonektoAtendante
+Name[es]=Nueva conexión en espera
+Name[et]=Uus ühendus ootel
+Name[eu]=Konexio berria itxarote moduan
+Name[fa]=اتصال جدید نگه‌داشته
+Name[fr]=Nouvelle connexion au raccroché
+Name[ga]=CeangalNuaAgFanacht
+Name[gl]=Conexión en espera
+Name[he]=חיבור חדש בהמתנה
+Name[hi]=नया-कनेक्शन-आन-होल्ड
+Name[hr]=NovaVezaNaČekanju
+Name[hu]=ÚjKapcsolatTartva
+Name[is]=NýTengingÁBið
+Name[it]=Nuova connessione da tenere
+Name[ja]=保留中の新規接続
+Name[kk]=Жаңа қосылым талап етілуде
+Name[km]=ការ​ត​ភ្ជាប់​ថ្មី កំពុង​ស្ថិត​នៅ​ក្នុង​ការ​រង់​ចាំ
+Name[lt]=Naujas kvietimas ryšiui sulaikytas
+Name[mk]=Нова врска на чекање
+Name[mn]=Шинэ холболт тогтоов
+Name[ms]=Sambungan Baru Menunggu
+Name[mt]=KonnessjoniĠdidaMiżmuma
+Name[nb]=Ny oppkobling venter
+Name[nds]=NiegVerbinnenTöövt
+Name[ne]=समातिएको नयाँ जडान
+Name[nl]=Nieuwe verbinding is wachtende
+Name[nn]=Nytt samband ventar
+Name[nso]=Kgokagano ye Ntshwa e Emisitswe
+Name[pl]=Nowe połączenie wstrzymane
+Name[pt_BR]=Nova Conexão
+Name[ro]=Conexiune nouă în aşteptare
+Name[ru]=Новое соединение отключено
+Name[se]=Ođđa oktavuohta vuordimin
+Name[sk]=Nové spojenie podržané
+Name[sl]=Nova povezava na čakanju
+Name[sr]=Нова веза је на чекању
+Name[sr@Latn]=Nova veza je na čekanju
+Name[sv]=Ny anslutning väntar
+Name[ta]=புதிய இணைப்பு வைக்கப்பட்டது
+Name[tg]=Пайвастшавии Нав Нигоҳ дошта мешавад
+Name[tr]=Açık Yeni Bağlantı
+Name[uk]=ОчікуютьНовіЗ'єднання
+Name[ven]=Vhukwamani vhuswa ho imiswa
+Name[xh]=Uxhulumano Olutsha Lumisiwe
+Name[zh_CN]=新连接暂时搁置
+Name[zh_HK]=保持的新連線
+Name[zh_TW]=保持的新連線
+Name[zu]=UkuxhumanisaOkushaKubanjiwe
+Comment=Connection requested, user must accept
+Comment[af]=Verbinding versoekte, gebruiker moet aanvaar
+Comment[ar]=طلب اتصال, يجب أن يقبل المستخدم
+Comment[be]=Запыт злучэння, неабходнае пацвярджэнне
+Comment[bg]=Получи се нова заявка за връзка
+Comment[bn]=সংযোগ অনুরোধ করা হল, ব্যবহারকারীকে অবশ্যই স্বীকার করতে হবে
+Comment[bs]=Zatražena konekcija, korisnik mora prihvatiti
+Comment[ca]=Connexió sol·licitada, l'usuari ha d'acceptar-la
+Comment[cs]=Vyžadováno spojení, uživatel musí přijmout
+Comment[cy]=Cais wedi'i wneud am gysylltiad,rhaid i'r ddefnyddiwr ei dderbyn
+Comment[da]=Forbindelse forespurgt, bruger skal acceptere
+Comment[de]=Verbindungsanfrage, Benutzer muss bestätigen
+Comment[el]=Αιτήθηκε σύνδεση, ο χρήστης πρέπει να αποδεχθεί
+Comment[eo]=Konekto pridemandita, uzanto devas akcepti
+Comment[es]=Conexión solicitada, el usuario debe aceptar
+Comment[et]=Nõutakse ühendust, kasutaja peab seda lubama
+Comment[eu]=Konexioa eskatu da, erabiltzaileak onartu behar du
+Comment[fa]=اتصال درخواست شد، کاربر باید بپذیرد
+Comment[fi]=Pyydettiin yhteyttä, käyttäjän tulee hyväksyä
+Comment[fr]=Connexion demandée, l'utilisateur doit accepter
+Comment[ga]=Ceangal iarrtha; ní mór leis an úsáideoir glacadh leis
+Comment[gl]=Petición de conexión en curo. O usuario ten que aceptar
+Comment[he]=נתבקש חיבור, על המשתמש לקבלו
+Comment[hi]=कनेक्शन निवेदित. उपयोक्ता को स्वीकार होना चाहिए
+Comment[hr]=Veza je zatražena, korisnik mora prihvatiti
+Comment[hu]=Csatlakozási kérés, megerősítés szükséges
+Comment[is]=Beiðni um tengingu, notandi verður að samþykkja
+Comment[it]=Connessione richiesta, l'utente deve accettare
+Comment[ja]=接続が要求されています。ユーザが許可しなければなりません。
+Comment[ka]=კავშირის მოთხოვნა, მომხმარებელმა უნდა დაადასტუროს
+Comment[kk]=Қосылым талабы келді, пайдаланушы қабылдау керек
+Comment[km]=បាន​ស្នើ​ការ​ត​ភ្ជាប់​,​ អ្នក​ប្រើ​ត្រូវ​តែ​ទទួលយក
+Comment[lt]=Kvietimas ryšiui išsiųstas, naudotojas turi priimti kvietimą
+Comment[mk]=Побарано е поврзување, корисникот мора да прифати
+Comment[mn]=Холболт хүсэж байна, хэрэглэгч зөвшөөрөх ёстой
+Comment[ms]=Sambungan diminta, pengguna mesti menerima
+Comment[mt]=Konnessjoni mitluba, user irid jaċċetta
+Comment[nb]=Oppkobling ønskes, bruker må akseptere
+Comment[nds]=Tokoppelanfraag, Nafraag bi Bruker
+Comment[ne]=जडान अनुरोध गरियो, प्रयोगकर्ताले स्वीकार गर्नुपर्छ
+Comment[nl]=Verbinding verzocht, gebruiker dient te accepteren
+Comment[nn]=Samband førespurd, brukar må godta
+Comment[nso]=Kgokagano e kgopetswe, modirisi o swanetse go dumela
+Comment[pl]=Próba połączenia, musi być zaakceptowana przez użytkownika
+Comment[pt]=A ligação foi pedida e o utilizador deve aceitar
+Comment[pt_BR]=Conexão requisitada; o usuário deve aceitar
+Comment[ro]=Cerere de conectare; utilizatorul trebuie să accepte
+Comment[ru]=Запрос на соединение, требуется подтверждение пользователя
+Comment[se]=Oktavuohta jearahuvui, geavaheaddji ferte dohkkehit
+Comment[sk]=Vyžiadané spojenie, užívateľ musí akceptovať
+Comment[sl]=Povezava zahtevana, uporabnik mora sprejeti
+Comment[sr]=Захтевана је веза, корисник мора да је прихвати
+Comment[sr@Latn]=Zahtevana je veza, korisnik mora da je prihvati
+Comment[sv]=Anslutning begärd, användaren måste acceptera
+Comment[ta]=இணைப்பு கோரப்பட்டது, பயனர் கண்டிப்பாக ஏற்றுக்கொள்ள வேண்டும்
+Comment[tg]=Пайвастшавӣ дархоста шудааст, корванд бояд қабул кунад
+Comment[th]=มีการร้องขอเชื่อมต่อ ผู้ใช้ต้องทำการยอมรับ
+Comment[tr]=Bağlantı isteği, kullanıcı kabul etmeli
+Comment[uk]=Запрошено з'єднання, користувач має прийняти
+Comment[ven]=Vhukwamani ho humbelwa, mushumisi u fanela u tanganedza
+Comment[xh]=Uxhulumaniso luceliwe, umsebenzisi kufanele amkele
+Comment[zh_CN]=连接已请求,用户必须接受
+Comment[zh_HK]=已請求連線,用戶必須接受
+Comment[zh_TW]=已請求連線,使用者必須接受
+Comment[zu]=Ukuxhumanisa kuceliwe, umsebenzi kumele ivunyelwe
+default_presentation=4
+
+[NewConnectionAutoAccepted]
+Name=NewConnectionAutoAccepted
+Name[ar]=اتصال جديد مقبول تلقائياً
+Name[bg]=Нова връзка е установена автоматично
+Name[bn]=নতুন সংযোগ স্বয়ংক্রীয়ভাবে স্বীকৃত
+Name[ca]=Nova connexió auto-acceptada
+Name[cs]=Nové spojení automaticky přijato
+Name[cy]=CysylltiadNewyddAwtoDerbyn
+Name[da]=NyForbindelseAutomatiskAccepteret
+Name[de]=NeueVerbindungAutomatischAkzeptiert
+Name[el]=Αυτόματη αποδοχή νέας σύνδεσης
+Name[eo]=NovaKonektoAŭtomateAkceptita
+Name[es]=Nueva conexión auto aceptada
+Name[et]=Uue ühendusega automaatselt nõus
+Name[eu]=Konexio berria auto onartu da
+Name[fa]=پذیرش خودکار اتصال جدید
+Name[fr]=Nouvelle connexion auto-acceptée
+Name[gl]=Nova conexión aceptada automáticamente
+Name[he]=חיבור חדש נתקבל אוטומטית
+Name[hi]=नया-कनेक्शन-स्वचलित-स्वीकारा
+Name[hr]=NovaVezaAutoPrihvaćena
+Name[hu]=ÚjKapcsolatAutoElfogadva
+Name[is]=NýTengingSjálfvirktSamþykkt
+Name[it]=Accettata nuova connessione automatica
+Name[ja]=新規接続の自動受け入れ
+Name[kk]=Жаңа қосылым авто қабылданды
+Name[km]=បាន​ទទួល​យក​ការ​ត​ភ្ជាប់​ថ្មី​ដោយ​ស្វ័យ​ប្រវត្តិ
+Name[lt]=Naujas kvietimas ryšiui automatiškai priimtas
+Name[mk]=Ново поврзување автоматски прифатено
+Name[mn]=Шинэ холболтыг автоматаар зөвшөөрөв
+Name[ms]=Sambungan Baru Diterima Auto
+Name[mt]=KonnessjoniĠdidaAwtoAċċettata
+Name[nb]=Ny oppkobling tas imot automatisk
+Name[nds]=NiegVerbinnenAutomaatschTolaten
+Name[ne]=नयाँ जडान स्वत: स्वीकार गरियो
+Name[nl]=Nieuwe verbinding automatisch geaccepteerd
+Name[nn]=Nytt samband automatisk godteke
+Name[nso]=Kgokagano ye Ntshwa yago Itirisa e Amogetswe
+Name[pl]=Nowe połączenie automatycznie przyjęte
+Name[pt_BR]=Nova Conexão com aceitação automática
+Name[ro]=Conexiune nouă acceptată automat
+Name[ru]=Соединение создаётся автоматически
+Name[se]=Ođđa oktavuohta dohkkehuvui automáhtalaččat
+Name[sk]=Nové spojenie automaticky akceptované
+Name[sl]=Nova povezava samodejno sprejeta
+Name[sr]=Нова веза је аутоматски прихваћена
+Name[sr@Latn]=Nova veza je automatski prihvaćena
+Name[sv]=Ny anslutning accepterades automatiskt
+Name[ta]=புதிய இணைப்புக்கள் தானாக ஏற்பட்டது
+Name[tg]=Пайвастшавии Нав ба таври Худкор Пазируфта мешавад
+Name[th]=รับการเชื่อมต่ออัตโนมัติ
+Name[tr]=Otomatik Kabul Edilen Yeni Bağlantı
+Name[uk]=НовіЗ'єднанняАвтоматичноПрийняті
+Name[ven]=Vhukwamani vhuswa ho tanganedzhwa
+Name[xh]=Uxhulumano Olutsha Lwamkelwe Ngokuzenzekelayo
+Name[zh_CN]=新连接自动接受
+Name[zh_HK]=自動接受的新連線
+Name[zh_TW]=自動接受的新連線
+Name[zu]=UkuxhumanisaOkushaKokuzenzakalelaKuvunyelwe
+Comment=New connection automatically established
+Comment[af]=Nuwe verbinding automaties vasgestel
+Comment[ar]=اتصالات جديدة أُنشئت تلقائياً
+Comment[be]=Новае злучэнне аўтаматычна ўстаноўленае
+Comment[bg]=Нова връзка е установена автоматично
+Comment[bn]=নতুন সংযোগ স্বয়ংক্রীয়ভাবে স্থাপন করা হল
+Comment[bs]=Automatski uspostavljena nova konekcija
+Comment[ca]=Nova connexió establerta automàticament
+Comment[cs]=Automaticky navázáno nové spojení
+Comment[cy]=Sefydlwyd cysylltiad newydd yn awtomatig
+Comment[da]=Ny forbindelse automatisk etableret
+Comment[de]=Neue Verbindung automatisch hergestellt
+Comment[el]=Νέα σύνδεση αυτόματα αποκαταστάθηκε
+Comment[eo]=Nova konekto aŭtomate akceptita
+Comment[es]=Nueva conexión establecida automáticamente
+Comment[et]=Uus ühendus automaatselt loodud
+Comment[eu]=Konexio berria automatikoki ezarri da
+Comment[fa]=اتصال جدید به طور خودکار برقرار شد
+Comment[fi]=Uusi yhteys muodostettu automaattisesti
+Comment[fr]=Nouvelle connexion établie automatiquement
+Comment[ga]=Ceangal nua bunaithe go huathoibríoch
+Comment[gl]=Nova conexión automáticamente establecida
+Comment[he]=נוצר חיבור חדש באופן אוטומטי
+Comment[hi]=नया कनेक्शन स्वचलित स्थापित
+Comment[hr]=Nova veza automatski prihvaćena
+Comment[hu]=Automatikusan létrejött az új kapcsolat
+Comment[is]=Nýjar tengingar sjálfkrafa samþykktar
+Comment[it]=Stabilita nuova connessione automaticamente
+Comment[ja]=新規接続を自動的に確立しました
+Comment[ka]=ახალი კავშირი ავტომატურად დამყარდა
+Comment[kk]=Жаңа қосылым автоматты түрде орнатылды
+Comment[km]=បាន​បង្កើត​ការ​ត​ភ្ជាប់​ថ្មី​ដោយ​ស្វ័យ​ប្រវត្តិ
+Comment[lt]=Naujas ryšys užmegztas automatiškai
+Comment[mk]=Автоматски е воспоставено ново поврзување
+Comment[mn]=Шинэ холболт автоматаар тавигдав
+Comment[ms]=Sambungan baru secara automatik terjalin
+Comment[mt]=Konnessjoni ġdida aċċettata awtomatikament
+Comment[nb]=Ny oppkobling automatisk opprettet
+Comment[nds]=Nieg Verbinnen automaatsch inricht
+Comment[ne]=नयाँ जडान स्वचालित रूपमा स्थापित भयो
+Comment[nl]=Nieuwe verbinding automatisch opgebouwd
+Comment[nn]=Nytt samband automatisk oppretta
+Comment[nso]=Kgokagano ye ntshwa e hlagisitswe kago itirsa
+Comment[pl]=Nowe połączenie ustanowiono automatycznie
+Comment[pt]=A nova ligação foi estabelecida automaticamente
+Comment[pt_BR]=Nova conexão estabelecida automaticamente
+Comment[ro]=Conexiune nouă stabilită automat
+Comment[ru]=Новое соединение устанавливается автоматически
+Comment[se]=Ođđa oktavuohta automáhtalaččat váldui
+Comment[sk]=Nové spojenie automaticky vytvorené
+Comment[sl]=Nova povezava samodejno vzpostavljena
+Comment[sr]=Нова веза је аутоматски успостављена
+Comment[sr@Latn]=Nova veza je automatski uspostavljena
+Comment[sv]=Ny anslutning automatiskt upprättad
+Comment[ta]=இணைப்புகள் தானாக உருவாக்கப்பட்டது
+Comment[tg]=Пайвастшавии нав ба таври худкор барпо мегардад
+Comment[th]=เปิดการเชื่อมต่อใหม่อัตโนมัติ
+Comment[tr]=Yeni bağlantı otomatik olarak kuruldu
+Comment[uk]=Автоматично встановлено нове з'єднання
+Comment[ven]=Vhukwamani vhuswa ho itwa na zwenezwo
+Comment[xh]=Uxhulumaniso olutsha lufunyenwe ngokuzenzekelayo
+Comment[zh_CN]=自动建立新连接
+Comment[zh_HK]=已自動建立新連線
+Comment[zh_TW]=已自動建立新連線
+Comment[zu]=Ukuxhumana okusha kuyazisungulela
+default_presentation=4
+
+[TooManyConnections]
+Name=TooManyConnections
+Name[ar]=اتصالات عديدة جداً
+Name[bg]=Получиха се твърде много връзки
+Name[bn]=অত্যাধিক সংযোগ
+Name[br]=Re gevreadurioù zo
+Name[ca]=Masses connexions
+Name[cs]=Příliš mnoho spojení
+Name[cy]=GormodOGysylltiadau
+Name[da]=ForMangeForbindelser
+Name[de]=ZuVieleVerbindungen
+Name[el]=Πάρα πολλές συνδέσεις
+Name[eo]=TroMultajKonektoj
+Name[es]=Demasiadas conexiones
+Name[et]=Liiga palju ühendusi
+Name[eu]=Konexio gehiegi
+Name[fa]=اتصالات زیاد
+Name[fr]=Trop de connexions
+Name[ga]=AnIomarcaCeangal
+Name[gl]=Demasiadas conexións
+Name[he]=יותר מדיי חיבורים
+Name[hi]=Tबहुत-सारे-कनेक्शन
+Name[hr]=PrevišeVeza
+Name[hu]=TúlSokKapcsolat
+Name[is]=OfMargarTengingar
+Name[it]=Troppe Connessioni
+Name[ja]=多すぎる接続
+Name[kk]=Қосылымдар тым көп
+Name[km]=ការ​ត​ភ្ជាប់​ច្រើន​ពេក
+Name[lt]=Per daug užmegztų ryšių
+Name[mk]=Премногу поврзувања
+Name[mn]=Дэндүү олон холболт
+Name[ms]=Terlalu Banyak Sambungan
+Name[mt]=WisqKonnessjonijiet
+Name[nb]=For mange oppkoblinger
+Name[nds]=ToVeleVerbinnen
+Name[ne]=अति धेरै जडान
+Name[nl]=Teveel verbindingen
+Name[nn]=For mange samband
+Name[nso]=Dikgokagano tse Ntshi Kudu
+Name[pl]=Zbyt wiele połączeń
+Name[pt_BR]=Conexões em excesso
+Name[ro]=Prea multe conexiuni
+Name[ru]=Слишком много соединений
+Name[se]=Menddo ollu oktavuođat
+Name[sk]=Príliš veľa spojení
+Name[sl]=Preveč povezav
+Name[sr]=Исувише много веза
+Name[sr@Latn]=Isuviše mnogo veza
+Name[sv]=För många anslutningar
+Name[ta]=பல இணைப்புக்கள்
+Name[tg]=Аз Ҳад Зиёд Пайвастагиҳо
+Name[th]=มีการเชื่อมต่อมากเกินไป
+Name[tr]=ÇokFazlaBağlantı
+Name[uk]=ЗабагатоЗ'єднань
+Name[ven]=Vhukwamani vhunzhi
+Name[xh]=Uxhulumaniso Oluninzi Kakhulu
+Name[zh_CN]=连接太多
+Name[zh_HK]=太多連線
+Name[zh_TW]=太多連線
+Name[zu]=UkuxhumanaOkuningi
+Comment=Busy, connection refused
+Comment[af]=Besig, verbinding geweier
+Comment[ar]=مشغول , الاتصال رُفض
+Comment[be]=Занята, адмоўлена злучэнню
+Comment[bg]=Получиха се твърде много връзки
+Comment[bn]=ব্যস্ত, সংযোগ অস্বীকার করল
+Comment[br]=Dalc'het, kevreadenn disteuleret
+Comment[bs]=Zauzet, konekcija odbijena
+Comment[ca]=Ocupat, connexió refusada
+Comment[cs]=Zaneprázdněn, spojení odmítnuto
+Comment[cy]=Prysur, gwrthodwyd y cysylltiad
+Comment[da]=Optaget, forbindelse afslået
+Comment[de]=Beschäftigt, Verbindung abgelehnt
+Comment[el]=Απασχολημένο, η σύνδεση απορρίφθηκε
+Comment[eo]=Laborante, konekto rifuzita
+Comment[es]=Ocupado, conexión rechazada
+Comment[et]=Hõivatud, ühendusest keelduti
+Comment[eu]=Lanpetuta, konexioa ukatu da
+Comment[fa]=اشغال، اتصال پذیرفته نشد
+Comment[fi]=Varattu, yhteys hylättiin
+Comment[fr]=Occupé, connexion refusée
+Comment[ga]=Gnóthach; ceangal diúltaithe
+Comment[gl]=Ocupado, conexión rexeitada
+Comment[he]=תפוס, החיבור נדחה
+Comment[hi]=व्यस्त, कनेक्शन अस्वीकृत
+Comment[hr]=Zauzeto, veza odbijena
+Comment[hu]=Foglalt, a csatlakozási kérés visszautasítva
+Comment[is]=Uptekinn, tengingu hafnað
+Comment[it]=Occupato, connessione rifiutata
+Comment[ja]=ビジーです、接続を拒否しました
+Comment[ka]=დაკავებული, კავშირი უარყოფილია
+Comment[kk]=Бос емес, қосылым болмады
+Comment[km]=រវល់​,​បោះបង់​ការ​ត​ភ្ជាប់
+Comment[lt]=Užimta, kvietimas ryšiui atmestas
+Comment[mk]=Зафатено, поврзувањето е одбиено
+Comment[mn]=Шугам Чөлөөгүй, холболт зөвшөөрөгдсөнгүй
+Comment[ms]=Sibuk, sambungan ditolak
+Comment[mt]=Okkupat, konnessjoni miċħuda
+Comment[nb]=Opptatt, oppkobling avvist
+Comment[nds]=Bunnen, Verbinnen torüchwiest
+Comment[ne]=व्यस्त, जडान अस्वीकार गरियो
+Comment[nl]=Bezig, verbinding geweigerd
+Comment[nn]=Oppteken, samband nekta
+Comment[nso]=E swaregile, kgokagano e gannwe
+Comment[pl]=Zajęte, połączenie odrzucone
+Comment[pt]=Ocupado, a ligação foi recusada
+Comment[pt_BR]=Ocupado; conexão recusada
+Comment[ro]=Ocupat; conexiune refuzată
+Comment[ru]=Занято, соединение закрыто
+Comment[sk]=Zaneprázdneny, spojenie odmietnuté
+Comment[sl]=Zaposlen, povezava zavrnjena
+Comment[sr]=Заузето, веза је одбијена
+Comment[sr@Latn]=Zauzeto, veza je odbijena
+Comment[sv]=Upptagen, anslutning vägras
+Comment[ta]=வேலையில் உள்ளது, இணைப்பு நிராகரிக்கப்பட்டது
+Comment[tg]=Банд, пайвастшавӣ рад гардидааст
+Comment[th]=ยังไม่ว่าง ทำการปฏิเสธการเชื่อมต่อ
+Comment[tr]=Meşgul, bağlantı rededildi
+Comment[uk]=Зайнято, у з'єднанні відмовлено
+Comment[uz]=Band, aloqa rad etildi
+Comment[uz@cyrillic]=Банд, алоқа рад этилди
+Comment[ven]=U farakanea, vhukwamani ho hanwa
+Comment[xh]=Uxhulumaniso, olu xakekileyo lwaliwe
+Comment[zh_CN]=占线,连接拒绝
+Comment[zh_HK]=忙碌,已拒絕連線
+Comment[zh_TW]=忙碌,已拒絕連線
+Comment[zu]=Imatasa,ukuxhumana kwaliwe
+default_presentation=4
+default_logfile=
+
+[UnexpectedConnection]
+Name=UnexpectedConnection
+Name[ar]=اتصال غير متوقع
+Name[bg]=Получи се неочаквана връзка
+Name[bn]=অপ্রত্যাশিত সংযোগ
+Name[ca]=Connexió inesperada
+Name[cs]=Neočekávané spojení
+Name[cy]=CysylltiadAnnisgwyl
+Name[da]=UventetForbindelse
+Name[de]=UnerwarteteVerbindung
+Name[el]=Μη αναμενόμενη σύνδεση
+Name[eo]=NeatenditaKonekto
+Name[es]=Conexión inesperada
+Name[et]=Ootamatu ühendus
+Name[eu]=Ustekabeko konexioa
+Name[fa]=اتصال غیرمنتظره
+Name[fr]=Connexion inattendue
+Name[gl]=Conexión inesperada
+Name[he]=חיבור בלתי צפוי
+Name[hi]=अप्रत्याशित-कनेक्शन
+Name[hr]=NeočekivanaVeza
+Name[hu]=NemVártKapcsolat
+Name[is]=ÓvæntTenging
+Name[it]=Connessione inaspettata
+Name[ja]=予期しない接続
+Name[kk]=Күтілмеген қосылым
+Name[km]=ការ​ត​ភ្ជាប់​ដែល​មិន​បាន​រំពឹង​ទុក
+Name[lt]=Netikėtas prisijungimas
+Name[mk]=Неочекувано поврзување
+Name[mn]=Гэнэтийн Холболт
+Name[ms]=Sambungan Luar Jangka
+Name[mt]=KonnessjonijietMhuxMistennija
+Name[nb]=Uventet oppkobling
+Name[nds]=UnverwachtVerbinnen
+Name[ne]=अनपेक्षित जडान
+Name[nl]=Onverwachte verbinding
+Name[nn]=Uventa samband
+Name[nso]=Kgokagano yeo ebego esa Emelwa
+Name[pl]=Niespodziewane połączenie
+Name[pt_BR]=Conexão não-aceita
+Name[ro]=Conexiune neaşteptată
+Name[ru]=Неожиданное соединение
+Name[se]=Vuordekeahtes oktavuohta
+Name[sk]=Neočakávane spojenie
+Name[sl]=Nepričakovana povezava
+Name[sr]=Неочекивана веза
+Name[sr@Latn]=Neočekivana veza
+Name[sv]=Oväntad anslutning
+Name[ta]=பயனர் இணைப்பு ஏற்றுக்கொள்ளப்பட்டது
+Name[tg]=Пайвастшавии Ғайричашмдошт
+Name[th]=การเชื่อมต่อที่ไม่คาดหวัง
+Name[tr]=Beklenmedik Bağlantı
+Name[uk]=НеочікуванеЗ'єднання
+Name[ven]=Vhukwamani vhu songo lavhelelwaho
+Name[xh]=Uxhulumaniso Olungalindelwanga
+Name[zh_CN]=未料到的连接
+Name[zh_HK]=非預期的連線
+Name[zh_TW]=非預期的連線
+Name[zu]=UkuxhumanaOkungalindelwe
+Comment=Received unexpected connection, abort
+Comment[af]=Ontvang onverwagte verbinding, staak
+Comment[ar]=تم استلام اتصال غير متوقع , اقطع
+Comment[be]=Атрыманае нечаканае злучэнне
+Comment[bg]=Получи се неочаквана връзка
+Comment[bn]=অপ্রত্যাশিত সংযোগ গ্রহণ করল, বাতিল করুন
+Comment[bs]=Primio neočekivanu konekciju, prekidam
+Comment[ca]=Rebuda una connexió inesperada, avortant
+Comment[cs]=Obdrženo neočekávané spojení, přerušeno
+Comment[cy]=Derbynwyd cysylltiad annisgwyl,terfynu
+Comment[da]=Modtog uventet forbindelse, afbrød
+Comment[de]=Unerwartete Verbindung hergestellt, Abbruch
+Comment[el]=Λήψη μη αναμενόμενης σύνδεσης, εγκατάλειψη
+Comment[eo]=Ricevis neatenditan konekton, haltis
+Comment[es]=Recibida conexión inesperada, abortar
+Comment[et]=Saadi ootamatu ühendus, loobuti
+Comment[eu]=Ustegabeko konexioa jaso da, abortatzen
+Comment[fa]=اتصال غیرمنتظره پذیرفته شد، ساقط شد
+Comment[fi]=Vastaanotettiin odottamaton yhteys, lopeta
+Comment[fr]=Reçu une connexion inattendue, interruption
+Comment[gl]=Recibíuse unha conexión inesperada.
+Comment[he]=נתקבל חיבור בלתי צפוי, בוטל
+Comment[hi]=अप्रत्याशित कनेक्शन प्राप्त. छोड़ा
+Comment[hr]=Primio sam neočekivanu vezu, prekid
+Comment[hu]=Nem várt csatlakozási kérés, kilépés
+Comment[is]=Tók á móti óvæntri tengingu, hætti
+Comment[it]=Ricevuta connessione inaspettata, termina
+Comment[ja]=予期しない接続を受信しました。廃棄します。
+Comment[ka]=მოულოდნელი კავშირი მოვიდა, შესახებ
+Comment[kk]=Күтілмеген қосылым келді, доғарылды
+Comment[km]=បាន​ទទួលយក​ការ​ត​ភ្ជាប់​ដែល​មិន​បាន​រំពឹង​ទុក, ​បោះបង់
+Comment[lt]=Sulaukta netikėto prisijungimo, nutraukiama
+Comment[mk]=Примено е неочекувано поврзување, се прекинува
+Comment[mn]=Гэнэтийн холболтийг хүлээн авав.Аборт
+Comment[ms]=Menerima sambungan luar jangka, menamatkan
+Comment[mt]=Irċevejt konnessjoni mhux mistennija, ieqaf
+Comment[nb]=Mottok uventet oppkobling, avbryt
+Comment[nds]=Unverwacht Verbinnen kregen, afbraken
+Comment[ne]=अनपेक्षित जडान प्राप्त भयो, परित्याग गर्नुहोस्
+Comment[nl]=Ontving een onverwachte verbinding, gestopt
+Comment[nn]=Mottok uventa samband, avbryt
+Comment[nso]=Amogetse kgokagano yeo ebego esa emelwa, bolaya
+Comment[pl]=Otrzymano niespodziewane połączenie. Przerwane.
+Comment[pt]=Foi recebida uma ligação inesperada, a interromper
+Comment[pt_BR]=conexão recebida inesperadamente; abortar
+Comment[ro]=A fost recepţionată o conexiune neaşteptată şi a fost anulată
+Comment[ru]=Получено неожиданное соединение. Отключение
+Comment[se]=Oaččui vuordekeahtes oktavuođa, gaskkalduhte
+Comment[sk]=Prijaté neočakávane spojenie, ukončujem
+Comment[sl]=Prejeta nepričakovana povezava, prekinjeno
+Comment[sr]=Примљена је неочекивана веза, прекидам
+Comment[sr@Latn]=Primljena je neočekivana veza, prekidam
+Comment[sv]=Tog emot oväntad anslutning, avbryter
+Comment[ta]=எதிர்பாராத இணைப்பு, நிறுத்தப்பட்டது
+Comment[tg]=Пайвастшавии ғайричашмдош қабул гардид, кандашавӣ
+Comment[th]=ได้รับการเชื่อมต่อที่ไม่คาดหวัง ทำการยกเลิก
+Comment[tr]=Babul edilmiş beklenmedik bağlantı, durdur
+Comment[uk]=Отримано неочікуване з'єднання, скасовую
+Comment[ven]=Vhukwamani vhu songo lavhelelwaho ho tanganedzhwaho, litsha
+Comment[xh]=Ufumene uxhulumaniso olungalindelekanga, lahla
+Comment[zh_CN]=收到意外连接,中止
+Comment[zh_HK]=接收到非預期的連線,中止
+Comment[zh_TW]=接收到非預期的連線,放棄
+Comment[zu]=Isithole ukuxhumana okungalindelekanga, hushula
+default_presentation=4
+
diff --git a/krfb/krfb/eyes-closed24.png b/krfb/krfb/eyes-closed24.png
new file mode 100644
index 00000000..f8cd9adb
--- /dev/null
+++ b/krfb/krfb/eyes-closed24.png
Binary files differ
diff --git a/krfb/krfb/eyes-open.png b/krfb/krfb/eyes-open.png
new file mode 100644
index 00000000..b5a6328b
--- /dev/null
+++ b/krfb/krfb/eyes-open.png
Binary files differ
diff --git a/krfb/krfb/eyes-open24.png b/krfb/krfb/eyes-open24.png
new file mode 100644
index 00000000..860d6c7e
--- /dev/null
+++ b/krfb/krfb/eyes-open24.png
Binary files differ
diff --git a/krfb/krfb/invitation.cc b/krfb/krfb/invitation.cc
new file mode 100644
index 00000000..75c4758a
--- /dev/null
+++ b/krfb/krfb/invitation.cc
@@ -0,0 +1,125 @@
+/***************************************************************************
+ invitation.cpp
+ -------------------
+ begin : Sat Mar 30 2002
+ copyright : (C) 2002 by Tim Jansen
+ (C) Stefan Taferner (password encryption)
+ email : tim@tjansen.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "invitation.h"
+
+/*
+ * Function for (en/de)crypting strings for config file, taken from KMail
+ * Author: Stefan Taferner <taferner@alpin.or.at>
+ */
+QString cryptStr(const QString &aStr) {
+ QString result;
+ for (unsigned int i = 0; i < aStr.length(); i++)
+ result += (aStr[i].unicode() < 0x20) ? aStr[i] :
+ QChar(0x1001F - aStr[i].unicode());
+ return result;
+}
+
+// a random string that doesn't contain i, I, o, O, 1, 0
+// based on KApplication::randomString()
+static QString readableRandomString(int length) {
+ QString str;
+ while (length)
+ {
+ int r = KApplication::random() % 62;
+ r += 48;
+ if (r > 57)
+ r += 7;
+ if (r > 90)
+ r += 6;
+ char c = char(r);
+ if ((c == 'i') ||
+ (c == 'I') ||
+ (c == '1') ||
+ (c == 'o') ||
+ (c == 'O') ||
+ (c == '0'))
+ continue;
+ str += c;
+ length--;
+ }
+ return str;
+}
+
+Invitation::Invitation() :
+ m_viewItem(0) {
+ m_password = readableRandomString(4)+"-"+readableRandomString(3);
+ m_creationTime = QDateTime::currentDateTime();
+ m_expirationTime = QDateTime::currentDateTime().addSecs(INVITATION_DURATION);
+}
+
+Invitation::Invitation(const Invitation &x) :
+ m_password(x.m_password),
+ m_creationTime(x.m_creationTime),
+ m_expirationTime(x.m_expirationTime),
+ m_viewItem(0) {
+}
+
+Invitation::Invitation(KConfig* config, int num) {
+ m_password = cryptStr(config->readEntry(QString("password%1").arg(num), ""));
+ m_creationTime = config->readDateTimeEntry(QString("creation%1").arg(num));
+ m_expirationTime = config->readDateTimeEntry(QString("expiration%1").arg(num));
+ m_viewItem = 0;
+}
+
+Invitation::~Invitation() {
+ if (m_viewItem)
+ delete m_viewItem;
+}
+
+Invitation &Invitation::operator= (const Invitation&x) {
+ m_password = x.m_password;
+ m_creationTime = x.m_creationTime;
+ m_expirationTime = x.m_expirationTime;
+ if (m_viewItem)
+ delete m_viewItem;
+ m_viewItem = 0;
+ return *this;
+}
+
+void Invitation::save(KConfig *config, int num) const {
+ config->writeEntry(QString("password%1").arg(num), cryptStr(m_password));
+ config->writeEntry(QString("creation%1").arg(num), m_creationTime);
+ config->writeEntry(QString("expiration%1").arg(num), m_expirationTime);
+}
+
+QString Invitation::password() const {
+ return m_password;
+}
+
+QDateTime Invitation::expirationTime() const {
+ return m_expirationTime;
+}
+
+QDateTime Invitation::creationTime() const {
+ return m_creationTime;
+}
+
+bool Invitation::isValid() const {
+ return m_expirationTime > QDateTime::currentDateTime();
+}
+
+void Invitation::setViewItem(KListViewItem *i) {
+ if (m_viewItem)
+ delete m_viewItem;
+ m_viewItem = i;
+}
+
+KListViewItem *Invitation::getViewItem() const{
+ return m_viewItem;
+}
diff --git a/krfb/krfb/invitation.h b/krfb/krfb/invitation.h
new file mode 100644
index 00000000..4f1dd826
--- /dev/null
+++ b/krfb/krfb/invitation.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ invitation.h
+ -------------------
+ begin : Sat Mar 30 2002
+ copyright : (C) 2002 by Tim Jansen
+ email : tim@tjansen.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef INVITATION_H
+#define INVITATION_H
+
+#include <kapplication.h>
+#include <klistview.h>
+#include <kconfig.h>
+#include <qobject.h>
+#include <qstring.h>
+#include <qdatetime.h>
+
+
+const int INVITATION_DURATION = 60*60;
+
+QString cryptStr(const QString &aStr);
+
+class Invitation {
+public:
+ Invitation();
+ ~Invitation();
+ Invitation(KConfig* config, int num);
+ Invitation(const Invitation &x);
+ Invitation &operator= (const Invitation&x);
+
+ QString password() const;
+ QDateTime expirationTime() const;
+ QDateTime creationTime() const;
+ bool isValid() const;
+
+ void setViewItem(KListViewItem*);
+ KListViewItem* getViewItem() const;
+ void save(KConfig *config, int num) const;
+private:
+ QString m_password;
+ QDateTime m_creationTime;
+ QDateTime m_expirationTime;
+
+ KListViewItem *m_viewItem;
+};
+
+#endif
diff --git a/krfb/krfb/invitedialog.cc b/krfb/krfb/invitedialog.cc
new file mode 100644
index 00000000..a1177efa
--- /dev/null
+++ b/krfb/krfb/invitedialog.cc
@@ -0,0 +1,65 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Nadeem Hasan <nhasan@kde.org>
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "invitedialog.h"
+#include "invitewidget.h"
+
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kstdguiitem.h>
+
+#include <qlabel.h>
+#include <qpushbutton.h>
+
+InviteDialog::InviteDialog( QWidget *parent, const char *name )
+ : KDialogBase( parent, name, true, i18n( "Invitation" ),
+ User1|Close|Help, NoDefault, true )
+{
+ m_inviteWidget = new InviteWidget( this, "InviteWidget" );
+ m_inviteWidget->pixmapLabel->setPixmap(
+ UserIcon( "connection-side-image.png" ) );
+ setMainWidget( m_inviteWidget );
+
+ setButtonGuiItem( User1, KStdGuiItem::configure() );
+
+ connect( m_inviteWidget->btnCreateInvite, SIGNAL( clicked() ),
+ SIGNAL( createInviteClicked() ) );
+ connect( m_inviteWidget->btnEmailInvite, SIGNAL( clicked() ),
+ SIGNAL( emailInviteClicked() ) );
+ connect( m_inviteWidget->btnManageInvite, SIGNAL( clicked() ),
+ SIGNAL( manageInviteClicked() ) );
+}
+
+void InviteDialog::slotUser1()
+{
+ emit configureClicked();
+}
+
+void InviteDialog::enableInviteButton( bool enable )
+{
+ m_inviteWidget->btnCreateInvite->setEnabled( enable );
+}
+
+void InviteDialog::setInviteCount( int count )
+{
+ m_inviteWidget->btnManageInvite->setText(
+ i18n( "&Manage Invitations (%1)..." ).arg( count ) );
+}
+
+#include "invitedialog.moc"
diff --git a/krfb/krfb/invitedialog.h b/krfb/krfb/invitedialog.h
new file mode 100644
index 00000000..2db1e413
--- /dev/null
+++ b/krfb/krfb/invitedialog.h
@@ -0,0 +1,54 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Nadeem Hasan <nhasan@kde.org>
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef INVITEDIALOG_H
+#define INVITEDIALOG_H
+
+class InviteWidget;
+
+#include <kdialogbase.h>
+
+class InviteDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ InviteDialog( QWidget *parent, const char *name );
+ ~InviteDialog() {}
+
+ void enableInviteButton( bool enable );
+
+ public slots:
+ void setInviteCount( int count );
+
+ signals:
+ void createInviteClicked();
+ void emailInviteClicked();
+ void manageInviteClicked();
+ void configureClicked();
+
+ protected slots:
+ void slotUser1();
+
+ protected:
+ InviteWidget *m_inviteWidget;
+};
+
+#endif // INVITEDIALOG_H
+
diff --git a/krfb/krfb/invitewidget.ui b/krfb/krfb/invitewidget.ui
new file mode 100644
index 00000000..b0d80c36
--- /dev/null
+++ b/krfb/krfb/invitewidget.ui
@@ -0,0 +1,197 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>InviteWidget</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>InviteWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>521</width>
+ <height>328</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string></string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLabel" row="0" column="1" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property name="font">
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Welcome to KDE Desktop Sharing</string>
+ </property>
+ </widget>
+ <widget class="KActiveLabel" row="1" column="1" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>kActiveLabel1</cstring>
+ </property>
+ <property name="focusPolicy">
+ <enum>NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>KDE Desktop Sharing allows you to invite somebody at a remote location to watch and possibly control your desktop.
+&lt;a href="whatsthis:&lt;p&gt;An invitation creates a one-time password that allows the receiver to connect to your desktop. It is valid for only one successful connection and will expire after an hour if it has not been used. When somebody connects to your computer a dialog will appear and ask you for permission. The connection will not be established before you accept it. In this dialog you can also restrict the other person to view your desktop only, without the ability to move your mouse pointer or press keys.&lt;/p&gt;&lt;p&gt;If you want to create a permanent password for Desktop Sharing, allow 'Uninvited Connections' in the configuration.&lt;/p&gt;"&gt;More about invitations...&lt;/a&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="7" colspan="1">
+ <property name="name">
+ <cstring>pixmapLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>108</width>
+ <height>318</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>108</width>
+ <height>318</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>WinPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ <property name="alignment">
+ <set>AlignTop</set>
+ </property>
+ </widget>
+ <spacer row="4" column="3">
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton" row="3" column="2">
+ <property name="name">
+ <cstring>btnCreateInvite</cstring>
+ </property>
+ <property name="text">
+ <string>Create &amp;Personal Invitation...</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string></string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Create a new invitation and display the connection data. Use this option if you want to invite somebody personally, for example, to give the connection data over the phone.</string>
+ </property>
+ </widget>
+ <spacer row="6" column="2">
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>24</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="4" column="1">
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton" row="5" column="2">
+ <property name="name">
+ <cstring>btnManageInvite</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Manage Invitations (%1)...</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="4" column="2">
+ <property name="name">
+ <cstring>btnEmailInvite</cstring>
+ </property>
+ <property name="text">
+ <string>Invite via &amp;Email...</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This button will start your email application with a pre-configured text that explains to the recipient how to connect to your computer. </string>
+ </property>
+ </widget>
+ <spacer row="2" column="2">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>89</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+</widget>
+<signals>
+ <signal>createInviteClicked()</signal>
+ <signal>emailInviteClicked()</signal>
+ <signal>manageInviteClicked()</signal>
+</signals>
+<layoutdefaults spacing="6" margin="11"/>
+<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/>
+</UI>
diff --git a/krfb/krfb/kinetd_krfb.desktop b/krfb/krfb/kinetd_krfb.desktop
new file mode 100644
index 00000000..673a46d3
--- /dev/null
+++ b/krfb/krfb/kinetd_krfb.desktop
@@ -0,0 +1,150 @@
+[Desktop Entry]
+Type=Service
+
+ServiceTypes=KInetDModule
+Exec=krfb
+X-KDE-FactoryName=kinetd
+X-KDE-KINETD-id=krfb
+X-KDE-KINETD-port=5900
+X-KDE-KINETD-autoPortRange=100
+X-KDE-KINETD-enabled=false
+X-KDE-KINETD-argument=--kinetd
+X-KDE-KINETD-multiInstance=false
+X-KDE-KINETD-serviceURL=service:remotedesktop.kde:vnc://%h:%p;(type=shared),(username=%u),(fullname=%f),(serviceid=%i)
+X-KDE-KINETD-serviceAttributes=(type=shared),(username=%u),(fullname=%f),(serviceid=%i)
+X-KDE-KINETD-serviceLifetime=1200
+X-KDE-KINETD-DNSSD-Name=Remote Desktop of %u
+X-KDE-KINETD-DNSSD-Type=_rfb._tcp
+X-KDE-KINETD-DNSSD-Properties=type=shared,u=%u,fullname=%f
+
+Name=KRfb Desktop Sharing
+Name[ar]=KRfb مشاركة سطح المكتب
+Name[be]=Агульнае выкарыстанне кампутара KRfb
+Name[bg]=Споделяне на работното място (KRfb)
+Name[bn]=কে-আর-এফ-বি ডেস্কটপ ভাগাভাগি
+Name[br]=Rannañ burev KRfb
+Name[bs]=KRfb dijeljenje desktopa
+Name[ca]=Compartició de l'escriptori KRfb
+Name[cs]=Sdílení pracovní plochy KRfb
+Name[cy]=Rhannu Penbwrdd KRfb
+Name[da]=KRfb desktopdeling
+Name[de]=KRfb Arbeitsfläche freigeben
+Name[el]=Κοινή χρήση επιφάνειας εργασίας KRfb
+Name[eo]=KRfb Tabula fordonado
+Name[es]=Escritorio compartido KRfb
+Name[et]=KRfb Töölaua jagamine
+Name[eu]=KRfb mahaigain partekatzea
+Name[fa]=اشتراک رومیزی KRfb
+Name[fi]=KRfb työpöydän jakaminen
+Name[fr]=Partage de bureau KRfb
+Name[ga]=Roinnt Deisce KRfb
+Name[gl]=KRfb Compartición de Escritorios
+Name[he]=שיתוף שולחנות עבודה של KRfb
+Name[hi]=KRfb डेस्कटॉप साझेदारी
+Name[hr]=KRfb dijeljenje radne površine
+Name[hu]=KRfb munkaasztal-megosztás
+Name[is]=KRfb Skjáborðsmiðlun
+Name[it]=Condivisione desktop KRfb
+Name[ja]=KRfb デスクトップ共有
+Name[ka]=KRfb სამუშაო მაგიდის გაზიარება
+Name[kk]=KRfb ортақ үстелі
+Name[km]=ការ​ចែក​រំលែក​ផ្ទៃ​តុ KRfb
+Name[lt]=KRfb Dalinimasis darbastaliu
+Name[mk]=Делење на површина со KRfb
+Name[mn]=KRfb ажлын байр
+Name[ms]=Perkongsian Ruang Kerja KRfb
+Name[mt]=Qsim tad-desktop KRfb
+Name[nb]=KRfb skrivebordsdeling
+Name[nds]=KRfb-Schriefdischfreegaav
+Name[ne]=KRfb डेस्कटप साझेदारी
+Name[nl]=KRfb Bureaublad delen
+Name[nn]=KRfb-skrivebordsdeling
+Name[nso]=Kabagano ya Desktop ya KRfp
+Name[pa]=KRfb ਡੈਸਕਟਾਪ ਸਾਂਝ
+Name[pl]=KRfb Współdzielenie pulpitu
+Name[pt]=Partilha do Ecrã KRfb
+Name[pt_BR]=Compartilhamento do Ambiente de Trabalho KRfb
+Name[ro]=Partajare ecran KRfb
+Name[ru]=Общий рабочий стол KRfb
+Name[se]=KRfb-čállinbeavdejuohkin
+Name[sk]=KRfb zdieľanie pracovnej plochy
+Name[sl]=Deljenje namizja z KRfb
+Name[sr]=KRfb дељење радне површине
+Name[sr@Latn]=KRfb deljenje radne površine
+Name[sv]=Krfb dela ut skrivbord
+Name[ta]=KRfb பணிமேடை பகிர்வு
+Name[tg]=Истифодабарии муштакари Мизи кории KRfb
+Name[th]=แบ่งการใช้งานพื้นที่ทำงานร่วมกัน
+Name[tr]=KRfb Masaüstü Paylaşımı
+Name[uk]=Спільні стільниця KRfb
+Name[ven]=U kovhekana ha Desikithopo ya KRfb
+Name[xh]=Desktop ye KRfb Isebenza ngokuhlangeneyo
+Name[zh_CN]=KRfb 桌面共享
+Name[zh_HK]=KRfb 桌面分享
+Name[zh_TW]=KRfb 桌面分享
+Name[zu]=KRfb ukwahlukanisela kwe-Desktop Sharing
+Comment=A daemon that allows you to share your desktop
+Comment[af]='n bediener wat laat toe jy na deel jou werkskerm
+Comment[ar]=مراقب يسمح لك بمشاركة سطح مكتبك
+Comment[be]=Сервіс, які дае магчымасць кіравання стальніцай з іншага кампутара
+Comment[bg]=Демон за споделяне на работното място
+Comment[bn]=একটি ডিমন যে আপনার ডেস্কটপ ভাগাভাগি করতে আপনাকে অনুমতি দেয়
+Comment[bs]=Daemon koji vam omogućuje da dijelite vaš desktop
+Comment[ca]=Un dimoni que us permetrà compartir el vostre escriptori
+Comment[cs]=Démon umožňující sdílení vaší plochy
+Comment[cy]=Daemon sy'n gadael i chi rannu eich penbwrdd
+Comment[da]=En dæmon der tillader dig at dele din desktop
+Comment[de]=Ein Dienst, der die Freigabe der Arbeitsfläche erlaubt
+Comment[el]=Ένας δαίμονας που σας επιτρέπει να μοιραστείτε την επιφάνεια εργασίας σας
+Comment[eo]=demono por permesi retan fordonadon de via tabulo
+Comment[es]=Un demonio que le permite compartir su escritorio
+Comment[et]=Deemon, mis lubab sul töölauda jagada
+Comment[eu]=Zure mahaigaina partekatzeko aukera ematen duen deabrua da
+Comment[fa]=یک شبح که اجازۀ مشترک ساختن رومیزی را به شما می‌دهد
+Comment[fi]=Palvelin, joka mahdollistaa työpöydän jakamisen
+Comment[fr]=Un démon qui vous permet de partager votre bureau
+Comment[ga]=Deamhan a chuireann ar do chumas do dheasca a roinnt
+Comment[gl]=Un demo que permite a compartición do teu escritorio
+Comment[he]=תהליך רקע שמאפשר לך לשתף את שולחן העבודה שלך
+Comment[hi]=आपके डेस्कटॉप को साझेदारी करने देने वाला डेमन
+Comment[hr]=Daemon koji vam omogućuje da dijelite svoju radnu površinu s drugima
+Comment[hu]=Munkaasztal-megosztási szolgáltatás
+Comment[is]=Þjónn sem leyfir þér að miðla skjáborðinu þínu
+Comment[it]=Un demone che permette di condividere il tuo desktop
+Comment[ja]=デスクトップ共有を可能にするデーモン
+Comment[ka]=დემონი, რომელიც სამუშაო მაგიდის გაზიარების საშუალებას იძლევა
+Comment[kk]=Үстеліңізді ортақтастыруға мүмкіндік беретін қызмет
+Comment[km]=ដេមិន​ដែល​អនុញ្ញាត​ឲ្យ​អ្នក​ចែក​រំលែក​ផ្ទៃតុ​របស់​អ្នក
+Comment[lt]=Tarnyba, leidžianti dalintis savo darbastaliu
+Comment[mk]=Даемон кој ви дозволува да ја делите вашата работна површина
+Comment[mn]=Таны ажлын байрыг хамтран эзэмшихийгзөвшөөрсөн демон
+Comment[ms]=Daemon yang membenarkan anda berkongsi ruang kerja
+Comment[mt]=Daemon li jħallik taqsam id-desktop ma' ħaddieħor
+Comment[nb]=En programnisse som tillater deling av ditt skrivebord med andre
+Comment[nds]=En Dämoon, wo Du Dien Schriefdisch mit delen kannst
+Comment[ne]=एउटा डेइमन जसले तपाईँको डेस्कटप साझेदार गर्न अनुमति दिन्छ
+Comment[nl]=Een daemon waarmee u uw bureaublad kunt vrijgeven om te delen
+Comment[nn]=Ein nisse som let deg dela skrivebordet
+Comment[nso]=Daemon yeo ego dumelelago go abelana ka desktop ya gago
+Comment[pl]=Usługa, która pozwala na współdzielenie pulpitu
+Comment[pt]=Um servidor que lhe permite partilhar o seu ecrã
+Comment[pt_BR]=Um servidor que permite a você compartilhar o seu ambiente de trabalho
+Comment[ro]=Un demon care vă permite saă partajaţi sistemul dumneavoastră
+Comment[ru]=Служба совместного доступа к рабочему столу
+Comment[se]=Duogášprográmma mii diktá du juohkit čállinbeavddi earáiguin
+Comment[sk]=Démon ktorý umožní zdieľať vašu pracovnú plochu
+Comment[sl]=Strežnik, s katerim lahko delite vaše namizje
+Comment[sr]=Демон који вам дозвољава да делите вашу радну површину
+Comment[sr@Latn]=Demon koji vam dozvoljava da delite vašu radnu površinu
+Comment[sv]=Demon som låter dig dela ut skrivbordet
+Comment[ta]=ஒரு டேமொன் உங்கள் பணிமேடை பகிர்வை அளிக்கும்
+Comment[tg]=Азозиле, ки ба шумо истифодабарии муштараки мизи кориро медиҳад
+Comment[th]=เดมอนอนุญาตให้คุณแบ่งการใช้งานพื้นที่ทำงานร่วมกัน
+Comment[tr]=Masaüstünüzde paylaşılmasına izin verilmiş hayalet program
+Comment[uk]=Демон, що дозволяє спільне використання стільниць
+Comment[ven]=Daemon ine yani tendela nitshi kovhekana desktop yanu
+Comment[xh]=Daemon ekuvumela ukuba wabe i desktop yakho
+Comment[zh_CN]=允许您共享桌面的守护进程
+Comment[zh_HK]=讓您分享您的桌面的系統程式
+Comment[zh_TW]=讓您分享您的桌面的伺服程式
+Comment[zu]=I-daemoni ekuvumela uhlukaniselana nge-desktop
diff --git a/krfb/krfb/krfb.desktop b/krfb/krfb/krfb.desktop
new file mode 100644
index 00000000..6a39da53
--- /dev/null
+++ b/krfb/krfb/krfb.desktop
@@ -0,0 +1,64 @@
+# KDE Config File
+[Desktop Entry]
+Type=Application
+Exec=krfb -caption "%c" %i %m
+Icon=krfb
+DocPath=krfb/index.html
+Terminal=false
+Name=Krfb
+Name[bn]=কে-আর-এফ-বি
+Name[zh_TW]=Krfb 桌面分享
+GenericName=Desktop Sharing
+GenericName[be]=Агульнае выкарыстанне стальніцы
+GenericName[bg]=Споделяне на раб. място
+GenericName[bn]=ডেস্কটপ ভাগাভাগি
+GenericName[br]=Rannañ ar vurev
+GenericName[bs]=Dijeljenje desktopa
+GenericName[ca]=Compartició de l'escriptori
+GenericName[cs]=Sdílení pracovní plochy
+GenericName[cy]=Rhannu Penbwrdd
+GenericName[da]=Desktopdeling
+GenericName[de]=Arbeitsfläche freigeben
+GenericName[el]=Κοινή χρήση επιφάνειας εργασίας
+GenericName[eo]=Tabulkomunigado
+GenericName[es]=Escritorio compartido
+GenericName[et]=Töölaua jagamine
+GenericName[eu]=Mahaigain partekatzea
+GenericName[fa]=اشتراک رومیزی
+GenericName[fi]=Työpöydän jakaminen
+GenericName[fr]=Partage de bureau
+GenericName[ga]=Roinnt Deisce
+GenericName[gl]=Compartidor de Escritorio
+GenericName[he]=שיתוף שולחנות עבודה
+GenericName[hu]=Munkaasztal-megosztás
+GenericName[is]=Skjáborðsmiðlun
+GenericName[it]=Condivisione desktop
+GenericName[ja]=デスクトップ共有
+GenericName[ka]=სამუშაო მაგიდის გაზიარება
+GenericName[kk]=Үстелді ортақтастыру
+GenericName[km]=ការ​ចែក​រំលែក​ផ្ទៃ​តុ
+GenericName[lt]=Dalinimasis darbastaliu
+GenericName[mt]=Qsim tad-desktop
+GenericName[nb]=Delte skrivebord
+GenericName[nds]=Schriefdisch-Freegaav
+GenericName[ne]=डेस्कटप साझेदारी
+GenericName[nl]=Bureaublad delen
+GenericName[nn]=Skrivebordsdeling
+GenericName[pa]=ਡੈਸਕਟਾਪ ਸਾਂਝ
+GenericName[pl]=Współdzielenie pulpitu
+GenericName[pt]=Partilha do Ambiente de Trabalho
+GenericName[pt_BR]=Compartilhamento de Ambiente de Trabalho
+GenericName[ru]=Общий рабочий стол
+GenericName[sk]=Zdieľanie pracovnej plochy
+GenericName[sl]=Deljenje namizja
+GenericName[sr]=Дељење радне површине
+GenericName[sr@Latn]=Deljenje radne površine
+GenericName[sv]=Dela ut skrivbordet
+GenericName[tr]=Masaüstü Paylaşımı
+GenericName[uk]=Спільні стільниці
+GenericName[uz]=Ish stoli bilan boʻlishish
+GenericName[uz@cyrillic]=Иш столи билан бўлишиш
+GenericName[zh_CN]=桌面共享
+GenericName[zh_HK]=桌面分享
+GenericName[zh_TW]=桌面分享
+Categories=Qt;KDE;System;RemoteAccess;Network;
diff --git a/krfb/krfb/krfbiface.h b/krfb/krfb/krfbiface.h
new file mode 100644
index 00000000..365c4b7a
--- /dev/null
+++ b/krfb/krfb/krfbiface.h
@@ -0,0 +1,24 @@
+#ifndef __KRFB_IFACE_H
+#define __KRFB_IFACE_H
+
+#include <dcopobject.h>
+
+class krfbIface : virtual public DCOPObject
+{
+ K_DCOP
+k_dcop:
+
+ /**
+ * Quits krfb, connected clients will be disconnected.
+ */
+ virtual void exit() = 0;
+
+ /**
+ * If this feature is activated krfb allows the connecting client to
+ * control the desktop (pointer & keyboard).
+ * @return a true to activate desktop control
+ */
+ virtual void setAllowDesktopControl(bool a) = 0;
+
+};
+#endif
diff --git a/krfb/krfb/krfbifaceimpl.cc b/krfb/krfb/krfbifaceimpl.cc
new file mode 100644
index 00000000..a79b1437
--- /dev/null
+++ b/krfb/krfb/krfbifaceimpl.cc
@@ -0,0 +1,27 @@
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "krfbifaceimpl.h"
+
+KRfbIfaceImpl::KRfbIfaceImpl(RFBController *c) :
+ DCOPObject("krfbIface"),
+ controller(c)
+{
+}
+
+void KRfbIfaceImpl::exit()
+{
+ emit exitApp();
+}
+void KRfbIfaceImpl::setAllowDesktopControl(bool b)
+{
+ controller->enableDesktopControl(b);
+}
+
+#include "krfbifaceimpl.moc"
diff --git a/krfb/krfb/krfbifaceimpl.h b/krfb/krfb/krfbifaceimpl.h
new file mode 100644
index 00000000..430a0652
--- /dev/null
+++ b/krfb/krfb/krfbifaceimpl.h
@@ -0,0 +1,22 @@
+#ifndef __KRFB_IFACE_IMPL_H
+#define __KRFB_IFACE_IMPL_H
+
+#include <qobject.h>
+#include "rfbcontroller.h"
+#include "krfbiface.h"
+
+class KRfbIfaceImpl : public QObject, public virtual krfbIface
+{
+ Q_OBJECT
+private:
+ RFBController *controller;
+public:
+ KRfbIfaceImpl(RFBController *c);
+signals:
+ void exitApp();
+
+public:
+ void exit();
+ void setAllowDesktopControl(bool);
+};
+#endif
diff --git a/krfb/krfb/lo16-app-krfb.png b/krfb/krfb/lo16-app-krfb.png
new file mode 100644
index 00000000..3eb33109
--- /dev/null
+++ b/krfb/krfb/lo16-app-krfb.png
Binary files differ
diff --git a/krfb/krfb/lo32-app-krfb.png b/krfb/krfb/lo32-app-krfb.png
new file mode 100644
index 00000000..ef3d45d2
--- /dev/null
+++ b/krfb/krfb/lo32-app-krfb.png
Binary files differ
diff --git a/krfb/krfb/main.cpp b/krfb/krfb/main.cpp
new file mode 100644
index 00000000..4428e983
--- /dev/null
+++ b/krfb/krfb/main.cpp
@@ -0,0 +1,191 @@
+/***************************************************************************
+ main.cpp
+ -------------------
+ begin : Sat Dec 8 03:23:02 CET 2001
+ copyright : (C) 2001-2003 by Tim Jansen
+ email : tim@tjansen.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "trayicon.h"
+#include "configuration.h"
+#include "krfbifaceimpl.h"
+#include "rfbcontroller.h"
+
+#include <kpixmap.h>
+#include <kaction.h>
+#include <kdebug.h>
+#include <kapplication.h>
+#include <knotifyclient.h>
+#include <ksystemtray.h>
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+#include <kaboutapplication.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <qobject.h>
+#include <qwindowdefs.h>
+#include <qcstring.h>
+#include <qdatastream.h>
+#include <dcopref.h>
+
+#include <signal.h>
+
+#undef VERSION
+#define VERSION "1.0"
+
+static const char description[] = I18N_NOOP("VNC-compatible server to share "
+ "KDE desktops");
+#define ARG_KINETD "kinetd"
+
+
+static KCmdLineOptions options[] =
+{
+ { ARG_KINETD " ", I18N_NOOP("Used for calling from kinetd"), 0},
+ KCmdLineLastOption
+};
+
+void checkKInetd(bool &kinetdAvailable, bool &krfbAvailable) {
+ DCOPRef ref("kded", "kinetd");
+ ref.setDCOPClient(KApplication::dcopClient());
+
+ DCOPReply r = ref.call("isInstalled", QString("krfb"));
+ if (!r.isValid()) {
+ kinetdAvailable = false;
+ krfbAvailable = false;
+ return;
+ }
+
+ r.get(krfbAvailable);
+ kinetdAvailable = true;
+}
+
+int main(int argc, char *argv[])
+{
+ KAboutData aboutData( "krfb", I18N_NOOP("Desktop Sharing"),
+ VERSION, description, KAboutData::License_GPL,
+ "(c) 2001-2003, Tim Jansen\n"
+ "(c) 2001, Johannes E. Schindelin\n"
+ "(c) 2000, heXoNet Support GmbH, D-66424 Homburg\n"
+ "(c) 2000-2001, Const Kaplinsky\n"
+ "(c) 2000, Tridia Corporation\n"
+ "(c) 1999, AT&T Laboratories Cambridge\n",
+ 0, "", "tim@tjansen.de");
+ aboutData.addAuthor("Tim Jansen", "", "tim@tjansen.de");
+ aboutData.addAuthor("Ian Reinhart Geiser", "DCOP interface", "geiseri@kde.org");
+ aboutData.addCredit("Johannes E. Schindelin",
+ I18N_NOOP("libvncserver"));
+ aboutData.addCredit("Const Kaplinsky",
+ I18N_NOOP("TightVNC encoder"));
+ aboutData.addCredit("Tridia Corporation",
+ I18N_NOOP("ZLib encoder"));
+ aboutData.addCredit("AT&T Laboratories Cambridge",
+ I18N_NOOP("original VNC encoders and "
+ "protocol design"));
+ aboutData.addCredit("Jens Wagner (heXoNet Support GmbH)",
+ I18N_NOOP("X11 update scanner, "
+ "original code base"));
+ aboutData.addCredit("Jason Spisak",
+ I18N_NOOP("Connection side image"),
+ "kovalid@yahoo.com");
+ aboutData.addCredit("Karl Vogel",
+ I18N_NOOP("KDesktop background deactivation"));
+ KCmdLineArgs::init(argc, argv, &aboutData);
+ KCmdLineArgs::addCmdLineOptions(options);
+
+ KApplication app;
+
+ Configuration *config;
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ QString fdString;
+ if (!args->isSet(ARG_KINETD)) {
+ bool kinetdA, krfbA;
+ checkKInetd(kinetdA, krfbA);
+ if (!kinetdA) {
+ KMessageBox::error(0,
+ i18n("Cannot find KInetD. "
+ "The KDE daemon (kded) may have crashed or has not been started at all, or the installation failed."),
+ i18n("Desktop Sharing Error"));
+ return 1;
+ }
+ if (!krfbA) {
+ KMessageBox::error(0,
+ i18n("Cannot find KInetD service for Desktop Sharing (krfb). "
+ "The installation is incomplete or failed."),
+ i18n("Desktop Sharing Error"));
+ return 1;
+ }
+
+ config = new Configuration(KRFB_INVITATION_MODE);
+ config->showInvitationDialog();
+ return 0;
+ }
+ fdString = args->getOption(ARG_KINETD);
+ config = new Configuration(KRFB_KINETD_MODE);
+ args->clear();
+
+ if ((!config->allowUninvitedConnections()) && (config->invitations().size() == 0)) {
+ KNotifyClient::event("UnexpectedConnection");
+ return 1;
+ }
+
+ if (!RFBController::checkX11Capabilities())
+ return 1;
+
+ TrayIcon trayicon(new KAboutApplication(&aboutData),
+ config);
+ RFBController controller(config);
+ KRfbIfaceImpl dcopiface(&controller);
+
+ QObject::connect(&app, SIGNAL(lastWindowClosed()), // dont show passivepopup
+ &trayicon, SLOT(prepareQuit()));
+ QObject::connect(&app, SIGNAL(lastWindowClosed()),
+ &controller, SLOT(closeConnection()));
+
+ QObject::connect(&trayicon, SIGNAL(showManageInvitations()),
+ config, SLOT(showManageInvitationsDialog()));
+ QObject::connect(&trayicon, SIGNAL(enableDesktopControl(bool)),
+ &controller, SLOT(enableDesktopControl(bool)));
+ QObject::connect(&trayicon, SIGNAL(diconnectedMessageDisplayed()),
+ &app, SLOT(quit()));
+
+ QObject::connect(&dcopiface, SIGNAL(exitApp()),
+ &controller, SLOT(closeConnection()));
+ QObject::connect(&dcopiface, SIGNAL(exitApp()),
+ &app, SLOT(quit()));
+
+ QObject::connect(&controller, SIGNAL(sessionRefused()),
+ &app, SLOT(quit()));
+ QObject::connect(&controller, SIGNAL(sessionEstablished(QString)),
+ &trayicon, SLOT(showConnectedMessage(QString)));
+ QObject::connect(&controller, SIGNAL(sessionFinished()),
+ &trayicon, SLOT(showDisconnectedMessage()));
+ QObject::connect(&controller, SIGNAL(desktopControlSettingChanged(bool)),
+ &trayicon, SLOT(setDesktopControlSetting(bool)));
+ QObject::connect(&controller, SIGNAL(quitApp()),
+ &app, SLOT(quit()));
+
+ sigset_t sigs;
+ sigemptyset(&sigs);
+ sigaddset(&sigs, SIGPIPE);
+ sigprocmask(SIG_BLOCK, &sigs, 0);
+
+ bool ok;
+ int fdNum = fdString.toInt(&ok);
+ if (!ok) {
+ kdError() << "kinetd fd was not numeric." << endl;
+ return 2;
+ }
+ controller.startServer(fdNum);
+
+ return app.exec();
+}
+
diff --git a/krfb/krfb/manageinvitations.ui b/krfb/krfb/manageinvitations.ui
new file mode 100644
index 00000000..eae26507
--- /dev/null
+++ b/krfb/krfb/manageinvitations.ui
@@ -0,0 +1,216 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>ManageInvitationsDialog</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>ManageInvitationsDialog</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>680</width>
+ <height>350</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Manage Invitations - Desktop Sharing</string>
+ </property>
+ <property name="icon">
+ <pixmap>image0</pixmap>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <spacer row="7" column="0">
+ <property name="name">
+ <cstring>Spacer10</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="0" column="1">
+ <property name="name">
+ <cstring>Spacer7</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KListView" row="0" column="0" rowspan="5" colspan="1">
+ <column>
+ <property name="text">
+ <string>Created</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Expiration</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>listView</cstring>
+ </property>
+ <property name="hScrollBarMode">
+ <enum>AlwaysOff</enum>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="fullWidth">
+ <bool>true</bool>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string></string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Displays the open invitations. Use the buttons on the right to delete them or create a new invitation.</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="1">
+ <property name="name">
+ <cstring>newPersonalInvitationButton</cstring>
+ </property>
+ <property name="text">
+ <string>New &amp;Personal Invitation...</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Create a new personal invitation...</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Click this button to create a new personal invitation.</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="2" column="1">
+ <property name="name">
+ <cstring>newEmailInvitationButton</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;New Email Invitation...</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Send a new invitation via email...</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Click this button to send a new invitation via email.</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="3" column="1">
+ <property name="name">
+ <cstring>deleteAllButton</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Delete All</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Delete all invitations</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Deletes all open invitations.</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="4" column="1">
+ <property name="name">
+ <cstring>deleteOneButton</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Delete</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Delete the selected invitation</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Delete the selected invitation. The invited person will not be able to connect using this invitation anymore.</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="6" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>closeButton</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Close</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Closes this window.</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Closes this window.</string>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<images>
+ <image name="image0">
+ <data format="XPM.GZ" length="6958">789cdd9859531b490cc7dff914aee82db5a5784e7b6a6b1f38c219ee9bad7d98d30718830f8c9ddaefbe6a493d10e3002178b3b55118fae7eed1bf5b52f78cf9f4b172b6b75df9f869a13f8807adb49236e35ee56336ec74c67ffef5c7d7850f7ebd42ff1dcfadb81f7e5bf8b03fa8a4959dee756e00ae08a04aff6a09736eb9ee19c65ac9dc8fa1e5c8e7f159c929f3a5e598fbf1dc72227c5672c67c68390d984f4b96fe03cb19f7435ab2ccbf69390f79fc45c9dc8f27960bee878eb25fe3f5c1c4b2eaed5b56bdcfc28ece07162dabbfbeb0ab7ab02a1c44da7fcb5cafd6450f772cc71c2fdcb62ceb8742390d63e62f9625bec8ec98f948bcf6947d8d77ddb2c403968483a028981bcc75a71e88ff7dcb1a8fad92a51e362d6bbeaf95d3808b09ba865d5abf2ffe7acc915bf722e663cbbec3f35b2f59c6b72cebfc6e94534fc6af5956bd6d61cfe667201c3a723f8261cff1aa7aff96b22f0c27caaa8f3e73e4e97c715339558e0dfb8e5f95f9436259eb6b45d9d7fe53e5bacc17b97e2839566fd5b2ae676c59d7bfae9ceaf8c8b2f61f088781d6cbb270acf945ce6fe00655d55f560e546f47b816e8fed915ae47124fbc638e8348ea03772d6bfe374a967a5c52ce74fcd070e8864e28faf7ca8132d747188791d437562debfc27ca99d6ff9a701c6b3febd7bc9aa3fb69ac1c68fdee0947819e375c1fb5a416493d63a29c29733dd73d2a70f1776c59f55aca81f483c3fce0af2b5c8ff47c4c95336138128e023d1f797f46be9d2f16c29123f1c54be540e31d5bd6fc1f0a27a19c4731af274aed786c2bdbfce4ca99ea73bd53b9e97ce14cd8eac7a0ace331138e1d3d5f46ca8130f0f91ea736ff712c5cc62b52b67aae70b9debe302558f43acab930048613bfdccf8bc289abf9bd520e95f9fc48b224d6e7cbad722e0cf796f57ce4e7451ad8fd0255655bff4de1d4d5fd36520e953de6ccae1fee84d3589f17fcbccc02738232b785b350f33954ce95f9799be56eeacaf913081b63762cebf815e15c3946c37958c6eb48387775bd9c5f1aaefb095039d7f38cf3531485dd6f9e7221bc3f98affd9f3410e66ba5463c37b31a312698cec5128c4b8d14b3b9583aa59163f18e2b28c8df538d021bef988706f97baa919a0cbd9b953e9f6accae716cceb6efed89ff9606fbc9b0856dbca4e85e71555c61472bc6d83576f1e6a9de6b34749eb7747fce1a09f6c87797ae7da201b5867847bf5bd4eab3ca08afdfa47143f36ea9c63d5f8734f3312915e47fc8b59ee084567963d6f4231aec7d848b1497019f0009f99d50db5cc506fa8999c1907efab49ecb8798bd42e396fc7769de19fb3171e991cfa527d721f7f6e85ad03cda1cdb9b576a8c38d366a6e6c744fe8ebc4e5f87dcdbd331268a661f775fd6e0f57668dd63f6dda3eb32aeccb4cf94233be68eb506a4d6650fcf6bdc92f5b56e96e94468e02aaee1fa0c5ba39e86da1d6e908a5961ca1e9ed71891b5343e0ddcc42df2f505b77167cab6e9d335ea15dbd4188e295ac6c3f31a05d958e3d3a0f5ece21eeee3011e4ed9017dba47bd976c5d1a2bd11b53f693173436c8861a81091ee1319ee029f93cc3f34776469f9ce20556d141173d1a3729a3b644f6bcc626994f639b18d09d6ea9718e21d6d442a24356a963442a1e8d3ba2f14dd618e04b7565ec1efb80e801400c09a4460132c8a180065941ad4c54a0092d6893061bddd327ff26332f6be85dd0260f4df6750957d0816bd30bd7d4ba82cba71a6ced979f1fdfd5e840176e58e3865a9db968dc42cf3ee3a047f4abd66132dffa098dd7e4c35470fc4a8db1d655a931bbae20853e0c60a833baa3353cbc75bc74ee0236608401dcc39876c0a9a84cef0f98c0222cc132ac689452f1fecab31df8fda8813db8a79d7c317b9fc36758853552d07d0eeb3fa2c1634ce4d731850dd8842df8327d5ec136ecc02eec51ee8ca546e14def25e51b19ec4f9fbb7000877044275b39e68def3e0f1ac7d34f0f3881533a69e39fd598a5366deff79ef8a3f6eb35decd666bd8ef1f9b6ffecef1f2f70ff91ed5a593e41ae7f43d0acee01c2ea00a0e16e08247ed7338d3ef756d7e9728f4cefc51fbdbde6f3f7faae1430021d4a04e1a11a52624f675acbc5b9bb774d1e896edc7bd8fc7ccd488c1fc9196bc2798533ba2b61f838ecdf5ccc855232fdb8f7b1f8f99d6f0f91d791eb684febffab78c796afcfdfbc23fde05c197</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>listView</sender>
+ <signal>selectionChanged()</signal>
+ <receiver>ManageInvitationsDialog</receiver>
+ <slot>listSelectionChanged()</slot>
+ </connection>
+ <connection>
+ <sender>closeButton</sender>
+ <signal>clicked()</signal>
+ <receiver>ManageInvitationsDialog</receiver>
+ <slot>accept()</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="global" impldecl="in declaration">klistview.h</include>
+ <include location="local" impldecl="in implementation">manageinvitations.ui.h</include>
+</includes>
+<slots>
+ <slot>listSizeChanged( int i )</slot>
+ <slot>listSelectionChanged()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>klistview.h</includehint>
+</includehints>
+</UI>
diff --git a/krfb/krfb/manageinvitations.ui.h b/krfb/krfb/manageinvitations.ui.h
new file mode 100644
index 00000000..86c1fa4b
--- /dev/null
+++ b/krfb/krfb/manageinvitations.ui.h
@@ -0,0 +1,15 @@
+void ManageInvitationsDialog::listSizeChanged(int i) {
+ deleteAllButton->setEnabled(i);
+}
+
+void ManageInvitationsDialog::listSelectionChanged() {
+ QListViewItem *i = listView->firstChild();
+ while(i) {
+ if (i->isSelected()) {
+ deleteOneButton->setEnabled(true);
+ return;
+ }
+ i = i->nextSibling();
+ }
+ deleteOneButton->setEnabled(false);
+}
diff --git a/krfb/krfb/personalinvitedialog.cc b/krfb/krfb/personalinvitedialog.cc
new file mode 100644
index 00000000..aa00cc24
--- /dev/null
+++ b/krfb/krfb/personalinvitedialog.cc
@@ -0,0 +1,54 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Nadeem Hasan <nhasan@kde.org>
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "personalinvitedialog.h"
+#include "personalinvitewidget.h"
+
+#include <qlabel.h>
+
+#include <kactivelabel.h>
+#include <kiconloader.h>
+#include <klocale.h>
+
+PersonalInviteDialog::PersonalInviteDialog( QWidget *parent, const char *name )
+ : KDialogBase( parent, name, true, i18n( "Personal Invitation" ),
+ Close, Close, true )
+{
+ m_inviteWidget = new PersonalInviteWidget( this, "PersonalInviteWidget" );
+ m_inviteWidget->pixmapLabel->setPixmap(
+ UserIcon( "connection-side-image.png" ) );
+
+ setMainWidget( m_inviteWidget );
+}
+
+void PersonalInviteDialog::setHost( const QString &host, uint port )
+{
+ m_inviteWidget->hostLabel->setText( QString( "%1:%2" )
+ .arg( host ).arg( port ) );
+}
+
+void PersonalInviteDialog::setPassword( const QString &passwd )
+{
+ m_inviteWidget->passwordLabel->setText( passwd );
+}
+
+void PersonalInviteDialog::setExpiration( const QDateTime &expire )
+{
+ m_inviteWidget->expirationLabel->setText( expire.toString( Qt::LocalDate ) );
+}
diff --git a/krfb/krfb/personalinvitedialog.h b/krfb/krfb/personalinvitedialog.h
new file mode 100644
index 00000000..85a5966c
--- /dev/null
+++ b/krfb/krfb/personalinvitedialog.h
@@ -0,0 +1,44 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Nadeem Hasan <nhasan@kde.org>
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef PERSONALINVITEDIALOG_H
+#define PERSONALINVITEDIALOG_H
+
+class PersonalInviteWidget;
+
+#include <qdatetime.h>
+
+#include <kdialogbase.h>
+
+class PersonalInviteDialog : public KDialogBase
+{
+ public:
+ PersonalInviteDialog( QWidget *parent, const char *name );
+ virtual ~PersonalInviteDialog() {}
+
+ void setHost( const QString &host, uint port );
+ void setPassword( const QString &passwd );
+ void setExpiration( const QDateTime &expire );
+
+ protected:
+ PersonalInviteWidget *m_inviteWidget;
+};
+
+#endif // PERSONALINVITEDIALOG_H
+
diff --git a/krfb/krfb/personalinvitewidget.ui b/krfb/krfb/personalinvitewidget.ui
new file mode 100644
index 00000000..9ac68eb7
--- /dev/null
+++ b/krfb/krfb/personalinvitewidget.ui
@@ -0,0 +1,241 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>PersonalInviteWidget</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Form1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>519</width>
+ <height>328</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string></string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="resizeMode">
+ <enum>Fixed</enum>
+ </property>
+ <widget class="KActiveLabel" row="0" column="1" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>mainTextLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;Personal Invitation&lt;/h2&gt;
+Give the information below to the person that you want to invite (&lt;a href="whatsthis:Desktop Sharing uses the VNC protocol. You can use any VNC client to connect. In KDE the client is called 'Remote Desktop Connection'. Enter the host information into the client and it will connect.."&gt;how to connect&lt;/a&gt;). Note that everybody who gets the password can connect, so be careful.</string>
+ </property>
+ </widget>
+ <spacer row="1" column="2">
+ <property name="name">
+ <cstring>spacer9</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>34</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0" rowspan="6" colspan="1">
+ <property name="name">
+ <cstring>pixmapLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>108</width>
+ <height>318</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>108</width>
+ <height>318</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>WinPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer row="5" column="2">
+ <property name="name">
+ <cstring>spacer10</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>30</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KActiveLabel" row="2" column="2">
+ <property name="name">
+ <cstring>hostLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>cookie.tjansen.de:0</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="1">
+ <property name="name">
+ <cstring>kActiveLabel6</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Password:&lt;/b&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="1">
+ <property name="name">
+ <cstring>kActiveLabel7</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Expiration time:&lt;/b&gt;</string>
+ </property>
+ </widget>
+ <widget class="KActiveLabel" row="3" column="2">
+ <property name="name">
+ <cstring>passwordLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>12345</string>
+ </property>
+ </widget>
+ <widget class="KActiveLabel" row="4" column="2">
+ <property name="name">
+ <cstring>expirationLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>NoFocus</enum>
+ </property>
+ <property name="text">
+ <string>17:12</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="1">
+ <property name="name">
+ <cstring>kActiveLabel5</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Host:&lt;/b&gt;</string>
+ </property>
+ </widget>
+ <widget class="KActiveLabel" row="2" column="3">
+ <property name="name">
+ <cstring>hostHelpLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>(&lt;a href="whatsthis:This field contains the address of your computer and the display number, separated by a colon. The address is just a hint - you can use any address that can reach your computer. Desktop Sharing tries to guess your address from your network configuration, but does not always succeed in doing so. If your computer is behind a firewall it may have a different address or be unreachable for other computers."&gt;Help&lt;/a&gt;)</string>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/>
+</UI>
diff --git a/krfb/krfb/rfbcontroller.cc b/krfb/krfb/rfbcontroller.cc
new file mode 100644
index 00000000..e6277b59
--- /dev/null
+++ b/krfb/krfb/rfbcontroller.cc
@@ -0,0 +1,902 @@
+/***************************************************************************
+ rfbcontroller.cpp
+ -------------------
+ begin : Sun Dec 9 2001
+ copyright : (C) 2001-2003 by Tim Jansen
+ email : tim@tjansen.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/*
+ * Contains keyboard & pointer handling from libvncserver's x11vnc.c
+ */
+
+#include "rfbcontroller.h"
+#include "kuser.h"
+
+#include <netinet/tcp.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#ifdef USE_SOLARIS
+#include <strings.h>
+#endif
+
+#include <kapplication.h>
+#include <knotifyclient.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kextsock.h>
+#include <qstring.h>
+#include <qcursor.h>
+#include <qwindowdefs.h>
+#include <qtimer.h>
+#include <qcheckbox.h>
+#include <qpushbutton.h>
+#include <qglobal.h>
+#include <qlabel.h>
+#include <qmutex.h>
+#include <qdeepcopy.h>
+#include <qclipboard.h>
+#include <qdesktopwidget.h>
+
+#include <X11/Xutil.h>
+#include <X11/extensions/XTest.h>
+
+#ifndef ASSERT
+#define ASSERT(x) Q_ASSERT(x)
+#endif
+
+#define IDLE_PAUSE (1000/50)
+#define MAX_SELECTION_LENGTH (4096)
+
+static XTestDisabler disabler;
+
+static const char* cur=
+" "
+" x "
+" xx "
+" xxx "
+" xxxx "
+" xxxxx "
+" xxxxxx "
+" xxxxxxx "
+" xxxxxxxx "
+" xxxxxxxxx "
+" xxxxxxxxxx "
+" xxxxx "
+" xx xxx "
+" x xxx "
+" xxx "
+" xxx "
+" xxx "
+" xxx "
+" ";
+
+static const char* mask=
+"xx "
+"xxx "
+"xxxx "
+"xxxxx "
+"xxxxxx "
+"xxxxxxx "
+"xxxxxxxx "
+"xxxxxxxxx "
+"xxxxxxxxxx "
+"xxxxxxxxxxx "
+"xxxxxxxxxxxx "
+"xxxxxxxxxx "
+"xxxxxxxx "
+"xxxxxxxx "
+"xx xxxxx "
+" xxxxx "
+" xxxxx "
+" xxxxx "
+" xxx ";
+
+static rfbCursorPtr myCursor;
+
+// only one controller exists, so we can do this workaround for functions:
+static RFBController *self;
+
+class AppLocker
+{
+public:
+ AppLocker() {
+ KApplication::kApplication()->lock();
+ }
+
+ ~AppLocker() {
+ KApplication::kApplication()->unlock();
+ }
+};
+
+static enum rfbNewClientAction newClientHook(struct _rfbClientRec *cl)
+{
+ AppLocker a;
+ return self->handleNewClient(cl);
+}
+
+static Bool passwordCheck(rfbClientPtr cl,
+ const char* encryptedPassword,
+ int len)
+{
+ AppLocker a;
+ return self->handleCheckPassword(cl, encryptedPassword, len);
+}
+
+static void keyboardHook(Bool down, KeySym keySym, rfbClientPtr)
+{
+ self->handleKeyEvent(down ? true : false, keySym);
+}
+
+static void pointerHook(int bm, int x, int y, rfbClientPtr)
+{
+ self->handlePointerEvent(bm, x, y);
+}
+
+static void clientGoneHook(rfbClientPtr)
+{
+ self->handleClientGone();
+}
+
+static void negotiationFinishedHook(rfbClientPtr cl)
+{
+ self->handleNegotiationFinished(cl);
+}
+
+static void inetdDisconnectHook()
+{
+ self->handleClientGone();
+}
+
+static void clipboardHook(char* str,int len, rfbClientPtr)
+{
+ self->clipboardToServer(QString::fromUtf8(str, len));
+}
+
+VNCEvent::~VNCEvent() {
+}
+
+Display *KeyboardEvent::dpy;
+signed char KeyboardEvent::modifiers[0x100];
+KeyCode KeyboardEvent::keycodes[0x100];
+KeyCode KeyboardEvent::leftShiftCode;
+KeyCode KeyboardEvent::rightShiftCode;
+KeyCode KeyboardEvent::altGrCode;
+const int KeyboardEvent::LEFTSHIFT = 1;
+const int KeyboardEvent::RIGHTSHIFT = 2;
+const int KeyboardEvent::ALTGR = 4;
+char KeyboardEvent::ModifierState;
+
+KeyboardEvent::KeyboardEvent(bool d, KeySym k) :
+ down(d),
+ keySym(k) {
+}
+
+void KeyboardEvent::initKeycodes() {
+ KeySym key,*keymap;
+ int i,j,minkey,maxkey,syms_per_keycode;
+
+ dpy = qt_xdisplay();
+
+ memset(modifiers,-1,sizeof(modifiers));
+
+ XDisplayKeycodes(dpy,&minkey,&maxkey);
+ ASSERT(minkey >= 8);
+ ASSERT(maxkey < 256);
+ keymap = (KeySym*) XGetKeyboardMapping(dpy, minkey,
+ (maxkey - minkey + 1),
+ &syms_per_keycode);
+ ASSERT(keymap);
+
+ for (i = minkey; i <= maxkey; i++)
+ for (j=0; j<syms_per_keycode; j++) {
+ key = keymap[(i-minkey)*syms_per_keycode+j];
+ if (key>=' ' && key<0x100 && i==XKeysymToKeycode(dpy,key)) {
+ keycodes[key]=i;
+ modifiers[key]=j;
+ }
+ }
+
+ leftShiftCode = XKeysymToKeycode(dpy, XK_Shift_L);
+ rightShiftCode = XKeysymToKeycode(dpy, XK_Shift_R);
+ altGrCode = XKeysymToKeycode(dpy, XK_Mode_switch);
+
+ XFree ((char *)keymap);
+}
+
+/* this function adjusts the modifiers according to mod (as from modifiers) and ModifierState */
+void KeyboardEvent::tweakModifiers(signed char mod, bool down) {
+
+ bool isShift = ModifierState & (LEFTSHIFT|RIGHTSHIFT);
+ if(mod < 0)
+ return;
+
+ if(isShift && mod != 1) {
+ if(ModifierState & LEFTSHIFT)
+ XTestFakeKeyEvent(dpy, leftShiftCode,
+ !down, CurrentTime);
+ if(ModifierState & RIGHTSHIFT)
+ XTestFakeKeyEvent(dpy, rightShiftCode,
+ !down, CurrentTime);
+ }
+
+ if(!isShift && mod==1)
+ XTestFakeKeyEvent(dpy, leftShiftCode,
+ down, CurrentTime);
+
+ if((ModifierState&ALTGR) && mod != 2)
+ XTestFakeKeyEvent(dpy, altGrCode,
+ !down, CurrentTime);
+ if(!(ModifierState&ALTGR) && mod==2)
+ XTestFakeKeyEvent(dpy, altGrCode,
+ down, CurrentTime);
+}
+
+void KeyboardEvent::exec() {
+#define ADJUSTMOD(sym,state) \
+ if(keySym==sym) { if(down) ModifierState|=state; else ModifierState&=~state; }
+
+ ADJUSTMOD(XK_Shift_L,LEFTSHIFT);
+ ADJUSTMOD(XK_Shift_R,RIGHTSHIFT);
+ ADJUSTMOD(XK_Mode_switch,ALTGR);
+
+ if(keySym>=' ' && keySym<0x100) {
+ KeyCode k;
+ if (down)
+ tweakModifiers(modifiers[keySym],True);
+ k = keycodes[keySym];
+ if (k != NoSymbol)
+ XTestFakeKeyEvent(dpy, k, down, CurrentTime);
+
+ if (down)
+ tweakModifiers(modifiers[keySym],False);
+ } else {
+ KeyCode k = XKeysymToKeycode(dpy, keySym );
+ if (k != NoSymbol)
+ XTestFakeKeyEvent(dpy, k, down, CurrentTime);
+ }
+}
+
+bool PointerEvent::initialized = false;
+Display *PointerEvent::dpy;
+int PointerEvent::buttonMask = 0;
+
+PointerEvent::PointerEvent(int b, int _x, int _y) :
+ button_mask(b),
+ x(_x),
+ y(_y) {
+ if (!initialized) {
+ initialized = true;
+ dpy = qt_xdisplay();
+ buttonMask = 0;
+ }
+}
+
+void PointerEvent::exec() {
+ QDesktopWidget *desktopWidget = QApplication::desktop();
+
+ int screen = desktopWidget->screenNumber();
+ if (screen < 0)
+ screen = 0;
+ XTestFakeMotionEvent(dpy, screen, x, y, CurrentTime);
+ for(int i = 0; i < 5; i++)
+ if ((buttonMask&(1<<i))!=(button_mask&(1<<i)))
+ XTestFakeButtonEvent(dpy,
+ i+1,
+ (button_mask&(1<<i))?True:False,
+ CurrentTime);
+
+ buttonMask = button_mask;
+}
+
+
+ClipboardEvent::ClipboardEvent(RFBController *c, const QString &ctext) :
+ controller(c),
+ text(QDeepCopy<QString>(ctext)) {
+}
+
+void ClipboardEvent::exec() {
+ if ((controller->lastClipboardDirection == RFBController::LAST_SYNC_TO_CLIENT) &&
+ (controller->lastClipboardText == text)) {
+ return;
+ }
+ controller->lastClipboardDirection = RFBController::LAST_SYNC_TO_SERVER;
+ controller->lastClipboardText = text;
+
+ controller->clipboard->setText(text, QClipboard::Clipboard);
+ controller->clipboard->setText(text, QClipboard::Selection);
+}
+
+
+KNotifyEvent::KNotifyEvent(const QString &n, const QString &d) :
+ name(n),
+ desc(d) {
+}
+
+KNotifyEvent::~KNotifyEvent() {
+}
+
+void KNotifyEvent::exec() {
+ KNotifyClient::event(name, desc);
+}
+
+SessionEstablishedEvent::SessionEstablishedEvent(RFBController *c) :
+ controller(c)
+{ }
+
+void SessionEstablishedEvent::exec() {
+ controller->sendSessionEstablished();
+}
+
+RFBController::RFBController(Configuration *c) :
+ allowDesktopControl(false),
+ lastClipboardDirection(LAST_SYNC_TO_SERVER),
+ configuration(c),
+ dialog( 0, "ConnectionDialog" ),
+ disableBackgroundPending(false),
+ disableBackgroundState(false),
+ closePending(false),
+ forcedClose(false)
+{
+ self = this;
+ connect(&dialog, SIGNAL(okClicked()), SLOT(dialogAccepted()));
+ connect(&dialog, SIGNAL(cancelClicked()), SLOT(dialogRefused()));
+ connect(&initIdleTimer, SIGNAL(timeout()), SLOT(checkAsyncEvents()));
+ connect(&idleTimer, SIGNAL(timeout()), SLOT(idleSlot()));
+
+ clipboard = QApplication::clipboard();
+ connect(clipboard, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
+ connect(clipboard, SIGNAL(dataChanged()), this, SLOT(clipboardChanged()));
+
+ asyncQueue.setAutoDelete(true);
+
+ KeyboardEvent::initKeycodes();
+
+ char hostname[256];
+ if (gethostname(hostname, 255))
+ hostname[0] = 0;
+ hostname[255] = 0;
+ desktopName = i18n("%1@%2 (shared desktop)").arg(KUser().loginName()).arg(hostname);
+}
+
+RFBController::~RFBController()
+{
+ stopServer();
+}
+
+
+
+void RFBController::startServer(int inetdFd, bool xtestGrab)
+{
+ framebufferImage = XGetImage(qt_xdisplay(),
+ QApplication::desktop()->winId(),
+ 0,
+ 0,
+ QApplication::desktop()->width(),
+ QApplication::desktop()->height(),
+ AllPlanes,
+ ZPixmap);
+
+ int w = framebufferImage->width;
+ int h = framebufferImage->height;
+ char *fb = framebufferImage->data;
+
+ rfbLogEnable(0);
+ server = rfbGetScreen(0, 0, w, h,
+ framebufferImage->bits_per_pixel,
+ 8,
+ framebufferImage->bits_per_pixel/8);
+
+ server->paddedWidthInBytes = framebufferImage->bytes_per_line;
+
+ server->rfbServerFormat.bitsPerPixel = framebufferImage->bits_per_pixel;
+ server->rfbServerFormat.depth = framebufferImage->depth;
+ server->rfbServerFormat.trueColour = (CARD8) TRUE;
+ server->rfbServerFormat.bigEndian = (CARD8) ((framebufferImage->bitmap_bit_order == MSBFirst) ? TRUE : FALSE);
+
+ if ( server->rfbServerFormat.bitsPerPixel == 8 ) {
+ server->rfbServerFormat.redShift = 0;
+ server->rfbServerFormat.greenShift = 3;
+ server->rfbServerFormat.blueShift = 6;
+ server->rfbServerFormat.redMax = 7;
+ server->rfbServerFormat.greenMax = 7;
+ server->rfbServerFormat.blueMax = 3;
+ } else {
+ server->rfbServerFormat.redShift = 0;
+ if ( framebufferImage->red_mask )
+ while ( ! ( framebufferImage->red_mask & (1 << server->rfbServerFormat.redShift) ) )
+ server->rfbServerFormat.redShift++;
+ server->rfbServerFormat.greenShift = 0;
+ if ( framebufferImage->green_mask )
+ while ( ! ( framebufferImage->green_mask & (1 << server->rfbServerFormat.greenShift) ) )
+ server->rfbServerFormat.greenShift++;
+ server->rfbServerFormat.blueShift = 0;
+ if ( framebufferImage->blue_mask )
+ while ( ! ( framebufferImage->blue_mask & (1 << server->rfbServerFormat.blueShift) ) )
+ server->rfbServerFormat.blueShift++;
+ server->rfbServerFormat.redMax = framebufferImage->red_mask >> server->rfbServerFormat.redShift;
+ server->rfbServerFormat.greenMax = framebufferImage->green_mask >> server->rfbServerFormat.greenShift;
+ server->rfbServerFormat.blueMax = framebufferImage->blue_mask >> server->rfbServerFormat.blueShift;
+ }
+
+ server->frameBuffer = fb;
+ server->autoPort = TRUE;
+ server->inetdSock = inetdFd;
+
+ server->kbdAddEvent = keyboardHook;
+ server->ptrAddEvent = pointerHook;
+ server->newClientHook = newClientHook;
+ server->inetdDisconnectHook = inetdDisconnectHook;
+ server->passwordCheck = passwordCheck;
+ server->setXCutText = clipboardHook;
+
+ server->desktopName = desktopName.latin1();
+
+ if (!myCursor)
+ myCursor = rfbMakeXCursor(19, 19, (char*) cur, (char*) mask);
+ server->cursor = myCursor;
+
+ passwordChanged();
+
+ scanner = new XUpdateScanner(qt_xdisplay(),
+ QApplication::desktop()->winId(),
+ (unsigned char*)fb, w, h,
+ server->rfbServerFormat.bitsPerPixel,
+ server->paddedWidthInBytes,
+ !configuration->disableXShm());
+
+ rfbInitServer(server);
+ state = RFB_WAITING;
+
+ if (xtestGrab) {
+ disabler.disable = false;
+ XTestGrabControl(qt_xdisplay(), true);
+ }
+
+ rfbRunEventLoop(server, -1, TRUE);
+ initIdleTimer.start(IDLE_PAUSE);
+}
+
+void RFBController::stopServer(bool xtestUngrab)
+{
+ rfbScreenCleanup(server);
+ state = RFB_STOPPED;
+ delete scanner;
+
+ XDestroyImage(framebufferImage);
+
+ if (xtestUngrab) {
+ disabler.disable = true;
+ QTimer::singleShot(0, &disabler, SLOT(exec()));
+ }
+}
+
+void RFBController::connectionAccepted(bool aRC)
+{
+ if (state != RFB_CONNECTING)
+ return;
+
+ allowDesktopControl = aRC;
+ emit desktopControlSettingChanged(aRC);
+ initIdleTimer.stop();
+ idleTimer.start(IDLE_PAUSE);
+
+ server->rfbClientHead->clientGoneHook = clientGoneHook;
+ state = RFB_CONNECTED;
+ if (!server->rfbAuthPasswdData)
+ emit sessionEstablished(remoteIp);
+}
+
+void RFBController::acceptConnection(bool aRemoteControl)
+{
+ KNotifyClient::event("UserAcceptsConnection",
+ i18n("User accepts connection from %1")
+ .arg(remoteIp));
+
+ if (state != RFB_CONNECTING)
+ return;
+
+ connectionAccepted(aRemoteControl);
+ rfbStartOnHoldClient(server->rfbClientHead);
+}
+
+void RFBController::refuseConnection()
+{
+ KNotifyClient::event("UserRefusesConnection",
+ i18n("User refuses connection from %1")
+ .arg(remoteIp));
+
+ if (state != RFB_CONNECTING)
+ return;
+ rfbRefuseOnHoldClient(server->rfbClientHead);
+ state = RFB_WAITING;
+}
+
+// checks async events, returns true if client disconnected
+bool RFBController::checkAsyncEvents()
+{
+ bool closed = false;
+ bool backgroundActionRequired = false;
+ asyncMutex.lock();
+ VNCEvent *e;
+ for (e = asyncQueue.first(); e; e = asyncQueue.next())
+ e->exec();
+ asyncQueue.clear();
+ if (closePending) {
+ connectionClosed();
+ closed = true;
+ closePending = false;
+ }
+ if (disableBackgroundPending != disableBackgroundState)
+ backgroundActionRequired = true;
+ asyncMutex.unlock();
+
+ if (backgroundActionRequired && (!closed) && !configuration->disableBackground())
+ disableBackground(disableBackgroundPending);
+
+ return closed;
+}
+
+void RFBController::disableBackground(bool state) {
+ if (disableBackgroundState == state)
+ return;
+
+ disableBackgroundState = state;
+ DCOPRef ref("kdesktop", "KBackgroundIface");
+ ref.setDCOPClient(KApplication::dcopClient());
+
+ ref.send("setBackgroundEnabled(bool)", bool(!state));
+}
+
+void RFBController::connectionClosed()
+{
+ KNotifyClient::event("ConnectionClosed",
+ i18n("Closed connection: %1.")
+ .arg(remoteIp));
+
+ idleTimer.stop();
+ initIdleTimer.stop();
+ disableBackground(false);
+ state = RFB_WAITING;
+ if (forcedClose)
+ emit quitApp();
+ else
+ emit sessionFinished();
+}
+
+void RFBController::closeConnection()
+{
+ forcedClose = true;
+ if (state == RFB_CONNECTED) {
+ disableBackground(false);
+
+ if (!checkAsyncEvents()) {
+ asyncMutex.lock();
+ if (!closePending)
+ rfbCloseClient(server->rfbClientHead);
+ asyncMutex.unlock();
+ }
+ }
+ else if (state == RFB_CONNECTING)
+ refuseConnection();
+}
+
+void RFBController::enableDesktopControl(bool b) {
+ if (b != allowDesktopControl)
+ emit desktopControlSettingChanged(b);
+ allowDesktopControl = b;
+}
+
+void RFBController::idleSlot()
+{
+ if (state != RFB_CONNECTED)
+ return;
+ if (checkAsyncEvents() || forcedClose)
+ return;
+
+ rfbUndrawCursor(server);
+
+ QPtrList<Hint> v;
+ v.setAutoDelete(true);
+ QPoint p = QCursor::pos();
+ scanner->searchUpdates(v, p.y());
+
+ Hint *h;
+
+ for (h = v.first(); h != 0; h = v.next())
+ rfbMarkRectAsModified(server, h->left(),
+ h->top(),
+ h->right(),
+ h->bottom());
+
+ asyncMutex.lock();
+ if (!closePending)
+ defaultPtrAddEvent(0, p.x(),p.y(), server->rfbClientHead);
+ asyncMutex.unlock();
+
+ checkAsyncEvents(); // check 2nd time (see 3rd line)
+}
+
+void RFBController::dialogAccepted()
+{
+ dialog.hide();
+ acceptConnection(dialog.allowRemoteControl());
+}
+
+void RFBController::dialogRefused()
+{
+ refuseConnection();
+ dialog.hide();
+ emit sessionRefused();
+}
+
+bool checkPassword(const QString &p,
+ unsigned char *ochallenge,
+ const char *response,
+ int len) {
+
+ if ((len == 0) && (p.length() == 0))
+ return true;
+
+ char passwd[MAXPWLEN];
+ unsigned char challenge[CHALLENGESIZE];
+
+ memcpy(challenge, ochallenge, CHALLENGESIZE);
+ bzero(passwd, MAXPWLEN);
+ if (!p.isNull())
+ strncpy(passwd, p.latin1(),
+ (MAXPWLEN <= p.length()) ? MAXPWLEN : p.length());
+
+ vncEncryptBytes(challenge, passwd);
+ return memcmp(challenge, response, len) == 0;
+}
+
+bool RFBController::handleCheckPassword(rfbClientPtr cl,
+ const char *response,
+ int len)
+{
+
+ bool authd = false;
+
+ if (configuration->allowUninvitedConnections())
+ authd = checkPassword(configuration->password(),
+ cl->authChallenge, response, len);
+
+ if (!authd) {
+ QValueList<Invitation>::iterator it =
+ configuration->invitations().begin();
+ while (it != configuration->invitations().end()) {
+ if (checkPassword((*it).password(),
+ cl->authChallenge, response, len) &&
+ (*it).isValid()) {
+ authd = true;
+ configuration->removeInvitation(it);
+ break;
+ }
+ it++;
+ }
+ }
+
+ if (!authd) {
+ if (configuration->invitations().size() > 0) {
+ sendKNotifyEvent("InvalidPasswordInvitations",
+ i18n("Failed login attempt from %1: wrong password")
+ .arg(remoteIp));
+}
+ else
+ sendKNotifyEvent("InvalidPassword",
+ i18n("Failed login attempt from %1: wrong password")
+ .arg(remoteIp));
+ return FALSE;
+ }
+
+ asyncMutex.lock();
+ asyncQueue.append(new SessionEstablishedEvent(this));
+ asyncMutex.unlock();
+
+ return TRUE;
+}
+
+enum rfbNewClientAction RFBController::handleNewClient(rfbClientPtr cl)
+{
+ int socket = cl->sock;
+ cl->negotiationFinishedHook = negotiationFinishedHook;
+
+ QString host, port;
+ KSocketAddress *ksa = KExtendedSocket::peerAddress(socket);
+ if (ksa) {
+ hostent *he = 0;
+ KInetSocketAddress *kisa = (KInetSocketAddress*) ksa;
+ in_addr ia4 = kisa->hostV4();
+ he = gethostbyaddr((const char*)&ia4,
+ sizeof(ia4),
+ AF_INET);
+
+ if (he && he->h_name)
+ host = QString(he->h_name);
+ else
+ host = ksa->nodeName();
+ delete ksa;
+ }
+
+ if (state != RFB_WAITING) {
+ sendKNotifyEvent("TooManyConnections",
+ i18n("Connection refused from %1, already connected.")
+ .arg(host));
+ return RFB_CLIENT_REFUSE;
+ }
+ remoteIp = host;
+ state = RFB_CONNECTING;
+
+ if ((!configuration->askOnConnect()) &&
+ (configuration->invitations().size() == 0)) {
+ sendKNotifyEvent("NewConnectionAutoAccepted",
+ i18n("Accepted uninvited connection from %1")
+ .arg(remoteIp));
+
+ connectionAccepted(configuration->allowDesktopControl());
+ return RFB_CLIENT_ACCEPT;
+ }
+
+ sendKNotifyEvent("NewConnectionOnHold",
+ i18n("Received connection from %1, on hold (waiting for confirmation)")
+ .arg(remoteIp));
+
+ dialog.setRemoteHost(remoteIp);
+ dialog.setAllowRemoteControl( true );
+ dialog.setFixedSize(dialog.sizeHint());
+ dialog.show();
+ return RFB_CLIENT_ON_HOLD;
+}
+
+void RFBController::handleClientGone()
+{
+ asyncMutex.lock();
+ closePending = true;
+ asyncMutex.unlock();
+}
+
+void RFBController::handleNegotiationFinished(rfbClientPtr cl)
+{
+ asyncMutex.lock();
+ disableBackgroundPending = cl->disableBackground;
+ asyncMutex.unlock();
+}
+
+void RFBController::handleKeyEvent(bool down, KeySym keySym) {
+ if (!allowDesktopControl)
+ return;
+
+ asyncMutex.lock();
+ asyncQueue.append(new KeyboardEvent(down, keySym));
+ asyncMutex.unlock();
+}
+
+void RFBController::handlePointerEvent(int button_mask, int x, int y) {
+ if (!allowDesktopControl)
+ return;
+
+ asyncMutex.lock();
+ asyncQueue.append(new PointerEvent(button_mask, x, y));
+ asyncMutex.unlock();
+}
+
+
+void RFBController::clipboardToServer(const QString &ctext) {
+ if (!allowDesktopControl)
+ return;
+
+ asyncMutex.lock();
+ asyncQueue.append(new ClipboardEvent(this, ctext));
+ asyncMutex.unlock();
+}
+
+void RFBController::clipboardChanged() {
+ if (state != RFB_CONNECTED)
+ return;
+ if (clipboard->ownsClipboard())
+ return;
+
+ QString text = clipboard->text(QClipboard::Clipboard);
+
+ // avoid ping-pong between client&server
+ if ((lastClipboardDirection == LAST_SYNC_TO_SERVER) &&
+ (lastClipboardText == text))
+ return;
+ if ((text.length() > MAX_SELECTION_LENGTH) || text.isNull())
+ return;
+
+ lastClipboardDirection = LAST_SYNC_TO_CLIENT;
+ lastClipboardText = text;
+ QCString ctext = text.utf8();
+ rfbSendServerCutText(server, ctext.data(), ctext.length());
+}
+
+void RFBController::selectionChanged() {
+ if (state != RFB_CONNECTED)
+ return;
+ if (clipboard->ownsSelection())
+ return;
+
+ QString text = clipboard->text(QClipboard::Selection);
+ // avoid ping-pong between client&server
+ if ((lastClipboardDirection == LAST_SYNC_TO_SERVER) &&
+ (lastClipboardText == text))
+ return;
+ if ((text.length() > MAX_SELECTION_LENGTH) || text.isNull())
+ return;
+
+ lastClipboardDirection = LAST_SYNC_TO_CLIENT;
+ lastClipboardText = text;
+ QCString ctext = text.utf8();
+ rfbSendServerCutText(server, ctext.data(), ctext.length());
+}
+
+void RFBController::passwordChanged() {
+ bool authRequired = (!configuration->allowUninvitedConnections()) ||
+ (configuration->password().length() != 0) ||
+ (configuration->invitations().count() > 0);
+
+ server->rfbAuthPasswdData = (void*) (authRequired ? 1 : 0);
+}
+
+void RFBController::sendKNotifyEvent(const QString &n, const QString &d)
+{
+ asyncMutex.lock();
+ asyncQueue.append(new KNotifyEvent(n, d));
+ asyncMutex.unlock();
+}
+
+void RFBController::sendSessionEstablished()
+{
+ if (configuration->disableBackground())
+ disableBackground(true);
+ emit sessionEstablished(remoteIp);
+}
+
+#ifdef __osf__
+extern "C" Bool XShmQueryExtension(Display*);
+#endif
+
+bool RFBController::checkX11Capabilities() {
+ int bp1, bp2, majorv, minorv;
+ Bool r = XTestQueryExtension(qt_xdisplay(), &bp1, &bp2,
+ &majorv, &minorv);
+ if ((!r) || (((majorv*1000)+minorv) < 2002)) {
+ KMessageBox::error(0,
+ i18n("Your X11 Server does not support the required XTest extension version 2.2. Sharing your desktop is not possible."),
+ i18n("Desktop Sharing Error"));
+ return false;
+ }
+
+ return true;
+}
+
+
+XTestDisabler::XTestDisabler() :
+ disable(false) {
+}
+
+void XTestDisabler::exec() {
+ if (disable)
+ XTestDiscard(qt_xdisplay());
+}
+
+#include "rfbcontroller.moc"
diff --git a/krfb/krfb/rfbcontroller.h b/krfb/krfb/rfbcontroller.h
new file mode 100644
index 00000000..948456f2
--- /dev/null
+++ b/krfb/krfb/rfbcontroller.h
@@ -0,0 +1,221 @@
+/***************************************************************************
+ rfbcontroller.h
+ -------------------
+ begin : Sun Dec 9 2001
+ copyright : (C) 2001 by Tim Jansen
+ email : tim@tjansen.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * Contains portions & concept from rfb's x0rfbserver.cc
+ * Copyright (C) 2000 heXoNet Support GmbH, D-66424 Homburg.
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef RFBCONTROLLER_H
+#define RFBCONTROLLER_H
+
+#include "configuration.h"
+#include "connectiondialog.h"
+#include "xupdatescanner.h"
+#include <ksock.h>
+#include <qobject.h>
+#include <qtimer.h>
+#include <qmutex.h>
+
+#define HAVE_PTHREADS
+#include "rfb.h"
+
+#include <X11/Xlib.h>
+
+
+
+class QCloseEvent;
+class QClipboard;
+class RFBController;
+
+typedef enum {
+ RFB_STOPPED,
+ RFB_WAITING,
+ RFB_CONNECTING,
+ RFB_CONNECTED
+} RFBState;
+
+class VNCEvent {
+public:
+ virtual void exec() = 0;
+ virtual ~VNCEvent();
+};
+
+
+class KeyboardEvent : public VNCEvent {
+ bool down;
+ KeySym keySym;
+
+ static Display *dpy;
+ static signed char modifiers[0x100];
+ static KeyCode keycodes[0x100], leftShiftCode, rightShiftCode, altGrCode;
+ static const int LEFTSHIFT;
+ static const int RIGHTSHIFT;
+ static const int ALTGR;
+ static char ModifierState;
+
+ static void tweakModifiers(signed char mod, bool down);
+public:
+ static void initKeycodes();
+
+ KeyboardEvent(bool d, KeySym k);
+ virtual void exec();
+};
+
+class PointerEvent : public VNCEvent {
+ int button_mask, x, y;
+
+ static bool initialized;
+ static Display *dpy;
+ static int buttonMask;
+public:
+ PointerEvent(int b, int _x, int _y);
+ virtual void exec();
+};
+
+class ClipboardEvent : public VNCEvent {
+ RFBController *controller;
+ QString text;
+public:
+ ClipboardEvent(RFBController *c, const QString &text);
+ virtual void exec();
+};
+
+class KNotifyEvent : public VNCEvent {
+ QString name;
+ QString desc;
+public:
+ KNotifyEvent(const QString &n, const QString &d);
+ virtual ~KNotifyEvent();
+ virtual void exec();
+};
+
+class SessionEstablishedEvent : public VNCEvent {
+ RFBController *controller;
+public:
+ SessionEstablishedEvent(RFBController *c);
+ virtual void exec();
+};
+
+/**
+ * Manages sockets, drives the RGBConnection and triggers the connection
+ * dialog.
+ * The controller has three states: 'waiting for connection',
+ * 'waiting for confirmation' and 'connected'. In the first state socket and
+ * connection are null, in the second socket is set and in the last both are
+ * set.
+ * @author Tim Jansen
+ */
+class RFBController : public QObject {
+ Q_OBJECT
+
+ friend class SessionEstablishedEvent;
+ friend class ClipboardEvent;
+public:
+ RFBController(Configuration *c);
+ virtual ~RFBController();
+
+ RFBState state;
+
+ void acceptConnection(bool allowRemoteConnection);
+ void connectionAccepted(bool allowRemoteConnection);
+ void refuseConnection();
+ void connectionClosed();
+ bool handleCheckPassword(rfbClientPtr, const char *, int);
+ void handleKeyEvent(bool down, KeySym keySym);
+ void handlePointerEvent(int button_mask, int x, int y);
+ enum rfbNewClientAction handleNewClient(rfbClientPtr cl);
+ void clipboardToServer(const QString &text);
+ void handleClientGone();
+ void handleNegotiationFinished(rfbClientPtr cl);
+ int getPort();
+ void startServer(int inetdFd = -1, bool xtestGrab = true);
+
+ static bool checkX11Capabilities();
+
+public slots:
+ void passwordChanged();
+ void closeConnection();
+ void enableDesktopControl(bool c);
+
+signals:
+ void sessionEstablished(QString host);
+ void sessionFinished();
+ void sessionRefused();
+ void quitApp();
+ void desktopControlSettingChanged(bool);
+
+private:
+ void stopServer(bool xtestUngrab = true);
+ void sendKNotifyEvent(const QString &name, const QString &desc);
+ void sendSessionEstablished();
+ void disableBackground(bool state);
+
+ QString remoteIp;
+ volatile bool allowDesktopControl;
+
+ QTimer initIdleTimer;
+ QTimer idleTimer;
+
+ enum {
+ LAST_SYNC_TO_SERVER,
+ LAST_SYNC_TO_CLIENT
+ } lastClipboardDirection;
+ QString lastClipboardText;
+ QClipboard *clipboard;
+
+ Configuration *configuration;
+ XUpdateScanner *scanner;
+ ConnectionDialog dialog;
+
+ QString desktopName;
+
+ rfbScreenInfoPtr server;
+
+ XImage *framebufferImage;
+
+ QMutex asyncMutex;
+ QPtrList<VNCEvent> asyncQueue;
+
+ bool disableBackgroundPending; // background, as desired by libvncserver
+ bool disableBackgroundState; // real background state
+ bool closePending; // set when libvncserver detected close
+ bool forcedClose; // set when user closed connection
+private slots:
+ bool checkAsyncEvents();
+ void idleSlot();
+ void dialogAccepted();
+ void dialogRefused();
+ void selectionChanged();
+ void clipboardChanged();
+};
+
+/*
+ * Class to call XTestDiscard at idle time (because otherwise
+ * it will not work with QT)
+ */
+class XTestDisabler : public QObject {
+ Q_OBJECT
+public:
+ XTestDisabler();
+ bool disable;
+ Display *dpy;
+public slots:
+ void exec();
+};
+
+#endif
diff --git a/krfb/krfb/templates/cpp_template b/krfb/krfb/templates/cpp_template
new file mode 100644
index 00000000..6afef5d4
--- /dev/null
+++ b/krfb/krfb/templates/cpp_template
@@ -0,0 +1,16 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
diff --git a/krfb/krfb/templates/header_template b/krfb/krfb/templates/header_template
new file mode 100644
index 00000000..6afef5d4
--- /dev/null
+++ b/krfb/krfb/templates/header_template
@@ -0,0 +1,16 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
diff --git a/krfb/krfb/trayicon.cpp b/krfb/krfb/trayicon.cpp
new file mode 100644
index 00000000..220ff7c0
--- /dev/null
+++ b/krfb/krfb/trayicon.cpp
@@ -0,0 +1,138 @@
+/***************************************************************************
+ trayicon.cpp
+ -------------------
+ begin : Tue Dec 11 2001
+ copyright : (C) 2001-2002 by Tim Jansen
+ email : tim@tjansen.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "trayicon.h"
+#include <qtooltip.h>
+#include <kstdaction.h>
+#include <kapplication.h>
+#include <klocale.h>
+#include <kdialog.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <kpopupmenu.h>
+
+KPassivePopup2::KPassivePopup2(QWidget *parent) :
+ KPassivePopup(parent){
+}
+
+void KPassivePopup2::hideEvent( QHideEvent *e )
+{
+ KPassivePopup::hideEvent(e);
+ emit hidden();
+}
+
+KPassivePopup2 *KPassivePopup2::message( const QString &caption, const QString &text,
+ const QPixmap &icon,
+ QWidget *parent)
+{
+ KPassivePopup2 *pop = new KPassivePopup2( parent);
+ pop->setView( caption, text, icon );
+ pop->show();
+
+ return pop;
+}
+
+
+TrayIcon::TrayIcon(KDialog *d, Configuration *c) :
+ KSystemTray(0, "krfb trayicon"),
+ configuration(c),
+ aboutDialog(d),
+ actionCollection(this),
+ quitting(false)
+{
+ KIconLoader *loader = KGlobal::iconLoader();
+ trayIconOpen = loader->loadIcon("eyes-open24", KIcon::User);
+ trayIconClosed = loader->loadIcon("eyes-closed24", KIcon::User);
+ setPixmap(trayIconClosed);
+ QToolTip::add(this, i18n("Desktop Sharing - connecting"));
+
+ manageInvitationsAction = new KAction(i18n("Manage &Invitations"), QString::null,
+ 0, this, SIGNAL(showManageInvitations()),
+ &actionCollection);
+ manageInvitationsAction->plug(contextMenu());
+
+ contextMenu()->insertSeparator();
+
+ enableControlAction = new KToggleAction(i18n("Enable Remote Control"));
+ enableControlAction->setCheckedState(i18n("Disable Remote Control"));
+ enableControlAction->plug(contextMenu());
+ enableControlAction->setEnabled(false);
+ connect(enableControlAction, SIGNAL(toggled(bool)), SIGNAL(enableDesktopControl(bool)));
+
+ contextMenu()->insertSeparator();
+
+ aboutAction = KStdAction::aboutApp(this, SLOT(showAbout()), &actionCollection);
+ aboutAction->plug(contextMenu());
+
+ show();
+}
+
+TrayIcon::~TrayIcon(){
+}
+
+void TrayIcon::showAbout() {
+ aboutDialog->show();
+}
+
+void TrayIcon::prepareQuit() {
+ quitting = true;
+}
+
+
+
+void TrayIcon::showConnectedMessage(QString host) {
+
+ setPixmap(trayIconOpen);
+ KPassivePopup2::message(i18n("Desktop Sharing"),
+ i18n("The remote user has been authenticated and is now connected."),
+ trayIconOpen,
+ this);
+ QToolTip::add(this, i18n("Desktop Sharing - connected with %1").arg(host));
+}
+
+void TrayIcon::showDisconnectedMessage() {
+ if (quitting)
+ return;
+
+ QToolTip::add(this, i18n("Desktop Sharing - disconnected"));
+ setPixmap(trayIconClosed);
+ KPassivePopup2 *p = KPassivePopup2::message(i18n("Desktop Sharing"),
+ i18n("The remote user has closed the connection."),
+ trayIconClosed,
+ this);
+ connect(p, SIGNAL(hidden()), this, SIGNAL(diconnectedMessageDisplayed()));
+}
+
+void TrayIcon::setDesktopControlSetting(bool b) {
+ enableControlAction->setEnabled(true);
+ enableControlAction->setChecked(b);
+}
+
+void TrayIcon::mousePressEvent(QMouseEvent *e)
+{
+ if (!rect().contains(e->pos()))
+ return;
+
+ if (e->button() == LeftButton) {
+ contextMenuAboutToShow(contextMenu());
+ contextMenu()->popup(e->globalPos());
+ }
+ else
+ KSystemTray::mousePressEvent(e);
+}
+
+#include "trayicon.moc"
diff --git a/krfb/krfb/trayicon.h b/krfb/krfb/trayicon.h
new file mode 100644
index 00000000..4e586efa
--- /dev/null
+++ b/krfb/krfb/trayicon.h
@@ -0,0 +1,90 @@
+/***************************************************************************
+ trayicon.h - description
+ -------------------
+ begin : Tue Dec 11 2001
+ copyright : (C) 2001-2002 by Tim Jansen
+ email : tim@tjansen.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef TRAYICON_H
+#define TRAYICON_H
+
+#include "configuration.h"
+
+#include <qwidget.h>
+#include <kpixmap.h>
+#include <kaction.h>
+#include <ksystemtray.h>
+#include <kpassivepopup.h>
+
+class KDialog;
+
+class KPassivePopup2 : public KPassivePopup {
+ Q_OBJECT
+public:
+ KPassivePopup2(QWidget *parent);
+ static KPassivePopup2 *message( const QString &caption, const QString &text,
+ const QPixmap &icon,
+ QWidget *parent);
+
+signals:
+ void hidden();
+
+protected:
+ /**
+ * Reimplemented to detect hide events.
+ */
+ virtual void hideEvent( QHideEvent *e );
+};
+
+/**
+ * Implements the trayicon.
+ * @author Tim Jansen
+ */
+
+class TrayIcon : public KSystemTray {
+ Q_OBJECT
+public:
+ TrayIcon(KDialog*, Configuration*);
+ ~TrayIcon();
+
+signals:
+ void showManageInvitations();
+ void diconnectedMessageDisplayed();
+ void enableDesktopControl(bool);
+
+public slots:
+ void prepareQuit();
+ void showConnectedMessage(QString host);
+ void showDisconnectedMessage();
+ void setDesktopControlSetting(bool);
+
+protected:
+ void mousePressEvent(QMouseEvent *e);
+
+private:
+
+ KPixmap trayIconOpen;
+ KPixmap trayIconClosed;
+ Configuration *configuration;
+ KDialog* aboutDialog;
+ KActionCollection actionCollection;
+ KAction* manageInvitationsAction;
+ KAction* aboutAction;
+ KToggleAction* enableControlAction;
+ bool quitting;
+
+private slots:
+ void showAbout();
+};
+
+#endif
diff --git a/krfb/krfb/xupdatescanner.cc b/krfb/krfb/xupdatescanner.cc
new file mode 100644
index 00000000..1c4a0fad
--- /dev/null
+++ b/krfb/krfb/xupdatescanner.cc
@@ -0,0 +1,481 @@
+/*
+ * Copyright (C) 2000 heXoNet Support GmbH, D-66424 Homburg.
+ * All Rights Reserved.
+ *
+ * This 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 software 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 software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+/*
+ * December 15th 2001: removed coments, mouse pointer options and some
+ * other stuff
+ * January 10th 2002: improved hint creation (join adjacent hints)
+ * February 20th: use only partial tiles
+ * January 21st 2003: remember last modified scanlines, and scan them and
+ * in every cycle, reduce scanlines to every 35th
+ * January 21st 2003: scan lines around the cursor in every cycle
+ *
+ * Tim Jansen <tim@tjansen.de>
+ */
+
+#include <kdebug.h>
+
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XShm.h>
+
+#include <string.h>
+#include <assert.h>
+
+#include "xupdatescanner.h"
+
+/* ../../krfb/libvncserver/rfb.h */
+#ifdef Bool
+#undef Bool
+#endif
+#define Bool int
+
+
+#define SCANLINES 35
+unsigned int scanlines[SCANLINES] = { 0, 16, 8, 24,
+ 33, 4, 20, 12, 28,
+ 10, 26, 18, 34, 2,
+ 22, 6, 30, 14,
+ 1, 17, 32, 9, 25,
+ 7, 23, 15, 31,
+ 19, 3, 27, 11,
+ 29, 13, 5, 21 };
+#define MAX_ADJ_TOLERANCE 8
+
+#define MAX_RECENT_HITS 12
+unsigned int recentHitScanlines[MAX_RECENT_HITS];
+
+#define CURSOR_SCANLINES 5
+int cursorScanlines[CURSOR_SCANLINES] = {
+ -10, -4, 0, 4, 10
+};
+
+
+
+
+XUpdateScanner::XUpdateScanner(Display *_dpy,
+ Window _window,
+ unsigned char *_fb,
+ int _width,
+ int _height,
+ int _bitsPerPixel,
+ int _bytesPerLine,
+ bool useXShm) :
+ dpy(_dpy),
+ window(_window),
+ fb(_fb),
+ width(_width),
+ height(_height),
+ bitsPerPixel(_bitsPerPixel),
+ bytesPerLine(_bytesPerLine),
+ tileWidth(32),
+ tileHeight(32),
+ count (0),
+ scanline(NULL),
+ tile(NULL)
+{
+ useShm = useXShm && XShmQueryExtension(dpy);
+ if (useShm) {
+ int major, minor;
+ Bool pixmaps;
+ if ((!XShmQueryVersion(dpy, &major, &minor, &pixmaps)) || !pixmaps)
+ useShm = false;
+ }
+
+ if (useShm) {
+ tile = XShmCreateImage(dpy,
+ DefaultVisual( dpy, 0 ),
+ bitsPerPixel,
+ ZPixmap,
+ NULL,
+ &shminfo_tile,
+ tileWidth,
+ tileHeight);
+
+ shminfo_tile.shmid = shmget(IPC_PRIVATE,
+ tile->bytes_per_line * tile->height,
+ IPC_CREAT | 0777);
+ shminfo_tile.shmaddr = tile->data = (char *)
+ shmat(shminfo_tile.shmid, 0, 0);
+ shminfo_tile.readOnly = False;
+
+ XShmAttach(dpy, &shminfo_tile);
+ }
+ else {
+ int tlen = tileWidth*(bitsPerPixel/8);
+ void *data = malloc(tlen*tileHeight);
+
+ tile = XCreateImage(dpy,
+ DefaultVisual(dpy, 0),
+ bitsPerPixel,
+ ZPixmap,
+ 0,
+ (char*)data,
+ tileWidth,
+ tileHeight,
+ 8,
+ tlen);
+ }
+
+ tilesX = (width + tileWidth - 1) / tileWidth;
+ tilesY = (height + tileHeight - 1) / tileHeight;
+ tileMap = new bool[tilesX * tilesY];
+ tileRegionMap = new struct TileChangeRegion[tilesX * tilesY];
+
+ unsigned int i;
+ for (i = 0; i < tilesX * tilesY; i++)
+ tileMap[i] = false;
+
+ if (useShm) {
+ scanline = XShmCreateImage(dpy,
+ DefaultVisual(dpy, 0),
+ bitsPerPixel,
+ ZPixmap,
+ NULL,
+ &shminfo_scanline,
+ width,
+ 1);
+
+ shminfo_scanline.shmid = shmget(IPC_PRIVATE,
+ scanline->bytes_per_line,
+ IPC_CREAT | 0777);
+ shminfo_scanline.shmaddr = scanline->data = (char *)
+ shmat( shminfo_scanline.shmid, 0, 0 );
+ shminfo_scanline.readOnly = False;
+
+ XShmAttach(dpy, &shminfo_scanline);
+ }
+ else {
+ int slen = width*(bitsPerPixel/8);
+ void *data = malloc(slen);
+ scanline = XCreateImage(dpy,
+ DefaultVisual(dpy, 0),
+ bitsPerPixel,
+ ZPixmap,
+ 0,
+ (char*)data,
+ width,
+ 1,
+ 8,
+ slen);
+ }
+
+ for (int i = 0; i < MAX_RECENT_HITS; i++)
+ recentHitScanlines[i] = i;
+}
+
+
+XUpdateScanner::~XUpdateScanner()
+{
+ if (useShm) {
+ XShmDetach(dpy, &shminfo_scanline);
+ XDestroyImage(scanline);
+ shmdt(shminfo_scanline.shmaddr);
+ shmctl(shminfo_scanline.shmid, IPC_RMID, 0);
+ XShmDetach(dpy, &shminfo_tile);
+ XDestroyImage(tile);
+ shmdt(shminfo_tile.shmaddr);
+ shmctl(shminfo_tile.shmid, IPC_RMID, 0);
+ }
+ else {
+ free(tile->data);
+ free(scanline->data);
+ XDestroyImage(scanline);
+ XDestroyImage(tile);
+ }
+ delete [] tileMap;
+ delete [] tileRegionMap;
+}
+
+
+// returns true if last line changed. this is used to re-scan the tile under
+// this one because it is likely to be modified but missed by the probe
+bool XUpdateScanner::copyTile(int x, int y, int tx, int ty)
+{
+ unsigned int maxWidth = width - x;
+ unsigned int maxHeight = height - y;
+ if (maxWidth > tileWidth)
+ maxWidth = tileWidth;
+ if (maxHeight > tileHeight)
+ maxHeight = tileHeight;
+
+ if (useShm) {
+ if ((maxWidth == tileWidth) && (maxHeight == tileHeight)) {
+ XShmGetImage(dpy, window, tile, x, y, AllPlanes);
+ } else {
+ XGetSubImage(dpy, window, x, y, maxWidth, maxHeight,
+ AllPlanes, ZPixmap, tile, 0, 0);
+ }
+ }
+ else
+ XGetSubImage(dpy, window, x, y, maxWidth, maxHeight,
+ AllPlanes, ZPixmap, tile, 0, 0);
+
+ unsigned int line;
+ int pixelsize = bitsPerPixel >> 3;
+ unsigned char *src = (unsigned char*) tile->data;
+ unsigned char *dest = fb + y * bytesPerLine + x * pixelsize;
+
+ unsigned char *ssrc = src;
+ unsigned char *sdest = dest;
+ int firstLine = maxHeight;
+
+ for (line = 0; line < maxHeight; line++) {
+ if (memcmp(sdest, ssrc, maxWidth * pixelsize)) {
+ firstLine = line;
+ break;
+ }
+ ssrc += tile->bytes_per_line;
+ sdest += bytesPerLine;
+ }
+
+ if (firstLine == maxHeight) {
+ tileMap[tx + ty * tilesX] = false;
+ return false;
+ }
+
+ unsigned char *msrc = src + (tile->bytes_per_line * maxHeight);
+ unsigned char *mdest = dest + (bytesPerLine * maxHeight);
+ int lastLine = firstLine;
+
+ for (line = maxHeight-1; line > firstLine; line--) {
+ msrc -= tile->bytes_per_line;
+ mdest -= bytesPerLine;
+ if (memcmp(mdest, msrc, maxWidth * pixelsize)) {
+ lastLine = line;
+ break;
+ }
+ }
+
+ for (line = firstLine; line <= lastLine; line++) {
+ memcpy(sdest, ssrc, maxWidth * pixelsize );
+ ssrc += tile->bytes_per_line;
+ sdest += bytesPerLine;
+ }
+
+ struct TileChangeRegion *r = &tileRegionMap[tx + (ty * tilesX)];
+ r->firstLine = firstLine;
+ r->lastLine = lastLine;
+
+ return lastLine == (maxHeight-1);
+}
+
+void XUpdateScanner::copyAllTiles()
+{
+ for (unsigned int y = 0; y < tilesY; y++) {
+ for (unsigned int x = 0; x < tilesX; x++) {
+ if (tileMap[x + y * tilesX])
+ if (copyTile(x*tileWidth, y*tileHeight, x, y) &&
+ ((y+1) < tilesY))
+ tileMap[x + (y+1) * tilesX] = true;
+ }
+ }
+
+}
+
+void XUpdateScanner::createHintFromTile(int x, int y, int th, Hint &hint)
+{
+ unsigned int w = width - x;
+ unsigned int h = height - y;
+ if (w > tileWidth)
+ w = tileWidth;
+ if (h > th)
+ h = th;
+
+ hint.x = x;
+ hint.y = y;
+ hint.w = w;
+ hint.h = h;
+}
+
+void XUpdateScanner::addTileToHint(int x, int y, int th, Hint &hint)
+{
+ unsigned int w = width - x;
+ unsigned int h = height - y;
+ if (w > tileWidth)
+ w = tileWidth;
+ if (h > th)
+ h = th;
+
+ if (hint.x > x) {
+ hint.w += hint.x - x;
+ hint.x = x;
+ }
+
+ if (hint.y > y) {
+ hint.h += hint.y - y;
+ hint.y = y;
+ }
+
+ if ((hint.x+hint.w) < (x+w)) {
+ hint.w = (x+w) - hint.x;
+ }
+
+ if ((hint.y+hint.h) < (y+h)) {
+ hint.h = (y+h) - hint.y;
+ }
+}
+
+static void printStatistics(Hint &hint) {
+ static int snum = 0;
+ static float ssum = 0.0;
+
+ int oX0 = hint.x & 0xffffffe0;
+ int oY0 = hint.y & 0xffffffe0;
+ int oX2 = (hint.x+hint.w) & 0x1f;
+ int oY2 = (hint.y+hint.h) & 0x1f;
+ int oX3 = (((hint.x+hint.w) | 0x1f) + ((oX2 == 0) ? 0 : 1)) & 0xffffffe0;
+ int oY3 = (((hint.y+hint.h) | 0x1f) + ((oY2 == 0) ? 0 : 1)) & 0xffffffe0;
+ float s0 = hint.w*hint.h;
+ float s1 = (oX3-oX0)*(oY3-oY0);
+ float p = (100*s0/s1);
+ ssum += p;
+ snum++;
+ float avg = ssum / snum;
+ kdDebug() << "avg size: "<< avg <<"%"<<endl;
+}
+
+void XUpdateScanner::flushHint(int x, int y, int &x0,
+ Hint &hint, QPtrList<Hint> &hintList)
+{
+ if (x0 < 0)
+ return;
+
+ x0 = -1;
+
+ assert (hint.w > 0);
+ assert (hint.h > 0);
+
+ //printStatistics(hint);
+
+ hintList.append(new Hint(hint));
+}
+
+void XUpdateScanner::createHints(QPtrList<Hint> &hintList)
+{
+ Hint hint;
+ int x0 = -1;
+
+ for (int y = 0; y < tilesY; y++) {
+ int x;
+ for (x = 0; x < tilesX; x++) {
+ int idx = x + y * tilesX;
+ if (tileMap[idx]) {
+ int ty = tileRegionMap[idx].firstLine;
+ int th = tileRegionMap[idx].lastLine - ty +1;
+ if (x0 < 0) {
+ createHintFromTile(x * tileWidth,
+ (y * tileHeight) + ty,
+ th,
+ hint);
+ x0 = x;
+
+ } else {
+ addTileToHint(x * tileWidth,
+ (y * tileHeight) + ty,
+ th,
+ hint);
+ }
+ }
+ else
+ flushHint(x, y, x0, hint, hintList);
+ }
+ flushHint(x, y, x0, hint, hintList);
+ }
+}
+
+void XUpdateScanner::testScanline(int y, bool rememberHits) {
+ if (y < 0)
+ return;
+ if (y >= (int)height)
+ return;
+
+ int x = 0;
+ bool hit = false;
+ if (useShm)
+ XShmGetImage(dpy, window, scanline, 0, y, AllPlanes);
+ else
+ XGetSubImage(dpy, window, 0, y, width, 1,
+ AllPlanes, ZPixmap, scanline, 0, 0);
+
+ while (x < width) {
+ int pixelsize = bitsPerPixel >> 3;
+ unsigned char *src = (unsigned char*) scanline->data +
+ x * pixelsize;
+ unsigned char *dest = fb +
+ y * bytesPerLine + x * pixelsize;
+ int w = (x + 32) > width ? (width-x) : 32;
+ if (memcmp(dest, src, w * pixelsize)) {
+ hit = true;
+ tileMap[(x / tileWidth) +
+ (y / tileHeight) * tilesX] = true;
+ }
+ x += 32;
+ }
+
+ if (!rememberHits)
+ return;
+
+ for (int i = 1; i < MAX_RECENT_HITS; i++)
+ recentHitScanlines[i-1] = recentHitScanlines[i];
+ recentHitScanlines[MAX_RECENT_HITS-1] = y;
+}
+
+void XUpdateScanner::searchUpdates(QPtrList<Hint> &hintList, int ptrY)
+{
+ count++;
+ count %= SCANLINES;
+
+ unsigned int i;
+ unsigned int y;
+
+ for (i = 0; i < (tilesX * tilesY); i++) {
+ tileMap[i] = false;
+ }
+
+ // test last scanlines with hits
+ for (i = 0; i < MAX_RECENT_HITS; i++)
+ testScanline(recentHitScanlines[i], true);
+
+ // test scanlines around the cursor
+ for (i = 0; i < CURSOR_SCANLINES; i++)
+ testScanline(ptrY+cursorScanlines[i], false);
+ // test last/first line of the tiles around the cursor
+ // (assumes tileHeight = 32)
+ testScanline((ptrY&0xffe0)-1, false);
+ testScanline((ptrY|0x1f)+1, false);
+
+ // test every SCANLINESth scanline
+ y = scanlines[count];
+ while (y < (int)height) {
+ testScanline(y, true);
+ y += SCANLINES;
+ }
+
+ copyAllTiles();
+
+ createHints(hintList);
+}
+
+
+
diff --git a/krfb/krfb/xupdatescanner.h b/krfb/krfb/xupdatescanner.h
new file mode 100644
index 00000000..535b2ac9
--- /dev/null
+++ b/krfb/krfb/xupdatescanner.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2000 heXoNet Support GmbH, D-66424 Homburg.
+ * All Rights Reserved.
+ *
+ * This 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 software 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 software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+
+#ifndef _hexonet_rfb_XUpdateScanner_h_
+#define _hexonet_rfb_XUpdateScanner_h_
+
+#include <qptrlist.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/XShm.h>
+
+
+class Hint {
+ public:
+ int x, y, w, h;
+
+ Hint() :
+ x(0),
+ y(0),
+ w(0),
+ h(0)
+ {}
+ Hint(Hint &h) :
+ x(h.x),
+ y(h.y),
+ w(h.w),
+ h(h.h)
+ {
+ }
+ int left() {
+ return x;
+ }
+ int right() {
+ return x+w;
+ }
+ int top() {
+ return y;
+ }
+ int bottom() {
+ return y+h;
+ }
+};
+
+struct TileChangeRegion {
+ short firstLine, lastLine;
+};
+
+
+class XUpdateScanner
+{
+ public:
+ XUpdateScanner( Display *_dpy,
+ Window _window,
+ unsigned char *_fb,
+ int _width, int _height,
+ int _bitsPerPixel, int _bytesPerLine,
+ bool useXShm);
+
+ ~XUpdateScanner();
+
+ // hitList: returns list of changes
+ // ptrY: ptrY: position of the cursor
+ void searchUpdates( QPtrList<Hint> &hintList, int ptrY);
+
+ private:
+ void testScanline(int y, bool rememberHits);
+ bool copyTile(int x, int y, int tx, int ty);
+ void copyAllTiles();
+ void flushHint(int x, int y, int &x0, Hint &hint,
+ QPtrList<Hint> &hintList);
+ void createHints(QPtrList<Hint> &hintList);
+ void addTileToHint(int x, int y, int th, Hint &hint);
+ void createHintFromTile(int x, int y, int th, Hint &hint);
+
+ Display *dpy;
+ Window window;
+ unsigned char *fb;
+ int width, height;
+ int bitsPerPixel, bytesPerLine;
+ unsigned int tileWidth, tileHeight;
+ unsigned int count;
+ bool useShm;
+
+ XImage *scanline;
+ XShmSegmentInfo shminfo_scanline;
+
+ XImage *tile;
+ XShmSegmentInfo shminfo_tile;
+
+ unsigned int tilesX, tilesY;
+ bool *tileMap;
+ struct TileChangeRegion *tileRegionMap;
+};
+
+
+#endif // _hexonet_rfb_XUpdateScanner_h_