Compare commits

..

13 Commits

Author SHA1 Message Date
Burkhard Lück
830160689b doc backport from trunk
svn path=/branches/KDE/4.4/kdenetwork/doc/krfb/; revision=1098398
2010-03-03 16:55:12 +00:00
Script Kiddy
9801f0e7c1 SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.4/kdenetwork/krfb/; revision=1090812
2010-02-16 04:33:07 +00:00
Script Kiddy
344c10643f SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.4/kdenetwork/krfb/; revision=1088978
2010-02-12 04:16:45 +00:00
Script Kiddy
b02a0ce845 SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.4/kdenetwork/krfb/; revision=1080505
2010-01-26 11:11:36 +00:00
Script Kiddy
ac1305aee8 SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.4/kdenetwork/krfb/; revision=1078036
2010-01-21 10:21:18 +00:00
Script Kiddy
5ea5cc92af SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.4/kdenetwork/krfb/; revision=1077556
2010-01-20 11:32:59 +00:00
Script Kiddy
8c960301d4 SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.4/kdenetwork/krfb/; revision=1077110
2010-01-19 12:37:08 +00:00
Script Kiddy
8d97f0fa97 SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.4/kdenetwork/krfb/; revision=1076018
2010-01-17 10:24:35 +00:00
Script Kiddy
6fa080af19 SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.4/kdenetwork/krfb/; revision=1075606
2010-01-16 11:50:36 +00:00
Script Kiddy
ff86e80b6c SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.4/kdenetwork/krfb/; revision=1072994
2010-01-11 11:14:02 +00:00
Script Kiddy
e8584a39f1 SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.4/kdenetwork/krfb/; revision=1072532
2010-01-10 10:48:46 +00:00
Script Kiddy
7eb5aea35a SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.4/kdenetwork/krfb/; revision=1072125
2010-01-09 13:10:48 +00:00
Script Kiddy
ac35d646f9 SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.4/kdenetwork/krfb/; revision=1071570
2010-01-08 10:33:16 +00:00
156 changed files with 2879 additions and 33728 deletions

View File

@@ -1,23 +1,15 @@
project(krfb)
if(NOT INSIDE_KDENETWORK)
message("Not building inside KDENetwork, loading KDE CMake Macros.")
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH})
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/../cmake/modules ${CMAKE_MODULE_PATH})
find_package(KDE4 REQUIRED)
include(KDE4Defaults)
include(MacroLibrary)
include(CheckSymbolExists)
if (BUILD_EXPERIMENTAL_TUBES_SUPPORT)
message(WARNING "You enabled experimental Tubes support. Expect breakage!!")
macro_optional_find_package(TelepathyQt4)
macro_log_feature(TELEPATHY_QT4_FOUND "telepathy-qt4" "Telepathy Qt Bindings" "http://telepathy.freedesktop.org" FALSE "0.18" "Needed to build Telepathy Tubes support.")
endif (BUILD_EXPERIMENTAL_TUBES_SUPPORT)
find_package(LibVNCServer)
macro_optional_find_package(LibVNCServer)
set(CMAKE_REQUIRED_DEFINITIONS ${_KDE_PLATFORM_DEFINITIONS})
@@ -25,26 +17,115 @@ if(NOT INSIDE_KDENETWORK)
include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES})
endif(NOT INSIDE_KDENETWORK)
check_symbol_exists(rfbInitServer "rfb/rfb.h" HAVE_LIBVNCSERVER)
macro_bool_to_01(X11_Xdamage_FOUND HAVE_XDAMAGE)
macro_bool_to_01(X11_XShm_FOUND HAVE_XSHM)
include_directories ("${CMAKE_CURRENT_BINARY_DIR}/krfb"
"${CMAKE_CURRENT_SOURCE_DIR}/krfb"
"${CMAKE_CURRENT_SOURCE_DIR}/krfb/ui"
"${CMAKE_CURRENT_SOURCE_DIR}/libvncserver/"
"${CMAKE_CURRENT_BINARY_DIR}/libvncserver/"
)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-krfb.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-krfb.h )
include_directories(${CMAKE_CURRENT_BINARY_DIR}) # for config-krfb.h
if(Q_WS_X11)
if(NOT X11_XTest_FOUND)
message(FATAL_ERROR "krfb requires the libXtst (http://xorg.freedesktop.org) to be built")
macro_log_feature(X11_XTest_FOUND "libXtst" "X11 Testing Resource extension library" "http://xorg.freedesktop.org" FALSE "" "useful for automated testing of X clients.")
endif(NOT X11_XTest_FOUND)
endif(Q_WS_X11)
add_subdirectory(libvncserver)
add_subdirectory(krfb)
#add_subdirectory(kinetd)
#add_subdirectory(kcm_krfb)
if (HAVE_LIBVNCSERVER)
#####################################
# First target: libkrfb - a library
# for linking plugins against.
set (krfbprivate_SRCS
framebuffer.cpp
framebufferplugin.cpp
)
kde4_add_library (krfbprivate
SHARED
${krfbprivate_SRCS}
)
target_link_libraries (krfbprivate
${QT_QTCORE_LIBRARY}
${QT_QTGUI_LIBRARY}
${X11_X11_LIB}
${LIBVNCSERVER_LIBRARIES}
)
set_target_properties (krfbprivate PROPERTIES
VERSION ${GENERIC_LIB_VERSION}
SOVERSION ${GENERIC_LIB_VERSION}
)
install (TARGETS krfbprivate
${INSTALL_TARGETS_DEFAULT_ARGS}
)
install (FILES
krfb-framebuffer.desktop
DESTINATION ${SERVICETYPES_INSTALL_DIR}
)
#####################################
# Build the plugins
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory (framebuffers)
if (NOT INSIDE_KDENETWORK)
macro_display_feature_log()
endif ()
#####################################
# Second target: krfb - the app
# itself.
set(krfb_SRCS
main.cpp
trayicon.cpp
krfbserver.cpp
manageinvitationsdialog.cpp
invitationmanager.cpp
invitedialog.cpp
invitation.cpp
connectiondialog.cpp
personalinvitedialog.cpp
connectioncontroller.cpp
events.cpp
framebuffermanager.cpp
)
kde4_add_kcfg_files(krfb_SRCS krfbconfig.kcfgc)
kde4_add_ui_files(krfb_SRCS connectionwidget.ui
manageinvitations.ui
personalinvitewidget.ui
invitewidget.ui
configtcp.ui
configsecurity.ui
)
kde4_add_executable(krfb ${krfb_SRCS})
target_link_libraries(krfb
krfbprivate
${JPEG_LIBRARIES}
${LIBVNCSERVER_LIBRARIES}
${X11_Xext_LIB}
${X11_X11_LIB}
${X11_Xdamage_LIB}
${QT_QTNETWORK_LIBRARY}
${KDE4_KDNSSD_LIBS}
${KDE4_KDEUI_LIBS}
)
if(X11_XTest_FOUND)
target_link_libraries(krfb ${X11_XTest_LIB})
endif(X11_XTest_FOUND)
install(TARGETS krfb ${INSTALL_TARGETS_DEFAULT_ARGS})
########### install files ###############
install(FILES krfb.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
install(FILES krfb.notifyrc DESTINATION ${DATA_INSTALL_DIR}/krfb)
endif (HAVE_LIBVNCSERVER)

View File

@@ -1,3 +1,2 @@
#! /bin/sh
$EXTRACTRC ui/*.ui *.kcfg >> rc.cpp
$XGETTEXT *.cpp -o $podir/krfb.pot

View File

@@ -1,22 +0,0 @@
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,39 +0,0 @@
# Try to find the Qt4 binding of the Telepathy library
# TELEPATHY_QT4_FOUND - system has TelepathyQt4
# TELEPATHY_QT4_INCLUDE_DIR - the TelepathyQt4 include directory
# TELEPATHY_QT4_LIBRARIES - Link these to use TelepathyQt4
# Copyright (c) 2008, Allen Winter <winter@kde.org>
# Copyright (c) 2009, Andre Moreira Magalhaes <andrunko@gmail.com>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
set(TELEPATHY_QT4_FIND_REQUIRED ${TelepathyQt4_FIND_REQUIRED})
if(TELEPATHY_QT4_INCLUDE_DIR AND TELEPATHY_QT4_LIBRARIES)
# Already in cache, be silent
set(TELEPATHY_QT4_FIND_QUIETLY TRUE)
endif(TELEPATHY_QT4_INCLUDE_DIR AND TELEPATHY_QT4_LIBRARIES)
find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
pkg_check_modules(PC_TELEPATHY_QT4 QUIET TelepathyQt4>=0.1.8)
endif(PKG_CONFIG_FOUND)
find_path(TELEPATHY_QT4_INCLUDE_DIR
NAMES TelepathyQt4/Types
HINTS
${PC_TELEPATHY_QT4_INCLUDEDIR}
${PC_TELEPATHY_QT4_INCLUDE_DIRS}
)
find_library(TELEPATHY_QT4_LIBRARIES
NAMES telepathy-qt4
HINTS
${PC_TELEPATHY_QT4_LIBDIR}
${PC_TELEPATHY_QT4_LIBRARY_DIRS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(TELEPATHY_QT4 DEFAULT_MSG
TELEPATHY_QT4_LIBRARIES TELEPATHY_QT4_INCLUDE_DIR)

View File

@@ -12,15 +12,9 @@
</property>
<layout class="QVBoxLayout">
<item>
<widget class="QCheckBox" name="kcfg_askOnConnect">
<property name="enabled">
<bool>true</bool>
</property>
<widget class="QCheckBox" name="kcfg_allowUninvitedConnections">
<property name="text">
<string>Ask before accepting connections</string>
</property>
<property name="checked">
<bool>true</bool>
<string>Allow uninvited connections</string>
</property>
</widget>
</item>
@@ -35,9 +29,15 @@
</widget>
</item>
<item>
<widget class="QCheckBox" name="kcfg_allowUninvitedConnections">
<widget class="QCheckBox" name="kcfg_askOnConnect">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Allow uninvited connections</string>
<string>Ask before accepting connections</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
@@ -88,6 +88,22 @@
</customwidgets>
<resources/>
<connections>
<connection>
<sender>kcfg_allowUninvitedConnections</sender>
<signal>toggled(bool)</signal>
<receiver>kcfg_askOnConnect</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>22</x>
<y>24</y>
</hint>
<hint type="destinationlabel">
<x>29</x>
<y>80</y>
</hint>
</hints>
</connection>
<connection>
<sender>kcfg_allowUninvitedConnections</sender>
<signal>toggled(bool)</signal>

253
connectioncontroller.cpp Normal file
View File

@@ -0,0 +1,253 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
(C) 2001-2003 by Tim Jansen <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 "connectioncontroller.h"
#include "connectioncontroller.moc"
#include <QX11Info>
#include <QHostInfo>
#include <QApplication>
#include <QDesktopWidget>
#include <QTcpSocket>
#include <QTimer>
#include <KConfig>
#include <KGlobal>
#include <KUser>
#include <KNotification>
#include <KLocale>
#include <KDebug>
#include "invitationmanager.h"
#include "connectiondialog.h"
#include "events.h"
#include "krfbserver.h"
#include "krfbconfig.h"
#include <X11/Xutil.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
static QString peerAddress(int sock) {
const int ADDR_SIZE = 50;
struct sockaddr sa;
socklen_t salen = sizeof(struct sockaddr);
if (getpeername(sock, &sa, &salen) == 0) {
if (sa.sa_family == AF_INET) {
struct sockaddr_in *si = (struct sockaddr_in *)&sa;
return QString(inet_ntoa(si->sin_addr));
}
if (sa.sa_family == AF_INET6) {
char inetbuf[ADDR_SIZE];
inet_ntop(sa.sa_family, &sa, inetbuf, ADDR_SIZE);
return QString(inetbuf);
}
return QString("not a network address");
}
return QString("unable to determine...");
}
static void clientGoneHook(rfbClientPtr cl)
{
ConnectionController *cc = static_cast<ConnectionController *>(cl->clientData);
cc->handleClientGone();
}
static 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.toLatin1(),
(MAXPWLEN <= p.length()) ? MAXPWLEN : p.length());
}
rfbEncryptBytes(challenge, passwd);
return memcmp(challenge, response, len) == 0;
}
ConnectionController::ConnectionController(struct _rfbClientRec *_cl, KrfbServer * parent)
: QObject(parent), cl(_cl)
{
cl->clientData = (void*)this;
}
ConnectionController::~ConnectionController()
{
}
enum rfbNewClientAction ConnectionController::handleNewClient()
{
kDebug();
bool askOnConnect = KrfbConfig::askOnConnect();
bool allowUninvited = KrfbConfig::allowUninvitedConnections();
remoteIp = peerAddress(cl->sock);
if (!allowUninvited && InvitationManager::self()->activeInvitations() == 0) {
KNotification::event("UnexpectedConnection",
i18n("Refused uninvited connection attempt from %1",
remoteIp));
return RFB_CLIENT_REFUSE;
}
// In the remaining cases, the connection will be at least partially established, so we need
// the clientGoneHook to be called when the connection ends.
cl->clientGoneHook = clientGoneHook;
if (!askOnConnect) {
KNotification::event("NewConnectionAutoAccepted",
i18n("Accepted uninvited connection from %1",
remoteIp));
emit sessionEstablished(remoteIp);
return RFB_CLIENT_ACCEPT;
}
KNotification::event("NewConnectionOnHold",
i18n("Received connection from %1, on hold (waiting for confirmation)",
remoteIp));
ConnectionDialog *dialog = new ConnectionDialog(0);
dialog->setRemoteHost(remoteIp);
dialog->setAllowRemoteControl(KrfbConfig::allowDesktopControl());
connect(dialog, SIGNAL(okClicked()), SLOT(dialogAccepted()));
connect(dialog, SIGNAL(cancelClicked()), SLOT(dialogRejected()));
dialog->show();
return RFB_CLIENT_ON_HOLD;
}
bool ConnectionController::handleCheckPassword(rfbClientPtr cl, const char *response, int len)
{
bool allowUninvited = KrfbConfig::allowUninvitedConnections();
QString password = KrfbConfig::uninvitedConnectionPassword();
bool authd = false;
kDebug() << "about to start autentication";
if (allowUninvited) {
authd = checkPassword(password, cl->authChallenge, response, len);
}
if (!authd) {
QList<Invitation> invlist = InvitationManager::self()->invitations();
foreach(const Invitation &it, invlist) {
kDebug() << "checking password";
if (checkPassword(it.password(), cl->authChallenge, response, len) && it.isValid()) {
authd = true;
InvitationManager::self()->removeInvitation(it);
break;
}
}
}
if (!authd) {
if (InvitationManager::self()->invitations().size() > 0) {
KNotification::event("InvalidPasswordInvitations",
i18n("Failed login attempt from %1: wrong password",
remoteIp));
} else {
KNotification::event("InvalidPassword",
i18n("Failed login attempt from %1: wrong password",
remoteIp));
}
return false;
}
return true;
}
void ConnectionController::handleKeyEvent(bool down, rfbKeySym keySym)
{
if (controlEnabled) {
KeyboardEvent ev(down, keySym);
ev.exec();
}
}
void ConnectionController::handlePointerEvent(int bm, int x, int y)
{
if (controlEnabled) {
PointerEvent ev(bm, x, y);
ev.exec();
}
}
void ConnectionController::handleClientGone()
{
emit clientDisconnected(this);
kDebug() << "client gone";
deleteLater();
}
void ConnectionController::clipboardToServer(const QString &s)
{
ClipboardEvent ev(this, s);
ev.exec();
}
void ConnectionController::dialogAccepted()
{
ConnectionDialog *dialog = qobject_cast<ConnectionDialog*>(sender());
if (!dialog) {
kWarning() << "Wrong type of sender.";
return;
}
// rfbStartOnHoldClient(cl);
cl->onHold = false;
setControlEnabled(dialog->cbAllowRemoteControl->isChecked());
setControlCanBeEnabled(dialog->cbAllowRemoteControl->isChecked());
emit sessionEstablished(remoteIp);
}
void ConnectionController::dialogRejected()
{
kDebug() << "refused connection";
rfbRefuseOnHoldClient(cl);
}
void ConnectionController::setControlEnabled(bool enable)
{
controlEnabled = enable;
}
void ConnectionController::setControlCanBeEnabled(bool canBeEnabled)
{
m_controlCanBeEnabled = canBeEnabled;
}
bool ConnectionController::controlCanBeEnabled() const
{
return m_controlCanBeEnabled;
}

68
connectioncontroller.h Normal file
View File

@@ -0,0 +1,68 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
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 CONNECTIONCONTROLLER_H
#define CONNECTIONCONTROLLER_H
#include <QObject>
#include <rfb/rfb.h>
class KrfbServer;
/**
@author Alessandro Praduroux <pradu@pradu.it>
*/
class ConnectionController : public QObject
{
Q_OBJECT
public:
ConnectionController(struct _rfbClientRec *_cl, KrfbServer *parent);
~ConnectionController();
bool handleCheckPassword(rfbClientPtr cl, const char *response, int len);
void handleNegotiationFinished(struct _rfbClientRec *cl);
void handleKeyEvent(bool down , rfbKeySym keySym );
void handlePointerEvent( int bm, int x, int y);
void handleClientGone();
void clipboardToServer(const QString &);
enum rfbNewClientAction handleNewClient();
void setControlEnabled(bool enable);
void setControlCanBeEnabled(bool canBeEnabled);
bool controlCanBeEnabled() const;
Q_SIGNALS:
void sessionEstablished(QString);
void notification(QString, QString);
void clientDisconnected(ConnectionController *);
protected Q_SLOTS:
void dialogAccepted();
void dialogRejected();
private:
QString remoteIp;
struct _rfbClientRec *cl;
bool controlEnabled;
bool m_controlCanBeEnabled;
/*
int fd;
KrfbServer *server;
rfbScreenInfoPtr screen;
rfbClientPtr client;
QTcpSocket *tcpConn;
*/
};
#endif

71
connectiondialog.cpp Normal file
View File

@@ -0,0 +1,71 @@
/* 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., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "connectiondialog.h"
#include <QCheckBox>
#include <QLabel>
#include <KIconLoader>
#include <KLocale>
#include <KStandardGuiItem>
ConnectionDialog::ConnectionDialog( QWidget *parent )
: KDialog( parent )
{
setCaption(i18n("New Connection"));
setButtons(Ok|Cancel);
setDefaultButton(Cancel);
setModal(true);
setMinimumSize(500, 200);
m_connectWidget = new QWidget( this );
setupUi(m_connectWidget);
pixmapLabel->setPixmap(KIcon("krfb").pixmap(128));
KGuiItem accept = KStandardGuiItem::ok();
accept.setText( i18n( "Accept Connection" ) );
setButtonGuiItem(Ok, accept);
KGuiItem refuse = KStandardGuiItem::cancel();
refuse.setText( i18n( "Refuse Connection" ) );
setButtonGuiItem(Cancel, refuse);
setMainWidget( m_connectWidget );
}
void ConnectionDialog::setRemoteHost( const QString &host )
{
remoteHost->setText( host );
}
void ConnectionDialog::setAllowRemoteControl( bool b )
{
cbAllowRemoteControl->setChecked( b );
cbAllowRemoteControl->setVisible(b);
}
bool ConnectionDialog::allowRemoteControl()
{
return cbAllowRemoteControl->isChecked();
}
#include "connectiondialog.moc"

View File

@@ -1,8 +1,5 @@
/* This file is part of the KDE project
Copyright (C) 2009 Collabora Ltd <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
Copyright (C) 2001-2003 by Tim Jansen <tim@tjansen.de>
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
@@ -20,11 +17,29 @@
Boston, MA 02110-1301, USA.
*/
#include <QtCore/QString>
#ifndef CONNECTIONDIALOG_H
#define CONNECTIONDIALOG_H
QString peerAddress(int sock);
unsigned short peerPort(int sock);
#include <KDialog>
#include "ui_connectionwidget.h"
QString localAddress(int sock);
unsigned short localPort(int sock);
class QWidget;
class ConnectionDialog : public KDialog, public Ui::ConnectionWidget
{
Q_OBJECT
public:
ConnectionDialog( QWidget *parent );
~ConnectionDialog() {};
void setRemoteHost( const QString &host );
void setAllowRemoteControl( bool b );
bool allowRemoteControl();
protected:
QWidget *m_connectWidget;
};
#endif // CONNECTIONDIALOG_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 55 KiB

View File

@@ -324,7 +324,7 @@ as &krdc;.
<para>
If you select the <guilabel>Use default port</guilabel> checkbox,
then &krfb; will locate a suitable port, and invitations will match
this port. If you deselect this checkbox, you can specify a particular
this port. If you deselect the this checkbox, you can specify a particular
port. Specifying a particular port may be useful if you are using
port-forwarding on the firewall. Note that if Service Location
Protocol is turned on, this will automatically deal with identifying

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 54 KiB

197
events.cpp Normal file
View File

@@ -0,0 +1,197 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
(C) 2001-2003 by Tim Jansen <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 "events.h"
#include <QApplication>
#include <QX11Info>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/extensions/XTest.h>
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;
bool KeyboardEvent::initDone = false;
KeyboardEvent::KeyboardEvent(bool d, KeySym k)
: down(d), keySym(k)
{
initKeycodes();
}
void KeyboardEvent::initKeycodes()
{
if (initDone) return;
initDone = true;
KeySym key,*keymap;
int i,j,minkey,maxkey,syms_per_keycode;
dpy = QX11Info::display();
memset(modifiers,-1,sizeof(modifiers));
XDisplayKeycodes(dpy,&minkey,&maxkey);
Q_ASSERT(minkey >= 8);
Q_ASSERT(maxkey < 256);
keymap = (KeySym*) XGetKeyboardMapping(dpy, minkey,
(maxkey - minkey + 1),
&syms_per_keycode);
Q_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 = QX11Info::display();
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(ConnectionController *c, const QString &ctext)
:controller(c),text(ctext)
{
}
void ClipboardEvent::exec()
{
#if 0
if ((controller->lastClipboardDirection == ConnectionController::LAST_SYNC_TO_CLIENT) &&
(controller->lastClipboardText == text)) {
return;
}
controller->lastClipboardDirection = ConnectionController::LAST_SYNC_TO_SERVER;
controller->lastClipboardText = text;
controller->clipboard->setText(text, QClipboard::Clipboard);
controller->clipboard->setText(text, QClipboard::Selection);
#endif
}
VNCEvent::~ VNCEvent()
{
}

70
events.h Normal file
View File

@@ -0,0 +1,70 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
(C) 2001-2003 by Tim Jansen <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 EVENTS_H
#define EVENTS_H
#include <QDesktopWidget>
#include <QEvent>
#include <QString>
#include <X11/Xlib.h>
class ConnectionController;
class QCursor;
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 bool initDone;
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 {
ConnectionController *controller;
QString text;
public:
ClipboardEvent(ConnectionController *c, const QString &text);
virtual void exec();
};
#endif

View File

@@ -8,14 +8,15 @@
*/
#include "framebuffer.h"
#include "framebuffer.moc"
#include "config-krfb.h"
#include <config-krfb.h>
#include <X11/Xutil.h>
FrameBuffer::FrameBuffer(WId id, QObject *parent)
: QObject(parent), win(id)
: QObject(parent), win(id)
{
}
@@ -24,7 +25,7 @@ FrameBuffer::~FrameBuffer()
delete fb;
}
char *FrameBuffer::data()
char * FrameBuffer::data()
{
return fb;
}
@@ -68,6 +69,3 @@ void FrameBuffer::stopMonitor()
{
}
#include "framebuffer.moc"

View File

@@ -10,29 +10,28 @@
#ifndef FRAMEBUFFER_H
#define FRAMEBUFFER_H
#include "rfb.h"
#include <QObject>
#include <QRect>
#include <QList>
#include <QWidget>
#include <kdemacros.h>
#include <QtCore/QObject>
#include <QtCore/QRect>
#include <QtCore/QList>
#include <QtGui/QWidget>
#include <rfb/rfb.h>
class FrameBuffer;
/**
@author Alessandro Praduroux <pradu@pradu.it>
@author Alessandro Praduroux <pradu@pradu.it>
*/
class KDE_EXPORT FrameBuffer : public QObject
{
Q_OBJECT
Q_OBJECT
public:
explicit FrameBuffer(WId id, QObject *parent = 0);
virtual ~FrameBuffer();
char *data();
char * data();
virtual QList<QRect> modifiedTiles();
virtual int paddedWidth();

View File

@@ -64,26 +64,25 @@ void FrameBufferManager::loadPlugins()
KService::List offers = KServiceTypeTrader::self()->query("krfb/framebuffer");
KService::List::const_iterator iter;
for (iter = offers.constBegin(); iter < offers.constEnd(); ++iter) {
QString error;
KService::Ptr service = *iter;
QString error;
KService::Ptr service = *iter;
KPluginFactory *factory = KPluginLoader(service->library()).factory();
KPluginFactory *factory = KPluginLoader(service->library()).factory();
if (!factory) {
kWarning() << "KPluginFactory could not load the plugin:" << service->library();
continue;
}
FrameBufferPlugin *plugin = factory->create<FrameBufferPlugin>(this);
FrameBufferPlugin *plugin = factory->create<FrameBufferPlugin>(this);
if (plugin) {
kDebug() << "Loaded plugin:" << service->name();
m_plugins.insert(service->library(), plugin);
} else {
kDebug() << error;
}
if (plugin) {
kDebug() << "Loaded plugin:" << service->name();
m_plugins.insert(service->library(), plugin);
} else {
kDebug() << error;
}
}
}
@@ -105,8 +104,7 @@ QSharedPointer<FrameBuffer> FrameBufferManager::frameBuffer(WId id)
}
// We don't already have that frame buffer.
QMap<QString, FrameBufferPlugin *>::const_iterator iter = m_plugins.constBegin();
QMap<QString, FrameBufferPlugin*>::const_iterator iter = m_plugins.constBegin();
while (iter != m_plugins.constEnd()) {
if (iter.key() == KrfbConfig::preferredFrameBufferPlugin()) {

View File

@@ -29,7 +29,6 @@
#include <QtCore/QObject>
#include <QtCore/QSharedPointer>
#include <QtCore/QWeakPointer>
#include <QtGui/QWidget>
class FrameBufferPlugin;
@@ -54,7 +53,7 @@ private:
void loadPlugins();
QMap<QString, FrameBufferPlugin *> m_plugins;
QMap<QString, FrameBufferPlugin*> m_plugins;
QMap<WId, QWeakPointer<FrameBuffer> > m_frameBuffers;
};

View File

@@ -23,7 +23,7 @@
#include "framebuffer.h"
FrameBufferPlugin::FrameBufferPlugin(QObject *parent, const QVariantList &)
: QObject(parent)
: QObject(parent)
{
}

View File

@@ -24,7 +24,6 @@
#include <kdemacros.h>
#include <QtCore/QVariantList>
#include <QtGui/QWidget>
class FrameBuffer;

View File

@@ -2,38 +2,28 @@
Encoding=UTF-8
Comment=Qt based Framebuffer for KRfb.
Comment[ast]=Esquema Qt de buffer pa KRfb
Comment[bs]=Kadrobafer za KRfb na osnovu Qt
Comment[ca]=«Framebuffer» basat en Qt per al KRfb.
Comment[ca@valencia]=«Framebuffer» basat en Qt per al KRfb.
Comment[cs]=Framebuffer založený na Qt pro KRfb.
Comment[da]=Qt-baseret framebuffer til KRfb.
Comment[de]=Qt-basierter Framebuffer für KRfb
Comment[el]=Μνήμη εξόδου βίντεο καρέ με βάση το Qt για το KRfb.
Comment[en_GB]=Qt based Framebuffer for KRfb.
Comment[es]=Memoria intermedia de vídeo basada en Qt para KRfb.
Comment[es]=Esquema Qt de buffer para KRfb
Comment[et]=KRfb Qt põhine kaadripuhver
Comment[eu]=Qt-n oinarritutako KRfb-ren irteerako bideoa
Comment[fi]=QT-perustainen Kehyspuskuri KRfb:lle
Comment[fr]=Sortie vidéo fondée sur Qt pour KRfb.
Comment[ga]=Maolán fráma le haghaidh KRfb, bunaithe ar Qt.
Comment[fr]=Sortie vidéo basée sur Qt pour KRfb.
Comment[gl]=Framebuffer baseado en Qt para KRfb.
Comment[hr]=Međuspremnik okvira baziran na Qt-u za KRfb.
Comment[hu]=Qt-alapú framebuffer a Krfb-hez.
Comment[ia]=Framebuffer basate sur Qt per KRfb
Comment[hu]=Qt-alapú keretpuffer a KRfb-hez.
Comment[it]=Framebuffer basato su Qt per KRfb.
Comment[kk]=Qt негіздеген KRfb-нің кадр буфері.
Comment[km]=Framebuffer មាន​មូលដ្ឋាន​លើ Qt សម្រាប់ KRfb 
Comment[ko]=KRfb를 위한 Qt 기반 프레임버퍼.
Comment[lt]=Qt pagrindu veikiantis Framebuffer skirtas KRfb.
Comment[lv]=Qt balstīts kadrbuferis priekš KRfb.
Comment[nb]=Qt-basert rammebuffer for KRfb.
Comment[nds]=Op Qt opbuut Bildpuffer för KRfb
Comment[nl]=Op Qt gebaseerd framebuffer voor KRfb.
Comment[nn]=Qt basert framebuffer for KRfb.
Comment[pl]=Bufor ramki na podstawie Qt dla KRfb.
Comment[pt]='Framebuffer' baseado no Qt para o KRfb.
Comment[pt_BR]=Framebuffer baseado no Qt para o KRfb.
Comment[si]=KRfb සඳහා Qt මත පදනම් වූ රාමු බෆරය
Comment[sk]=Framebuffer založený na Qt pre KRfb.
Comment[sl]=Slikovni medpomnilnik za KRFB, ki temelji na Qt
Comment[sr]=Кадробафер за КРФБ на основу КуТу
@@ -48,38 +38,28 @@ Comment[zh_CN]=基于 Qt 的 KRfb 帧缓冲机制
Comment[zh_TW]=KRfb 的 Qt-based Framebuffer
Name=Qt Framebuffer for KRfb
Name[ast]=Esquema Qt de buffer pa KRfb
Name[bs]=Qt-ov kadrobafer za KRFB
Name[ca]=«Framebuffer» Qt per al KRfb.
Name[ca@valencia]=«Framebuffer» Qt per al KRfb.
Name[cs]=Qt Framebuffer pro KRfb
Name[da]=Qt-framebuffer til KRfb
Name[de]=Qt-Framebuffer für KRfb
Name[el]=Qt Framebuffer for KRfb
Name[en_GB]=Qt Framebuffer for KRfb
Name[es]=Memoria intermedia de vídeo Qt para KRfb
Name[es]=Esquema Qt de buffer para KRfb
Name[et]=KRfb Qt kaadripuhver
Name[eu]=KRfb-ren Qt-ko irteerako bideoa
Name[fi]=QT-kehyspuskuri KRfb:lle
Name[fr]=Sortie vidéo Qt pour KRfb
Name[ga]=Maolán fráma Qt le haghaidh KRfb
Name[gl]=Framebuffer de Qt para KRfb
Name[hr]=Qt Framebuffer za KRfb
Name[hu]=Qt framebuffer a Krfb-hez
Name[ia]=Framebuffer Qt per KRfb
Name[hu]=Qt-alapú keretpuffer a KRfb-hez
Name[it]=Framebuffer Qt per KRfb
Name[kk]=Qt KRfb кадр буфері
Name[km]=Qt Framebuffer សម្រាប់for KRfb
Name[ko]=KRfb를 위한 Qt 프레임버퍼
Name[lt]=Qt Framebufferis skirtas KRfb
Name[lv]=Qt kadrbuferis priekš KRfb.
Name[nb]=Qt rammebuffer for KRfb
Name[nds]=Qt-Bildpuffer för KRfb
Name[nl]=Qt-framebuffer voor KRfb
Name[nn]=Qt-framebuffer for KRfb
Name[pl]=Bufor ramki Qt dla KRfb
Name[pt]='Framebuffer' do Qt para o KRfb
Name[pt_BR]=Framebuffer do Qt para o KRfb
Name[si]=KRfb සඳහා වන Qt රාමුබෆරය
Name[sk]=Qt Framebuffer pre KRfb
Name[sl]=Slikovni medpomnilnik Qt za KRFB
Name[sr]=КуТ‑ов кадробафер за КРФБ

View File

@@ -19,7 +19,7 @@
const int UPDATE_TIME = 500;
QtFrameBuffer::QtFrameBuffer(WId id, QObject *parent)
: FrameBuffer(id, parent)
: FrameBuffer(id, parent)
{
fbImage = QPixmap::grabWindow(win).toImage();
fb = new char[fbImage.numBytes()];
@@ -49,7 +49,7 @@ int QtFrameBuffer::width()
return fbImage.width();
}
void QtFrameBuffer::getServerFormat(rfbPixelFormat &format)
void QtFrameBuffer::getServerFormat(rfbPixelFormat& format)
{
format.bitsPerPixel = 32;
format.depth = 32;
@@ -80,12 +80,12 @@ void QtFrameBuffer::updateFrameBuffer()
map.fill(0);
for (int x = 0; x < imgSize.width(); x++) {
for (int y = 0; y < imgSize.height(); y++) {
if (img.pixel(x, y) != fbImage.pixel(x, y)) {
map.setPixel(x, y, 1);
}
}
}
for (int y = 0; y < imgSize.height(); y++) {
if (img.pixel(x,y) != fbImage.pixel(x,y)) {
map.setPixel(x,y,1);
}
}
}
QRegion r(QBitmap::fromImage(map));
tiles = tiles + r.rects();
@@ -94,7 +94,7 @@ void QtFrameBuffer::updateFrameBuffer()
tiles.append(img.rect());
#endif
memcpy(fb, (const char *)img.bits(), img.numBytes());
memcpy(fb, (const char*)img.bits(), img.numBytes());
fbImage = img;
}

View File

@@ -15,11 +15,11 @@
class QTimer;
/**
@author Alessandro Praduroux <pradu@pradu.it>
@author Alessandro Praduroux <pradu@pradu.it>
*/
class QtFrameBuffer : public FrameBuffer
{
Q_OBJECT
Q_OBJECT
public:
explicit QtFrameBuffer(WId id, QObject *parent = 0);
@@ -29,7 +29,7 @@ public:
virtual int height();
virtual int width();
virtual int paddedWidth();
virtual void getServerFormat(rfbPixelFormat &format);
virtual void getServerFormat(rfbPixelFormat& format);
virtual void startMonitor();
virtual void stopMonitor();

View File

@@ -26,7 +26,7 @@
QtFrameBufferPlugin::QtFrameBufferPlugin(QObject *parent, const QVariantList &args)
: FrameBufferPlugin(parent, args)
: FrameBufferPlugin(parent, args)
{
}

View File

@@ -2,38 +2,28 @@
Encoding=UTF-8
Comment=X11 XDamage/XShm based Framebuffer for KRfb.
Comment[ast]=Esquema de buffer pa KRfb basáu en XDamage/XShm
Comment[bs]=X11 XDamage/XShm baziran framebafer za KRfb.
Comment[ca]=«Framebuffer» basat en XDamage/XShmQt de l'X11 per al KRfb.
Comment[ca@valencia]=«Framebuffer» basat en XDamage/XShmQt de l'X11 per al KRfb.
Comment[cs]=Framebuffer založený na X11 XDamage/XShm pro KRfb.
Comment[da]=X11 XDamage/XShm-baseret framebuffer til KRfb.
Comment[de]=X11 XDamage/XShm-basierter Framebuffer für KRfb.
Comment[el]=Μνήμη εξόδου βίντεο καρέ με βάση το X11 XDamage/XShm για το KRfb.
Comment[en_GB]=X11 XDamage/XShm based Framebuffer for KRfb.
Comment[es]=Memoria intermedia de vídeo basada en X11 Damage/XShm para KRfb.
Comment[es]=Esquema de buffer para KRfb basado en XDamage/XShm
Comment[et]=KRfb X11 XDamage/XShm põhine kaadripuhver
Comment[eu]=X11 XDamage/XShm oinarritutako KRfb-ren irteerako bideoa.
Comment[fi]=X11 XDamage/XShm-perustainen kehyspuskui KRfb:lle.
Comment[fr]=Sortie vidéo fondée sur X11 XDamage / XShm pour KRfb.
Comment[ga]=Maolán fráma le haghaidh KRfb, bunaithe ar X11 XDamage/XShm
Comment[fr]=Sortie vidéo basée sur X11 XDamage / XShm pour KRfb.
Comment[gl]=Framebuffer baseado en Xll XDamage/Xshm para XRfb.
Comment[hr]=Međuspreminik okvira baziran na X11 XDamage/XShm za KRfb.
Comment[hu]=X11 XDamage/XShm-alapú framebuffer a Krfb-hez.
Comment[ia]=Framebuffer basate sur X11 XDamage/XShm per KRfb.
Comment[hu]=X11 XDamage/XShm-alapú keretpuffer a KRfb-hez.
Comment[it]=Framebuffer basato su XDamage/XShm di X11 per KRfb.
Comment[kk]=X11 XDamage/XShm негіздеген KRfb кадр буфері.
Comment[km]=X11 XDamage/XShm based Framebuffer សម្រាប់ KRfb 
Comment[ko]=KRfb를 위한 X11 XDamage/XShm 기반 프레임버퍼.
Comment[lt]=X11 XDamage/XShm paremtas Framebuffer skirtas KRfb.
Comment[lv]=X11 XDamage/XShm balstīts kadrbuferis priekš KRfb.
Comment[nb]=Rammebuffer for KRfb basert på X11 XDamage/XShm.
Comment[nds]=Op X11-XDamage/-XShm opbuut Bildpuffer för KRfb
Comment[nl]=Op X11 XDamage/XShm gebaseerd framebuffer voor KRfb.
Comment[nn]=X11 XDamage/XShm basert framebuffer for KRfb.
Comment[pl]=Bufor ramki na podstawie X11 XDamage/XShm dla KRfb.
Comment[pt]='Framebuffer' baseado no XDamage/XShm do X11 para o KRfb.
Comment[pt_BR]=Framebuffer baseado no XDamage/XShm do X11 para o KRfb.
Comment[si]=KRfb සඳහා වන රාමු බෆරය මත පදනම් වූ X11 XDamage/XShm.
Comment[sk]=Framebuffer založený na X11 XDamage/XShm pre KRfb.
Comment[sl]=Slikovni medpomnilnik za KRFB, ki temelji na X11 XDamage/XShm
Comment[sr]=Кадробафер за КРФБ на основу Икс‑демиџа/Икс‑схма у Иксу11.
@@ -48,38 +38,28 @@ Comment[zh_CN]=基于 X11 XDamage/XShm 扩展的 KRfb 帧缓冲机制。
Comment[zh_TW]=KRfb 的 X11 XDamage/XShm based Framebuffer
Name=X11 Framebuffer for KRfb
Name[ast]=Buffer de X11 pa KRfb
Name[bs]=X11 frame bafer za KRfb
Name[ca]=«Framebuffer» de l'X11 per al KRfb.
Name[ca@valencia]=«Framebuffer» de l'X11 per al KRfb.
Name[cs]=X11 Framebuffer pro KRfb
Name[da]=X11-framebuffer til KRfb
Name[de]=X11-Framebuffer für KRfb
Name[el]=X11 Framebuffer for KRfb
Name[en_GB]=X11 Framebuffer for KRfb
Name[es]=Memoria intermedia de vídeo X11 para KRfb
Name[es]=Buffer de X11 para KRfb
Name[et]=KRfb X11 kaadripuhver
Name[eu]=KRfb-ren X11-ko irteerako bideoa
Name[fi]=X11-kehyspuskuri KRfb:lle
Name[fr]=Sortie vidéo X11 pour KRfb
Name[ga]=Maolán fráma X11 le haghaidh KRfb
Name[gl]=Framebuffer de X11 para KRfb
Name[hr]=Međuspremnik okvira X11 za KRfb
Name[hu]=X11 framebuffer a Krfb-hez
Name[ia]=Framebuffer X11 per KRfb
Name[hu]=X11-alapú keretpuffer a KRfb-hez
Name[it]=Framebuffer X11 per KRfb
Name[kk]=X11 KRfb кадр буфері
Name[km]=X11 Framebuffer សម្រាប់ KRfb
Name[ko]=KRfb를 위한 X11 프레임버퍼
Name[lt]=X11 Framebuffer skirtas KRfb
Name[lv]=X11 kadrbuferis priekš KRfb
Name[nb]=X11 rammebuffer for KRfb
Name[nds]=X11-Bildpuffer för KRfb
Name[nl]=X11 framebuffer voor KRfb
Name[nn]=X11-framebuffer for KRfb
Name[pl]=Bufor ramki X11 dla KRfb
Name[pt]='Framebuffer' do X11 para o KRfb
Name[pt_BR]=Framebuffer do X11 para o KRfb
Name[si]=KRfb සඳහා X11 රාමු බෆරය
Name[sk]=X11 Framebuffer pre KRfb
Name[sl]=Slikovni medpomnilnik X11 za KRFB
Name[sr]=Икс11 кадробафер за КРФБ.

View File

@@ -32,8 +32,7 @@
#include <X11/extensions/XShm.h>
#endif
class X11FrameBuffer::P
{
class X11FrameBuffer::P {
public:
#ifdef HAVE_XDAMAGE
@@ -51,8 +50,8 @@ public:
bool running;
};
X11FrameBuffer::X11FrameBuffer(WId id, QObject *parent)
: FrameBuffer(id, parent), d(new X11FrameBuffer::P)
X11FrameBuffer::X11FrameBuffer(WId id, QObject* parent)
:FrameBuffer(id, parent), d(new X11FrameBuffer::P)
{
#ifdef HAVE_XSHM
d->useShm = XShmQueryExtension(QX11Info::display());
@@ -69,11 +68,10 @@ X11FrameBuffer::X11FrameBuffer(WId id, QObject *parent)
QApplication::desktop()->height(),
AllPlanes,
ZPixmap);
if (d->useShm) {
#ifdef HAVE_XSHM
d->updateTile = XShmCreateImage(QX11Info::display(),
DefaultVisual(QX11Info::display(), 0),
DefaultVisual( QX11Info::display(), 0 ),
d->framebufferImage->bits_per_pixel,
ZPixmap,
NULL,
@@ -85,7 +83,7 @@ X11FrameBuffer::X11FrameBuffer(WId id, QObject *parent)
IPC_CREAT | 0777);
d->shminfo.shmaddr = d->updateTile->data = (char *)
shmat(d->shminfo.shmid, 0, 0);
shmat(d->shminfo.shmid, 0, 0);
d->shminfo.readOnly = False;
XShmAttach(QX11Info::display(), &d->shminfo);
@@ -93,12 +91,11 @@ X11FrameBuffer::X11FrameBuffer(WId id, QObject *parent)
} else {
;
}
kDebug() << "Got image. bpp: " << d->framebufferImage->bits_per_pixel
<< ", depth: " << d->framebufferImage->depth
<< ", padded width: " << d->framebufferImage->bytes_per_line
<< " (sent: " << d->framebufferImage->width * 4 << ")"
<< endl;
<< ", depth: " << d->framebufferImage->depth
<< ", padded width: " << d->framebufferImage->bytes_per_line
<< " (sent: " << d->framebufferImage->width * 4 << ")"
<< endl;
fb = d->framebufferImage->data;
#ifdef HAVE_XDAMAGE
@@ -145,14 +142,14 @@ int X11FrameBuffer::paddedWidth()
return d->framebufferImage->bytes_per_line;
}
void X11FrameBuffer::getServerFormat(rfbPixelFormat &format)
void X11FrameBuffer::getServerFormat(rfbPixelFormat& format)
{
format.bitsPerPixel = d->framebufferImage->bits_per_pixel;
format.depth = d->framebufferImage->depth;
format.trueColour = true;
format.bigEndian = ((d->framebufferImage->bitmap_bit_order == MSBFirst) ? true : false);
if (format.bitsPerPixel == 8) {
if ( format.bitsPerPixel == 8 ) {
format.redShift = 0;
format.greenShift = 3;
format.blueShift = 6;
@@ -161,33 +158,24 @@ void X11FrameBuffer::getServerFormat(rfbPixelFormat &format)
format.blueMax = 3;
} else {
format.redShift = 0;
if (d->framebufferImage->red_mask)
while (!(d->framebufferImage->red_mask & (1 << format.redShift))) {
if ( d->framebufferImage->red_mask )
while ( ! ( d->framebufferImage->red_mask & (1 << format.redShift) ) )
format.redShift++;
}
format.greenShift = 0;
if (d->framebufferImage->green_mask)
while (!(d->framebufferImage->green_mask & (1 << format.greenShift))) {
if ( d->framebufferImage->green_mask )
while ( ! ( d->framebufferImage->green_mask & (1 << format.greenShift) ) )
format.greenShift++;
}
format.blueShift = 0;
if (d->framebufferImage->blue_mask)
while (!(d->framebufferImage->blue_mask & (1 << format.blueShift))) {
if ( d->framebufferImage->blue_mask )
while ( ! ( d->framebufferImage->blue_mask & (1 << format.blueShift) ) )
format.blueShift++;
}
format.redMax = d->framebufferImage->red_mask >> format.redShift;
format.greenMax = d->framebufferImage->green_mask >> format.greenShift;
format.blueMax = d->framebufferImage->blue_mask >> format.blueShift;
}
}
void X11FrameBuffer::handleXDamage(XEvent *event)
void X11FrameBuffer::handleXDamage(XEvent * event)
{
#ifdef HAVE_XDAMAGE
XDamageNotifyEvent *dev = (XDamageNotifyEvent *)event;
@@ -201,141 +189,118 @@ void X11FrameBuffer::handleXDamage(XEvent *event)
}
void X11FrameBuffer::cleanupRects()
{
void X11FrameBuffer::cleanupRects() {
QList<QRect> cpy = tiles;
bool inserted = false;
tiles.clear();
// kDebug() << "before cleanup: " << cpy.size();
foreach(const QRect & r, cpy) {
foreach (const QRect &r, cpy) {
if (tiles.size() > 0) {
for (int i = 0; i < tiles.size(); i++) {
// kDebug() << r << tiles[i];
for(int i = 0; i < tiles.size(); i++) {
// kDebug() << r << tiles[i];
if (r.intersects(tiles[i])) {
tiles[i] |= r;
inserted = true;
break;
// kDebug() << "merged into " << tiles[i];
// kDebug() << "merged into " << tiles[i];
}
}
if (!inserted) {
tiles.append(r);
// kDebug() << "appended " << r;
// kDebug() << "appended " << r;
}
} else {
// kDebug() << "appended " << r;
// kDebug() << "appended " << r;
tiles.append(r);
}
}
for (int i = 0; i < tiles.size(); i++) {
tiles[i].adjust(-30, -30, 30, 30);
if (tiles[i].top() < 0) {
for(int i = 0; i < tiles.size(); i++) {
tiles[i].adjust(-30,-30,30,30);
if (tiles[i].top() < 0){
tiles[i].setTop(0);
}
if (tiles[i].left() < 0) {
if (tiles[i].left() < 0){
tiles[i].setLeft(0);
}
if (tiles[i].bottom() > d->framebufferImage->height) {
tiles[i].setBottom(d->framebufferImage->height);
}
if (tiles[i].right() > d->framebufferImage->width) {
tiles[i].setRight(d->framebufferImage->width);
}
}
// kDebug() << "after cleanup: " << tiles.size();
}
void X11FrameBuffer::acquireEvents()
{
void X11FrameBuffer::acquireEvents() {
XEvent ev;
while (XCheckTypedEvent(QX11Info::display(), d->xdamageBaseEvent + XDamageNotify, &ev)) {
while (XCheckTypedEvent(QX11Info::display(), d->xdamageBaseEvent+XDamageNotify, &ev)) {
handleXDamage(&ev);
}
XDamageSubtract(QX11Info::display(), d->damage, None, None);
XDamageSubtract(QX11Info::display(),d->damage, None, None);
}
QList< QRect > X11FrameBuffer::modifiedTiles()
{
QList<QRect> ret;
if (!d->running) {
return ret;
}
if (!d->running) return ret;
kapp->processEvents(); // try to make sure every damage event goes trough;
cleanupRects();
QRect gl;
//d->useShm = false;
if (tiles.size() > 0) {
if (d->useShm) {
#ifdef HAVE_XSHM
foreach(const QRect & r, tiles) {
foreach(const QRect &r, tiles) {
// kDebug() << r;
gl |= r;
int y = r.y();
int x = r.x();
while (x < r.right()) {
while (y < r.bottom()) {
if (y + d->updateTile->height > d->framebufferImage->height) {
while (x < r.right() ) {
while (y < r.bottom() ) {
if (y+d->updateTile->height > d->framebufferImage->height) {
y = d->framebufferImage->height - d->updateTile->height;
}
if (x + d->updateTile->width > d->framebufferImage->width) {
if (x+d->updateTile->width > d->framebufferImage->width) {
x = d->framebufferImage->width - d->updateTile->width;
}
// kDebug() << "x: " << x << " (" << r.x() << ") y: " << y << " (" << r.y() << ") " << r;
XShmGetImage(QX11Info::display(), win, d->updateTile, x, y, AllPlanes);
int pxsize = d->framebufferImage->bits_per_pixel / 8;
char *dest = fb + ((d->framebufferImage->bytes_per_line * y) + (x * pxsize));
char *dest = fb + ((d->framebufferImage->bytes_per_line * y) + (x*pxsize));
char *src = d->updateTile->data;
for (int i = 0; i < d->updateTile->height; i++) {
memcpy(dest, src, d->updateTile->bytes_per_line);
dest += d->framebufferImage->bytes_per_line;
src += d->updateTile->bytes_per_line;
}
y += d->updateTile->height;
}
x += d->updateTile->width;
y = r.y();
}
}
#endif
} else {
foreach(const QRect & r, tiles) {
foreach(const QRect &r, tiles) {
XGetSubImage(QX11Info::display(),
win,
r.left(),
r.top(),
r.width(),
r.height(),
AllPlanes,
ZPixmap,
d->framebufferImage,
r.left(),
r.top()
);
win,
r.left(),
r.top(),
r.width(),
r.height(),
AllPlanes,
ZPixmap,
d->framebufferImage,
r.left(),
r.top()
);
}
}
}
// kDebug() << "tot: " << gl;
// kDebug() << tiles.size();
ret = tiles;
@@ -348,7 +313,7 @@ void X11FrameBuffer::startMonitor()
d->running = true;
#ifdef HAVE_XDAMAGE
d->damage = XDamageCreate(QX11Info::display(), win, XDamageReportRawRectangles);
XDamageSubtract(QX11Info::display(), d->damage, None, None);
XDamageSubtract(QX11Info::display(),d->damage, None, None);
#endif
}
@@ -356,14 +321,14 @@ void X11FrameBuffer::stopMonitor()
{
d->running = false;
#ifdef HAVE_XDAMAGE
XDamageDestroy(QX11Info::display(), d->damage);
XDamageDestroy(QX11Info::display(),d->damage);
#endif
}
EvWidget::EvWidget(X11FrameBuffer *x11fb)
: QWidget(0), fb(x11fb)
EvWidget::EvWidget(X11FrameBuffer * x11fb)
:QWidget(0), fb(x11fb)
{
#ifdef HAVE_XDAMAGE
int er;
@@ -371,15 +336,13 @@ EvWidget::EvWidget(X11FrameBuffer *x11fb)
#endif
}
bool EvWidget::x11Event(XEvent *event)
bool EvWidget::x11Event(XEvent * event)
{
#ifdef HAVE_XDAMAGE
if (event->type == xdamageBaseEvent + XDamageNotify) {
if (event->type == xdamageBaseEvent+XDamageNotify) {
fb->handleXDamage(event);
return true;
}
#endif
return false;
}

View File

@@ -14,15 +14,14 @@
class X11FrameBuffer;
class EvWidget: public QWidget
{
class EvWidget: public QWidget {
Q_OBJECT
public:
EvWidget(X11FrameBuffer *x11fb);
protected:
bool x11Event(XEvent *event);
bool x11Event ( XEvent * event );
private:
X11FrameBuffer *fb;
@@ -30,13 +29,13 @@ private:
};
/**
@author Alessandro Praduroux <pradu@pradu.it>
@author Alessandro Praduroux <pradu@pradu.it>
*/
class X11FrameBuffer : public FrameBuffer
{
Q_OBJECT
Q_OBJECT
public:
X11FrameBuffer(WId id, QObject *parent = 0);
X11FrameBuffer(WId id, QObject* parent = 0);
~X11FrameBuffer();
@@ -45,18 +44,18 @@ public:
virtual int height();
virtual int width();
virtual int paddedWidth();
virtual void getServerFormat(rfbPixelFormat &format);
virtual void getServerFormat(rfbPixelFormat& format);
virtual void startMonitor();
virtual void stopMonitor();
void handleXDamage(XEvent *event);
void handleXDamage( XEvent *event);
private:
void cleanupRects();
void acquireEvents();
class P;
P *const d;
P * const d;
};
#endif

View File

@@ -26,7 +26,7 @@
X11FrameBufferPlugin::X11FrameBufferPlugin(QObject *parent, const QVariantList &args)
: FrameBufferPlugin(parent, args)
: FrameBufferPlugin(parent, args)
{
}

View File

@@ -21,45 +21,35 @@
// a random string that doesn't contain i, I, o, O, 1, 0
// based on KRandom::randomString()
static QString readableRandomString(int length)
{
QString str;
while (length) {
int r = KRandom::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;
static QString readableRandomString(int length) {
QString str;
while (length)
{
int r = KRandom::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_password = readableRandomString(4) + '-' + readableRandomString(3);
m_creationTime = QDateTime::currentDateTime();
m_expirationTime = QDateTime::currentDateTime().addSecs(INVITATION_DURATION);
m_password = readableRandomString(4)+'-'+readableRandomString(3);
m_creationTime = QDateTime::currentDateTime();
m_expirationTime = QDateTime::currentDateTime().addSecs(INVITATION_DURATION);
}
Invitation::Invitation(const Invitation &x)
@@ -67,54 +57,47 @@ Invitation::Invitation(const Invitation &x)
{
}
Invitation::Invitation(const KConfigGroup &config)
{
m_password = KStringHandler::obscure(config.readEntry("password", QString()));
Invitation::Invitation(const KConfigGroup &config) {
m_password = KStringHandler::obscure(config.readEntry("password", QString()));
kDebug() << "read: " << config.readEntry("password", QString()) << " = " << m_password;
m_creationTime = config.readEntry("creation", QDateTime());
m_expirationTime = config.readEntry("expiration", QDateTime());
m_creationTime = config.readEntry("creation", QDateTime());
m_expirationTime = config.readEntry("expiration", QDateTime());
}
Invitation::~Invitation()
{
Invitation::~Invitation() {
}
Invitation &Invitation::operator= (const Invitation &x)
{
m_password = x.m_password;
m_creationTime = x.m_creationTime;
m_expirationTime = x.m_expirationTime;
return *this;
Invitation &Invitation::operator= (const Invitation&x) {
m_password = x.m_password;
m_creationTime = x.m_creationTime;
m_expirationTime = x.m_expirationTime;
return *this;
}
void Invitation::save(KConfigGroup &config) const
void Invitation::save(KConfigGroup &config) const
{
config.writeEntry("password", KStringHandler::obscure(m_password));
config.writeEntry("creation", m_creationTime);
config.writeEntry("expiration", m_expirationTime);
}
QString Invitation::password() const
{
return m_password;
QString Invitation::password() const {
return m_password;
}
QDateTime Invitation::expirationTime() const
{
return m_expirationTime;
QDateTime Invitation::expirationTime() const {
return m_expirationTime;
}
QDateTime Invitation::creationTime() const
{
return m_creationTime;
QDateTime Invitation::creationTime() const {
return m_creationTime;
}
bool Invitation::isValid() const
{
return m_expirationTime > QDateTime::currentDateTime();
bool Invitation::isValid() const {
return m_expirationTime > QDateTime::currentDateTime();
}
bool Invitation::operator ==(const Invitation &ot)
bool Invitation::operator ==(const Invitation & ot)
{
return m_creationTime == ot.m_creationTime && m_password == ot.m_password;
}

View File

@@ -20,33 +20,33 @@
#include <KApplication>
#include <KConfig>
#include <QObject>
#include <QtCore/QDateTime>
#include <QtCore/QObject>
#include <QDateTime>
const int INVITATION_DURATION = 60 * 60;
class Invitation
{
const int INVITATION_DURATION = 60*60;
class Invitation {
public:
Invitation();
~Invitation();
Invitation(const KConfigGroup &config);
Invitation(const Invitation &x);
Invitation &operator= (const Invitation &x);
Invitation();
~Invitation();
Invitation(const KConfigGroup &config);
Invitation(const Invitation &x);
Invitation &operator= (const Invitation&x);
bool operator == (const Invitation &ot);
QString password() const;
QDateTime expirationTime() const;
QDateTime creationTime() const;
bool isValid() const;
QString password() const;
QDateTime expirationTime() const;
QDateTime creationTime() const;
bool isValid() const;
void save(KConfigGroup &config) const;
void save(KConfigGroup &config) const;
private:
QString m_password;
QDateTime m_creationTime;
QDateTime m_expirationTime;
QString m_password;
QDateTime m_creationTime;
QDateTime m_expirationTime;
};

View File

@@ -13,7 +13,7 @@
#include <KConfig>
#include <KGlobal>
#include <QtCore/QTimer>
#include <QTimer>
class InvitationManagerPrivate
{
@@ -23,8 +23,7 @@ public:
K_GLOBAL_STATIC(InvitationManagerPrivate, invitationManagerPrivate)
InvitationManager *InvitationManager::self()
{
InvitationManager * InvitationManager::self() {
return &invitationManagerPrivate->instance;
}
@@ -34,7 +33,7 @@ InvitationManager::InvitationManager()
QTimer *refreshTimer = new QTimer(this);
connect(refreshTimer, SIGNAL(timeout()), SLOT(loadInvitations()));
refreshTimer->start(1000 * 60);
refreshTimer->start(1000*60);
}
@@ -43,16 +42,14 @@ InvitationManager::~InvitationManager()
}
void InvitationManager::invalidateOldInvitations()
{
void InvitationManager::invalidateOldInvitations() {
int invNum = invitationList.size();
while (invNum--) {
while(invNum--) {
if (!invitationList[invNum].isValid()) {
invitationList.removeAt(invNum);
}
}
saveInvitations();
}
@@ -63,17 +60,15 @@ void InvitationManager::loadInvitations()
KSharedConfigPtr conf = KGlobal::config();
KConfigGroup invitationConfig(conf, "Invitations");
int numInv = invitationConfig.readEntry("invitation_num", 0);
int numInv = invitationConfig.readEntry("invitation_num",0);
invitationList.clear();
for (int i = 0; i < numInv; i++) {
KConfigGroup ic(conf, QString("Invitation_%1").arg(i));
invitationList.append(Invitation(ic));
}
invalidateOldInvitations();
if (numInv != invNum) {
emit invitationNumChanged(invitationList.size());
}
@@ -99,13 +94,11 @@ void InvitationManager::saveInvitations()
KSharedConfigPtr conf = KGlobal::config();
KConfigGroup invitationConfig(conf, "Invitations");
int invNum = invitationList.size();
invitationConfig.writeEntry("invitation_num", invNum);
invitationConfig.writeEntry("invitation_num",invNum);
for (int i = 0; i < invNum; i++) {
KConfigGroup ic(conf, QString("Invitation_%1").arg(i));
invitationList[i].save(ic);
}
conf->sync();
}
@@ -115,7 +108,7 @@ int InvitationManager::activeInvitations()
return invitationList.size();
}
void InvitationManager::removeInvitation(const Invitation &inv)
void InvitationManager::removeInvitation(const Invitation & inv)
{
invitationList.removeAll(inv);
saveInvitations();

View File

@@ -9,19 +9,19 @@
#ifndef INVITATIONMANAGER_H
#define INVITATIONMANAGER_H
#include <QObject>
#include <QList>
#include "invitation.h"
#include <QtCore/QList>
#include <QtCore/QObject>
class InvitationManagerPrivate;
/**
@author Alessandro Praduroux <pradu@pradu.it>
@author Alessandro Praduroux <pradu@pradu.it>
*/
class InvitationManager : public QObject
{
Q_OBJECT
friend class InvitationManagerPrivate;
Q_OBJECT
friend class InvitationManagerPrivate;
public:
static InvitationManager *self();

87
invitedialog.cpp Normal file
View File

@@ -0,0 +1,87 @@
/* 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., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "invitedialog.h"
#include <kiconloader.h>
#include <klocale.h>
#include <KStandardGuiItem>
#include <QtGui/QLabel>
#include <QtGui/QPushButton>
#include <QtGui/QToolTip>
#include <QtGui/QCursor>
InviteDialog::InviteDialog( QWidget *parent )
: KDialog( parent )
{
setCaption(i18n("Invitation"));
setButtons(User1|Close|Help);
setHelp(QString(), "krfb");
setDefaultButton(NoDefault);
setMinimumSize(500, 300);
m_inviteWidget = new QWidget( this );
setupUi(m_inviteWidget);
pixmapLabel->setPixmap(KIcon("krfb").pixmap(128));
setMainWidget( m_inviteWidget );
setButtonGuiItem( User1, KStandardGuiItem::configure() );
connect( btnCreateInvite, SIGNAL( clicked() ),
SIGNAL( createInviteClicked() ) );
connect( btnEmailInvite, SIGNAL( clicked() ),
SIGNAL( emailInviteClicked() ) );
connect( btnManageInvite, SIGNAL( clicked() ),
SIGNAL( manageInviteClicked() ) );
connect( helpLabel, SIGNAL( linkActivated ( QString ) ),
SLOT( showWhatsthis() ));
}
void InviteDialog::slotUser1()
{
emit configureClicked();
}
void InviteDialog::enableInviteButton( bool enable )
{
btnCreateInvite->setEnabled( enable );
}
void InviteDialog::setInviteCount( int count )
{
btnManageInvite->setText(
i18n( "&Manage Invitations (%1)...", count ) );
}
void InviteDialog::showWhatsthis()
{
QToolTip::showText(QCursor::pos(),
i18n("An invitation creates a one-time password that allows the receiver to connect to your desktop.\n"
"It is valid for only one successful connection and will expire after an hour if it has not been used. \n"
"When somebody connects to your computer a dialog will appear and ask you for permission.\n "
"The connection will not be established before you accept it. In this dialog you can also\n restrict "
"the other person to view your desktop only, without the ability to move your\n mouse pointer or press "
"keys.\nIf you want to create a permanent password for Desktop Sharing, allow 'Uninvited Connections' \n"
"in the configuration."));
}
#include "invitedialog.moc"

View File

@@ -28,28 +28,28 @@ class QWidget;
class InviteDialog : public KDialog, public Ui::InviteWidget
{
Q_OBJECT
Q_OBJECT
public:
InviteDialog(QWidget *parent);
public:
InviteDialog( QWidget *parent );
~InviteDialog() {}
void enableInviteButton(bool enable);
void enableInviteButton( bool enable );
public Q_SLOTS:
void setInviteCount(int count);
public Q_SLOTS:
void setInviteCount( int count );
void showWhatsthis();
signals:
signals:
void createInviteClicked();
void emailInviteClicked();
void manageInviteClicked();
void configureClicked();
protected Q_SLOTS:
protected Q_SLOTS:
void slotUser1();
protected:
protected:
QWidget *m_inviteWidget;
};

View File

@@ -1,6 +1,6 @@
include_directories(${CMAKE_BINARY_DIR}/krfb/krfb)
include_directories(${CMAKE_BINARY_DIR}/krfb/krfb/ ${CMAKE_SOURCE_DIR}/krfb/srvloc/)
set(kcm_krfb_PART_SRCS kcm_krfb.cpp ${krfbconfig_SRCS})
set(kcm_krfb_PART_SRCS kcm_krfb.cpp ${srvloc_SRCS} ${krfbconfig_SRCS})
kde4_add_ui3_files(kcm_krfb_PART_SRCS configurationwidget.ui)
kde4_add_ui3_files(kcm_krfb_PART_SRCS
@@ -10,7 +10,7 @@ kde4_add_ui3_files(kcm_krfb_PART_SRCS
kde4_add_plugin(kcm_krfb ${kcm_krfb_PART_SRCS})
target_link_libraries(kcm_krfb ${KDE4_KDECORE_LIBS} ${KDE4_KDE3SUPPORT_LIBS})
target_link_libraries(kcm_krfb ${KDE4_KDECORE_LIBS} ${KDE4_KDE3SUPPORT_LIBS} ${SLP_LIBRARIES})
install(TARGETS kcm_krfb DESTINATION ${PLUGIN_INSTALL_DIR})

View File

@@ -1,3 +1,2 @@
#! /bin/sh
$EXTRACTRC *.ui >> rc.cpp
$XGETTEXT *.cpp -o $podir/kcm_krfb.pot

View File

@@ -39,142 +39,128 @@
typedef KGenericFactory<KcmKRfb, QWidget> KcmKRfbFactory;
K_EXPORT_COMPONENT_FACTORY(krfb, KcmKRfbFactory("kcm_krfb"))
K_EXPORT_COMPONENT_FACTORY( krfb, KcmKRfbFactory( "kcm_krfb" ) )
KcmKRfb::KcmKRfb(QWidget *p, const QStringList &) :
KCModule(KcmKRfbFactory::componentData(), p),
m_configuration(KRFB_CONFIGURATION_MODE)
{
KCModule(KcmKRfbFactory::componentData(), p),
m_configuration(KRFB_CONFIGURATION_MODE) {
KGlobal::locale()->insertCatalog("krfb");
m_confWidget = new ConfigurationWidget(this);
KGlobal::locale()->insertCatalog("krfb");
m_confWidget = new ConfigurationWidget(this);
QVBoxLayout *l = new QVBoxLayout(this);
l->setSpacing(KDialog::spacingHint());
l->setMargin(0);
l->add(m_confWidget);
QVBoxLayout *l = new QVBoxLayout(this);
l->setSpacing(KDialog::spacingHint());
l->setMargin(0);
l->add(m_confWidget);
setButtons(Default | Apply | Default);
setButtons(Default|Apply|Default);
KAboutData *about = new KAboutData("kcm_krfb", 0, ki18n("Desktop Sharing Control Module"),
VERSION,
ki18n("Configure desktop sharing"), KAboutData::License_GPL,
ki18n("(c) 2002, Tim Jansen\n"),
KLocalizedString(), "http://www.tjansen.de/krfb", "tim@tjansen.de");
about->addAuthor(ki18n("Tim Jansen"), KLocalizedString(), "tim@tjansen.de");
setAboutData(about);
KAboutData* about = new KAboutData( "kcm_krfb", 0, ki18n("Desktop Sharing Control Module"),
VERSION,
ki18n("Configure desktop sharing"), KAboutData::License_GPL,
ki18n("(c) 2002, Tim Jansen\n"),
KLocalizedString(), "http://www.tjansen.de/krfb", "tim@tjansen.de");
about->addAuthor(ki18n("Tim Jansen"), KLocalizedString(), "tim@tjansen.de");
setAboutData( about );
load();
load();
connect(m_confWidget->passwordInput, SIGNAL(textChanged(QString)), SLOT(configChanged()));
connect(m_confWidget->allowUninvitedCB, SIGNAL(clicked()), SLOT(configChanged()));
connect(m_confWidget->enableSLPCB, SIGNAL(clicked()), SLOT(configChanged()));
connect(m_confWidget->confirmConnectionsCB, SIGNAL(clicked()), SLOT(configChanged()));
connect(m_confWidget->allowDesktopControlCB, SIGNAL(clicked()), SLOT(configChanged()));
connect(m_confWidget->autoPortCB, SIGNAL(clicked()), SLOT(configChanged()));
connect(m_confWidget->portInput, SIGNAL(valueChanged(int)), SLOT(configChanged()));
connect((QObject *)m_confWidget->manageInvitations, SIGNAL(clicked()),
&m_configuration, SLOT(showManageInvitationsDialog()));
connect(&m_configuration, SIGNAL(invitationNumChanged(int)),
this, SLOT(setInvitationNum(int)));
setInvitationNum(m_configuration.invitations().size());
connect(m_confWidget->disableBackgroundCB, SIGNAL(clicked()), SLOT(configChanged()));
connect(m_confWidget->passwordInput, SIGNAL(textChanged(const QString&)), SLOT(configChanged()) );
connect(m_confWidget->allowUninvitedCB, SIGNAL(clicked()), SLOT(configChanged()) );
connect(m_confWidget->enableSLPCB, SIGNAL(clicked()), SLOT(configChanged()) );
connect(m_confWidget->confirmConnectionsCB, SIGNAL(clicked()), SLOT(configChanged()) );
connect(m_confWidget->allowDesktopControlCB, SIGNAL(clicked()), SLOT(configChanged()) );
connect(m_confWidget->autoPortCB, SIGNAL(clicked()), SLOT(configChanged()) );
connect(m_confWidget->portInput, SIGNAL(valueChanged(int)), SLOT(configChanged()) );
connect((QObject*)m_confWidget->manageInvitations, SIGNAL(clicked()),
&m_configuration, SLOT(showManageInvitationsDialog()) );
connect(&m_configuration, SIGNAL(invitationNumChanged(int)),
this, SLOT(setInvitationNum(int)));
setInvitationNum(m_configuration.invitations().size());
connect(m_confWidget->disableBackgroundCB, SIGNAL(clicked()), SLOT(configChanged()) );
}
void KcmKRfb::configChanged()
{
emit changed(true);
void KcmKRfb::configChanged() {
emit changed(true);
}
void KcmKRfb::setInvitationNum(int num)
{
if (num == 0) {
m_confWidget->invitationNumLabel->setText(i18n("You have no open invitation."));
} else {
m_confWidget->invitationNumLabel->setText(i18n("Open invitations: %1", num));
}
void KcmKRfb::setInvitationNum(int num) {
if (num == 0)
m_confWidget->invitationNumLabel->setText(i18n("You have no open invitation."));
else
m_confWidget->invitationNumLabel->setText(i18n("Open invitations: %1", num));
}
void KcmKRfb::checkKInetd(bool &kinetdAvailable, bool &krfbAvailable)
{
kinetdAvailable = false;
krfbAvailable = false;
//TODO verify it when kinetd will port
QDBusInterface kinetd("org.kde.kded", "/modules/kinetd", "org.kde.kinetd");
QDBusReply<bool> reply = kinetd.call("isInstalled", "krfb");
if (!reply.isValid()) {
return;
}
krfbAvailable = reply;
kinetdAvailable = true;
void KcmKRfb::checkKInetd(bool &kinetdAvailable, bool &krfbAvailable) {
kinetdAvailable = false;
krfbAvailable = false;
//TODO verify it when kinetd will port
QDBusInterface kinetd("org.kde.kded", "/modules/kinetd", "org.kde.kinetd");
QDBusReply<bool> reply = kinetd.call("isInstalled","krfb");
if(!reply.isValid())
return;
krfbAvailable = reply;
kinetdAvailable=true;
}
void KcmKRfb::load()
{
bool kinetdAvailable, krfbAvailable;
checkKInetd(kinetdAvailable, krfbAvailable);
void KcmKRfb::load() {
bool kinetdAvailable, krfbAvailable;
checkKInetd(kinetdAvailable, krfbAvailable);
m_confWidget->allowUninvitedCB->setChecked(m_configuration.allowUninvitedConnections());
m_confWidget->enableSLPCB->setChecked(m_configuration.enableSLP());
m_confWidget->confirmConnectionsCB->setChecked(m_configuration.askOnConnect());
m_confWidget->allowDesktopControlCB->setChecked(m_configuration.allowDesktopControl());
m_confWidget->passwordInput->setText(m_configuration.password());
m_confWidget->autoPortCB->setChecked(m_configuration.preferredPort() < 0);
m_confWidget->portInput->setValue(m_configuration.preferredPort() > 0 ?
m_configuration.preferredPort() : 5900);
m_confWidget->disableBackgroundCB->setChecked(m_configuration.disableBackground());
emit changed(false);
m_confWidget->allowUninvitedCB->setChecked(m_configuration.allowUninvitedConnections());
m_confWidget->enableSLPCB->setChecked(m_configuration.enableSLP());
m_confWidget->confirmConnectionsCB->setChecked(m_configuration.askOnConnect());
m_confWidget->allowDesktopControlCB->setChecked(m_configuration.allowDesktopControl());
m_confWidget->passwordInput->setText(m_configuration.password());
m_confWidget->autoPortCB->setChecked(m_configuration.preferredPort()<0);
m_confWidget->portInput->setValue(m_configuration.preferredPort()> 0 ?
m_configuration.preferredPort() : 5900);
m_confWidget->disableBackgroundCB->setChecked(m_configuration.disableBackground());
emit changed(false);
}
void KcmKRfb::save()
{
void KcmKRfb::save() {
m_configuration.update();
bool allowUninvited = m_confWidget->allowUninvitedCB->isChecked();
m_configuration.setAllowUninvited(allowUninvited);
m_configuration.setEnableSLP(m_confWidget->enableSLPCB->isChecked());
m_configuration.setAskOnConnect(m_confWidget->confirmConnectionsCB->isChecked());
m_configuration.setAllowDesktopControl(m_confWidget->allowDesktopControlCB->isChecked());
m_configuration.setPassword(m_confWidget->passwordInput->text());
if (m_confWidget->autoPortCB->isChecked()) {
m_configuration.setPreferredPort(-1);
} else {
m_configuration.setPreferredPort(m_confWidget->portInput->value());
}
m_configuration.setDisableBackground(m_confWidget->disableBackgroundCB->isChecked());
m_configuration.save();
m_configuration.update();
bool allowUninvited = m_confWidget->allowUninvitedCB->isChecked();
m_configuration.setAllowUninvited(allowUninvited);
m_configuration.setEnableSLP(m_confWidget->enableSLPCB->isChecked());
m_configuration.setAskOnConnect(m_confWidget->confirmConnectionsCB->isChecked());
m_configuration.setAllowDesktopControl(m_confWidget->allowDesktopControlCB->isChecked());
m_configuration.setPassword(m_confWidget->passwordInput->text());
if (m_confWidget->autoPortCB->isChecked())
m_configuration.setPreferredPort(-1);
else
m_configuration.setPreferredPort(m_confWidget->portInput->value());
m_configuration.setDisableBackground(m_confWidget->disableBackgroundCB->isChecked());
m_configuration.save();
#if 0
kapp->dcopClient()->emitDCOPSignal("KRFB::ConfigChanged", "KRFB_ConfigChanged()", QByteArray());
kapp->dcopClient()->emitDCOPSignal("KRFB::ConfigChanged", "KRFB_ConfigChanged()", QByteArray());
#endif
emit changed(false);
emit changed(false);
}
void KcmKRfb::defaults()
{
bool kinetdAvailable, krfbAvailable;
checkKInetd(kinetdAvailable, krfbAvailable);
void KcmKRfb::defaults() {
bool kinetdAvailable, krfbAvailable;
checkKInetd(kinetdAvailable, krfbAvailable);
m_confWidget->allowUninvitedCB->setChecked(false);
m_confWidget->enableSLPCB->setChecked(true);
m_confWidget->confirmConnectionsCB->setChecked(false);
m_confWidget->allowDesktopControlCB->setChecked(false);
m_confWidget->passwordInput->setText("");
m_confWidget->autoPortCB->setChecked(true);
m_confWidget->portInput->setValue(5900);
m_confWidget->disableBackgroundCB->setChecked(false);
emit changed(true);
m_confWidget->allowUninvitedCB->setChecked(false);
m_confWidget->enableSLPCB->setChecked(true);
m_confWidget->confirmConnectionsCB->setChecked(false);
m_confWidget->allowDesktopControlCB->setChecked(false);
m_confWidget->passwordInput->setText("");
m_confWidget->autoPortCB->setChecked(true);
m_confWidget->portInput->setValue(5900);
m_confWidget->disableBackgroundCB->setChecked(false);
emit changed(true);
}
QString KcmKRfb::quickHelp() const
{
return i18n("<h1>Desktop Sharing</h1> This module allows you to configure"
" the KDE desktop sharing.");
return i18n("<h1>Desktop Sharing</h1> This module allows you to configure"
" the KDE desktop sharing.");
}

View File

@@ -27,23 +27,22 @@
#include "configurationwidget.h"
#include "../krfb/configuration.h"
class KcmKRfb : public KCModule
{
Q_OBJECT
class KcmKRfb : public KCModule {
Q_OBJECT
private:
Configuration m_configuration;
ConfigurationWidget *m_confWidget;
void checkKInetd(bool &, bool &);
Configuration m_configuration;
ConfigurationWidget *m_confWidget;
void checkKInetd(bool&, bool&);
public:
KcmKRfb(QWidget *p, const QStringList &);
KcmKRfb(QWidget *p, const QStringList &);
void load();
void save();
void defaults();
QString quickHelp() const;
void load();
void save();
void defaults();
QString quickHelp() const;
private slots:
void setInvitationNum(int num);
void configChanged();
void setInvitationNum(int num);
void configChanged();
};

View File

@@ -14,10 +14,9 @@ Name=Desktop Sharing
Name[af]=Werkskerm Deeling
Name[ar]=مشاركة سطح المكتب
Name[ast]=Escritoriu compartiu
Name[bg]=Споделяне на работния плот
Name[bg]=Споделяне на работното място
Name[bn]=ডেস্কটপ ভাগাভাগি
Name[br]=Rannañ ar vurev
Name[bs]=Dijeljenje radne površine
Name[ca]=Compartició de l'escriptori
Name[ca@valencia]=Compartició de l'escriptori
Name[cs]=Sdílení pracovní plochy
@@ -40,7 +39,6 @@ Name[hi]=डेस्कटॉप साझेदारी
Name[hne]=डेस्कटाप साझेदारी
Name[hr]=Dijeljenje radne površine
Name[hu]=Munkaasztal-megosztás
Name[ia]=Compartir de scriptorio
Name[is]=Skjáborðamiðlun
Name[it]=Condivisione del desktop
Name[ja]=デスクトップ共有
@@ -60,11 +58,10 @@ Name[nn]=Skrivebordsdeling
Name[pa]=ਡੈਸਕਟਾਪ ਸ਼ੇਅਰਿੰਗ
Name[pl]=Współdzielenie pulpitu
Name[pt]=Partilha do Ecrã
Name[pt_BR]=Compartilhamento do área de trabalho
Name[pt_BR]=Compartilhamento do Desktop
Name[ro]=Partajare birou
Name[ru]=Общий рабочий стол
Name[se]=Čállinbeavdejuohkkin
Name[si]=වැඩතල හවුල්
Name[sk]=Zdieľanie pracovnej plochy
Name[sl]=Deljenje namizja
Name[sr]=Дељење површи
@@ -74,9 +71,7 @@ Name[sr@latin]=Deljenje površi
Name[sv]=Dela ut skrivbordet
Name[ta]=பணிமேடை பகிர்வு
Name[tg]=Истифодабарии муштараки Мизи корӣ
Name[th]=ใช้งานพื้นที่ทำงานร่วมกัน
Name[tr]=Masaüstü Paylaşımı
Name[ug]=ئۈستەلئۈستىنى ھەمبەھىرلەش
Name[uk]=Спільні стільниці
Name[vi]=Chia sẻ màn hình nền
Name[xh]=Ukwehlulelana kwe Desktop
@@ -89,10 +84,9 @@ Comment=Configure Desktop Sharing
Comment[af]=Konfigureer Werkskerm Deeling
Comment[ar]=تعديل مشاركة سطح المكتب
Comment[ast]=Configura'l to escritoriu compartíu
Comment[bg]=Настройки на споделянето на работния плот
Comment[bg]=Настройване споделянето на работното място
Comment[bn]=ডেস্কটপ ভাগাভাগি কনফিগার করুন
Comment[br]=Kefluniañ rannañ ar vurev
Comment[bs]=Podešavanje dijeljenja površine
Comment[ca]=Lupa de l'escriptori
Comment[ca@valencia]=Lupa de l'escriptori
Comment[cs]=Nastavit sdílení pracovní plochy
@@ -115,7 +109,6 @@ Comment[hi]=डेस्कटॉप साझेदारी कॉन्फ़
Comment[hne]=डेस्कटाप साझेदारी कान्फिगर करव
Comment[hr]=Podešavanje dijeljenja radne površine
Comment[hu]=A munkaasztal-megosztás beállításai
Comment[ia]=Configura le compartir de scriptorio
Comment[is]=Stilla skjáborðsmiðlun
Comment[it]=Configura condivisione del desktop
Comment[ja]=デスクトップ共有の設定
@@ -135,11 +128,10 @@ Comment[nn]=Set opp skrivebordsdeling
Comment[pa]=ਡੈਸਕਟਾਪ ਸ਼ੇਅਰਿੰਗ ਸੰਰਚਨਾ
Comment[pl]=Konfiguracja współdzielenia pulpitu
Comment[pt]=Configurar a Partilha do Ecrã
Comment[pt_BR]=Configura o compartilhamento da área de trabalho
Comment[pt_BR]=Configurar compartilhamento do Desktop
Comment[ro]=Configurează partajarea biroului
Comment[ru]=Параметры общего рабочего стола
Comment[se]=Heivet čállinbeavdejuohkkima
Comment[si]=වැඩතල හවුල් සකසන්න
Comment[sk]=Nastavenie zdieľania pracovnej plochy
Comment[sl]=Nastavi deljenje namizja
Comment[sr]=Подешавање дељења површи
@@ -149,7 +141,6 @@ Comment[sr@latin]=Podešavanje deljenja površi
Comment[sv]=Anpassa utdelning av skrivbord
Comment[ta]=பணிமேடை பகிர்வை உள்ளமை
Comment[tg]=Батанзимдарории Истифодабарии муштараки Мизи корӣ
Comment[th]=ปรับแต่งการแบ่งการใช้งานพื้นที่ทำงานร่วมกัน
Comment[tr]=Masaüstü Paylaşımını Yapılandır
Comment[uk]=Налаштувати спільні стільниці
Comment[vi]=Cấu hình chia sẻ màn hình nền
@@ -159,35 +150,47 @@ Comment[zh_CN]=配置桌面共享
Comment[zh_HK]=設定桌面分享
Comment[zh_TW]=設定桌面分享
X-KDE-Keywords=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited
X-KDE-Keywords[ca]=compartició d'escriptori,krfb,vnc,compartició,krdc,connexió d'escriptori remot,invitació,port,slp,no invitat
X-KDE-Keywords[ca@valencia]=compartició d'escriptori,krfb,vnc,compartició,krdc,connexió d'escriptori remot,invitació,port,slp,no invitat
X-KDE-Keywords[da]=skrivebordsdeling,krfb,vnc,deling,krdc,remote desktop,fjernskrivebord,invitation,port,slp,uinviteret
X-KDE-Keywords[de]=freigabe der arbeitsfläche,krfb,vnc,freigabe,krdc,fernwartung,einladung,port,slp
X-KDE-Keywords[el]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited
X-KDE-Keywords[es]=compartición de escritorio,krfb,vnc,compartición,krdc,conexión de escritorio en remoto,invitación,puerto,slp,no invitado
X-KDE-Keywords[bg]=Keywords=споделяне, работно, място, десктоп, покана, връзка, desktop sharing, krfb, vnc, sharing, krdc, remote desktop connection, invitation, port, slp, uninvited
X-KDE-Keywords[ca]=compartició de l'escriptori,krfb,vnc,compartir,krdc,connexió a l'escriptori remot,invitació,port,slp,no invitat
X-KDE-Keywords[cs]=sdílení plochy,krfb,vnc,sdílení,rdp,krdc,připojení vzdálené plochy,pozvánka,port,slp
X-KDE-Keywords[cy]=rhannu penbwrdd,krfb,vnc,rhannu,rdp,krdc,cysylltiad penbwrdd pell,gwahoddiad,porth,slp,heb wahoddiad
X-KDE-Keywords[da]=desktopdeling,krfb,vnc,deling,krdc,ekstern desktopforbindelse,invitation,port,slp,ikke inviteret
X-KDE-Keywords[de]=Arbeitsfläche freigeben,krfb,VNC,freigeben,krdc,Entfernte Arbeitsfläche,Einladung,Port,slp,uneingeladen,rdp,remote desktop
X-KDE-Keywords[el]=κοινή χρήση επιφάνειας εργασίας,krfb,vnc,κοινή χρήση,krdc,σύνδεση σε απομακρυσμένη επιφάνεια εργασίας,πρόσκληση,θύρα,slp,απρόσκλητο
X-KDE-Keywords[es]=escritorio compartido,krfb,vnc,compartir,rdp,krdc, conexión escritorio remoto,invitación,puerto,slp,no invitado
X-KDE-Keywords[et]=töölaua jagamine,krfb,vnc,jagamine,rdp,krdc,kaugtöölaua ühendus,rdp,kutse,port,slp,kutsumata
X-KDE-Keywords[fr]=partage de bureau,krfb,vnc,partage,krdc,connexion à un bureau distant,invitation,port,slp,non-invité
X-KDE-Keywords[hu]=asztalmegosztás,krfb,vnc,megosztás,krdc,távoliasztal-kapcsolat,meghívás,port,slp,meghívatlan
X-KDE-Keywords[ia]=compartir de scriptorio,krfb.vnc,compartir,krdc,connexion de scriptorio remote,invitation,porto,slp,non invitate
X-KDE-Keywords[eu]=mahaigain partekatzea,krfb,vnc,partekatzea,krdc,urruneko mahaigain konexioa,gonbidapena,ataka,slp,gonbidapen gabea
X-KDE-Keywords[fa]=اشتراک رومیزی، krfb، vnc، اتصال رومیزی راه دور، دعوت، درگاه، slp، دعوت‌نشده
X-KDE-Keywords[fi]=työpöydän jakaminen,krfb,vnc,jakaminen,krdc,etätyöpöytäyhteys, kutsu,portti,slp,kutsumaton, työpöytä
X-KDE-Keywords[fr]=partage de bureau,krfb,vnc,partage,rdp,krdc,connexion à un bureau distant,invitation,port,slp,non invité
X-KDE-Keywords[gl]=compartilla de escritorio, vnc, compartir, krdc, conexón ao escritorio remoto, invitación, porto, slt, convidado, compartillar
X-KDE-Keywords[he]=שיתוף שולחן עבודה,שיתוף,חיבור לשולחן עבודה מרוחק,desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection, invitation, port, slp, uninvited
X-KDE-Keywords[hu]=munkaasztal-megosztás,krfb,vnc,megosztás,krdc,csatlakozás távoli munkaasztalhoz,meghívás,port,slp,meghívás nélkül
X-KDE-Keywords[is]=skjáborðsmiðlun,miðlun,krfb,vnc,rdp,krdc,fjarvinnsla,remote desktop connection,rdp
X-KDE-Keywords[it]=condivisione desktop,krfb,vnc,condivisione,krdc,connessione desktop remoto,invito,porta,slp,non invitato
X-KDE-Keywords[kk]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited
X-KDE-Keywords[km]=ការ​ចែក​រំលែក​ផ្ទៃតុ,krfb,vnc,ការ​ចែក​រំលែក,krdc,ការ​តភ្ជាប់​ផ្ទៃ​តុ​ពី​ចម្ងាយ,​ការ​អញ្ជើញ,ច្រក,slp,មិន​ត្រូវ​បានអញ្ជើញ
X-KDE-Keywords[ko]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,데스크톱,공유,원격 데스크톱,포트
X-KDE-Keywords[nb]=skrivebordsdeling,krfb,vnc,deling,krdc,tilkoblng til annet skrivebord,invitasjon,port,slp,ikke invitert
X-KDE-Keywords[nds]=Schriefdischfreegaav,krfb,vnc,Freegaav,Verbinnen na feern Schriefdisch,Inladen,Port,Koppelsteed,slp,nich inlaadt
X-KDE-Keywords[nl]=delen van bureaublad,krfb,vnc,delen,krdc,verbinding naar bureaublad op afstand,invitatie,poort,slp,ongenodigd
X-KDE-Keywords[pl]=współdzielenie pulpitu,krfb,vnc,współdzielenie,krdc,podłączenie zdalnego pulpitu,zaproszenie,port,slp,niezaproszony
X-KDE-Keywords[pt]=partilha do ecrã,krfb,vnc,partilha,krdc,ligação ecrã remoto,convite,porto,slp,sem convite
X-KDE-Keywords[pt_BR]=compartilhamento da área de trabalho,krfb,vnc,compartilhar,krdc,conexão à área de trabalho remota,convite,porta,desconvidar
X-KDE-Keywords[sk]=zdieľanie plochy,krfb,vnc,zdieľanie,krdc,vzdialené pripojenie plochy,pozvanie,port,slp,nepozvaný
X-KDE-Keywords[sr]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,дељење површи,КРФБ,ВНЦ,дељење,КРДЦ,удаљена површ,позивница,порт,СЛП,непозван
X-KDE-Keywords[sr@ijekavian]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,дељење површи,КРФБ,ВНЦ,дељење,КРДЦ,удаљена површ,позивница,порт,СЛП,непозван
X-KDE-Keywords[sr@ijekavianlatin]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,deljenje površi,KRFB,VNC,deljenje,KRDC,udaljena površ,pozivnica,port,SLP,nepozvan
X-KDE-Keywords[sr@latin]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,deljenje površi,KRFB,VNC,deljenje,KRDC,udaljena površ,pozivnica,port,SLP,nepozvan
X-KDE-Keywords[sv]=dela skrivbord,krfb,vnc,dela,krdc,fjärrskrivbordsanslutning,inbjudan,port,slp,oinbjuden
X-KDE-Keywords[uk]=krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,спільне використання,керування,оприлюднення,віддалене з’єднання,запрошення,порт,небажане
X-KDE-Keywords[ja]=デスクトップ共有,krfb,vnc,共有,rdp,krdc,リモートデスクトップ接続,招待,ポート,slp,uninvited
X-KDE-Keywords[km]=ការ​ចែក​រំលែក​ផ្ទៃតុ,krfb,vnc,ការ​ចែក​រំលែក,krdc,ការ​តភ្ជាប់​ផ្ទៃ​តុ​ពី​ចម្ងាយ,អញ្ជើញ,ច្រក,slp,មិន​បានអញ្ជើញ
X-KDE-Keywords[lt]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,dalinimasis darbastaliu,nutolusio darbastalio prijungimas,kvietimas,ryšys,nekviestas,jungtis,prievadas,dalintis,pasidalinti,jungimasis,prisijungti,kviesti
X-KDE-Keywords[mk]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,делење на површината,krfb,vnc,делење,krdc,поврзување со оддалечена површина,покана,порта,slp,непоканет
X-KDE-Keywords[ms]= perkongsian ruang kerja, sambungan, liang, desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited
X-KDE-Keywords[nb]=skrivebordsdeling,krfb,vnc,deling,krdc,tilkobling til fjernt skrivebord,invitasjon,port,slp,ikke invitert
X-KDE-Keywords[nds]=schriefdisch,freegeven,freegaav,krfb,vnc,delen,krdc,feern Schriefdisch,verbinnen,inladen,port,slp,nich inlaadt
X-KDE-Keywords[ne]=डेस्कटप साझेदारी,krfb,vnc,साझेदारी,krdc, टाढाको डेस्कटप जडान,निमन्त्रणा,पोर्ट,slp,निमन्त्रणा नगरिएको
X-KDE-Keywords[nl]=desktop sharing,krfb,vnc,sharing,rdp,krdc,remote desktop connection,uitnodiging,slp,rdp,verbinding, bureaublad delen,bureaublad op afstand
X-KDE-Keywords[nn]=skrivebordsdeling,krfb,vnc,deling,krdc,nettverksskrivebord,invitasjon,port,slp,ikkje invitert
X-KDE-Keywords[pl]=współdzielenie pulpitu,krfb,vnc,współdzielenie,rdp,krdc,zdalne połączenie, zdalne biurko, zdalny pulpit, zaproszenie,port,slp
X-KDE-Keywords[pt]=partilha do ecrã,krfb,vnc,partilha,krdc,ligação a um ecrã remoto,convite,porto,slp,sem convite
X-KDE-Keywords[pt_BR]=compartilhamento de desktop,krfb,vnc,compartilhamento,krdc,conexão a desktop remoto,convite,porta,slp,não convidado
X-KDE-Keywords[sl]=namizje,souporaba,krfb,vnc,krdc,povezava oddaljenega namizja, povabilo,port,slp,nepovabljen
X-KDE-Keywords[sr]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,радна површина,дељење,позив,порт,непозван,удаљено
X-KDE-Keywords[sr@latin]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,radna površina,deljenje,poziv,port,nepozvan,udaljeno
X-KDE-Keywords[sv]=dela skrivbord,krfb,vnc,dela,krdc,fjärrskrivbordsanslutning,inbjudan,port,slp
X-KDE-Keywords[ta]=பணிமேடை பகிர்வு,krfb,vnc,பகிர்வு,krdc,தொலை பணிமேடை இணைப்பு,அழைப்பிதழ், துறை, slp, uninvited
X-KDE-Keywords[tr]=masaüstü paylaşımı,krfb,vnc,paylaşım,krdc,uzak masaüstü bağlantısı,davet,port,slp
X-KDE-Keywords[uk]=спільні стільниці,krfb,vnc,спільний,rdp,krdc,з'єднання віддаленої стільниці,запрошення,rdp,slp,без запрошення
X-KDE-Keywords[vi]=chia sẻ màn hình,krfb,vnc,chia sẻ,krdc,màn hình ở xa kết nối,mời kết nối,cổng,slp,không được mời
X-KDE-Keywords[x-test]=xxdesktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvitedxx
X-KDE-Keywords[zh_CN]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,桌面共享,共享,远程桌面,远程桌面连接,邀请,端口,取消邀请
X-KDE-Keywords[zh_TW]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited
X-KDE-Keywords[zh_CN]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,桌面共享,共享,远程桌面连接,邀请,端口,邀请
X-KDE-Keywords[zh_TW]=desktop sharing,krfb,vnc,sharing,rdp,krdc,remote desktop connection,rdp,桌面分享,分享,遠端桌面連線,invitation,port,slp,uninvited
Categories=Qt;KDE;X-KDE-settings-network;Settings;

View File

@@ -1,6 +1,10 @@
include_directories( ${CMAKE_SOURCE_DIR}/krfb/srvloc )
########### next target ###############
set(kded_kinetd_PART_SRCS kinetd.cpp)
set(kded_kinetd_PART_SRCS kinetd.cpp ${srvloc_SRCS})
message(STATUS "Port to krfb DBUS")
# kde4_add_dcop_skels(kded_kinetd_PART_SRCS kinetd.h )
@@ -8,7 +12,7 @@ message(STATUS "Port to krfb DBUS")
kde4_add_plugin(kded_kinetd ${kded_kinetd_PART_SRCS})
target_link_libraries(kded_kinetd ${KDE4_KIO_LIBS} ${KDE4_KDNSSD_LIBS})
target_link_libraries(kded_kinetd ${KDE4_KIO_LIBS} ${KDE4_KDNSSD_LIBS} ${SLP_LIBRARIES})
install(TARGETS kded_kinetd DESTINATION ${PLUGIN_INSTALL_DIR})
@@ -18,3 +22,7 @@ install(TARGETS kded_kinetd DESTINATION ${PLUGIN_INSTALL_DIR})
install(FILES kinetd.notifyrc DESTINATION ${DATA_INSTALL_DIR}/krfb)
install(FILES kinetdmodule.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR})
install(FILES kinetd.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kded)

File diff suppressed because it is too large Load Diff

View File

@@ -10,10 +10,9 @@ Name=KDE Internet Daemon
Name[af]=Kde Internet Bediener
Name[ar]=كيدي إنترنت مراقب
Name[ast]=Degorriu d'Internet de KDE
Name[bg]=Интернет демон (KDE)
Name[bg]=Интернет демон
Name[bn]=কে-ডি-ই ইন্টারনেট ডিমন
Name[br]=Diaoul kenrouedad KDE
Name[bs]=KDE-ov Internet Demon
Name[ca]=Dimoni d'Internet per al KDE
Name[ca@valencia]=Dimoni d'Internet per al KDE
Name[cs]=KDE Internet démon
@@ -25,7 +24,7 @@ Name[en_GB]=KDE Internet Dæmon
Name[eo]=KDE interreta demono
Name[es]=Demonio de Internet de KDE
Name[et]=KDE internetideemon
Name[eu]=KDEren interneteko daemona
Name[eu]=KDE interneteko daemona
Name[fa]=شبح اینترنتی KDE
Name[fi]=KDE:n Internet-palvelin
Name[fr]=Démon Internet de KDE
@@ -36,7 +35,6 @@ Name[hi]=केडीई इंटरनेट डेमन
Name[hne]=केडीई इंटरनेट डेमन
Name[hr]=KDE Internet Daemon
Name[hu]=KDE internetes szolgáltatás
Name[ia]=Demone Internet de KDE
Name[is]=KDE Internetþjónn
Name[it]=Demone Internet di KDE
Name[ja]=KDE インターネットデーモン
@@ -54,16 +52,14 @@ Name[ne]=केडीई इन्टरनेट डेइमोन
Name[nl]=KDE Internet Daemon
Name[nn]=KDE-Internett-teneste
Name[pa]=KDE ਇੰਟਰਨੈੱਟ ਡੈਮਨ
Name[pl]=Demon internetowy dla KDE
Name[pl]=Internet/sieć
Name[pt]=Servidor de Internet do KDE
Name[pt_BR]=Servidor de Internet do KDE
Name[ro]=Demon de Internet KDE
Name[ru]=Доступ к Интернету
Name[se]=KDE-Interneahtta-duogášprográmma
Name[si]=KDE ජාල ඩීමනය
Name[sk]=KDE Internet démon
Name[sl]=Internetni strežnik za KDE
Name[sq]=KDE Internet Daemon
Name[sr]=КДЕ‑ов интернет демон
Name[sr@ijekavian]=КДЕ‑ов интернет демон
Name[sr@ijekavianlatin]=KDEov internet demon
@@ -71,7 +67,6 @@ Name[sr@latin]=KDEov internet demon
Name[sv]=KDE:s Internetdemon
Name[ta]=கேடிஇ இணைய டேமொன்
Name[tg]=KDE Азозили Интернет
Name[th]=ดีมอนอินเทอร์เน็ตของ KDE
Name[tr]=KDE İnternet Programı
Name[uk]=Фонова служба Інтернет KDE
Name[uz]=KDE Internet demoni
@@ -85,9 +80,8 @@ Name[zh_TW]=KDE Internet 伺服程式
Comment=An Internet daemon that starts network services on demand
Comment[ar]=رقيب الإنترنت بدأ خدمة الشبكة على الرقيب
Comment[ast]=Un degorriu d'Internet qu'entama los servicios de rede baxo demanda
Comment[bg]=Интернет демон, който зарежда мрежови услуги при поискване
Comment[bg]=Интернет демон, който служи за стартиране на мрежови услуги при поискване
Comment[bn]=একটি ইন্টারনেট ডিমন যে চাহিদা ভিত্তিক নেটওয়ার্ক সার্ভিস আরম্ভ করে
Comment[bs]=Internet daemon koji pokreće mrežne servise po zahtijevu
Comment[ca]=Un dimoni d'Internet que arrenca els serveis de xarxa sota demanda
Comment[ca@valencia]=Un dimoni d'Internet que arrenca els serveis de xarxa sota demanda
Comment[cs]=Internetový démon spouštějící síťové služby na požádání
@@ -99,7 +93,7 @@ Comment[en_GB]=An Internet dæmon that starts network services on demand
Comment[eo]=Interreta demono kiu lanĉas retajn servojn laŭ bezono
Comment[es]=Un demonio de Internet que inicia los servicios de red a demanda
Comment[et]=Internetideemon, mis käivitab nõudmisel võrguteenused
Comment[eu]=Sareko zerbitzuak eskatzean abiarazten dituen Interneteko daemona
Comment[eu]=Sare zerbitzuak eskatzean abiarazten dituen Interneteko daemona
Comment[fa]=یک شبح اینترنتی که خدمات شبکه را بر اساس تقاضا آغاز می‌کند
Comment[fi]=Internet-palvelin, joka käynnistää verkkopalveluita
Comment[fr]=Un démon Internet qui démarre le service réseau à la demande
@@ -110,7 +104,6 @@ Comment[hi]=एक इंटरनेट डेमन जो मांग पर
Comment[hne]=एक इंटरनेट डेमन जऊन मांग मं नेटवर्क सेवा चालू करथे
Comment[hr]=Internet daemon koji pokreće mrežne usluge kada su zatražene
Comment[hu]=A hálózati szolgáltatások vezérlését biztosító program
Comment[ia]=Un demone internet que starta servicios de rete sur requesta
Comment[is]=Internetþjónn sem ræsir tengingar við Internetið eftir þörfum
Comment[it]=Un demone Internet che avvia i servizi di rete a richiesta
Comment[ja]=要求時にネットワークサービスを起動するインターネットデーモン
@@ -128,24 +121,22 @@ Comment[ne]=एउटा इन्टरनेट डेइमोन जसल
Comment[nl]=Een internetdaemon die netwerkdiensten op afroep start
Comment[nn]=Internett-teneste som startar nettverkstenester når dei trengst
Comment[pa]=ਇੱਕ ਇੰਟਰਨੈੱਟ ਡੈਮਨ, ਜੋ ਕਿ ਲੋੜ ਪੈਣ ਉੱਤੇ ਨੈੱਟਵਰਕ ਸਰਵਿਸਾਂ ਸ਼ੁਰੂ ਕਰਦੀ ਹੈ।
Comment[pl]=Demon internetowy, który uruchamia usługi sieciowe na żądanie
Comment[pl]=Uruchamianie usług na żądanie
Comment[pt]=Um servidor da Internet que inicia os serviços de rede a pedido
Comment[pt_BR]=Um servidor Internet que inicia os serviços de rede por demanda
Comment[ro]=Un demon de Internet ce pornește serviciile de rețea la cerere
Comment[ru]=Служба установления подключения при запросе сетевых ресурсов
Comment[se]=Interneahtta-duogášprográmma mii álggaha fierpmádatbálvalusaid go dárbbašuvvo
Comment[si]=ඉල්ලුම පරිදි ජාල සේවා ආරම්භ කරන අන්තර්ජාල ඩීමනය
Comment[sk]=Internetový démon, ktorý spúšťa sieťové služby na požiadanie
Comment[sl]=Internetni strežnik, ki zažene omrežne storitve na zahtevo
Comment[sr]=Интернет демон који покреће мрежне сервисе по захтеву
Comment[sr@ijekavian]=Интернет демон који покреће мрежне сервисе по захтјеву
Comment[sr@ijekavianlatin]=Internet demon koji pokreće mrežne servise po zahtjevu
Comment[sr@ijekavian]=Интернет демон који покреће мрежне сервисе по захтеву
Comment[sr@ijekavianlatin]=Internet demon koji pokreće mrežne servise po zahtevu
Comment[sr@latin]=Internet demon koji pokreće mrežne servise po zahtevu
Comment[sv]=Internetdemon som startar nätverkstjänster vid behov
Comment[ta]=ஒரு இணைய டேமொன், டேமொன் பிணைய சேவையை ஆரம்பிக்கிறது
Comment[tg]=Азозили шабакавие, ки хидматрасони шабакавиро бо дархост сар медиҳад
Comment[th]=ดมอนอินเทอร์เน็ตซึ่งจะเริ่มทำงานบริการเครือข่ายเมื่อมีความต้องการใช้
Comment[tr]=Başlangıçta ağ servisleri tarafından istenen Internet hayalet programı
Comment[tr]=Başlangıçta ağ servisleri tarafından istenen internet hayalet programı
Comment[uk]=Фонова служба Інтернет, що запускає служби мережі при запиті
Comment[uz]=Talab qilinganda tarmoq xizmatlarini ishga tushuruvchi Internet demoni
Comment[uz@cyrillic]=Талаб қилинганда тармоқ хизматларини ишга тушурувчи Интернет демони

View File

@@ -31,170 +31,168 @@
#include <q3ptrlist.h>
#include "kserviceregistry.h"
class PortListener : public QObject
{
Q_OBJECT
class PortListener : public QObject {
Q_OBJECT
private:
bool m_valid;
QString m_serviceName;
QString m_serviceURL, m_serviceAttributes;
QStringList m_registeredServiceURLs;
QString m_dnssdName, m_dnssdType;
QMap<QString, QString> m_dnssdData;
int m_serviceLifetime;
int m_port;
int m_portBase, m_autoPortRange;
int m_defaultPortBase, m_defaultAutoPortRange;
bool m_multiInstance;
QString m_execPath;
QString m_argument;
bool m_enabled;
bool m_serviceRegistered, m_registerService;
bool m_dnssdRegister, m_dnssdRegistered;
QDateTime m_expirationTime;
QDateTime m_slpLifetimeEnd;
QString m_uuid;
bool m_valid;
QString m_serviceName;
QString m_serviceURL, m_serviceAttributes;
QStringList m_registeredServiceURLs;
QString m_dnssdName, m_dnssdType;
QMap<QString,QString> m_dnssdData;
int m_serviceLifetime;
int m_port;
int m_portBase, m_autoPortRange;
int m_defaultPortBase, m_defaultAutoPortRange;
bool m_multiInstance;
QString m_execPath;
QString m_argument;
bool m_enabled;
bool m_serviceRegistered, m_registerService;
bool m_dnssdRegister, m_dnssdRegistered;
QDateTime m_expirationTime;
QDateTime m_slpLifetimeEnd;
QString m_uuid;
KNetwork::KServerSocket *m_socket;
K3Process m_process;
KNetwork::KServerSocket *m_socket;
K3Process m_process;
KConfig *m_config;
KServiceRegistry *m_srvreg;
DNSSD::PublicService *m_dnssdreg;
KConfig *m_config;
KServiceRegistry *m_srvreg;
DNSSD::PublicService *m_dnssdreg;
void freePort();
void loadConfig(KService::Ptr s);
void setEnabledInternal(bool e, const QDateTime &ex);
void dnssdRegister(bool enabled);
void setServiceRegistrationEnabledInternal(bool enabled);
void freePort();
void loadConfig(KService::Ptr s);
void setEnabledInternal(bool e, const QDateTime &ex);
void dnssdRegister(bool enabled);
void setServiceRegistrationEnabledInternal(bool enabled);
public:
PortListener(KService::Ptr s, KConfig *c, KServiceRegistry *srvreg);
~PortListener();
PortListener(KService::Ptr s, KConfig *c, KServiceRegistry *srvreg);
~PortListener();
bool acquirePort();
bool isValid();
QString name();
void setEnabled(bool enabled);
void setEnabled(const QDateTime &expiration);
void setServiceRegistrationEnabled(bool enabled);
bool isServiceRegistrationEnabled();
QDateTime expiration();
QDateTime serviceLifetimeEnd();
bool isEnabled();
int port();
QStringList processServiceTemplate(const QString &a);
bool setPort(int port = -1, int autoProbeRange = 1);
void refreshRegistration();
bool acquirePort();
bool isValid();
QString name();
void setEnabled(bool enabled);
void setEnabled(const QDateTime &expiration);
void setServiceRegistrationEnabled(bool enabled);
bool isServiceRegistrationEnabled();
QDateTime expiration();
QDateTime serviceLifetimeEnd();
bool isEnabled();
int port();
QStringList processServiceTemplate(const QString &a);
bool setPort(int port = -1, int autoProbeRange = 1);
void refreshRegistration();
private slots:
void accepted(KSocket *);
void accepted(KSocket*);
};
class KInetD : public KDEDModule
{
Q_OBJECT
class KInetD : public KDEDModule {
Q_OBJECT
public slots:
/**
* Returns a list of all registered services in KInetd.
* To add a service you need to add a .desktop file with
* the servicetype "KInetDModule" into the services director
* (see kinetdmodule.desktop in servicetypes dir).
* @return a list with the names of all services
*/
QStringList services();
/**
* Returns a list of all registered services in KInetd.
* To add a service you need to add a .desktop file with
* the servicetype "KInetDModule" into the services director
* (see kinetdmodule.desktop in servicetypes dir).
* @return a list with the names of all services
*/
QStringList services();
/**
* Returns true if the service exists and is available.
* @param service name of a service as specified in its .desktop file
* @return true if a service with the given name exists and is enabled
*/
bool isEnabled(QString service);
/**
* Returns true if the service exists and is available.
* @param service name of a service as specified in its .desktop file
* @return true if a service with the given name exists and is enabled
*/
bool isEnabled(QString service);
/**
* Enables or disabled the given service. Ignored if the given service
* does not exist.
* @param service name of a service as specified in its .desktop file
* @param enable true to enable, false to disable.
*/
void setEnabled(QString service, bool enable);
/**
* Enables or disabled the given service. Ignored if the given service
* does not exist.
* @param service name of a service as specified in its .desktop file
* @param enable true to enable, false to disable.
*/
void setEnabled(QString service, bool enable);
/**
* Enables the given service until the given time. Ignored if the given
* service does not exist.
* @param service name of a service as specified in its .desktop file
* @param expiration the time the service will be disabled at
*/
void setEnabled(QString service, QDateTime expiration);
/**
* Enables the given service until the given time. Ignored if the given
* service does not exist.
* @param service name of a service as specified in its .desktop file
* @param expiration the time the service will be disabled at
*/
void setEnabled(QString service, QDateTime expiration);
/**
* Returns the port of the service, or -1 if not listening.
* @param service name of a service as specified in its .desktop file
* @return the port or -1 if no port used or service does not exist
*/
int port(QString service);
/**
* Returns the port of the service, or -1 if not listening.
* @param service name of a service as specified in its .desktop file
* @return the port or -1 if no port used or service does not exist
*/
int port(QString service);
/**
* Sets the port of the service, and possibly a range of ports to try.
* It will return true if a port could be found. If it did not find one
* but is enabled it will start a timer that probes that port every 30s.
* @param service name of a service as specified in its .desktop file
* @param port the first port number to try or -1 to restore defaults
* @param autoPortRange the number of ports to try
* @return true if a port could be found or service is disabled, false
* otherwise.
*/
bool setPort(QString service, int port = -1, int autoPortRange = 1);
/**
* Sets the port of the service, and possibly a range of ports to try.
* It will return true if a port could be found. If it did not find one
* but is enabled it will start a timer that probes that port every 30s.
* @param service name of a service as specified in its .desktop file
* @param port the first port number to try or -1 to restore defaults
* @param autoPortRange the number of ports to try
* @return true if a port could be found or service is disabled, false
* otherwise.
*/
bool setPort(QString service, int port = -1, int autoPortRange = 1);
/**
* Tests whether the given service is installed..
* @param service name of a service as specified in its .desktop file
* @return true if installed, false otherwise
*/
bool isInstalled(QString service);
/**
* Tests whether the given service is installed..
* @param service name of a service as specified in its .desktop file
* @return true if installed, false otherwise
*/
bool isInstalled(QString service);
/**
* Enables or disables the SLP registration. Ignored if the service does
* not have a service URL. If the service is disabled the service will
* registered as soon as it is enabled.
* @param service name of a service as specified in its .desktop file
* @param enable true to enable, false to disable.
*/
void setServiceRegistrationEnabled(QString service, bool enabled);
/**
* Enables or disables the SLP registration. Ignored if the service does
* not have a service URL. If the service is disabled the service will
* registered as soon as it is enabled.
* @param service name of a service as specified in its .desktop file
* @param enable true to enable, false to disable.
*/
void setServiceRegistrationEnabled(QString service, bool enabled);
/**
* Returns true if service registration for the given service is enabled.
* Note that this does not mean that the service is currently registered,
* because the service may be disabled.
* @param service name of a service as specified in its .desktop file
* @return true if service registration is enabled
*/
bool isServiceRegistrationEnabled(QString service);
/**
* Returns true if service registration for the given service is enabled.
* Note that this does not mean that the service is currently registered,
* because the service may be disabled.
* @param service name of a service as specified in its .desktop file
* @return true if service registration is enabled
*/
bool isServiceRegistrationEnabled(QString service);
private:
QDateTime getNextExpirationTime();
void setPortRetryTimer(bool retry);
void setReregistrationTimer();
private:
QDateTime getNextExpirationTime();
void setPortRetryTimer(bool retry);
void setReregistrationTimer();
KConfig *m_config;
KServiceRegistry *m_srvreg;
Q3PtrList<PortListener> m_portListeners;
QTimer m_expirationTimer;
QTimer m_portRetryTimer;
QTimer m_reregistrationTimer;
KConfig *m_config;
KServiceRegistry *m_srvreg;
Q3PtrList<PortListener> m_portListeners;
QTimer m_expirationTimer;
QTimer m_portRetryTimer;
QTimer m_reregistrationTimer;
private slots:
void setExpirationTimer();
void expirationTimer();
void portRetryTimer();
void reregistrationTimer();
private slots:
void setExpirationTimer();
void expirationTimer();
void portRetryTimer();
void reregistrationTimer();
public:
KInetD(QObject *parent, const QList<QVariant>&);
virtual ~KInetD();
void loadServiceList();
PortListener *getListenerByName(QString name);
public:
KInetD(QObject* parent, const QList<QVariant>&);
virtual ~KInetD();
void loadServiceList();
PortListener *getListenerByName(QString name);
};

View File

@@ -3,10 +3,8 @@ IconName=kinetd
Comment=KInetD
Comment[ar]=KInetD
Comment[ast]=KInetD
Comment[bg]=KInetD
Comment[bn]=কে-আইনেট-ডি
Comment[br]=KInetD
Comment[bs]=KInetD
Comment[ca]=KInetD
Comment[ca@valencia]=KInetD
Comment[cs]=KInetD
@@ -28,11 +26,9 @@ Comment[hi]=के-इनिट-डी
Comment[hne]=के-इनिट-डी
Comment[hr]=KInetD
Comment[hu]=KInetD
Comment[ia]=KInetD
Comment[is]=KInetD
Comment[it]=KInetD
Comment[ja]=KInetD
Comment[kk]=KInetD
Comment[km]=KInetD
Comment[ko]=KInetD
Comment[lt]=KInetD
@@ -50,10 +46,8 @@ Comment[pt]=KInetD
Comment[pt_BR]=KInetD
Comment[ro]=KInetD
Comment[ru]=KInetD
Comment[si]=KInetD
Comment[sk]=KInetD
Comment[sl]=KInetD
Comment[sq]=KInetD
Comment[sr]=КинетД
Comment[sr@ijekavian]=КинетД
Comment[sr@ijekavianlatin]=KInetD
@@ -63,7 +57,6 @@ Comment[ta]=KInetD
Comment[tg]=KInetD
Comment[tr]=KInetD
Comment[uk]=KInetD
Comment[wa]=KInetD
Comment[xh]=KInetD
Comment[x-test]=xxKInetDxx
Comment[zh_CN]=KInetD
@@ -74,10 +67,8 @@ Comment[zh_TW]=KInetD
Name=IncomingConnection
Name[ar]=اتصال وارد
Name[ast]=Conexón entrante
Name[bg]=Входяща връзка
Name[bn]=অন্তর্মুখী সংযোগ
Name[br]=Kevreadenn resev
Name[bs]=Dolazna veza
Name[ca]=Connexió entrant
Name[ca@valencia]=Connexió entrant
Name[cs]=Příchozí spojení
@@ -99,11 +90,9 @@ Name[hi]=आवक-कनेक्शन
Name[hne]=आवक-कनेक्सन
Name[hr]=DolaznaVeza
Name[hu]=Bejövő kapcsolat
Name[ia]=Connexion in arrivata
Name[is]=IncomingConnection
Name[it]=Connessioni in entrata
Name[ja]=外部からの接続
Name[kk]=Кіріс қосылым
Name[km]=ការ​តភ្ជាប់​ចូល
Name[ko]=IncomingConnection
Name[lt]=Gautas kvietimas ryšiui
@@ -121,7 +110,6 @@ Name[pt]=IncomingConnection
Name[pt_BR]=Conexões de entrada
Name[ro]=ConexiuneDeIntrare
Name[ru]=Входящее соединение
Name[si]=පැමිණෙන සබැඳිය
Name[sk]=Prichádzajúce pripojenie
Name[sl]=Prejeta povezava
Name[sr]=Долазна веза
@@ -131,7 +119,6 @@ Name[sr@latin]=Dolazna veza
Name[sv]=Inkommande anslutning
Name[ta]=உள்வரும் இணைப்புகள்
Name[tg]=Пайвастшавии Воридшаванда
Name[th]=มีการเชื่อมต่อเข้ามา
Name[tr]=Gelen Bağlantı
Name[uk]=IncomingConnection
Name[xh]=Uxhumaniso Olungenayo
@@ -143,9 +130,7 @@ Comment=Received incoming connection
Comment[af]=Ontvang inkomende verbinding
Comment[ar]=تلقي اتصال وارد
Comment[ast]=Recibida conexón entrante
Comment[bg]=Получана е входяща връзка
Comment[bn]=অন্তর্মুখী সংযোগ গ্রহণ করল
Comment[bs]=Primljena dolazeća veza
Comment[ca]=Rebuda connexió entrant
Comment[ca@valencia]=Rebuda connexió entrant
Comment[cs]=Obdrženo příchozí spojení
@@ -167,11 +152,9 @@ Comment[hi]=आवक कनेक्शन प्राप्त
Comment[hne]=आवक कनेक्सन प्राप्त
Comment[hr]=Primio dolaznu vezu
Comment[hu]=Csatlakozási kérés érkezett
Comment[ia]=Connexion in arrivata recipite
Comment[is]=Tók á móti uppkalli
Comment[it]=Ricevuta connessione in entrata
Comment[ja]=外部からの接続がありました
Comment[kk]=Кіріс қосылым ұсынылды
Comment[km]=បាន​ទទួល​ការ​តភ្ជាប់​ចូល
Comment[ko]=들어오는 연결을 받았습니다
Comment[lt]=Gautas kvietimas ryšiui
@@ -189,7 +172,6 @@ Comment[pt]=Foi recebida uma ligação
Comment[pt_BR]=Recebendo conexão de entrada
Comment[ro]=Conexiune de intrare recepționată
Comment[ru]=Входящее соединение завершилось успешно
Comment[si]=ලැබුනු පැමිණෙන සබැඳිය
Comment[sk]=Prijaté prichádzajúce pripojenie
Comment[sl]=Prejeta je prihajajoča povezava
Comment[sr]=Примљена је долазна веза
@@ -198,7 +180,6 @@ Comment[sr@ijekavianlatin]=Primljena je dolazna veza
Comment[sr@latin]=Primljena je dolazna veza
Comment[sv]=Tar emot inkommande anslutning
Comment[tg]=Пайвастшавии воридшаванда қабул гардид
Comment[th]=ได้รับการเชื่อมต่อเข้ามา
Comment[tr]=Gelen bağlantı alınıyor
Comment[uk]=Отримано вхідне з’єднання
Comment[xh]=Uxhulumano olungenayo olufunyenweyo
@@ -213,7 +194,6 @@ Name=ProcessFailed
Name[ar]=فشلت العملية
Name[ast]=Procesu fallíu
Name[bn]=প্রসেস ব্যর্থ
Name[bs]=Neuspio proces
Name[ca]=Procés erroni
Name[ca@valencia]=Procés erroni
Name[cs]=Proces selhal
@@ -235,11 +215,9 @@ Name[hi]=प्रक्रिया-असफल
Name[hne]=काम-फेल
Name[hr]=ProcesNeuspješan
Name[hu]=Hibás folyamat
Name[ia]=Processo falleva
Name[is]=ProcessFailed
Name[it]=Processo non riuscito
Name[ja]=プロセス失敗
Name[kk]=Процес жаңылысы
Name[km]=ដំណើរ​ការ​បាន​បរាជ័យ
Name[ko]=ProcessFailed
Name[lt]=Procesas nepavyko
@@ -257,17 +235,15 @@ Name[pt]=ProcessFailed
Name[pt_BR]=Falha de processo
Name[ro]=ProcesEșuat
Name[ru]=Ошибка процесса
Name[si]=සැකසුම අසාර්ථකයි
Name[sk]=Proces zlyhal
Name[sl]=Proces ni uspel
Name[sr]=Процес није успео
Name[sr@ijekavian]=Процес није успио
Name[sr@ijekavianlatin]=Proces nije uspio
Name[sr@ijekavian]=Процес није успео
Name[sr@ijekavianlatin]=Proces nije uspeo
Name[sr@latin]=Proces nije uspeo
Name[sv]=Process misslyckades
Name[ta]=செயல் தோல்வியுற்றது
Name[tg]=Ҷараён бо Нокомӣ анҷомид
Name[th]=โพรเซสล้มเหลว
Name[tr]=Başarısız İşlemler
Name[uk]=ProcessFailed
Name[xh]=Inkqubo Yahlulekile
@@ -280,7 +256,6 @@ Comment[af]=Kon nie roep proses na handvatsel verbinding
Comment[ar]= لا يمكن نداء الإجراء إلى مؤشر الاتصال
Comment[ast]=Nun puede llamase a un procesu pa remanar la conexón
Comment[bn]=সংযোগ পরিচালনা করতে প্রসেস শুরু করতে পারল না
Comment[bs]=Nisam mogao da pozovem proces da opsluži vezu
Comment[ca]=No es pot cridar al procés per a manejar la connexió
Comment[ca@valencia]=No es pot cridar al procés per a manejar la connexió
Comment[cs]=Nelze spustit proces k obsluze spojení
@@ -302,11 +277,9 @@ Comment[hi]=कनेक्शन हैंडल करने के लिए
Comment[hne]=कनेक्सन हेंडल करे बर काम काल नइ कर सकिस
Comment[hr]=Nisam mogao pozvati proces za kontrolu veze
Comment[hu]=A kapcsolat kezelése nem sikerült
Comment[ia]=Il non pote appellar processo pro manear connexion
Comment[is]=Gat ekki kallað á forrit til að höndla tengingu
Comment[it]=Impossibile richiamare il processo per gestire la connessione
Comment[ja]=接続を扱うプロセスを呼び出せません
Comment[kk]=Қосылыммен айналысатын процесс шақырылмады
Comment[km]=មិន​អាច​ហៅ​ដំណើរ​ការ ដើម្បី​ដោះស្រាយ​ការ​ត​ភ្ជាប់​បាន​ឡើយ
Comment[ko]=연결을 처리하기 위한 프로세스를 부를 수 없습니다
Comment[lt]=Nepavyko iškviesti proceso apdoroti prisijungimui
@@ -323,7 +296,6 @@ Comment[pt]=Não foi possível invocar o processo para lidar com as ligações
Comment[pt_BR]=Não foi possível chamar o processo de controle da conexão
Comment[ro]=Procesul ce manipulează conexiunea nu a putut fi apelat
Comment[ru]=Не удаётся запустить процесс обработки соединения
Comment[si]=සබඳතාව හැසිරවීම සඳහා සැකසීම නොකැඳවන්න
Comment[sk]=Nepodarilo sa spustiť proces na spracovanie pripojenia
Comment[sl]=Ni možno poklicati procesa za upravljanje s povezavo
Comment[sr]=Нисам могао да позовем процес да опслужи везу
@@ -333,7 +305,6 @@ Comment[sr@latin]=Nisam mogao da pozovem proces da opsluži vezu
Comment[sv]=Kunde inte anropa process för att hantera anslutning
Comment[ta]=இணைப்பை கையாள செயற்பாட்டை அழைக்க முடியவில்லை
Comment[tg]=Барои даскории пайвастшавӣ ҷараён бозхонда нашуд
Comment[th]=ไม่สามารถเรียกโพรเซสเพื่อจัดการรับการเชื่อมต่อได้
Comment[tr]=Elle bağlantıda başarısız çağrı işlemleri
Comment[uk]=Не вдалося викликати процес для з’єднання
Comment[xh]=Ayikwazanga ukubiza inkqubo ezakuphatha uxhulumano

View File

@@ -9,7 +9,6 @@ Name[ast]=Triba de módulu KInetD
Name[bg]=Модул на KInetD
Name[bn]=কে-আইনেট-ডি মডিউল ধরন
Name[br]=Seurt ar mollad KInetD
Name[bs]=Vrsta modula KInetD-a
Name[ca]=Tipus de mòdul del KInetD
Name[ca@valencia]=Tipus de mòdul del KInetD
Name[cs]=Typ modulu KInetD
@@ -22,7 +21,7 @@ Name[eo]=KInetD modulotipo
Name[es]=Tipo de módulo KInetD
Name[et]=KInetD mooduli tüüp
Name[eu]=KInetD modulu mota
Name[fa]=نوع پیمانه KInetD
Name[fa]=نوع پیمانۀ KInetD
Name[fi]=KInetD-moduulityyppi
Name[fr]=Type de module de KInetD
Name[ga]=Cineál Modúil KInetD
@@ -32,7 +31,6 @@ Name[hi]=के-इनिट-डी मॉड्यूल प्रकार
Name[hne]=के-इनिट-डी माड्यूल किसम
Name[hr]=Tip KInetD Modula
Name[hu]=KInetD modultípus
Name[ia]=Typo de modulo KInetD
Name[is]=KInetD Module tegund
Name[it]=Tipo di modulo KInetD
Name[ja]=KInetD モジュールタイプ
@@ -56,7 +54,6 @@ Name[pt_BR]=Módulo KInetD
Name[ro]=Tip modul KInetD
Name[ru]=Модуль KInetD
Name[se]=KInetD-moduvlašládja
Name[si]=KInetD මොඩියුල වර්‍ගය
Name[sk]=Typ modulu KInetD
Name[sl]=Vrsta modula KInetD
Name[sr]=Врста модула КинетД‑а
@@ -66,7 +63,7 @@ Name[sr@latin]=Vrsta modula KInetDa
Name[sv]=Kinetd-modultyp
Name[ta]=KInetD கூறு வகை
Name[tg]=Навъи Модули KInetD
Name[tr]=KInetD Modül Türü
Name[tr]=KDED Modül Türü
Name[uk]=Тип модулю KinetD
Name[vi]=Kiểu môđun KInetD
Name[xh]=Udidi Lomqongo womlinganiselo we KInetD

View File

@@ -4,41 +4,30 @@ X-KDE-ServiceType=krfb/framebuffer
Comment=Frame Buffer plugins for KRfb
Comment[ast]=Complementu de buffer pa KRfb
Comment[bs]=Priključci framebafera za KRfb
Comment[ca]=Connectors de «framebuffer» per al KRfb.
Comment[ca@valencia]=Connectors de «framebuffer» per al KRfb.
Comment[cs]=Moduly Frame bufferu pro KRfb
Comment[da]=Framebuffer-plugins til KRfb
Comment[de]=Framebuffer-Module für KRfb
Comment[el]=Πρόσθετα μνήμης εξόδου βίντεο καρέ για το KRfb
Comment[en_GB]=Frame Buffer plugins for KRfb
Comment[es]=Complementos de memoria intermedia de vídeo para KRfb
Comment[es]=Complemento de buffer para KRfb
Comment[et]=KRfb kaadripuhvri plugin
Comment[eu]=Irteerako bideoaren pluginak KRfb-rentzako
Comment[fi]=Kehyspuskuriliitännäinen kohteelle KRfb
Comment[fr]=Modules de sortie vidéo pour KRfb
Comment[ga]=Breiseáin Mhaoláin Fráma le haghaidh KRfb
Comment[gl]=Engadido de frame buffer para KRfb
Comment[hr]=Priključci za međuspremnike okvira za KRfb
Comment[hu]=Framebuffer bővítmények a Krfb-hez
Comment[ia]=Plug-ins de Frame Buffer per KRfb
Comment[hu]=Keretpuffer-modulok a KRfb-hez
Comment[it]=Estensioni del framebuffer per KRfb
Comment[ja]=KRfb
Comment[kk]=KRfb кадр буфер плагині
Comment[km]= Frame Buffer KRfb
Comment[ko]=KRfb
Comment[lt]=Frame Buffer priedai skirti KRfb
Comment[lv]=Kadru bufera sprudņi priekš KRfb
Comment[nb]=Rammebuffer-programtillegg for KRfb
Comment[nds]=Bildpuffer-Modulen för KRfb
Comment[nl]=Framebuffer-plugins voor KRfb
Comment[nn]=Framebuffer-tillegg KRfb
Comment[pa]=KRfb
Comment[pl]=Wtyczki buforów ramek dla KRfb
Comment[pt]='Plugins' de 'framebuffers' para o KRfb
Comment[pt_BR]=Plug-ins de framebuffers para o KRfb
Comment[ru]=Модуль буфера кадров для KRfb
Comment[si]=KRfb
Comment[sk]=Frame Buffer modul pre KRfb
Comment[sl]=Vstavki slikovnih medpomnilnikov za KRFB
Comment[sr]=Прикључци кадробафера за КРФБ
@@ -46,7 +35,6 @@ Comment[sr@ijekavian]=Прикључци кадробафера за КРФБ
Comment[sr@ijekavianlatin]=Priključci kadrobafera za KRFB
Comment[sr@latin]=Priključci kadrobafera za KRFB
Comment[sv]=Insticksprogram med rambuffert för Krfb
Comment[th]= KRfb
Comment[tr]=KRfb için Çerçeve Tamponu eklentileri
Comment[uk]=Додатки буфера кадрів для KRfb
Comment[x-test]=xxFrame Buffer plugins for KRfbxx

14
krfb/krfb.desktop → krfb.desktop Executable file → Normal file
View File

@@ -11,7 +11,6 @@ Name[ast]=Krfb
Name[bg]=Krfb
Name[bn]=---ি
Name[br]=Krfb
Name[bs]=Krfb
Name[ca]=Krfb
Name[ca@valencia]=Krfb
Name[cs]=Krfb
@@ -32,7 +31,6 @@ Name[hi]=केआरएफबी
Name[hne]=
Name[hr]=Krfb
Name[hu]=Krfb
Name[ia]=Krfb
Name[is]=Krfb
Name[it]=Krfb
Name[ja]=Krfb
@@ -53,17 +51,14 @@ Name[pt]=Krfb
Name[pt_BR]=Krfb
Name[ro]=Krfb
Name[ru]=Krfb
Name[si]=Krfb
Name[sk]=Krfb
Name[sl]=Krfb
Name[sq]=Krfb
Name[sr]=КРФБ
Name[sr@ijekavian]=КРФБ
Name[sr@ijekavianlatin]=KRFB
Name[sr@latin]=KRFB
Name[sv]=Krfb
Name[tr]=Krfb
Name[ug]=Krfb
Name[uk]=Krfb
Name[uz]=Krfb
Name[uz@cyrillic]=Krfb
@@ -71,14 +66,13 @@ Name[vi]=Krfb
Name[x-test]=xxKrfbxx
Name[zh_CN]=Krfb
Name[zh_HK]=Krfb
Name[zh_TW]=_Krfb
Name[zh_TW]=Krfb
GenericName=Desktop Sharing
GenericName[ar]=مشاركة سطح المكتب
GenericName[ast]=Escritoriu compartíu
GenericName[bg]=Споделяне на работния плот
GenericName[bg]=Споделяне на работното място
GenericName[bn]= ি
GenericName[br]=Rannañ ar vurev
GenericName[bs]=Dijeljenje radne površine
GenericName[ca]=Compartició de l'escriptori
GenericName[ca@valencia]=Compartició de l'escriptori
GenericName[cs]=Sdílení pracovní plochy
@@ -101,7 +95,6 @@ GenericName[hi]=डेस्कटॉप साझेदारी
GenericName[hne]=
GenericName[hr]=Dijeljenje radne površine
GenericName[hu]=Munkaasztal-megosztás
GenericName[ia]=Compartir de scriptorio
GenericName[is]=Skjáborðsmiðlun
GenericName[it]=Condivisione del desktop
GenericName[ja]=
@@ -122,7 +115,6 @@ GenericName[pt]=Partilha do Ecrã
GenericName[pt_BR]=Compartilhamento de ambiente de trabalho
GenericName[ro]=Partajare birou
GenericName[ru]=Общий рабочий стол
GenericName[si]=
GenericName[sk]=Zdieľanie pracovnej plochy
GenericName[sl]=Deljenje namizja
GenericName[sr]=Дељење површи
@@ -130,9 +122,7 @@ GenericName[sr@ijekavian]=Дијељење површи
GenericName[sr@ijekavianlatin]=Dijeljenje površi
GenericName[sr@latin]=Deljenje površi
GenericName[sv]=Dela ut skrivbordet
GenericName[th]=
GenericName[tr]=Masaüstü Paylaşımı
GenericName[ug]=ئۈستەلئۈستىنى ھەمبەھىرلەش
GenericName[uk]=Спільні стільниці
GenericName[uz]=Ish stoli bilan boʻlishish
GenericName[uz@cyrillic]=Иш столи билан бўлишиш

View File

@@ -4,10 +4,8 @@ Comment=Desktop Sharing
Comment[af]=Werkskerm Deeling
Comment[ar]=مشاركة سطح المكتب
Comment[ast]=Escritoriu compartíu
Comment[bg]=Споделяне на работния плот
Comment[bn]=ডেস্কটপ ভাগাভাগি
Comment[br]=Rannañ ar vurev
Comment[bs]=Dijeljenje radne površine
Comment[ca]=Compartició de l'escriptori
Comment[ca@valencia]=Compartició de l'escriptori
Comment[cs]=Sdílení pracovní plochy
@@ -29,11 +27,9 @@ Comment[hi]=डेस्कटॉप साझेदारी
Comment[hne]=डेस्कटाप साझेदारी
Comment[hr]=Dijeljenje radne površine
Comment[hu]=Munkaasztal-megosztás
Comment[ia]=Compartir de scriptorio
Comment[is]=Skjáborðamiðlun
Comment[it]=Condivisione del desktop
Comment[ja]=デスクトップ共有
Comment[kk]=Үстелді ортақтастыру
Comment[km]=ការ​ចែក​រំលែក​ផ្ទែ​តុ
Comment[ko]=데스크톱 공유
Comment[lt]=Dalinimasis darbastaliu
@@ -51,7 +47,6 @@ Comment[pt]=Partilha do Ecrã
Comment[pt_BR]=Compartilhamento do ambiente de trabalho
Comment[ro]=Partajare birou
Comment[ru]=Параметры общего рабочего стола
Comment[si]=වැඩතල හවුල්
Comment[sk]=Zdieľanie pracovnej plochy
Comment[sl]=Deljenje namizja
Comment[sr]=Дељење површи
@@ -61,9 +56,7 @@ Comment[sr@latin]=Deljenje površi
Comment[sv]=Dela ut skrivbordet
Comment[ta]=பணிமேடை பகிர்வு
Comment[tg]=Истифодаи Муштараки Мизи Корӣ
Comment[th]=ใช้งานพื้นที่ทำงานร่วมกัน
Comment[tr]=Masaüstü Paylaşımı
Comment[ug]=ئۈستەلئۈستىنى ھەمبەھىرلەش
Comment[uk]=Спільні стільниці
Comment[xh]=Ulwahlulelano lwe Desktop
Comment[x-test]=xxDesktop Sharingxx
@@ -75,8 +68,6 @@ Comment[zh_TW]=桌面分享
Name=User Accepts Connection
Name[ar]=المستخدم يقبل الاتصال
Name[ast]=L'usuariu aceuta la conexón
Name[bg]=Потребителят приема връзката
Name[bs]=Korisnik prihvata vezu
Name[ca]=L'usuari accepta la connexió
Name[ca@valencia]=L'usuari accepta la connexió
Name[cs]=Uživatel přijímá spojení
@@ -96,11 +87,9 @@ Name[hi]=उपयोक्ता ने कनेक्शन स्वीक
Name[hne]=कमइया हर कनेक्सन स्वीकारा
Name[hr]=Korisnik prihvaća vezu
Name[hu]=A felhasználó engedélyezi a csatlakozást
Name[ia]=Usator da acceptation a connexion
Name[is]=Notandi samþykkir tengingar
Name[it]=L'utente accetta la connessione
Name[ja]=ユーザが接続を許可
Name[kk]=Пайдаланушы қосылымды қабылдайды
Name[km]=អ្នក​ប្រើ​ទទួល​យក​ការ​ត​ភ្ជាប់
Name[ko]=사용자가 연결을 수락함
Name[lt]=Naudotojas priėmė kvietimą
@@ -116,7 +105,6 @@ Name[pt]=O Utilizador Aceita a Ligação
Name[pt_BR]=O usuário aceita a conexão
Name[ro]=Utilizatorul acceptă conexiunea
Name[ru]=Пользователь принимает соединения
Name[si]=සබැඳිය පරිශීලකයා තහවුරු කරයි
Name[sk]=Užívateľ akceptuje pripojenie
Name[sl]=Uporabnik sprejel povezavo
Name[sr]=Корисник прихвата везу
@@ -124,7 +112,6 @@ Name[sr@ijekavian]=Корисник прихвата везу
Name[sr@ijekavianlatin]=Korisnik prihvata vezu
Name[sr@latin]=Korisnik prihvata vezu
Name[sv]=Användaren accepterar anslutning
Name[th]=ผู้ใช้ยอมรับการเชื่อมต่อ
Name[tr]=Kullanıcı Bağlantıyı Kabul Etti
Name[uk]=Користувач приймає з’єднання
Name[x-test]=xxUser Accepts Connectionxx
@@ -134,9 +121,7 @@ Comment=User accepts connection
Comment[af]=Gebruiker aanvaar verbinding
Comment[ar]=المستخدم يقبل الاتصال
Comment[ast]=L'usuariu aceuta la conexón
Comment[bg]=Потребителят приема връзката
Comment[bn]=ব্যবহারকারী সংযোগ গ্রহণ করে
Comment[bs]=Korisnik prihvata vezu
Comment[ca]=L'usuari accepta la connexió
Comment[ca@valencia]=L'usuari accepta la connexió
Comment[cs]=Uživatel přijímá spojení
@@ -158,11 +143,9 @@ Comment[hi]=उपयोक्ता ने कनेक्शन स्वी
Comment[hne]=कमइया हर कनेक्सन स्वीकारा
Comment[hr]=Korisnik prihvaća vezu
Comment[hu]=A felhasználó engedélyezi a csatlakozást
Comment[ia]=Usator da acceptation a connexion
Comment[is]=Notandi samþykkir tengingu
Comment[it]=L'utente accetta la connessione
Comment[ja]=ユーザが接続を許可
Comment[kk]=Пайдаланушы қосылымды қабылдайды
Comment[km]=អ្នក​ប្រើ​ទទួល​យក​ការ​ត​ភ្ជាប់
Comment[ko]=사용자가 연결을 수락함
Comment[lt]=Naudotojas priėmė kvietimą
@@ -180,7 +163,6 @@ 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[si]=සබැඳිය පරිශීලකයා තහවුරු කරයි
Comment[sk]=Užívateľ akceptuje pripojenie
Comment[sl]=Uporabnik sprejel povezavo
Comment[sr]=Корисник прихвата везу
@@ -190,7 +172,6 @@ Comment[sr@latin]=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[xh]=Umsebenzisi wamkela uxhulumaniso
@@ -204,8 +185,6 @@ Action=Popup
Name=User Refuses Connection
Name[ar]=المستخدم يرفض الاتصال
Name[ast]=L'usuariu refuga la conexón
Name[bg]=Потребителят отказва връзката
Name[bs]=Korisnik odbija vezu
Name[ca]=L'usuari refusa la connexió
Name[ca@valencia]=L'usuari refusa la connexió
Name[cs]=Uživatel odmítá spojení
@@ -225,11 +204,9 @@ Name[hi]=उपयोक्ता ने कनेक्शन अस्वी
Name[hne]=कमइया हर कनेक्सन अस्वीकारा
Name[hr]=Korisnik odbija vezu
Name[hu]=A felhasználó elutasítja a csatlakozást
Name[ia]=Usator refuta connexion
Name[is]=Notandi hafnar tengingum
Name[it]=L'utente rifiuta la connessione
Name[ja]=ユーザが接続を拒否
Name[kk]=Пайдаланушы қосылымдан бас тартады
Name[km]=អ្នក​ប្រើ​បដិសេធ​ការ​ត​ភ្ជាប់
Name[ko]=사용자가 연결을 거부함
Name[lt]=Naudotojas atmetė kvietimą
@@ -245,7 +222,6 @@ Name[pt]=O Utilizador Recusa a Ligação
Name[pt_BR]=O usuário rejeita a conexão
Name[ro]=Utilizatorul refuză conexiunea
Name[ru]=Пользователь отклоняет соединения
Name[si]=සබැඳිය පරිශීලකයා තහවුරු නොකරයි
Name[sk]=Užívateľ odmieta pripojenie
Name[sl]=Uporabnik zavrnil povezavo
Name[sr]=Корисник одбија везу
@@ -253,7 +229,6 @@ Name[sr@ijekavian]=Корисник одбија везу
Name[sr@ijekavianlatin]=Korisnik odbija vezu
Name[sr@latin]=Korisnik odbija vezu
Name[sv]=Användaren vägrar anslutning
Name[th]=ผู้ใช้ปฏิเสธการเชื่อมต่อ
Name[tr]=Kullanıcı Bağlantıyı Reddetti
Name[uk]=Користувач не приймає з’єднання
Name[x-test]=xxUser Refuses Connectionxx
@@ -263,9 +238,7 @@ Comment=User refuses connection
Comment[af]=Gebruiker weier verbinding
Comment[ar]=المستخدم يرفض الاتصال
Comment[ast]=L'usuariu refuga la conexón
Comment[bg]=Потребителят отказва връзката
Comment[bn]=ব্যবহারকারী সংযোগ অস্বীকার করে
Comment[bs]=Korisnik odbija vezu
Comment[ca]=L'usuari refusa la connexió
Comment[ca@valencia]=L'usuari refusa la connexió
Comment[cs]=Uživatel odmítá spojení
@@ -287,11 +260,9 @@ Comment[hi]=उपयोक्ता ने कनेक्शन अस्व
Comment[hne]=कमइया हर कनेक्सन अस्वीकारा
Comment[hr]=Korisnik odbija vezu
Comment[hu]=A felhasználó elutasítja a csatlakozást
Comment[ia]=Usator refuta connexion
Comment[is]=Notandi hafnar tengingu
Comment[it]=L'utente rifiuta la connessione
Comment[ja]=ユーザが接続を拒否
Comment[kk]=Пайдаланушы қосылымды қабылдамайды
Comment[km]=អ្នក​ប្រើ​បដិសេធ​ការ​ត​ភ្ជាប់
Comment[ko]=사용자가 연결을 거부함
Comment[lt]=Naudotojas atmetė kvietimą
@@ -309,7 +280,6 @@ 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[si]=සබැඳිය පරිශීලකයා තහවුරු නොකරයි
Comment[sk]=Užívateľ odmieta pripojenie
Comment[sl]=Uporabnik zavrnil povezavo
Comment[sr]=Корисник одбија везу
@@ -319,7 +289,6 @@ Comment[sr@latin]=Korisnik odbija vezu
Comment[sv]=Användaren vägrar anslutning
Comment[ta]=பயனர் இணைப்பு ஏற்க மறுக்கப்பட்டது
Comment[tg]=Корванд пайвастшавиро рад мекунад
Comment[th]=ผู้ใช้ปฏิเสธการเชื่อมต่อ
Comment[tr]=Kullanıcı bağlantıyı reddetti
Comment[uk]=Користувач не приймає з’єднання
Comment[xh]=Umsebenzisi wala uxhulumaniso
@@ -333,8 +302,6 @@ Action=Popup
Name=Connection Closed
Name[ar]=الاتصال أغلق
Name[ast]=Conexón zarrada
Name[bg]=Връзката е прекъсната
Name[bs]=Konekcija zatvorena
Name[ca]=Connexió tancada
Name[ca@valencia]=Connexió tancada
Name[cs]=Spojení ukončeno
@@ -354,11 +321,9 @@ Name[hi]=कनेक्शन बन्द
Name[hne]=कनेक्सन बन्द
Name[hr]=Veza prekinuta
Name[hu]=A kapcsolat megszűnt
Name[ia]=Connexion claudite
Name[is]=Tengingu lokað
Name[it]=Connessione chiusa
Name[ja]=接続切断
Name[kk]=Қосылымдан жабылды
Name[km]=បាន​បិទ​ការ​ត​ភ្ជាប់
Name[ko]=연결이 닫힘
Name[lt]=Ryšys baigtas
@@ -375,16 +340,13 @@ Name[pt]=Ligação Fechada
Name[pt_BR]=Conexão encerrada
Name[ro]=Conexiune închisă
Name[ru]=Соединение закрыто
Name[si]=සබඳතාව වසා දැමිනි
Name[sk]=Pripojenie bolo ukončené
Name[sk]=Pripojenie ukončené
Name[sl]=Povezava zaprta
Name[sq]=Lidhja u Mbyll
Name[sr]=Веза затворена
Name[sr@ijekavian]=Веза затворена
Name[sr@ijekavianlatin]=Veza zatvorena
Name[sr@latin]=Veza zatvorena
Name[sv]=Anslutning stängd
Name[th]=การเชื่อมต่อยุติ
Name[tr]=Bağlantı Kapatıldı
Name[uk]=З'єднання закрито
Name[x-test]=xxConnection Closedxx
@@ -394,10 +356,8 @@ Comment=Connection closed
Comment[af]=Verbinding gesluit
Comment[ar]=تمّ غلق الاتصال
Comment[ast]=Conexón zarrada
Comment[bg]=Връзката е прекъсната
Comment[bn]=সংযোগ বন্ধ করা হল
Comment[br]=Serret eo ar gevreadenn
Comment[bs]=Veza je zatvorena
Comment[ca]=Connexió tancada
Comment[ca@valencia]=Connexió tancada
Comment[cs]=Spojení ukončeno
@@ -419,11 +379,9 @@ Comment[hi]=कनेक्शन बन्द
Comment[hne]=कनेक्सन बन्द
Comment[hr]=Veza prekinuta
Comment[hu]=A kapcsolat megszűnt
Comment[ia]=Connexion claudite
Comment[is]=Tengingu lokað
Comment[it]=Connessione chiusa
Comment[ja]=接続が閉じられました
Comment[kk]=Қосылымдан жабылды
Comment[km]=បាន​បិទ​ការ​ត​ភ្ជាប់
Comment[ko]=연결이 닫힘
Comment[lt]=Ryšys baigtas
@@ -441,10 +399,8 @@ Comment[pt]=A ligação foi encerrada
Comment[pt_BR]=Conexão encerrada
Comment[ro]=Conexiune închisă
Comment[ru]=Соединение закрыто
Comment[si]=සබඳතාව වසාදැමිනි
Comment[sk]=Pripojenie bolo ukončené
Comment[sk]=Pripojenie ukončené
Comment[sl]=Povezava zaprta
Comment[sq]=Lidhja u mbyll
Comment[sr]=Веза је затворена
Comment[sr@ijekavian]=Веза је затворена
Comment[sr@ijekavianlatin]=Veza je zatvorena
@@ -452,9 +408,7 @@ Comment[sr@latin]=Veza je zatvorena
Comment[sv]=Anslutning stängd
Comment[ta]=இணைப்புகள் மூடப்பட்டது
Comment[tg]=Пайвастшавӣ пӯшида аст
Comment[th]=การเชื่อมต่อยุติ
Comment[tr]=Bağlantı kapatıldı
Comment[ug]=باغلىنىش تاقالدى
Comment[uk]=З'єднання закрито
Comment[uz]=Aloqa uzildi
Comment[uz@cyrillic]=Алоқа узилди
@@ -469,8 +423,6 @@ Action=Popup
Name=Invalid Password
Name[ar]=كلمة المرور غير صحيحة
Name[ast]=Contraseña incorreuta
Name[bg]=Неправилна парола
Name[bs]=Neispravna šifra
Name[ca]=Contrasenya no vàlida
Name[ca@valencia]=Contrasenya no vàlida
Name[cs]=Neplatné heslo
@@ -490,11 +442,9 @@ Name[hi]=अवैध पासवर्ड
Name[hne]=अवैध पासवर्ड
Name[hr]=Nevažeća zaporka
Name[hu]=Érvénytelen jelszó
Name[ia]=Contrasigno invalide
Name[is]=Ógilt lykilorð
Name[it]=Password non valida
Name[ja]=無効なパスワード
Name[kk]=Жарамсыз паролі
Name[km]=ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ
Name[ko]=잘못된 암호
Name[lt]=Neteisingas slaptažodžis
@@ -510,20 +460,15 @@ Name[pt]=Senha Inválida
Name[pt_BR]=Senha inválida
Name[ro]=Parolă nevalidă
Name[ru]=Неверный пароль
Name[si]=වැරදි මුරපදය
Name[sk]=Neplatné heslo
Name[sl]=Neveljavno geslo
Name[sq]=Fjalëkalim i Pavlefshëm
Name[sr]=Неисправна лозинка
Name[sr@ijekavian]=Неисправна лозинка
Name[sr@ijekavianlatin]=Neispravna lozinka
Name[sr@latin]=Neispravna lozinka
Name[sv]=Ogiltigt lösenord
Name[th]=รหัสผ่านไม่ถูกต้อง
Name[tr]=Geçersiz Parola
Name[ug]=ئىناۋەتسىز ئىم
Name[uk]=Неправильний пароль
Name[wa]=Sicret nén valåbe
Name[x-test]=xxInvalid Passwordxx
Name[zh_CN]=无效密码
Name[zh_TW]=不正確的密碼
@@ -531,10 +476,8 @@ Comment=Invalid password
Comment[af]=Ongeldige wagwoord
Comment[ar]=كلمة المرور غير صحيحة
Comment[ast]=Contraseña incorreuta
Comment[bg]=Неправилна парола
Comment[bn]=অবৈধ পাসওয়ার্ড
Comment[br]=Tremenger siek
Comment[bs]=Neispravna šifra
Comment[ca]=Contrasenya no vàlida
Comment[ca@valencia]=Contrasenya no vàlida
Comment[cs]=Neplatné heslo
@@ -556,11 +499,9 @@ Comment[hi]=अवैध पासवर्ड
Comment[hne]=अवैध पासवर्ड
Comment[hr]=Nevažeća šifra
Comment[hu]=Érvénytelen jelszó
Comment[ia]=Contrasigno invalide
Comment[is]=Lykilorð ógilt
Comment[it]=Password non valida
Comment[ja]=無効なパスワード
Comment[kk]=Паролі дұрыс емес
Comment[km]=ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ
Comment[ko]=잘못된 암호
Comment[lt]=Neteisingas slaptažodis
@@ -580,10 +521,8 @@ Comment[pt]=A senha é inválida
Comment[pt_BR]=Senha inválida
Comment[ro]=Parolă nevalidă
Comment[ru]=Неверный пароль
Comment[si]=වැරදි මුරපදය
Comment[sk]=Neplatné heslo
Comment[sl]=Neveljavno geslo
Comment[sq]=Fjalëkalim i pavlefshëm
Comment[sr]=Неисправна лозинка
Comment[sr@ijekavian]=Неисправна лозинка
Comment[sr@ijekavianlatin]=Neispravna lozinka
@@ -591,9 +530,7 @@ Comment[sr@latin]=Neispravna lozinka
Comment[sv]=Ogiltigt lösenord
Comment[ta]=செல்லாத கடவுச்சொல்
Comment[tg]=Гузарвожаи нодуруст
Comment[th]=รหัสผ่านไม่ถูกต้อง
Comment[tr]=Geçersiz parola
Comment[ug]=ئىناۋەتسىز ئىم
Comment[uk]=Неправильний пароль
Comment[uz]=Maxfiy soʻz haqiqiy emas
Comment[uz@cyrillic]=Махфий сўз ҳақиқий эмас
@@ -609,8 +546,6 @@ Action=Popup
Name=Invalid Password Invitations
Name[ar]=كلمة المرور الدعوات غير صحيحة
Name[ast]=Contraseñas d'invitaciones incorreutes
Name[bg]=Неправилна парола за покана
Name[bs]=Neispravna šifra pozivnice
Name[ca]=Contrasenya de les invitacions no vàlides
Name[ca@valencia]=Contrasenya de les invitacions no vàlides
Name[cs]=Neplatné hesla výzev
@@ -621,7 +556,7 @@ Name[en_GB]=Invalid Password Invitations
Name[eo]=Nevalidaj pasvortaj invitoj
Name[es]=Contraseñas de invitaciones incorrectas
Name[et]=Kutsutu vale parool
Name[eu]=Gonbitearen pasahitza baliogabea
Name[eu]=Baliogabeko pasahitz gonbidapena
Name[fi]=Virheellinen salasana kutsuun
Name[fr]=Invitations de mot de passe non valables
Name[ga]=Cuirí Neamhbhailí Focal Faire
@@ -630,13 +565,11 @@ Name[hi]=अवैध पासवर्ड निमंत्रण
Name[hne]=अवैध पासवर्ड निमंत्रन
Name[hr]=Pozivnice s nevažećim zaporkama
Name[hu]=Érvénytelen jelszavas meghívó
Name[ia]=Invitationes de contrasigno invalide
Name[is]=Ógild lykilorðsboð
Name[it]=Password di invito non valida
Name[ja]=招待に対する無効なパスワード
Name[kk]=Жарамсыз паролімен шақыру
Name[km]=ការ​អញ្ជើញ​ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ
Name[ko]=잘못된 호 초대장
Name[ko]=잘못된 비밀번호 초대장
Name[lt]=Neteisingas kvietimo slaptažodis
Name[lv]=Nepareiza parole ar ielūgumu
Name[ml]=അസാധുവായ അടയാളവാക്ക് ക്ഷണങ്ങള്‍
@@ -650,7 +583,6 @@ Name[pt]=Convites de Senha Inválidos
Name[pt_BR]=Avisos de senha inválida
Name[ro]=Parolă nevalidă Invitații
Name[ru]=Неверный пароль приглашения
Name[si]=වැරදි මුරපද ආරාධනාවක්
Name[sk]=Neplatné heslo pozvánky
Name[sl]=Povabila z neveljavnimi gesli
Name[sr]=Неисправна лозинка позивнице
@@ -658,7 +590,6 @@ Name[sr@ijekavian]=Неисправна лозинка позивнице
Name[sr@ijekavianlatin]=Neispravna lozinka pozivnice
Name[sr@latin]=Neispravna lozinka pozivnice
Name[sv]=Ogiltigt lösenord vid inbjudan
Name[th]=รหัสผ่านของการเชื้อเชิญไม่ถูกต้อง
Name[tr]=Geçersiz Parola Daveti
Name[uk]=Запрошення з некоректними паролями
Name[x-test]=xxInvalid Password Invitationsxx
@@ -668,9 +599,7 @@ Comment=The invited party sent an invalid password. Connection refused.
Comment[af]=Die uitgenooi party gestuur 'n ongeldige wagwoord. Verbinding geweier.
Comment[ar]=المدعو أرسل كلمة مرور غير صحيحة. رفض الإتصال.
Comment[ast]=L'invitáu unvió una contraseña incorreuta. Conexón refugada.
Comment[bg]=Поканената страна изпрати неправилна парола. Връзката е отказана.
Comment[bn]=আমন্ত্রিত দল একটি অবৈধ পাসওয়ার্ড পাঠাল। সংযোগ অস্বীকার করা হল।
Comment[bs]=Pozvana strana je poslala pogrešnu šifru. Veza je odbijena.
Comment[ca]=La part invitada ha enviat una contrasenya no vàlida. Connexió refusada.
Comment[ca@valencia]=La part invitada ha enviat una contrasenya no vàlida. Connexió refusada.
Comment[cs]=Pozvaná strana poslala neplatné heslo. Spojení odmítnuto.
@@ -682,7 +611,7 @@ Comment[en_GB]=The invited party sent an invalid password. Connection refused.
Comment[eo]=La invitita kliento sendis nevalidan pasvorton. Konekto rifuzita.
Comment[es]=El invitado 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 ukatuta.
Comment[eu]=Gonbidatutako parekoak baliogabeko pasahitza bidali du. Konexioa ukatu da.
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[ga]=Sheol an duine le cuireadh focal faire neamhbhailí. Diúltaíodh an ceangal.
@@ -692,13 +621,11 @@ Comment[hi]=निमंत्रित पार्टी ने अवैध
Comment[hne]=निमंत्रित पार्टी हर अवैध पासवर्ड भेजिस. कनेक्सन अस्वीकृत.
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ási kérés elutasítva.
Comment[ia]=Le partita invitate inviava un contrasigno invalide. Connexion refusate.
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[kk]=Шқырылған жақ дұрыс емес парольді жіберді. Қосылымдан бас тартылды..
Comment[km]=ភាគី​ដែល​បាន​អញ្ជើញ បាន​ផ្ញើ​ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ ។ ការ​តភ្ជាប់​ត្រូវ​បាន​បដិសេធ ។
Comment[ko]=초대한 사람이 잘못된 호를 보냈습니다. 연결이 잘못되었습니다.
Comment[ko]=초대한 사람이 잘못된 비밀번호를 보냈습니다. 연결이 잘못되었습니다.
Comment[lt]=Pakviestoji pusė atsiuntė neteisingą slaptažodį. Ryšys nutrauktas.
Comment[lv]=Ielūgtā persona nosūtīja nepareizu paroli. Savienojums noraidīts.
Comment[mk]=Поканетата страна испрати невалидна лозинка. Поврзувањето е одбиено.
@@ -712,9 +639,8 @@ Comment[pl]=Z drugiej strony podano błędne hasło. Połączenie odrzucone.
Comment[pt]=O utilizador 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[ro]=Partea care invită a trimis o parolă nevalidă. Conexiune refuzată.
Comment[ru]=Приглашённый пользователь ввёл неправильный пароль. Соединение отклонено.
Comment[si]=ආරාධිත පාර්‍ශවය වැරදි මුරපදයක් එවන ලද බැවින් සබඳතාව ප්‍රතික්‍ෂේප විය.
Comment[sk]=Pozvaná strana poslala neplatné heslo. Pripojenie bolo odmietnuté.
Comment[ru]=Приглашенный пользователь ввёл неверный пароль. Соединение отклонено.
Comment[sk]=Pozvaná strana poslala neplatné heslo. Pripojenie odmietnuté.
Comment[sl]=Povabljena stranka je poslala neveljavno geslo. Povezava zavrnjena.
Comment[sr]=Позвана страна је послала погрешну лозинку. Веза је одбијена.
Comment[sr@ijekavian]=Позвана страна је послала погрешну лозинку. Веза је одбијена.
@@ -723,8 +649,7 @@ Comment[sr@latin]=Pozvana strana 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ı reddedildi.
Comment[tr]=Davet edilenden gönderilmiş geçersiz parola. Bağlantı rededildi.
Comment[uk]=Запрошений учасник надіслав некоректний пароль. У з’єднанні відмовлено.
Comment[xh]=Umhlangano omenyiweyo uthumele igama lokugqitha elisebenzayo. Uxhulumano lwa liwe.
Comment[x-test]=xxThe invited party sent an invalid password. Connection refused.xx
@@ -737,8 +662,6 @@ Action=Popup
Name=New Connection on Hold
Name[ar]=اتصال جديد على التوقف
Name[ast]=Conexón nueva a la espera
Name[bg]=Изчакване на новата връзка
Name[bs]=Nova veza je na čekanju
Name[ca]=Nova connexió en espera
Name[ca@valencia]=Nova connexió en espera
Name[cs]=Nové spojení pozdrženo
@@ -758,11 +681,9 @@ Name[hi]=नया कनेक्शन होल्ड पर रखा
Name[hne]=नवा कनेक्सन होल्ड मं रखा
Name[hr]=Nova veza na čekanju
Name[hu]=Új kapcsolat tartva
Name[ia]=Nove connexion in pausa
Name[is]=Ný tenging á bið
Name[it]=Nuova connessione in attesa
Name[ja]=保留中の新しい接続
Name[kk]=Жаңа қосылым күтілуде
Name[ja]=保留中の新接続
Name[km]=ការ​តភ្ជាប់​ថ្មី កំពុង​ស្ថិត​នៅ​ក្នុង​ការ​រង់ចាំ
Name[ko]=새 연결 대기 중
Name[lt]=Naujas kvietimas ryšiui sulaikytas
@@ -778,15 +699,13 @@ Name[pt]=Ligação Nova em Espera
Name[pt_BR]=Nova conexão ativa
Name[ro]=Conexiune nouă în așteptare
Name[ru]=Новое соединение приостановлено
Name[si]=නව සබඳතාවක් රඳවා ඇත
Name[sk]=Nové pripojenie bolo pozdržané
Name[sk]=Nové pripojenie pozdržané
Name[sl]=Nova povezava na čakanju
Name[sr]=Нова веза је на чекању
Name[sr@ijekavian]=Нова веза је на чекању
Name[sr@ijekavianlatin]=Nova veza je na čekanju
Name[sr@latin]=Nova veza je na čekanju
Name[sv]=Ny anslutning väntar
Name[th]=การเชื่อมต่อใหม่ถูกพักรอไว้ก่อน
Name[tr]=Yeni Açık Bağlantı
Name[uk]=Очікування на нове з’єднання
Name[x-test]=xxNew Connection on Holdxx
@@ -796,9 +715,7 @@ Comment=Connection requested, user must accept
Comment[af]=Verbinding versoekte, gebruiker moet aanvaar
Comment[ar]=الاتصال طلب، يجب موافقة المستخدم
Comment[ast]=Conexón solicitada, l'usuario tien d'aceutala
Comment[bg]=Поискана е връзка, следва потребителят да приеме
Comment[bn]=সংযোগ অনুরোধ করা হল, ব্যবহারকারীকে অবশ্যই স্বীকার করতে হবে
Comment[bs]=Veza je zahtijevana, korinik mora da je prihvati
Comment[ca]=Connexió sol·licitada, l'usuari ha d'acceptar-la
Comment[ca@valencia]=Connexió sol·licitada, l'usuari ha d'acceptar-la
Comment[cs]=Vyžadováno spojení, uživatel musí přijmout
@@ -810,7 +727,7 @@ Comment[en_GB]=Connection requested, user must accept
Comment[eo]=Konekto pridemandita, la uzanto devas akcepti
Comment[es]=Conexión solicitada, el usuario debe aceptarla
Comment[et]=Nõutakse ühendust, kasutaja peab seda lubama
Comment[eu]=Konexioa eskatuta, erabiltzaileak onartu behar du
Comment[eu]=Konexioa eskatu da, erabiltzaileak onartu behar du
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 don úsáideoir glacadh leis
@@ -820,11 +737,9 @@ Comment[hi]=कनेक्शन निवेदित. उपयोक्त
Comment[hne]=कनेक्सन निवेदित. कमइया ल स्वीकार होना चाही
Comment[hr]=Veza je zatražena, korisnik mora prihvatiti
Comment[hu]=Csatlakozási kérés, a felhasználónak el kell fogadnia
Comment[ia]=Connexion requirite, usator debe dar acceptation
Comment[is]=Beiðni um tengingu, notandi verður að samþykkja
Comment[it]=Connessione richiesta, l'utente deve accettare
Comment[ja]=接続が要求されています。ユーザが許可しなければなりません。
Comment[kk]=Қосылым сұралды, пайдаланушы жауап беруге тиіс
Comment[km]=បាន​ស្នើ​ការ​ត​ភ្ជាប់​​ អ្នក​ប្រើ​ត្រូវ​តែ​ទទួល​យក
Comment[ko]=연결 요청됨, 사용자가 수락해야 함
Comment[lt]=Kvietimas ryšiui išsiųstas, naudotojas turi priimti kvietimą
@@ -842,8 +757,7 @@ Comment[pt]=Foi pedida uma ligação que o utilizador deverá aceitar
Comment[pt_BR]=Conexão requisitada; o usuário deve aceitar
Comment[ro]=Conexiune cerută, utilizatorul trebuie să accepte
Comment[ru]=Запрос на соединение, требуется подтверждение пользователя
Comment[si]=සබඳතාව ඉල්ලා ඇත, පරිශීලක තහවුරු කල යුතුයි
Comment[sk]=Vyžiadané pripojenie, užívateľ ho musí akceptovať
Comment[sk]=Vyžiadané pripojenie, užívateľ musí akceptovať
Comment[sl]=Povezava zahtevana, uporabnik mora sprejeti
Comment[sr]=Захтевана је веза, корисник мора да је прихвати
Comment[sr@ijekavian]=Захтијевана је веза, корисник мора да је прихвати
@@ -852,7 +766,6 @@ Comment[sr@latin]=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[xh]=Uxhulumaniso luceliwe, umsebenzisi kufanele amkele
@@ -866,8 +779,6 @@ Action=Popup
Name=New Connection Auto Accepted
Name[ar]=اتصال جديد مقبول تلقائيا
Name[ast]=Conexón nueva aceutada automáticamente
Name[bg]=Автоматично приемане на новата връзка
Name[bs]=Nova veza je automatski prihvaćena
Name[ca]=Nova connexió acceptada automàticament
Name[ca@valencia]=Nova connexió acceptada automàticament
Name[cs]=Nové spojení automaticky přijato
@@ -878,7 +789,7 @@ Name[en_GB]=New Connection Auto Accepted
Name[eo]=Nova konekto aŭtomate akceptita
Name[es]=Conexión nueva aceptada automáticamente
Name[et]=Uue ühendusega automaatselt nõus
Name[eu]=Konexio berria automatikoki onartuta
Name[eu]=Konexio berria auto-onartu da
Name[fi]=Uusi yhteys hyväksyttiin automaattisesti
Name[fr]=Nouvelle connexion auto-acceptée
Name[ga]=Ceangal nua bunaithe go huathoibríoch
@@ -887,11 +798,9 @@ Name[hi]=नय कनेक्शन स्वचालित स्वीक
Name[hne]=नय कनेक्सन अपने अपन स्वीकारा
Name[hr]=Nova veza automatski prihvaćena
Name[hu]=Új kapcsolat automatikusan engedélyezve
Name[ia]=Nove connexion con acceptation automatic
Name[is]=Ný tenging sjálfvirkt samþykkt
Name[it]=Nuova connessione accettata automaticamente
Name[ja]=新しい接続の自動受け入れ
Name[kk]=Жаңа қосылым автоқабылданды
Name[ja]=新接続の自動受け入れ
Name[km]=បាន​ទទួល​យក​ការ​តភ្ជាប់​ថ្មី​ដោយ​ស្វ័យ​ប្រវត្តិ
Name[ko]=새 연결 자동 수락
Name[lt]=Naujas kvietimas ryšiui automatiškai priimtas
@@ -907,15 +816,13 @@ Name[pt]=Nova Ligação Aceite Automaticamente
Name[pt_BR]=Nova conexão com aceitação automática
Name[ro]=Conexiune nouă acceptată automat
Name[ru]=Новое соединение принимается автоматически
Name[si]=නව සබඳතාව ස්වයංක්‍රීයව පිළිගැණිනි
Name[sk]=Nové pripojenie bolo automaticky akceptované
Name[sk]=Nové pripojenie automaticky akceptované
Name[sl]=Nova povezava samodejno sprejeta
Name[sr]=Нова веза је аутоматски прихваћена
Name[sr@ijekavian]=Нова веза је аутоматски прихваћена
Name[sr@ijekavianlatin]=Nova veza je automatski prihvaćena
Name[sr@latin]=Nova veza je automatski prihvaćena
Name[sv]=Ny anslutning accepterades automatiskt
Name[th]=รับการเชื่อมต่อใหม่โดยอัตโนมัติ
Name[tr]=Yeni Bağlantı Otomatik olarak Kabul Edildi
Name[uk]=Нове з’єднання автоматично прийнято
Name[x-test]=xxNew Connection Auto Acceptedxx
@@ -925,9 +832,7 @@ Comment=New connection automatically established
Comment[af]=Nuwe verbinding automaties vasgestel
Comment[ar]=اتصال جديد مفعل تلقائيا
Comment[ast]=Conexón nueva afitada automáticamente
Comment[bg]=Новата връзка е автоматично приета
Comment[bn]=নতুন সংযোগ স্বয়ংক্রীয়ভাবে স্থাপন করা হল
Comment[bs]=Nova veza je automatski uspostavljena
Comment[ca]=Nova connexió establerta automàticament
Comment[ca@valencia]=Nova connexió establerta automàticament
Comment[cs]=Automaticky navázáno nové spojení
@@ -939,7 +844,7 @@ Comment[en_GB]=New connection automatically established
Comment[eo]=Nova konekto aŭtomate establita
Comment[es]=Conexión nueva establecida automáticamente
Comment[et]=Uus ühendus automaatselt loodud
Comment[eu]=Konexio berria automatikoki ezarrita
Comment[eu]=Konexio berria automatikoki ezarri da
Comment[fi]=Uusi yhteys muodostettiin automaattisesti
Comment[fr]=Nouvelle connexion établie automatiquement
Comment[ga]=Ceangal nua bunaithe go huathoibríoch
@@ -949,11 +854,9 @@ Comment[hi]=नया कनेक्शन स्वचलित स्था
Comment[hne]=नवा कनेक्सन अपने अपन स्थापित
Comment[hr]=Nova veza automatski prihvaćena
Comment[hu]=Automatikusan létrejött egy új kapcsolat
Comment[ia]=Nove connexion establite automaticamente
Comment[is]=Nýjar tengingar sjálfkrafa samþykktar
Comment[it]=Nuova connessione stabilita automaticamente
Comment[ja]=新しい接続を自動的に確立しました
Comment[kk]=Жаңа қосылым автоматты түрде орнатылды
Comment[ja]=新接続を自動的に確立しました
Comment[km]=បាន​បង្កើត​ការ​ត​ភ្ជាប់​ថ្មី​ដោយ​ស្វ័យ​ប្រវត្តិ
Comment[ko]=새 연결이 자동으로 성립됨
Comment[lt]=Naujas ryšys užmegztas automatiškai
@@ -971,8 +874,7 @@ Comment[pt]=Foi estabelecida automaticamente uma nova ligação
Comment[pt_BR]=Nova conexão estabelecida automaticamente
Comment[ro]=Conexiune nouă stabilită automat
Comment[ru]=Новое соединение устанавливается автоматически
Comment[si]=නව සබඳතාව ස්වයංක්‍රීයව සැකසිනි
Comment[sk]=Nové pripojenie bolo automaticky nadviazané
Comment[sk]=Nové pripojenie automaticky vytvorené
Comment[sl]=Nova povezava samodejno vzpostavljena
Comment[sr]=Нова веза је аутоматски успостављена
Comment[sr@ijekavian]=Нова веза је аутоматски успостављена
@@ -981,7 +883,6 @@ Comment[sr@latin]=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[xh]=Uxhulumaniso olutsha lufunyenwe ngokuzenzekelayo
@@ -995,8 +896,6 @@ Action=Popup
Name=Too Many Connections
Name[ar]=اتصالات عديدة
Name[ast]=Abondes conexones
Name[bg]=Твърде много връзки
Name[bs]=Previše veza
Name[ca]=Massa connexions
Name[ca@valencia]=Massa connexions
Name[cs]=Příliš mnoho spojení
@@ -1016,11 +915,9 @@ Name[hi]=बहुत सारे कनेक्शन
Name[hne]=बहुत अकन कनेक्सन
Name[hr]=Previše veza
Name[hu]=Túl sok kapcsolat
Name[ia]=Nimie connexiones
Name[is]=Of margar tengingar
Name[it]=Troppe connessioni
Name[ja]=多すぎる接続
Name[kk]=Тым көп қосылым
Name[km]=ការ​តភ្ជាប់​ច្រើន​ពេក
Name[ko]=너무 많은 연결
Name[lt]=Per daug užmegztų ryšių
@@ -1036,7 +933,6 @@ Name[pt]=Demasiadas Ligações
Name[pt_BR]=Conexões em excesso
Name[ro]=Prea multe conexiuni
Name[ru]=Слишком много соединений
Name[si]=වඩා වැඩි සබඳතා ගණනක්
Name[sk]=Príliš veľa pripojení
Name[sl]=Preveč povezav
Name[sr]=Исувише веза
@@ -1044,7 +940,6 @@ Name[sr@ijekavian]=Исувише веза
Name[sr@ijekavianlatin]=Isuviše veza
Name[sr@latin]=Isuviše veza
Name[sv]=För många anslutningar
Name[th]=มีการเชื่อมต่อมากเกินไป
Name[tr]=Çok Fazla Bağlantı
Name[uk]=Забагато з’єднань
Name[x-test]=xxToo Many Connectionsxx
@@ -1054,10 +949,8 @@ Comment=Busy, connection refused
Comment[af]=Besig, verbinding geweier
Comment[ar]=مشغول، الإتصال رفض
Comment[ast]=Ocupáu, conexón refugada
Comment[bg]=Заето. Връзката е отказана.
Comment[bn]=ব্যস্ত, সংযোগ অস্বীকার করল
Comment[br]=Dalc'het, kevreadenn disteuleret
Comment[bs]=Zauzeto, veza je odbijena
Comment[ca]=Ocupat, connexió refusada
Comment[ca@valencia]=Ocupat, connexió refusada
Comment[cs]=Zaneprázdněn, spojení odmítnuto
@@ -1079,11 +972,9 @@ Comment[hi]=व्यस्त, कनेक्शन अस्वीकृत
Comment[hne]=व्यस्त, कनेक्सन अस्वीकृत
Comment[hr]=Zauzeto, veza odbijena
Comment[hu]=A csatlakozási kérés elutasítva túlterhelés miatt
Comment[ia]=Occupate, connexion refusate
Comment[is]=Uptekinn, tengingu hafnað
Comment[it]=Occupato, connessione rifiutata
Comment[ja]=ビジーです、接続を拒否しました
Comment[kk]=Бос емес, қосылым болмады
Comment[km]=រវល់ បដិសេធ​ការ​ត​ភ្ជាប់
Comment[ko]=바쁨, 연결 거부됨
Comment[lt]=Užimta, kvietimas ryšiui atmestas
@@ -1101,8 +992,7 @@ Comment[pt]=Ocupado, pelo a ligação foi recusada
Comment[pt_BR]=Ocupado; conexão recusada
Comment[ro]=Ocupat, conexiune refuzată
Comment[ru]=Занят, соединение отклонено
Comment[si]=කාර්‍යබහුලයි, සබඳතාව නොපිළිගැණිනි
Comment[sk]=Zaneprázdnený, pripojenie bolo odmietnuté
Comment[sk]=Zaneprázdnený, pripojenie odmietnuté
Comment[sl]=Zaposlen, povezava zavrnjena
Comment[sr]=Заузето, веза је одбијена
Comment[sr@ijekavian]=Заузето, веза је одбијена
@@ -1111,8 +1001,7 @@ Comment[sr@latin]=Zauzeto, veza je odbijena
Comment[sv]=Upptagen, anslutning vägras
Comment[ta]=வேலையில் உள்ளது, இணைப்பு நிராகரிக்கப்பட்டது
Comment[tg]=Банд, пайвастшавӣ рад гардидааст
Comment[th]=ยังไม่ว่าง ทำการปฏิเสธการเชื่อมต่อ
Comment[tr]=Meşgul, bağlantı reddedildi
Comment[tr]=Meşgul, bağlantı rededildi
Comment[uk]=Зайнято, у з’єднанні відмовлено
Comment[uz]=Band, aloqa rad etildi
Comment[uz@cyrillic]=Банд, алоқа рад этилди
@@ -1127,8 +1016,6 @@ Action=Popup
Name=Unexpected Connection
Name[ar]=الاتصال غير متوقّع
Name[ast]=Conexón inesperada
Name[bg]=Неочаквана връзка
Name[bs]=Neočekivana veza
Name[ca]=Connexió inesperada
Name[ca@valencia]=Connexió inesperada
Name[cs]=Neočekávané spojení
@@ -1148,11 +1035,9 @@ Name[hi]=अप्रत्याशित कनेक्शन
Name[hne]=अप्रत्यासित कनेक्सन
Name[hr]=Neočekivana veza
Name[hu]=Nem várt kapcsolat
Name[ia]=Connexion impreviste
Name[is]=Óvænt Tenging
Name[it]=Connessione inattesa
Name[ja]=予期しない接続
Name[kk]=Күтпеген қосылым
Name[km]=ការ​តភ្ជាប់​ដែល​មិន​បាន​រំពឹង​ទុក
Name[ko]=예상하지 않은 연결
Name[lt]=Netikėtas kvietimas ryšiui
@@ -1168,18 +1053,14 @@ Name[pt]=Ligação Inesperada
Name[pt_BR]=Conexão inesperada
Name[ro]=Conexiune neașteptată
Name[ru]=Неожиданное соединение
Name[si]=බලාපොරොත්තු රහිත සබඳතාවක්
Name[sk]=Neočakávané pripojenie
Name[sl]=Nepričakovana povezava
Name[sq]=Lidhje e Papritur
Name[sr]=Неочекивана веза
Name[sr@ijekavian]=Неочекивана веза
Name[sr@ijekavianlatin]=Neočekivana veza
Name[sr@latin]=Neočekivana veza
Name[sv]=Oväntad anslutning
Name[th]=เกิดการเชื่อมต่อที่ไม่คาดคิด
Name[tr]=Beklenmeyen Bağlantı
Name[ug]=كۈتۈلمىگەن باغلىنىش
Name[uk]=Неочікуване з’єднання
Name[x-test]=xxUnexpected Connectionxx
Name[zh_CN]=未预料的连接
@@ -1188,9 +1069,7 @@ Comment=Received unexpected connection, abort
Comment[af]=Ontvang onverwagte verbinding, staak
Comment[ar]=استقبال اتصال غير متوقع، إنهاء
Comment[ast]=Recibióse conexón inesperada, albortando
Comment[bg]=Получена е неочаквана връзка. Прекъсване.
Comment[bn]=অপ্রত্যাশিত সংযোগ গ্রহণ করল, বাতিল করুন
Comment[bs]=Primljena je neočekivana veza, prekini
Comment[ca]=Rebuda una connexió inesperada, avortant
Comment[ca@valencia]=Rebuda una connexió inesperada, avortant
Comment[cs]=Obdrženo neočekávané spojení, přerušeno
@@ -1202,7 +1081,7 @@ Comment[en_GB]=Received unexpected connection, abort
Comment[eo]=Ricevis neatenditan konekton, ĉesi
Comment[es]=Recibida conexión inesperada, interrumpir
Comment[et]=Saadi ootamatu ühendus, loobuti
Comment[eu]=Ustekabeko konexioa jaso da, abortatzen
Comment[eu]=Ustegabeko konexioa jaso da, abortatzen
Comment[fi]=Vastaanotettiin odottamaton yhteys, lopeta
Comment[fr]=Reçu une connexion inattendue, interruption
Comment[ga]=Fuarthas ceangal gan choinne, á thobscor
@@ -1212,11 +1091,9 @@ Comment[hi]=अप्रत्याशित कनेक्शन प्रा
Comment[hne]=अप्रत्यासित कनेक्सन प्राप्त. छोड़ा
Comment[hr]=Primio sam neočekivanu vezu, prekid
Comment[hu]=Nem várt csatlakozási kérés érkezett, megszakítás
Comment[ia]=On recipeva connexion impreviste, aborta
Comment[is]=Tók á móti óvæntri tengingu, hætti
Comment[it]=Ricevuta connessione inattesa, terminata
Comment[ja]=予期しない接続を受信しました。廃棄します。
Comment[kk]=Күтпеген қосылым ұсынысы, доғарылды
Comment[km]=បាន​ទទួល​យក​ការ​តភ្ជាប់​ដែល​មិន​បាន​រំពឹង​ទុក ​បោះបង់
Comment[ko]=예상하지 않은 연결을 받았습니다, 중지합니다
Comment[lt]=Sulaukta netikėto kvietimo ryšiui, nutraukiama
@@ -1233,7 +1110,6 @@ Comment[pt]=Foi recebida uma ligação inesperada, pelo que foi interrompida
Comment[pt_BR]=Conexão recebida inesperadamente; abortar
Comment[ro]=Conexiune neașteptată recepționată, abandonare
Comment[ru]=Получено неожиданное соединение. Отключение
Comment[si]=බලාපොරොත්තු රහිත සබඳතාවක් ලැබිනි, පිටවෙමින්
Comment[sk]=Prijaté neočakávané pripojenie, prerušené
Comment[sl]=Prejeta nepričakovana povezava, prekinjeno
Comment[sr]=Примљена је неочекивана веза, прекидам
@@ -1243,8 +1119,7 @@ Comment[sr@latin]=Primljena je neočekivana veza, prekidam
Comment[sv]=Tog emot oväntad anslutning, avbryter
Comment[ta]=எதிர்பாராத இணைப்பு, நிறுத்தப்பட்டது
Comment[tg]=Пайвастшавии ғайричашмдош қабул гардид, кандашавӣ
Comment[th]=ได้รับการเชื่อมต่อมาอย่างไม่คาดคิด ทำการยกเลิก
Comment[tr]=Beklenmeyen bir bağlantı alındı, vazgeçiliyor
Comment[tr]=Babul edilmiş beklenmedik bağlantı, durdur
Comment[uk]=Отримано з’єднання, яке не очікувалось, припиняється
Comment[xh]=Ufumene uxhulumaniso olungalindelekanga, lahla
Comment[x-test]=xxReceived unexpected connection, abortxx

View File

@@ -1,144 +0,0 @@
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/config-krfb.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/config-krfb.h
)
#####################################
# First target: libkrfbprivate - a library
# for linking plugins against.
set (krfbprivate_SRCS
framebuffer.cpp
framebufferplugin.cpp
)
kde4_add_library (krfbprivate
SHARED
${krfbprivate_SRCS}
)
target_link_libraries (krfbprivate
${QT_QTCORE_LIBRARY}
${QT_QTGUI_LIBRARY}
${X11_X11_LIB}
)
set_target_properties (krfbprivate PROPERTIES
VERSION ${GENERIC_LIB_VERSION}
SOVERSION ${GENERIC_LIB_VERSION}
)
install (TARGETS krfbprivate
${INSTALL_TARGETS_DEFAULT_ARGS}
LIBRARY NAMELINK_SKIP
)
install (FILES
krfb-framebuffer.desktop
DESTINATION ${SERVICETYPES_INSTALL_DIR}
)
#####################################
# Second target: krfb - the app
# itself.
if(BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_FOUND)
add_definitions(-DKRFB_WITH_TELEPATHY_TUBES)
include_directories(${TELEPATHY_QT4_INCLUDE_DIR})
endif(BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_FOUND)
set (krfb_SRCS
connectiondialog.cpp
events.cpp
framebuffermanager.cpp
invitation.cpp
invitedialog.cpp
invitationmanager.cpp
main.cpp
manageinvitationsdialog.cpp
personalinvitedialog.cpp
sockethelpers.cpp
trayicon.cpp
rfbservermanager.cpp
rfbserver.cpp
rfbclient.cpp
invitationsrfbserver.cpp
invitationsrfbclient.cpp
)
if (BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_FOUND)
set (krfb_SRCS
${krfb_SRCS}
tubesrfbserver.cpp
tubesrfbclient.cpp
tubesclienthandler.cpp
)
endif (BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_FOUND)
kde4_add_kcfg_files (krfb_SRCS
krfbconfig.kcfgc
)
kde4_add_ui_files (krfb_SRCS
ui/configtcp.ui
ui/configsecurity.ui
ui/connectionwidget.ui
ui/invitewidget.ui
ui/manageinvitations.ui
ui/personalinvitewidget.ui
)
if (BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_FOUND)
kde4_add_ui_files(krfb_SRCS ui/tubesconnectionwidget.ui)
endif(BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_FOUND)
kde4_add_executable (krfb
${krfb_SRCS}
)
target_link_libraries (krfb
krfbprivate
vncserver
${JPEG_LIBRARIES}
${X11_Xext_LIB}
${X11_X11_LIB}
${X11_Xdamage_LIB}
${QT_QTNETWORK_LIBRARY}
${KDE4_KDNSSD_LIBS}
${KDE4_KDEUI_LIBS}
)
if (BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_FOUND)
target_link_libraries(krfb
${TELEPATHY_QT4_LIBRARIES}
)
endif (BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_FOUND)
if (X11_XTest_FOUND)
target_link_libraries (krfb
${X11_XTest_LIB}
)
endif (X11_XTest_FOUND)
install (TARGETS krfb
${INSTALL_TARGETS_DEFAULT_ARGS}
)
if (BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_FOUND)
configure_file(org.freedesktop.Telepathy.Client.krfb_rfb_handler.service.in
org.freedesktop.Telepathy.Client.krfb_rfb_handler.service)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.freedesktop.Telepathy.Client.krfb_rfb_handler.service
DESTINATION ${DBUS_SERVICES_INSTALL_DIR})
install(FILES krfb_rfb_handler.client DESTINATION ${CMAKE_INSTALL_PREFIX}/share/telepathy/clients/)
endif (BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_FOUND)
########### install files ###############
install (PROGRAMS krfb.desktop
DESTINATION ${XDG_APPS_INSTALL_DIR}
)
install (FILES krfb.notifyrc
DESTINATION ${DATA_INSTALL_DIR}/krfb
)

View File

@@ -1,88 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2010 Collabora Ltd <info@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
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., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "connectiondialog.h"
#include <KIconLoader>
#include <KLocale>
#include <KStandardGuiItem>
#include <QtGui/QCheckBox>
#include <QtGui/QLabel>
template <typename UI>
ConnectionDialog<UI>::ConnectionDialog(QWidget *parent)
: KDialog(parent)
{
setCaption(i18n("New Connection"));
setButtons(Ok | Cancel);
setDefaultButton(Cancel);
setModal(true);
setMinimumSize(500, 200);
m_connectWidget = new QWidget(this);
m_ui.setupUi(m_connectWidget);
m_ui.pixmapLabel->setPixmap(KIcon("krfb").pixmap(128));
KGuiItem accept = KStandardGuiItem::ok();
accept.setText(i18n("Accept Connection"));
setButtonGuiItem(Ok, accept);
KGuiItem refuse = KStandardGuiItem::cancel();
refuse.setText(i18n("Refuse Connection"));
setButtonGuiItem(Cancel, refuse);
setMainWidget(m_connectWidget);
}
//**********
InvitationsConnectionDialog::InvitationsConnectionDialog(QWidget *parent)
: ConnectionDialog<Ui::ConnectionWidget>(parent)
{
}
void InvitationsConnectionDialog::setRemoteHost(const QString &host)
{
m_ui.remoteHost->setText(host);
}
//**********
#ifdef KRFB_WITH_TELEPATHY_TUBES
TubesConnectionDialog::TubesConnectionDialog(QWidget *parent)
: ConnectionDialog<Ui::TubesConnectionWidget>(parent)
{
}
void TubesConnectionDialog::setContactName(const QString & name)
{
QString txt = i18n("You have requested to share your desktop with %1. If you proceed, "
"you will allow the remote user to watch your desktop.", name);
m_ui.mainTextLabel->setText(txt);
}
#endif // KRFB_WITH_TELEPATHY_TUBES
#include "connectiondialog.moc"

View File

@@ -1,82 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2010 Collabora Ltd <info@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
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., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef CONNECTIONDIALOG_H
#define CONNECTIONDIALOG_H
#include "ui_connectionwidget.h"
#include <KDialog>
template <typename UI>
class ConnectionDialog : public KDialog
{
public:
ConnectionDialog(QWidget *parent);
~ConnectionDialog() {};
void setAllowRemoteControl(bool b);
bool allowRemoteControl();
protected:
QWidget *m_connectWidget;
UI m_ui;
};
template <typename UI>
void ConnectionDialog<UI>::setAllowRemoteControl(bool b)
{
m_ui.cbAllowRemoteControl->setChecked(b);
m_ui.cbAllowRemoteControl->setVisible(b);
}
template <typename UI>
bool ConnectionDialog<UI>::allowRemoteControl()
{
return m_ui.cbAllowRemoteControl->isChecked();
}
//*********
class InvitationsConnectionDialog : public ConnectionDialog<Ui::ConnectionWidget>
{
Q_OBJECT
public:
InvitationsConnectionDialog(QWidget *parent);
void setRemoteHost(const QString & host);
};
//*********
#ifdef KRFB_WITH_TELEPATHY_TUBES
# include "ui_tubesconnectionwidget.h"
class TubesConnectionDialog : public ConnectionDialog<Ui::TubesConnectionWidget>
{
Q_OBJECT
public:
TubesConnectionDialog(QWidget *parent);
void setContactName(const QString & name);
};
#endif // KRFB_WITH_TELEPATHY_TUBES
#endif // CONNECTIONDIALOG_H

View File

@@ -1,200 +0,0 @@
/*
This file is part of the KDE project
Copyright (C) 2010 Collabora Ltd.
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
Copyright (C) 2001-2003 by Tim Jansen <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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "events.h"
#include <QtGui/QApplication>
#include <QtGui/QX11Info>
#include <QtGui/QDesktopWidget>
#include <KGlobal>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/extensions/XTest.h>
enum {
LEFTSHIFT = 1,
RIGHTSHIFT = 2,
ALTGR = 4
};
class EventData
{
public:
EventData();
//keyboard
Display *dpy;
signed char modifiers[0x100];
KeyCode keycodes[0x100];
KeyCode leftShiftCode;
KeyCode rightShiftCode;
KeyCode altGrCode;
char modifierState;
//mouse
int buttonMask;
private:
void init();
};
K_GLOBAL_STATIC(EventData, data)
EventData::EventData()
{
init();
}
void EventData::init()
{
dpy = QX11Info::display();
buttonMask = 0;
//initialize keycodes
KeySym key, *keymap;
int i, j, minkey, maxkey, syms_per_keycode;
memset(modifiers, -1, sizeof(modifiers));
XDisplayKeycodes(dpy, &minkey, &maxkey);
Q_ASSERT(minkey >= 8);
Q_ASSERT(maxkey < 256);
keymap = (KeySym *) XGetKeyboardMapping(dpy, minkey,
(maxkey - minkey + 1),
&syms_per_keycode);
Q_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 data->modifierState */
static void tweakModifiers(signed char mod, bool down)
{
bool isShift = data->modifierState & (LEFTSHIFT | RIGHTSHIFT);
if (mod < 0) {
return;
}
if (isShift && mod != 1) {
if (data->modifierState & LEFTSHIFT) {
XTestFakeKeyEvent(data->dpy, data->leftShiftCode,
down, CurrentTime);
}
if (data->modifierState & RIGHTSHIFT) {
XTestFakeKeyEvent(data->dpy, data->rightShiftCode,
down, CurrentTime);
}
}
if (!isShift && mod == 1) {
XTestFakeKeyEvent(data->dpy, data->leftShiftCode,
down, CurrentTime);
}
if ((data->modifierState & ALTGR) && mod != 2) {
XTestFakeKeyEvent(data->dpy, data->altGrCode,
!down, CurrentTime);
}
if (!(data->modifierState & ALTGR) && mod == 2) {
XTestFakeKeyEvent(data->dpy, data->altGrCode,
down, CurrentTime);
}
}
void EventHandler::handleKeyboard(bool down, rfbKeySym keySym)
{
#define ADJUSTMOD(sym,state) \
if(keySym==sym) { if(down) data->modifierState|=state; else data->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(data->modifiers[keySym], True);
}
k = data->keycodes[keySym];
if (k != NoSymbol) {
XTestFakeKeyEvent(data->dpy, k, down, CurrentTime);
}
if (down) {
tweakModifiers(data->modifiers[keySym], False);
}
} else {
KeyCode k = XKeysymToKeycode(data->dpy, keySym);
if (k != NoSymbol) {
XTestFakeKeyEvent(data->dpy, k, down, CurrentTime);
}
}
}
void EventHandler::handlePointer(int buttonMask, int x, int y)
{
QDesktopWidget *desktopWidget = QApplication::desktop();
int screen = desktopWidget->screenNumber();
if (screen < 0) {
screen = 0;
}
XTestFakeMotionEvent(data->dpy, screen, x, y, CurrentTime);
for (int i = 0; i < 5; i++) {
if ((data->buttonMask&(1 << i)) != (buttonMask&(1 << i))) {
XTestFakeButtonEvent(data->dpy,
i + 1,
(buttonMask&(1 << i)) ? True : False,
CurrentTime);
}
}
data->buttonMask = buttonMask;
}

View File

@@ -1,37 +0,0 @@
/*
This file is part of the KDE project
Copyright (C) 2010 Collabora Ltd.
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
Copyright (C) 2001-2003 by Tim Jansen <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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef EVENTS_H
#define EVENTS_H
#include "rfb.h"
class EventHandler
{
public:
static void handleKeyboard(bool down, rfbKeySym key);
static void handlePointer(int buttonMask, int x, int y);
};
#endif

View File

@@ -1,112 +0,0 @@
/*
Copyright (C) 2009-2010 Collabora Ltd <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
Copyright (C) 2001-2003 by Tim Jansen <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.
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 Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "invitationsrfbclient.h"
#include "invitationmanager.h"
#include "krfbconfig.h"
#include "sockethelpers.h"
#include "connectiondialog.h"
#include <KNotification>
#include <KLocale>
bool InvitationsRfbClient::checkPassword(const QByteArray & encryptedPassword)
{
bool allowUninvited = KrfbConfig::allowUninvitedConnections();
QByteArray password = KrfbConfig::uninvitedConnectionPassword().toLocal8Bit();
bool authd = false;
kDebug() << "about to start autentication";
if (allowUninvited) {
authd = vncAuthCheckPassword(password, encryptedPassword);
}
if (!authd) {
QList<Invitation> invlist = InvitationManager::self()->invitations();
foreach(const Invitation & it, invlist) {
kDebug() << "checking password";
if (vncAuthCheckPassword(it.password().toLocal8Bit(), encryptedPassword)
&& it.isValid())
{
authd = true;
InvitationManager::self()->removeInvitation(it);
break;
}
}
}
if (!authd) {
if (InvitationManager::self()->invitations().size() > 0) {
KNotification::event("InvalidPasswordInvitations",
i18n("Failed login attempt from %1: wrong password", name()));
} else {
KNotification::event("InvalidPassword",
i18n("Failed login attempt from %1: wrong password", name()));
}
return false;
}
return true;
}
void PendingInvitationsRfbClient::processNewClient()
{
QString host = peerAddress(m_rfbClient->sock) + ":" + QString::number(peerPort(m_rfbClient->sock));
bool allowUninvited = KrfbConfig::allowUninvitedConnections();
if (!allowUninvited && InvitationManager::self()->activeInvitations() == 0) {
KNotification::event("UnexpectedConnection",
i18n("Refused uninvited connection attempt from %1", host));
reject();
} else if (!KrfbConfig::askOnConnect()) {
KNotification::event("NewConnectionAutoAccepted",
i18n("Accepted connection from %1", host));
accept(new InvitationsRfbClient(m_rfbClient, parent()));
} else {
KNotification::event("NewConnectionOnHold",
i18n("Received connection from %1, on hold (waiting for confirmation)",
host));
InvitationsConnectionDialog *dialog = new InvitationsConnectionDialog(0);
dialog->setRemoteHost(host);
dialog->setAllowRemoteControl(KrfbConfig::allowDesktopControl());
connect(dialog, SIGNAL(okClicked()), SLOT(dialogAccepted()));
connect(dialog, SIGNAL(cancelClicked()), SLOT(reject()));
dialog->show();
}
}
void PendingInvitationsRfbClient::dialogAccepted()
{
InvitationsConnectionDialog *dialog = qobject_cast<InvitationsConnectionDialog *>(sender());
Q_ASSERT(dialog);
InvitationsRfbClient *client = new InvitationsRfbClient(m_rfbClient, parent());
client->setControlEnabled(dialog->allowRemoteControl());
accept(client);
}
#include "invitationsrfbclient.moc"

View File

@@ -1,48 +0,0 @@
/*
Copyright (C) 2010 Collabora Ltd <info@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
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 Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INVITATIONSRFBCLIENT_H
#define INVITATIONSRFBCLIENT_H
#include "rfbclient.h"
class InvitationsRfbClient : public RfbClient
{
public:
InvitationsRfbClient(rfbClientPtr client, QObject* parent = 0)
: RfbClient(client, parent) {}
protected:
virtual bool checkPassword(const QByteArray & encryptedPassword);
};
class PendingInvitationsRfbClient : public PendingRfbClient
{
Q_OBJECT
public:
PendingInvitationsRfbClient(rfbClientPtr client, QObject *parent = 0)
: PendingRfbClient(client, parent) {}
protected Q_SLOTS:
virtual void processNewClient();
private Q_SLOTS:
void dialogAccepted();
};
#endif // INVITATIONSRFBCLIENT_H

View File

@@ -1,71 +0,0 @@
/*
Copyright (C) 2009-2010 Collabora Ltd <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
Copyright (C) 2001-2003 by Tim Jansen <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.
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 Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "invitationsrfbserver.h"
#include "invitationsrfbclient.h"
#include "krfbconfig.h"
#include "rfbservermanager.h"
#include <QtCore/QTimer>
#include <QtGui/QApplication>
#include <QtNetwork/QHostInfo>
#include <KNotification>
#include <KLocale>
#include <KMessageBox>
#include <KUser>
#include <DNSSD/PublicService>
void InvitationsRfbServer::init()
{
InvitationsRfbServer *server;
server = new InvitationsRfbServer;
server->setListeningPort(KrfbConfig::port());
server->setListeningAddress("0.0.0.0"); // Listen on all available network addresses
server->setPasswordRequired(true);
QTimer::singleShot(0, server, SLOT(startAndCheck()));
}
PendingRfbClient* InvitationsRfbServer::newClient(rfbClientPtr client)
{
return new PendingInvitationsRfbClient(client, this);
}
void InvitationsRfbServer::startAndCheck()
{
if (!start()) {
KMessageBox::error(0, i18n("Failed to start the krfb server. Invitation-based sharing "
"will not work. Try setting another port in the settings and "
"restart krfb."));
} else {
//publish service
if (KrfbConfig::publishService()) {
DNSSD::PublicService *service = new DNSSD::PublicService(i18n("%1@%2 (shared desktop)",
KUser().loginName(),
QHostInfo::localHostName()),
"_rfb._tcp",
listeningPort());
service->publishAsync();
}
//disconnect when qApp quits
connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(stop()));
}
}
#include "invitationsrfbserver.moc"

View File

@@ -1,43 +0,0 @@
/*
Copyright (C) 2009-2010 Collabora Ltd <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
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 Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INVITATIONSRFBSERVER_H
#define INVITATIONSRFBSERVER_H
#include "rfbserver.h"
class InvitationsRfbServer : public RfbServer
{
Q_OBJECT
public:
static void init();
protected:
InvitationsRfbServer() : RfbServer(0) {}
virtual PendingRfbClient* newClient(rfbClientPtr client);
private Q_SLOTS:
void startAndCheck();
private:
Q_DISABLE_COPY(InvitationsRfbServer)
};
#endif // INVITATIONSRFBSERVER_H

View File

@@ -1,87 +0,0 @@
/* 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., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "invitedialog.h"
#include <KIconLoader>
#include <KLocale>
#include <KStandardGuiItem>
#include <QtGui/QCursor>
#include <QtGui/QLabel>
#include <QtGui/QPushButton>
#include <QtGui/QToolTip>
InviteDialog::InviteDialog(QWidget *parent)
: KDialog(parent)
{
setCaption(i18n("Invitation"));
setButtons(User1 | Close | Help);
setHelp(QString(), "krfb");
setDefaultButton(NoDefault);
setMinimumSize(500, 300);
m_inviteWidget = new QWidget(this);
setupUi(m_inviteWidget);
pixmapLabel->setPixmap(KIcon("krfb").pixmap(128));
setMainWidget(m_inviteWidget);
setButtonGuiItem(User1, KStandardGuiItem::configure());
connect(btnCreateInvite, SIGNAL(clicked()),
SIGNAL(createInviteClicked()));
connect(btnEmailInvite, SIGNAL(clicked()),
SIGNAL(emailInviteClicked()));
connect(btnManageInvite, SIGNAL(clicked()),
SIGNAL(manageInviteClicked()));
connect(helpLabel, SIGNAL(linkActivated(QString)),
SLOT(showWhatsthis()));
}
void InviteDialog::slotUser1()
{
emit configureClicked();
}
void InviteDialog::enableInviteButton(bool enable)
{
btnCreateInvite->setEnabled(enable);
}
void InviteDialog::setInviteCount(int count)
{
btnManageInvite->setText(
i18n("&Manage Invitations (%1)...", count));
}
void InviteDialog::showWhatsthis()
{
QToolTip::showText(QCursor::pos(),
i18n("An invitation creates a one-time password that allows the receiver to connect to your desktop.\n"
"It is valid for only one successful connection and will expire after an hour if it has not been used. \n"
"When somebody connects to your computer a dialog will appear and ask you for permission.\n "
"The connection will not be established before you accept it. In this dialog you can also\n restrict "
"the other person to view your desktop only, without the ability to move your\n mouse pointer or press "
"keys.\nIf you want to create a permanent password for Desktop Sharing, allow 'Uninvited Connections' \n"
"in the configuration."));
}
#include "invitedialog.moc"

View File

@@ -1,7 +0,0 @@
[org.freedesktop.Telepathy.Client]
Interfaces=org.freedesktop.Telepathy.Client.Handler;
[org.freedesktop.Telepathy.Client.Handler.HandlerChannelFilter 0]
org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.StreamTube
org.freedesktop.Telepathy.Channel.Type.StreamTube.Service s=rfb
org.freedesktop.Telepathy.Channel.Requested b=true

View File

@@ -1,130 +0,0 @@
/***************************************************************************
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 "manageinvitationsdialog.h"
#include "trayicon.h"
#include "invitationsrfbserver.h"
#include <KAboutApplicationDialog>
#include <KAboutData>
#include <KAction>
#include <KApplication>
#include <KCmdLineArgs>
#include <KDebug>
#include <KLocale>
#include <KMessageBox>
#include <KNotification>
#include <QtGui/QPixmap>
#include <QtGui/qwindowdefs.h>
#ifdef KRFB_WITH_TELEPATHY_TUBES
# include "tubesclienthandler.h"
# include <TelepathyQt4/ClientRegistrar>
#endif
#include <signal.h>
#include <X11/extensions/XTest.h>
static const char description[] = I18N_NOOP("VNC-compatible server to share "
"KDE desktops");
static bool checkX11Capabilities()
{
int bp1, bp2, majorv, minorv;
Bool r = XTestQueryExtension(QX11Info::display(), &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;
}
int main(int argc, char *argv[])
{
KAboutData aboutData("krfb", 0, ki18n("Desktop Sharing"), KDE_VERSION_STRING,
ki18n(description), KAboutData::License_GPL,
ki18n("(c) 2009-2010, Collabora Ltd.\n"
"(c) 2007, Alessandro Praduroux\n"
"(c) 2001-2003, Tim Jansen\n"
"(c) 2001, Johannes E. Schindelin\n"
"(c) 2000-2001, Const Kaplinsky\n"
"(c) 2000, Tridia Corporation\n"
"(c) 1999, AT&T Laboratories Boston\n"));
aboutData.addAuthor(ki18n("George Goldberg"),
ki18n("Telepathy tubes support"),
"george.goldberg@collabora.co.uk");
aboutData.addAuthor(ki18n("George Kiagiadakis"),
KLocalizedString(),
"george.kiagiadakis@collabora.co.uk");
aboutData.addAuthor(ki18n("Alessandro Praduroux"), ki18n("KDE4 porting"), "pradu@pradu.it");
aboutData.addAuthor(ki18n("Tim Jansen"), ki18n("Original author"), "tim@tjansen.de");
aboutData.addCredit(ki18n("Johannes E. Schindelin"),
ki18n("libvncserver"));
aboutData.addCredit(ki18n("Const Kaplinsky"),
ki18n("TightVNC encoder"));
aboutData.addCredit(ki18n("Tridia Corporation"),
ki18n("ZLib encoder"));
aboutData.addCredit(ki18n("AT&T Laboratories Boston"),
ki18n("original VNC encoders and "
"protocol design"));
KCmdLineArgs::init(argc, argv, &aboutData);
KCmdLineOptions options;
options.add("nodialog", ki18n("Do not show the invitations management dialog at startup"));
KCmdLineArgs::addCmdLineOptions(options);
KApplication app;
app.setQuitOnLastWindowClosed(false);
if (!checkX11Capabilities()) {
return 1;
}
//init the core
InvitationsRfbServer::init();
#ifdef KRFB_WITH_TELEPATHY_TUBES
Tp::ClientRegistrarPtr clientRegistrar = Tp::ClientRegistrar::create();
clientRegistrar->registerClient(Tp::AbstractClientPtr(new TubesClientHandler),
"krfb_rfb_handler");
#endif
//init the GUI
ManageInvitationsDialog invitationsDialog;
TrayIcon trayicon(&invitationsDialog);
if (app.isSessionRestored() && KMainWindow::canBeRestored(1)) {
invitationsDialog.restore(1, false);
} else if (KCmdLineArgs::parsedArgs()->isSet("dialog")) {
invitationsDialog.show();
}
sigset_t sigs;
sigemptyset(&sigs);
sigaddset(&sigs, SIGPIPE);
sigprocmask(SIG_BLOCK, &sigs, 0);
return app.exec();
}

View File

@@ -1,253 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
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 "manageinvitationsdialog.h"
#include "invitationmanager.h"
#include "invitation.h"
#include "krfbconfig.h"
#include "personalinvitedialog.h"
#include "ui_configtcp.h"
#include "ui_configsecurity.h"
#include <KConfigDialog>
#include <KGlobal>
#include <KIconLoader>
#include <KLocale>
#include <KMessageBox>
#include <KStandardGuiItem>
#include <KSystemTimeZone>
#include <KToolInvocation>
#include <KStandardAction>
#include <KActionCollection>
#include <QtGui/QWidget>
#include <QtGui/QToolTip>
#include <QtGui/QCursor>
#include <QtCore/QDateTime>
#include <QtNetwork/QNetworkInterface>
class TCP: public QWidget, public Ui::TCP
{
public:
TCP(QWidget *parent = 0) : QWidget(parent) {
setupUi(this);
}
};
class Security: public QWidget, public Ui::Security
{
public:
Security(QWidget *parent = 0) : QWidget(parent) {
setupUi(this);
}
};
ManageInvitationsDialog::ManageInvitationsDialog(QWidget *parent)
: KXmlGuiWindow(parent)
{
setAttribute(Qt::WA_DeleteOnClose, false);
QWidget *mainWidget = new QWidget;
m_ui.setupUi(mainWidget);
m_ui.pixmapLabel->setPixmap(KIcon("krfb").pixmap(128));
setCentralWidget(mainWidget);
connect(m_ui.helpLabel, SIGNAL(linkActivated(QString)), SLOT(showWhatsthis()));
connect(m_ui.newPersonalInvitationButton, SIGNAL(clicked()), SLOT(inviteManually()));
connect(m_ui.newEmailInvitationButton, SIGNAL(clicked()), SLOT(inviteByMail()));
connect(InvitationManager::self(), SIGNAL(invitationNumChanged(int)), SLOT(reloadInvitations()));
connect(m_ui.deleteAllButton, SIGNAL(clicked()), SLOT(deleteAll()));
connect(m_ui.deleteOneButton, SIGNAL(clicked()), SLOT(deleteCurrent()));
connect(m_ui.invitationWidget, SIGNAL(itemSelectionChanged()), SLOT(selectionChanged()));
KStandardAction::quit(QCoreApplication::instance(), SLOT(quit()), actionCollection());
KStandardAction::preferences(this, SLOT(showConfiguration()), actionCollection());
setupGUI(QSize(550, 330));
setAutoSaveSettings();
reloadInvitations();
}
ManageInvitationsDialog::~ManageInvitationsDialog()
{
}
void ManageInvitationsDialog::showWhatsthis()
{
QToolTip::showText(QCursor::pos(),
i18n("An invitation creates a one-time password that allows the receiver to connect to your desktop.\n"
"It is valid for only one successful connection and will expire after an hour if it has not been used. \n"
"When somebody connects to your computer a dialog will appear and ask you for permission.\n"
"The connection will not be established before you accept it. In this dialog you can also\nrestrict "
"the other person to view your desktop only, without the ability to move your\nmouse pointer or press "
"keys.\nIf you want to create a permanent password for Desktop Sharing, allow 'Uninvited Connections' \n"
"in the configuration."));
}
void ManageInvitationsDialog::inviteManually()
{
Invitation inv = InvitationManager::self()->addInvitation();
PersonalInviteDialog *pid = new PersonalInviteDialog(this);
pid->setPassword(inv.password());
pid->setExpiration(inv.expirationTime());
pid->show();
}
void ManageInvitationsDialog::inviteByMail()
{
int r = KMessageBox::warningContinueCancel(this,
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"),
KStandardGuiItem::cont(),
KStandardGuiItem::cancel(),
"showEmailInvitationWarning");
if (r == KMessageBox::Cancel) {
return;
}
QList<QNetworkInterface> ifl = QNetworkInterface::allInterfaces();
QString host;
int port = KrfbConfig::port();
foreach(const QNetworkInterface & nif, ifl) {
if (nif.flags() & QNetworkInterface::IsLoopBack) {
continue;
}
if (nif.flags() & QNetworkInterface::IsRunning) {
if (!nif.addressEntries().isEmpty()) {
host = nif.addressEntries()[0].ip().toString();
}
}
}
Invitation inv = InvitationManager::self()->addInvitation();
KUrl invUrl(QString("vnc://invitation:%1@%2:%3").arg(inv.password()).arg(host).arg(port));
KToolInvocation::invokeMailer(QString(), QString(), QString(),
i18n("Desktop Sharing (VNC) invitation"),
ki18n("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"
"%1\n\n"
"Otherwise you can use any VNC client with the following parameters:\n\n"
"Host: %2:%3\n"
"Password: %4\n\n"
"For security reasons this invitation will expire at %5 (%6).")
.subs(invUrl.url())
.subs(host)
.subs(QString::number(port))
.subs(inv.password())
.subs(KGlobal::locale()->formatDateTime(inv.expirationTime()))
.subs(KSystemTimeZones::local().name())
.toString());
}
void ManageInvitationsDialog::reloadInvitations()
{
m_ui.invitationWidget->clear();
KLocale *loc = KGlobal::locale();
foreach(const Invitation & inv, InvitationManager::self()->invitations()) {
QStringList strs;
strs << loc->formatDateTime(inv.creationTime()) << loc->formatDateTime(inv.expirationTime());
QTreeWidgetItem *it = new QTreeWidgetItem(strs);
m_ui.invitationWidget->addTopLevelItem(it);
it->setData(0, Qt::UserRole + 1, inv.creationTime());
}
m_ui.invitationWidget->resizeColumnToContents(0);
m_ui.deleteAllButton->setEnabled(InvitationManager::self()->activeInvitations() > 0);
}
void ManageInvitationsDialog::showConfiguration()
{
if (KConfigDialog::showDialog("settings")) {
return;
}
KConfigDialog *dialog = new KConfigDialog(this, "settings", KrfbConfig::self());
dialog->addPage(new TCP, i18n("Network"), "network-workgroup");
dialog->addPage(new Security, i18n("Security"), "security-high");
dialog->setHelp(QString(), "krfb");
dialog->show();
}
void ManageInvitationsDialog::deleteAll()
{
if (KMessageBox::warningContinueCancel(this,
i18n("<qt>Are you sure you want to delete all invitations?</qt>"),
i18n("Confirm delete Invitations"),
KStandardGuiItem::ok(),
KStandardGuiItem::cancel(),
QString("krfbdeleteallinv")) !=
KMessageBox::Continue) {
return;
}
InvitationManager::self()->removeAllInvitations();
}
void ManageInvitationsDialog::deleteCurrent()
{
if (KMessageBox::warningContinueCancel(this,
i18n("<qt>Are you sure you want to delete this invitation?</qt>"),
i18n("Confirm delete Invitations"),
KStandardGuiItem::ok(),
KStandardGuiItem::cancel(),
QString("krfbdeleteoneinv")) !=
KMessageBox::Continue) {
return;
}
// disable updates while deleting items, otherwise the list would invalidate itself
disconnect(InvitationManager::self(), SIGNAL(invitationNumChanged(int)),
this, SLOT(reloadInvitations()));
QList<QTreeWidgetItem *> itl = m_ui.invitationWidget->selectedItems();
foreach(QTreeWidgetItem * itm, itl) {
foreach(const Invitation & inv, InvitationManager::self()->invitations()) {
if (inv.creationTime() == itm->data(0, Qt::UserRole + 1)) {
InvitationManager::self()->removeInvitation(inv);
}
}
}
// update it manually
reloadInvitations();
connect(InvitationManager::self(), SIGNAL(invitationNumChanged(int)),
SLOT(reloadInvitations()));
}
void ManageInvitationsDialog::selectionChanged()
{
m_ui.deleteOneButton->setEnabled(m_ui.invitationWidget->selectedItems().size() > 0);
}
void ManageInvitationsDialog::readProperties(const KConfigGroup& group)
{
if (group.readEntry("Visible", true)) {
show();
}
KMainWindow::readProperties(group);
}
void ManageInvitationsDialog::saveProperties(KConfigGroup& group)
{
group.writeEntry("Visible", isVisible());
KMainWindow::saveProperties(group);
}
#include "manageinvitationsdialog.moc"

View File

@@ -1,3 +0,0 @@
[D-BUS Service]
Name=org.freedesktop.Telepathy.Client.krfb_rfb_handler
Exec=@CMAKE_INSTALL_PREFIX@/bin/krfb --nodialog

View File

@@ -1,86 +0,0 @@
/*
Copyright (C) 2010 Collabora Ltd. <info@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 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 Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "pendingrfbclient.h"
#include "connectiondialog.h"
#include "krfbconfig.h"
#include <KDebug>
#include <KNotification>
PendingRfbClient::PendingRfbClient(rfbClientPtr client, QObject *parent)
: QObject(parent), m_client(0), m_rfbClient(client)
{
QMetaObject::invokeMethod(this, "processNewClient", Qt::QueuedConnection);
}
void PendingRfbClient::accept()
{
kDebug() << "accepted connection";
Q_ASSERT(m_client);
m_client->setOnHold(false);
Q_EMIT finished(m_client);
deleteLater();
}
void PendingRfbClient::reject()
{
kDebug() << "refused connection";
rfbCloseClient(m_rfbClient);
rfbClientConnectionGone(m_rfbClient);
Q_EMIT finished(NULL);
deleteLater();
}
void PendingRfbClient::showUserConfirmationDialog()
{
kDebug();
Q_ASSERT(m_client);
if (!KrfbConfig::askOnConnect()) {
KNotification::event("NewConnectionAutoAccepted",
i18n("Accepted connection from %1", m_client->name()));
accept();
} else {
KNotification::event("NewConnectionOnHold",
i18n("Received connection from %1, on hold (waiting for confirmation)",
m_client->name()));
ConnectionDialog *dialog = new ConnectionDialog(0);
dialog->setRemoteHost(m_client->name());
dialog->setAllowRemoteControl(KrfbConfig::allowDesktopControl());
connect(dialog, SIGNAL(okClicked()), SLOT(dialogAccepted()));
connect(dialog, SIGNAL(cancelClicked()), SLOT(dialogRejected()));
dialog->show();
}
}
void PendingRfbClient::dialogAccepted()
{
ConnectionDialog *dialog = qobject_cast<ConnectionDialog *>(sender());
Q_ASSERT(dialog);
m_client->setControlEnabled(dialog->cbAllowRemoteControl->isChecked());
accept();
}
void PendingRfbClient::dialogRejected()
{
reject();
}

View File

@@ -1,46 +0,0 @@
/*
Copyright (C) 2010 Collabora Ltd. <info@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 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 Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PENDINGRFBCLIENT_H
#define PENDINGRFBCLIENT_H
#include "rfbclient.h"
#include <QtCore/QObject>
class PendingRfbClient : public QObject
{
Q_OBJECT
public:
PendingRfbClient(rfbClientPtr client, QObject* parent = 0);
Q_SIGNALS:
void finished(RfbClient *client);
protected Q_SLOTS:
virtual void processNewClient() = 0;
void showUserConfirmationDialog();
void accept();
void reject();
protected:
RfbClient *m_client;
rfbClientPtr m_rfbClient;
};
#endif // PENDINGRFBCLIENT_H

View File

@@ -1,105 +0,0 @@
/* 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., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "personalinvitedialog.h"
#include "krfbconfig.h"
#include <KIconLoader>
#include <KLocale>
#include <QtGui/QLabel>
#include <QtGui/QToolTip>
#include <QtNetwork/QNetworkInterface>
PersonalInviteDialog::PersonalInviteDialog(QWidget *parent)
: KDialog(parent)
{
setCaption(i18n("Personal Invitation"));
setButtons(Close);
setDefaultButton(Close);
setModal(true);
setMinimumSize(500, 250);
int port = KrfbConfig::port();
m_inviteWidget = new QWidget(this);
setupUi(m_inviteWidget);
pixmapLabel->setPixmap(KIcon("krfb").pixmap(128));
QList<QNetworkInterface> ifl = QNetworkInterface::allInterfaces();
foreach(const QNetworkInterface & nif, ifl) {
if (nif.flags() & QNetworkInterface::IsLoopBack) {
continue;
}
if (nif.flags() & QNetworkInterface::IsRunning && !nif.addressEntries().isEmpty()) {
hostLabel->setText(QString("%1:%2").arg(nif.addressEntries().first().ip().toString()).arg(port));
}
}
connect(mainTextLabel, SIGNAL(linkActivated(QString)),
SLOT(showWhatsthis(QString)));
connect(hostHelpLabel, SIGNAL(linkActivated(QString)),
SLOT(showWhatsthis(QString)));
setMainWidget(m_inviteWidget);
}
void PersonalInviteDialog::setHost(const QString &host, uint port)
{
hostLabel->setText(QString("%1:%2")
.arg(host).arg(port));
}
void PersonalInviteDialog::setPassword(const QString &passwd)
{
passwordLabel->setText(passwd);
}
void PersonalInviteDialog::setExpiration(const QDateTime &expire)
{
expirationLabel->setText(expire.toString(Qt::LocalDate));
}
void PersonalInviteDialog::showWhatsthis(const QString &link)
{
if (link == "htc") {
QToolTip::showText(QCursor::pos(),
i18n("Desktop Sharing uses the VNC protocol. You can use any VNC client to connect. \n"
"In KDE the client is called 'Remote Desktop Connection'. Enter the host information\n"
"into the client and it will connect.."));
} else if (link == "help") {
QToolTip::showText(QCursor::pos(),
i18n("This field contains the address of your computer and the display number, separated by a colon.\n"
"The address is just a hint - you can use any address that can reach your computer. \n"
"Desktop Sharing tries to guess your address from your network configuration, but does\n"
"not always succeed in doing so. If your computer is behind a firewall it may have a\n"
"different address or be unreachable for other computers."));
}
}
#include "personalinvitedialog.moc"

View File

@@ -1,15 +0,0 @@
/**
* This file should always be included instead of <rfb/rfb.h> because otherwise it's redefinition
* of TRUE and FALSE plays havoc with other things.
*/
#ifndef KRFB_RFB_H
#define KRFB_RFB_H
#include "../libvncserver/rfb/rfb.h"
#undef TRUE
#undef FALSE
#endif // Header guard

View File

@@ -1,232 +0,0 @@
/*
Copyright (C) 2009-2010 Collabora Ltd <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
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 Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rfbclient.h"
#include "connectiondialog.h"
#include "krfbconfig.h"
#include "sockethelpers.h"
#include "events.h"
#include <QtCore/QSocketNotifier>
#include <KDebug>
#include <KNotification>
#include <poll.h>
#include <strings.h> //for bzero()
struct RfbClient::Private
{
Private(rfbClientPtr client) :
controlEnabled(KrfbConfig::allowDesktopControl()),
client(client)
{}
bool controlEnabled;
rfbClientPtr client;
QSocketNotifier *notifier;
QString remoteAddressString;
};
RfbClient::RfbClient(rfbClientPtr client, QObject* parent)
: QObject(parent), d(new Private(client))
{
d->remoteAddressString = peerAddress(d->client->sock) + ":" +
QString::number(peerPort(d->client->sock));
d->notifier = new QSocketNotifier(client->sock, QSocketNotifier::Read, this);
d->notifier->setEnabled(false);
connect(d->notifier, SIGNAL(activated(int)), this, SLOT(onSocketActivated()));
}
RfbClient::~RfbClient()
{
kDebug();
delete d;
}
QString RfbClient::name() const
{
return d->remoteAddressString;
}
//static
bool RfbClient::controlCanBeEnabled()
{
return KrfbConfig::allowDesktopControl();
}
bool RfbClient::controlEnabled() const
{
return d->controlEnabled;
}
void RfbClient::setControlEnabled(bool enabled)
{
if (controlCanBeEnabled() && d->controlEnabled != enabled) {
d->controlEnabled = enabled;
Q_EMIT controlEnabledChanged(enabled);
}
}
bool RfbClient::isOnHold() const
{
return d->client->onHold ? true : false;
}
void RfbClient::setOnHold(bool onHold)
{
if (isOnHold() != onHold) {
d->client->onHold = onHold;
d->notifier->setEnabled(!onHold);
Q_EMIT holdStatusChanged(onHold);
}
}
void RfbClient::closeConnection()
{
d->notifier->setEnabled(false);
rfbCloseClient(d->client);
rfbClientConnectionGone(d->client);
}
void RfbClient::handleKeyboardEvent(bool down, rfbKeySym keySym)
{
if (d->controlEnabled) {
EventHandler::handleKeyboard(down, keySym);
}
}
void RfbClient::handleMouseEvent(int buttonMask, int x, int y)
{
if (d->controlEnabled) {
EventHandler::handlePointer(buttonMask, x, y);
}
}
bool RfbClient::checkPassword(const QByteArray & encryptedPassword)
{
Q_UNUSED(encryptedPassword);
return d->client->screen->authPasswdData == (void*)0;
}
bool RfbClient::vncAuthCheckPassword(const QByteArray& password, const QByteArray& encryptedPassword) const
{
if (password.isEmpty() && encryptedPassword.isEmpty()) {
return true;
}
char passwd[MAXPWLEN];
unsigned char challenge[CHALLENGESIZE];
memcpy(challenge, d->client->authChallenge, CHALLENGESIZE);
bzero(passwd, MAXPWLEN);
if (!password.isEmpty()) {
strncpy(passwd, password,
(MAXPWLEN <= password.size()) ? MAXPWLEN : password.size());
}
rfbEncryptBytes(challenge, passwd);
return memcmp(challenge, encryptedPassword, encryptedPassword.size()) == 0;
}
void RfbClient::onSocketActivated()
{
//Process not only one, but all pending messages.
//poll() idea/code copied from vino:
// Copyright (C) 2003 Sun Microsystems, Inc.
// License: GPL v2 or later
struct pollfd pollfd = { d->client->sock, POLLIN|POLLPRI, 0 };
while(poll(&pollfd, 1, 0) == 1) {
rfbProcessClientMessage(d->client);
//This is how we handle disconnection.
//if rfbProcessClientMessage() finds out that it can't read the socket,
//it closes it and sets it to -1. So, we just have to check this here
//and call rfbClientConnectionGone() if necessary. This will call
//the clientGoneHook which in turn will remove this RfbClient instance
//from the server manager and will call deleteLater() to delete it
if (d->client->sock == -1) {
kDebug() << "disconnected from socket signal";
d->notifier->setEnabled(false);
rfbClientConnectionGone(d->client);
break;
}
}
}
void RfbClient::update()
{
rfbUpdateClient(d->client);
//This is how we handle disconnection.
//if rfbUpdateClient() finds out that it can't write to the socket,
//it closes it and sets it to -1. So, we just have to check this here
//and call rfbClientConnectionGone() if necessary. This will call
//the clientGoneHook which in turn will remove this RfbClient instance
//from the server manager and will call deleteLater() to delete it
if (d->client->sock == -1) {
kDebug() << "disconnected during update";
d->notifier->setEnabled(false);
rfbClientConnectionGone(d->client);
}
}
//*************
PendingRfbClient::PendingRfbClient(rfbClientPtr client, QObject *parent)
: QObject(parent), m_rfbClient(client)
{
kDebug();
QMetaObject::invokeMethod(this, "processNewClient", Qt::QueuedConnection);
}
PendingRfbClient::~PendingRfbClient()
{
kDebug();
}
void PendingRfbClient::accept(RfbClient *newClient)
{
kDebug() << "accepted connection";
m_rfbClient->clientData = newClient;
newClient->setOnHold(false);
Q_EMIT finished(newClient);
deleteLater();
}
static void clientGoneHookNoop(rfbClientPtr cl) { Q_UNUSED(cl); }
void PendingRfbClient::reject()
{
kDebug() << "refused connection";
//override the clientGoneHook that was previously set by RfbServer
m_rfbClient->clientGoneHook = clientGoneHookNoop;
rfbCloseClient(m_rfbClient);
rfbClientConnectionGone(m_rfbClient);
Q_EMIT finished(NULL);
deleteLater();
}
#include "rfbclient.moc"

View File

@@ -1,105 +0,0 @@
/*
Copyright (C) 2009-2010 Collabora Ltd <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
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 Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef RFBCLIENT_H
#define RFBCLIENT_H
#include "rfb.h"
#include <QtCore/QObject>
class RfbClient : public QObject
{
Q_OBJECT
Q_PROPERTY(bool controlEnabled READ controlEnabled WRITE setControlEnabled NOTIFY controlEnabledChanged)
Q_PROPERTY(bool onHold READ isOnHold WRITE setOnHold NOTIFY holdStatusChanged)
public:
RfbClient(rfbClientPtr client, QObject *parent = 0);
virtual ~RfbClient();
/** Returns a name for the client, to be shown to the user */
virtual QString name() const;
static bool controlCanBeEnabled();
bool controlEnabled() const;
bool isOnHold() const;
public Q_SLOTS:
void setControlEnabled(bool enabled);
void setOnHold(bool onHold);
void closeConnection();
Q_SIGNALS:
void controlEnabledChanged(bool enabled);
void holdStatusChanged(bool onHold);
protected:
friend class RfbServer; //the following event handling methods are called by RfbServer
virtual void handleKeyboardEvent(bool down, rfbKeySym keySym);
virtual void handleMouseEvent(int buttonMask, int x, int y);
/** This method is supposed to check if the provided \a encryptedPassword
* matches the criteria for authenticating the client.
* The default implementation returns false if a password is required.
* Reimplement to do more useful stuff.
*/
virtual bool checkPassword(const QByteArray & encryptedPassword);
/** This method checks if the \a encryptedPassword that was sent from the remote
* user matches the \a password that you have specified localy to be the password
* for this connection. This assumes that the standard VNC authentication mechanism
* is used. Returns true if the password matches or false otherwise.
*/
bool vncAuthCheckPassword(const QByteArray & password, const QByteArray & encryptedPassword) const;
private Q_SLOTS:
void onSocketActivated();
private:
///called by RfbServerManager to send framebuffer updates
///and check for possible disconnection
void update();
friend class RfbServerManager;
struct Private;
Private *const d;
};
class PendingRfbClient : public QObject
{
Q_OBJECT
public:
PendingRfbClient(rfbClientPtr client, QObject *parent = 0);
virtual ~PendingRfbClient();
Q_SIGNALS:
void finished(RfbClient *client);
protected Q_SLOTS:
virtual void processNewClient() = 0;
void accept(RfbClient *newClient);
void reject();
protected:
rfbClientPtr m_rfbClient;
};
#endif // RFBCLIENT_H

View File

@@ -1,268 +0,0 @@
/*
Copyright (C) 2009-2010 Collabora Ltd <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
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 Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rfbserver.h"
#include "rfbservermanager.h"
#include <QtCore/QSocketNotifier>
#include <KDebug>
struct RfbServer::Private
{
QByteArray listeningAddress;
int listeningPort;
bool passwordRequired;
rfbScreenInfoPtr screen;
QSocketNotifier *notifier;
};
RfbServer::RfbServer(QObject *parent)
: QObject(parent), d(new Private)
{
d->listeningAddress = "0.0.0.0";
d->listeningPort = 0;
d->passwordRequired = true;
d->screen = NULL;
d->notifier = NULL;
RfbServerManager::instance()->registerServer(this);
}
RfbServer::~RfbServer()
{
stop();
if (d->screen) {
rfbScreenCleanup(d->screen);
}
delete d;
RfbServerManager::instance()->unregisterServer(this);
}
QByteArray RfbServer::listeningAddress() const
{
return d->listeningAddress;
}
int RfbServer::listeningPort() const
{
return d->listeningPort;
}
bool RfbServer::passwordRequired() const
{
return d->passwordRequired;
}
void RfbServer::setListeningAddress(const QByteArray& address)
{
d->listeningAddress = address;
}
void RfbServer::setListeningPort(int port)
{
d->listeningPort = port;
}
void RfbServer::setPasswordRequired(bool passwordRequired)
{
d->passwordRequired = passwordRequired;
}
bool RfbServer::start()
{
if (!d->screen) {
d->screen = RfbServerManager::instance()->newScreen();
if (!d->screen) {
return false;
}
// server hooks
d->screen->screenData = this;
d->screen->newClientHook = newClientHook;
d->screen->kbdAddEvent = keyboardHook;
d->screen->ptrAddEvent = pointerHook;
d->screen->passwordCheck = passwordCheck;
d->screen->setXCutText = clipboardHook;
} else {
//if we already have a screen, stop listening first
rfbShutdownServer(d->screen, false);
}
if (listeningAddress() != "0.0.0.0") {
strncpy(d->screen->thisHost, listeningAddress().data(), 254);
}
if (listeningPort() == 0) {
d->screen->autoPort = 1;
}
d->screen->port = listeningPort();
// Disable/Enable password checking
if (passwordRequired()) {
d->screen->authPasswdData = (void *)1;
} else {
d->screen->authPasswdData = (void *)0;
}
kDebug() << "Starting server. Listen port:" << listeningPort()
<< "Listen Address:" << listeningAddress()
<< "Password enabled:" << passwordRequired();
rfbInitServer(d->screen);
if (!rfbIsActive(d->screen)) {
kDebug() << "Failed to start server";
rfbShutdownServer(d->screen, false);
return false;
};
d->notifier = new QSocketNotifier(d->screen->listenSock, QSocketNotifier::Read, this);
d->notifier->setEnabled(true);
connect(d->notifier, SIGNAL(activated(int)), this, SLOT(onListenSocketActivated()));
return true;
}
void RfbServer::stop(bool disconnectClients)
{
if (d->screen) {
rfbShutdownServer(d->screen, disconnectClients);
if (d->notifier) {
d->notifier->setEnabled(false);
d->notifier->deleteLater();
d->notifier = NULL;
}
}
}
void RfbServer::updateScreen(const QList<QRect> & modifiedTiles)
{
if (d->screen) {
QList<QRect>::const_iterator it = modifiedTiles.constBegin();
for(; it != modifiedTiles.constEnd(); ++it) {
rfbMarkRectAsModified(d->screen, it->x(), it->y(), it->right(), it->bottom());
}
}
}
/*
* Code copied from vino's bundled libvncserver:
* Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved.
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
* License: GPL v2 or later
*/
void krfb_rfbSetCursorPosition(rfbScreenInfoPtr screen, rfbClientPtr client, int x, int y)
{
rfbClientIteratorPtr iterator;
rfbClientPtr cl;
if (x == screen->cursorX || y == screen->cursorY)
return;
LOCK(screen->cursorMutex);
screen->cursorX = x;
screen->cursorY = y;
UNLOCK(screen->cursorMutex);
/* Inform all clients about this cursor movement. */
iterator = rfbGetClientIterator(screen);
while ((cl = rfbClientIteratorNext(iterator)) != NULL) {
cl->cursorWasMoved = TRUE;
}
rfbReleaseClientIterator(iterator);
/* The cursor was moved by this client, so don't send CursorPos. */
if (client) {
client->cursorWasMoved = FALSE;
}
}
void RfbServer::updateCursorPosition(const QPoint & position)
{
if (d->screen) {
krfb_rfbSetCursorPosition(d->screen, NULL, position.x(), position.y());
}
}
void RfbServer::onListenSocketActivated()
{
rfbProcessNewConnection(d->screen);
}
void RfbServer::pendingClientFinished(RfbClient *client)
{
kDebug();
if (client) {
RfbServerManager::instance()->addClient(client);
}
}
//static
rfbNewClientAction RfbServer::newClientHook(rfbClientPtr cl)
{
kDebug() << "New client";
RfbServer *server = static_cast<RfbServer*>(cl->screen->screenData);
PendingRfbClient *pendingClient = server->newClient(cl);
connect(pendingClient, SIGNAL(finished(RfbClient*)),
server, SLOT(pendingClientFinished(RfbClient*)));
cl->clientGoneHook = clientGoneHook;
return RFB_CLIENT_ON_HOLD;
}
//static
void RfbServer::clientGoneHook(rfbClientPtr cl)
{
kDebug() << "client gone";
RfbClient *client = static_cast<RfbClient*>(cl->clientData);
RfbServerManager::instance()->removeClient(client);
client->deleteLater();
}
//static
rfbBool RfbServer::passwordCheck(rfbClientPtr cl, const char *encryptedPassword, int len)
{
RfbClient *client = static_cast<RfbClient*>(cl->clientData);
return client->checkPassword(QByteArray::fromRawData(encryptedPassword, len));
}
//static
void RfbServer::keyboardHook(rfbBool down, rfbKeySym keySym, rfbClientPtr cl)
{
RfbClient *client = static_cast<RfbClient*>(cl->clientData);
client->handleKeyboardEvent(down ? true : false, keySym);
}
//static
void RfbServer::pointerHook(int bm, int x, int y, rfbClientPtr cl)
{
RfbClient *client = static_cast<RfbClient*>(cl->clientData);
client->handleMouseEvent(bm, x, y);
}
//static
void RfbServer::clipboardHook(char *str, int len, rfbClientPtr cl)
{
//TODO implement me
}
#include "rfbserver.moc"

View File

@@ -1,71 +0,0 @@
/*
Copyright (C) 2009-2010 Collabora Ltd <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
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 Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef RFBSERVER_H
#define RFBSERVER_H
#include "rfb.h"
#include "rfbclient.h"
#include <QtCore/QRect>
class RfbServer : public QObject
{
Q_OBJECT
public:
RfbServer(QObject *parent = 0);
virtual ~RfbServer();
QByteArray listeningAddress() const;
int listeningPort() const;
bool passwordRequired() const;
void setListeningAddress(const QByteArray & address);
void setListeningPort(int port);
void setPasswordRequired(bool passwordRequired);
public Q_SLOTS:
bool start();
void stop(bool disconnectClients = true);
void updateScreen(const QList<QRect> & modifiedTiles);
void updateCursorPosition(const QPoint & position);
private Q_SLOTS:
void onListenSocketActivated();
void pendingClientFinished(RfbClient *client);
protected:
virtual PendingRfbClient *newClient(rfbClientPtr client) = 0;
private:
static rfbNewClientAction newClientHook(rfbClientPtr cl);
static void clientGoneHook(rfbClientPtr cl);
static rfbBool passwordCheck(rfbClientPtr cl, const char *encryptedPassword, int len);
static void keyboardHook(rfbBool down, rfbKeySym keySym, rfbClientPtr cl);
static void pointerHook(int bm, int x, int y, rfbClientPtr cl);
static void clipboardHook(char *str, int len, rfbClientPtr cl);
Q_DISABLE_COPY(RfbServer)
struct Private;
Private *const d;
};
#endif // RFBSERVER_H

View File

@@ -1,235 +0,0 @@
/*
Copyright (C) 2009-2010 Collabora Ltd <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
Copyright (C) 2001-2003 by Tim Jansen <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.
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 Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rfbservermanager.h"
#include "rfbserver.h"
#include "framebuffer.h"
#include "framebuffermanager.h"
#include "sockethelpers.h"
#include "krfbconfig.h"
#include <QtCore/QTimer>
#include <QtGui/QApplication>
#include <QtGui/QDesktopWidget>
#include <QtNetwork/QHostInfo>
#include <KGlobal>
#include <KDebug>
#include <KLocale>
#include <KUser>
#include <KNotification>
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 ";
struct RfbServerManagerStatic
{
RfbServerManager server;
};
K_GLOBAL_STATIC(RfbServerManagerStatic, s_instance)
RfbServerManager* RfbServerManager::instance()
{
return &s_instance->server;
}
struct RfbServerManager::Private
{
QSharedPointer<FrameBuffer> fb;
rfbCursorPtr myCursor;
QByteArray desktopName;
QTimer rfbUpdateTimer;
QSet<RfbServer*> servers;
QSet<RfbClient*> clients;
};
RfbServerManager::RfbServerManager()
: QObject(), d(new Private)
{
init();
}
RfbServerManager::~RfbServerManager()
{
delete d;
}
void RfbServerManager::init()
{
kDebug();
d->fb = FrameBufferManager::instance()->frameBuffer(QApplication::desktop()->winId());
d->myCursor = rfbMakeXCursor(19, 19, (char *) cur, (char *) mask);
d->myCursor->cleanup = false;
d->desktopName = QString("%1@%2 (shared desktop)") //FIXME check if we can use utf8
.arg(KUser().loginName(),QHostInfo::localHostName()).toLatin1();
connect(&d->rfbUpdateTimer, SIGNAL(timeout()), SLOT(updateScreens()));
connect(qApp, SIGNAL(aboutToQuit()), SLOT(cleanup()));
}
void RfbServerManager::updateScreens()
{
QList<QRect> rects = d->fb->modifiedTiles();
QPoint currentCursorPos = QCursor::pos();
Q_FOREACH(RfbServer *server, d->servers) {
server->updateScreen(rects);
server->updateCursorPosition(currentCursorPos);
}
//update() might disconnect some of the clients, which will synchronously
//call the removeClient() method and will change d->clients, so we need
//to copy the set here to avoid problems.
QSet<RfbClient*> clients = d->clients;
Q_FOREACH(RfbClient *client, clients) {
client->update();
}
}
void RfbServerManager::cleanup()
{
kDebug();
//copy because d->servers is going to be modified while we delete the servers
QSet<RfbServer*> servers = d->servers;
Q_FOREACH(RfbServer *server, servers) {
delete server;
}
Q_ASSERT(d->servers.isEmpty());
Q_ASSERT(d->clients.isEmpty());
d->myCursor->cleanup = true;
rfbFreeCursor(d->myCursor);
d->fb.clear();
}
void RfbServerManager::registerServer(RfbServer* server)
{
d->servers.insert(server);
}
void RfbServerManager::unregisterServer(RfbServer* server)
{
d->servers.remove(server);
}
rfbScreenInfoPtr RfbServerManager::newScreen()
{
rfbScreenInfoPtr screen = NULL;
if (!d->fb.isNull()) {
int w = d->fb->width();
int h = d->fb->height();
int depth = d->fb->depth();
int bpp = depth >> 3;
if (bpp != 1 && bpp != 2 && bpp != 4) {
bpp = 4;
}
kDebug() << "bpp: " << bpp;
rfbLogEnable(0);
screen = rfbGetScreen(0, 0, w, h, 8, 3, bpp);
screen->paddedWidthInBytes = d->fb->paddedWidth();
d->fb->getServerFormat(screen->serverFormat);
screen->frameBuffer = d->fb->data();
screen->desktopName = d->desktopName.constData();
screen->cursor = d->myCursor;
}
return screen;
}
void RfbServerManager::addClient(RfbClient* cc)
{
if (d->clients.size() == 0) {
kDebug() << "Starting framebuffer monitor";
d->fb->startMonitor();
d->rfbUpdateTimer.start(50);
}
d->clients.insert(cc);
KNotification::event("UserAcceptsConnection",
i18n("The remote user %1 is now connected.", cc->name()));
Q_EMIT clientConnected(cc);
}
void RfbServerManager::removeClient(RfbClient* cc)
{
d->clients.remove(cc);
if (d->clients.size() == 0) {
kDebug() << "Stopping framebuffer monitor";
d->fb->stopMonitor();
d->rfbUpdateTimer.stop();
}
KNotification::event("ConnectionClosed", i18n("The remote user %1 disconnected.", cc->name()));
Q_EMIT clientDisconnected(cc);
}
#include "rfbservermanager.moc"

View File

@@ -1,65 +0,0 @@
/*
Copyright (C) 2009-2010 Collabora Ltd <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
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 Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef RFBSERVERMANAGER_H
#define RFBSERVERMANAGER_H
#include "rfb.h"
#include <QtCore/QObject>
class RfbClient;
class RfbServerManagerStatic;
class RfbServer;
class RfbServerManager : public QObject
{
Q_OBJECT
public:
static RfbServerManager *instance();
Q_SIGNALS:
void clientConnected(RfbClient *cc);
void clientDisconnected(RfbClient *cc);
private Q_SLOTS:
void init();
void updateScreens();
void cleanup();
private:
void registerServer(RfbServer *server);
void unregisterServer(RfbServer *server);
rfbScreenInfoPtr newScreen();
void addClient(RfbClient *cc);
void removeClient(RfbClient *cc);
RfbServerManager();
virtual ~RfbServerManager();
Q_DISABLE_COPY(RfbServerManager)
friend class RfbServer;
friend class RfbServerManagerStatic;
struct Private;
Private *const d;
};
#endif // RFBSERVERMANAGER_H

View File

@@ -1,106 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2009 Collabora Ltd <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
Copyright (C) 2001-2003 by Tim Jansen <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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "sockethelpers.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
QString peerAddress(int sock)
{
const int ADDR_SIZE = 50;
struct sockaddr sa;
socklen_t salen = sizeof(struct sockaddr);
if (getpeername(sock, &sa, &salen) == 0) {
if (sa.sa_family == AF_INET) {
struct sockaddr_in *si = (struct sockaddr_in *)&sa;
return QString(inet_ntoa(si->sin_addr));
}
if (sa.sa_family == AF_INET6) {
char inetbuf[ADDR_SIZE];
inet_ntop(sa.sa_family, &sa, inetbuf, ADDR_SIZE);
return QString(inetbuf);
}
return QString("not a network address");
}
return QString("unable to determine...");
}
unsigned short peerPort(int sock)
{
struct sockaddr sa;
socklen_t salen = sizeof(struct sockaddr);
if (getpeername(sock, &sa, &salen) == 0) {
struct sockaddr_in *si = (struct sockaddr_in *)&sa;
return ntohs(si->sin_port);
}
return 0;
}
QString localAddress(int sock)
{
const int ADDR_SIZE = 50;
struct sockaddr sa;
socklen_t salen = sizeof(struct sockaddr);
if (getsockname(sock, &sa, &salen) == 0) {
if (sa.sa_family == AF_INET) {
struct sockaddr_in *si = (struct sockaddr_in *)&sa;
return QString(inet_ntoa(si->sin_addr));
}
if (sa.sa_family == AF_INET6) {
char inetbuf[ADDR_SIZE];
inet_ntop(sa.sa_family, &sa, inetbuf, ADDR_SIZE);
return QString(inetbuf);
}
return QString("not a network address");
}
return QString("unable to determine...");
}
unsigned short localPort(int sock)
{
struct sockaddr sa;
socklen_t salen = sizeof(struct sockaddr);
if (getsockname(sock, &sa, &salen) == 0) {
struct sockaddr_in *si = (struct sockaddr_in *)&sa;
return ntohs(si->sin_port);
}
return 0;
}

View File

@@ -1,153 +0,0 @@
/*
Copyright (C) 2010 Collabora Ltd <info@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
Copyright (C) 2001-2002 Tim Jansen <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.
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 Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "trayicon.h"
#include "invitedialog.h"
#include "manageinvitationsdialog.h"
#include "rfbservermanager.h"
#include "rfbclient.h"
#include <KAboutApplicationDialog>
#include <KActionCollection>
#include <KDialog>
#include <KGlobal>
#include <KLocale>
#include <KMenu>
#include <KStandardAction>
#include <KDebug>
class ClientActions
{
public:
ClientActions(RfbClient *client, KMenu *menu, QAction *before);
virtual ~ClientActions();
private:
KMenu *m_menu;
QAction *m_title;
QAction *m_disconnectAction;
QAction *m_enableControlAction;
QAction *m_separator;
};
ClientActions::ClientActions(RfbClient* client, KMenu* menu, QAction* before)
: m_menu(menu)
{
m_title = m_menu->addTitle(client->name(), before);
m_disconnectAction = new KAction(i18n("Disconnect"), m_menu);
m_menu->insertAction(before, m_disconnectAction);
QObject::connect(m_disconnectAction, SIGNAL(triggered()), client, SLOT(closeConnection()));
if (client->controlCanBeEnabled()) {
m_enableControlAction = new KToggleAction(i18n("Enable Remote Control"), m_menu);
m_enableControlAction->setChecked(client->controlEnabled());
m_menu->insertAction(before, m_enableControlAction);
QObject::connect(m_enableControlAction, SIGNAL(triggered(bool)),
client, SLOT(setControlEnabled(bool)));
QObject::connect(client, SIGNAL(controlEnabledChanged(bool)),
m_enableControlAction, SLOT(setChecked(bool)));
} else {
m_enableControlAction = NULL;
}
m_separator = m_menu->insertSeparator(before);
}
ClientActions::~ClientActions()
{
kDebug();
m_menu->removeAction(m_title);
delete m_title;
m_menu->removeAction(m_disconnectAction);
delete m_disconnectAction;
if (m_enableControlAction) {
m_menu->removeAction(m_enableControlAction);
delete m_enableControlAction;
}
m_menu->removeAction(m_separator);
delete m_separator;
}
//**********
TrayIcon::TrayIcon(QWidget *mainWindow)
: KStatusNotifierItem(mainWindow)
{
setIconByPixmap(KIcon("krfb").pixmap(22, 22, KIcon::Disabled));
setToolTipTitle(i18n("Desktop Sharing - disconnected"));
setCategory(KStatusNotifierItem::ApplicationStatus);
connect(RfbServerManager::instance(), SIGNAL(clientConnected(RfbClient*)),
this, SLOT(onClientConnected(RfbClient*)));
connect(RfbServerManager::instance(), SIGNAL(clientDisconnected(RfbClient*)),
this, SLOT(onClientDisconnected(RfbClient*)));
m_aboutAction = KStandardAction::aboutApp(this, SLOT(showAbout()), actionCollection());
contextMenu()->addAction(m_aboutAction);
}
void TrayIcon::onClientConnected(RfbClient* client)
{
kDebug();
if (m_clientActions.isEmpty()) { //first client connected
setIconByName("krfb");
setToolTipTitle(i18n("Desktop Sharing - connected with %1", client->name()));
setStatus(KStatusNotifierItem::Active);
} else { //Nth client connected, N != 1
setToolTipTitle(i18n("Desktop Sharing - connected"));
}
m_clientActions[client] = new ClientActions(client, contextMenu(), m_aboutAction);
}
void TrayIcon::onClientDisconnected(RfbClient* client)
{
kDebug();
ClientActions *actions = m_clientActions.take(client);
delete actions;
if (m_clientActions.isEmpty()) {
setIconByPixmap(KIcon("krfb").pixmap(22, 22, KIcon::Disabled));
setToolTipTitle(i18n("Desktop Sharing - disconnected"));
setStatus(KStatusNotifierItem::Passive);
} else if (m_clientActions.size() == 1) { //clients number dropped back to 1
RfbClient *client = m_clientActions.constBegin().key();
setToolTipTitle(i18n("Desktop Sharing - connected with %1", client->name()));
}
}
void TrayIcon::showAbout()
{
KDialog *dlg = new KAboutApplicationDialog(KGlobal::mainComponent().aboutData());
dlg->setAttribute(Qt::WA_DeleteOnClose, true);
dlg->show();
}
#include "trayicon.moc"

View File

@@ -1,95 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2009 Collabora Ltd <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "tubesclienthandler.h"
#include "tubesrfbserver.h"
#include <TelepathyQt4/ChannelClassSpecList>
#include <TelepathyQt4/Constants>
#include <TelepathyQt4/Debug>
#include <KDebug>
using namespace Tp;
static inline Tp::ChannelClassSpecList channelClassSpecList()
{
Tp::ChannelClassSpec spec = Tp::ChannelClassSpec();
spec.setChannelType(TP_QT4_IFACE_CHANNEL_TYPE_STREAM_TUBE);
spec.setTargetHandleType(Tp::HandleTypeContact);
spec.setRequested(true);
spec.setProperty(QString(TP_QT4_IFACE_CHANNEL_TYPE_STREAM_TUBE) + ".Service", QVariant("rfb"));
return Tp::ChannelClassSpecList() << spec;
}
TubesClientHandler::TubesClientHandler()
: AbstractClientHandler(channelClassSpecList())
{
kDebug();
Tp::enableDebug(false);
Tp::enableWarnings(true);
/* Registering telepathy types */
registerTypes();
}
TubesClientHandler::~TubesClientHandler()
{
kDebug();
}
bool TubesClientHandler::bypassApproval() const
{
// Don't bypass approval of channels.
return false;
}
void TubesClientHandler::handleChannels(const Tp::MethodInvocationContextPtr<> &context,
const Tp::AccountPtr &account,
const Tp::ConnectionPtr &connection,
const QList<Tp::ChannelPtr> &channels,
const QList<Tp::ChannelRequestPtr> &requestsSatisfied,
const QDateTime &userActionTime,
const Tp::AbstractClientHandler::HandlerInfo &handlerInfo)
{
kDebug();
Q_UNUSED(account);
Q_UNUSED(connection);
Q_UNUSED(requestsSatisfied);
Q_UNUSED(userActionTime);
Q_UNUSED(handlerInfo);
foreach(const Tp::ChannelPtr &channel, channels) {
kDebug() << "Incoming channel: " << channel;
QVariantMap properties = channel->immutableProperties();
if (properties[TELEPATHY_INTERFACE_CHANNEL ".ChannelType"] ==
TELEPATHY_INTERFACE_CHANNEL_TYPE_STREAM_TUBE) {
kDebug() << "Channel is a stream tube. Handling: " << channel;
new TubesRfbServer(channel);
}
}
context->setFinished();
}

View File

@@ -1,45 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2009 Collabora Ltd <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KRFB_TUBESCLIENTHANDLER_H
#define KRFB_TUBESCLIENTHANDLER_H
#include <TelepathyQt4/AbstractClientHandler>
class TubesClientHandler : public Tp::AbstractClientHandler
{
public:
TubesClientHandler();
virtual ~TubesClientHandler();
virtual bool bypassApproval() const;
virtual void handleChannels(const Tp::MethodInvocationContextPtr<> &context,
const Tp::AccountPtr &account,
const Tp::ConnectionPtr &connection,
const QList<Tp::ChannelPtr> &channels,
const QList<Tp::ChannelRequestPtr> &requestsSatisfied,
const QDateTime &userActionTime,
const Tp::AbstractClientHandler::HandlerInfo &handlerInfo);
};
#endif // Header guard

View File

@@ -1,85 +0,0 @@
/*
Copyright (C) 2009-2010 Collabora Ltd. <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
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 Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tubesrfbclient.h"
#include "krfbconfig.h"
#include "connectiondialog.h"
#include <KNotification>
#include <KLocale>
QString TubesRfbClient::name() const
{
return m_contact->alias();
}
void PendingTubesRfbClient::setContact(const Tp::ContactPtr & contact)
{
m_contact = contact;
if (m_processNewClientCalled) {
//processNewClient has already been called, so we need to act here
showConfirmationDialog();
}
}
void PendingTubesRfbClient::processNewClient()
{
if (!m_contact) {
//no associated contact yet, hold.
m_processNewClientCalled = true; //act when a contact is set
} else {
//we have a contact, begin handling
showConfirmationDialog();
}
}
void PendingTubesRfbClient::showConfirmationDialog()
{
QString name = m_contact->alias();
if (!KrfbConfig::askOnConnect()) {
KNotification::event("NewConnectionAutoAccepted",
i18n("Accepted connection from %1", name));
accept(new TubesRfbClient(m_rfbClient, m_contact, parent()));
} else {
KNotification::event("NewConnectionOnHold",
i18n("Received connection from %1, on hold (waiting for confirmation)",
name));
TubesConnectionDialog *dialog = new TubesConnectionDialog(0);
dialog->setContactName(name);
dialog->setAllowRemoteControl(KrfbConfig::allowDesktopControl());
connect(dialog, SIGNAL(okClicked()), SLOT(dialogAccepted()));
connect(dialog, SIGNAL(cancelClicked()), SLOT(reject()));
dialog->show();
}
}
void PendingTubesRfbClient::dialogAccepted()
{
TubesConnectionDialog *dialog = qobject_cast<TubesConnectionDialog *>(sender());
Q_ASSERT(dialog);
TubesRfbClient *client = new TubesRfbClient(m_rfbClient, m_contact, parent());
client->setControlEnabled(dialog->allowRemoteControl());
accept(client);
}
#include "tubesrfbclient.moc"

View File

@@ -1,58 +0,0 @@
/*
Copyright (C) 2010 Collabora Ltd. <info@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
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 Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TUBESRFBCLIENT_H
#define TUBESRFBCLIENT_H
#include "rfbclient.h"
#include <TelepathyQt4/Contact>
class TubesRfbClient : public RfbClient
{
public:
TubesRfbClient(rfbClientPtr client, const Tp::ContactPtr & contact, QObject* parent = 0)
: RfbClient(client, parent), m_contact(contact) {}
virtual QString name() const;
private:
Tp::ContactPtr m_contact;
};
class PendingTubesRfbClient : public PendingRfbClient
{
Q_OBJECT
public:
PendingTubesRfbClient(rfbClientPtr client, QObject* parent = 0)
: PendingRfbClient(client, parent), m_processNewClientCalled(false) {}
void setContact(const Tp::ContactPtr & contact);
protected Q_SLOTS:
virtual void processNewClient();
private Q_SLOTS:
void showConfirmationDialog();
void dialogAccepted();
private:
Tp::ContactPtr m_contact;
bool m_processNewClientCalled;
};
#endif // TUBESRFBCLIENT_H

View File

@@ -1,294 +0,0 @@
/*
Copyright (C) 2009-2010 Collabora Ltd. <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
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 Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tubesrfbserver.h"
#include "tubesrfbclient.h"
#include "sockethelpers.h"
#include <QtGui/QApplication>
#include <KDebug>
#include <KMessageBox>
#include <KLocale>
#include <TelepathyQt4/Connection>
#include <TelepathyQt4/Contact>
#include <TelepathyQt4/ContactManager>
#include <TelepathyQt4/PendingContacts>
#include <TelepathyQt4/PendingOperation>
#include <TelepathyQt4/PendingReady>
/* workaround for QtDBus bug */
struct StreamTubeAddress
{
QString address;
uint port;
};
Q_DECLARE_METATYPE(StreamTubeAddress);
//Marshall the StreamTubeAddress data into a D-Bus argument
QDBusArgument &operator<<(QDBusArgument &argument,
const StreamTubeAddress &streamTubeAddress)
{
argument.beginStructure();
argument << streamTubeAddress.address << streamTubeAddress.port;
argument.endStructure();
return argument;
}
// Retrieve the StreamTubeAddress data from the D-Bus argument
const QDBusArgument &operator>>(const QDBusArgument &argument,
StreamTubeAddress &streamTubeAddress)
{
argument.beginStructure();
argument >> streamTubeAddress.address >> streamTubeAddress.port;
argument.endStructure();
return argument;
}
//**************
struct TubesRfbServer::Private
{
Tp::ChannelPtr channel;
QHash<int, Tp::ContactPtr> contactsPerPort;
QHash<int, PendingTubesRfbClient*> clientsPerPort;
};
TubesRfbServer::TubesRfbServer(const Tp::ChannelPtr & channel, QObject *parent)
: RfbServer(parent), d(new Private)
{
kDebug() << "starting ";
/* Registering struct containing the tube address */
qDBusRegisterMetaType<StreamTubeAddress>();
d->channel = channel;
connect(d->channel->becomeReady(),
SIGNAL(finished(Tp::PendingOperation*)),
SLOT(onChannelReady(Tp::PendingOperation*)));
setListeningPort(6789);
setListeningAddress("127.0.0.1"); // Listen only on the loopback network interface
setPasswordRequired(false);
}
TubesRfbServer::~TubesRfbServer()
{
kDebug();
delete d;
}
PendingRfbClient* TubesRfbServer::newClient(rfbClientPtr client)
{
kDebug() << "new tubes client";
PendingTubesRfbClient *c = new PendingTubesRfbClient(client, this);
int port = peerPort(client->sock);
d->clientsPerPort[port] = c;
if (d->contactsPerPort.contains(port)) {
kDebug() << "already have a contact";
c->setContact(d->contactsPerPort[port]);
}
return c;
}
/************************** TP TUBES CODE ************************************/
void TubesRfbServer::close()
{
kDebug();
d->channel->requestClose();
}
void TubesRfbServer::cleanup()
{
kDebug();
d->clientsPerPort.clear();
d->contactsPerPort.clear();
stop();
deleteLater();
}
void TubesRfbServer::onChannelReady(Tp::PendingOperation *op)
{
kDebug();
if (op->isError()) {
kWarning() << "Getting channel ready faied:" << op->errorName() << op->errorMessage();
KMessageBox::error(QApplication::activeWindow(),
i18n("An error occurred sharing your desktop."),
i18n("Error"));
cleanup();
return;
}
Tp::Contacts contacts = d->channel->groupContacts();
Tp::ContactManagerPtr contactManager = d->channel->connection()->contactManager();
if (!contactManager) {
kWarning() << "Invalid Contact Manager.";
KMessageBox::error(QApplication::activeWindow(),
i18n("An unknown error occurred sharing your desktop."),
i18n("Error"));
close();
return;
}
Tp::Features features;
features << Tp::Contact::FeatureAlias;
connect(contactManager->upgradeContacts(contacts.toList(), features),
SIGNAL(finished(Tp::PendingOperation*)),
SLOT(onContactsUpgraded(Tp::PendingOperation*)));
}
void TubesRfbServer::onContactsUpgraded(Tp::PendingOperation *op)
{
kDebug();
if (op->isError()) {
kWarning() << "Upgrading contacts failed:" << op->errorName() << op->errorMessage();
KMessageBox::error(QApplication::activeWindow(),
i18n("An unknown error occurred sharing your desktop."),
i18n("Error"));
close();
return;
}
offerTube();
}
void TubesRfbServer::offerTube()
{
kDebug() << "Channel is ready!";
//start the rfb server
if (!start()) {
kWarning() << "Could not start rfb server";
KMessageBox::error(QApplication::activeWindow(),
i18n("Failed to activate the rfb server."),
i18n("Error"));
close();
return;
}
connect(d->channel.data(),
SIGNAL(invalidated(Tp::DBusProxy*,QString,QString)),
SLOT(onChannelInvalidated(Tp::DBusProxy*, const QString&,
const QString&)));
/* Interface used to control the tube state */
Tp::Client::ChannelInterfaceTubeInterface *tubeInterface = d->channel->interface<Tp::Client::ChannelInterfaceTubeInterface>();
/* Interface used to control stream tube */
Tp::Client::ChannelTypeStreamTubeInterface *streamTubeInterface = d->channel->interface<Tp::Client::ChannelTypeStreamTubeInterface>();
if (streamTubeInterface && tubeInterface) {
kDebug() << "Offering tube";
connect(tubeInterface,
SIGNAL(TubeChannelStateChanged(uint)),
SLOT(onTubeStateChanged(uint)));
// Offer the stream tube
StreamTubeAddress streamTubeAddress;
streamTubeAddress.address = listeningAddress();
streamTubeAddress.port = listeningPort();
kDebug() << "Offering:" << streamTubeAddress.port << streamTubeAddress.address;
QDBusVariant address;
address.setVariant(qVariantFromValue(streamTubeAddress));
QDBusPendingReply<> ret = streamTubeInterface->Offer(
uint(Tp::SocketAddressTypeIPv4),
address,
uint(Tp::SocketAccessControlPort),
QVariantMap());
connect(new QDBusPendingCallWatcher(ret, this), SIGNAL(finished(QDBusPendingCallWatcher*)),
SLOT(onOfferTubeFinished(QDBusPendingCallWatcher*)));
connect(streamTubeInterface,
SIGNAL(NewRemoteConnection(uint,QDBusVariant,uint)),
SLOT(onNewRemoteConnection(uint,QDBusVariant,uint)));
}
}
void TubesRfbServer::onOfferTubeFinished(QDBusPendingCallWatcher *watcher)
{
QDBusPendingReply<void> reply = *watcher;
if (reply.isError()) {
kWarning() << "Offer tube failed:" << reply.error();
if (reply.error().name() == TELEPATHY_ERROR_NOT_AVAILABLE) {
KMessageBox::error(QApplication::activeWindow(),
i18n("An error occurred sharing your desktop. The person you are "
"trying to share your desktop with does not have the required "
"software installed to access it."),
i18n("Error"));
} else {
KMessageBox::error(QApplication::activeWindow(),
i18n("An unknown error occurred sharing your desktop."),
i18n("Error"));
}
} else {
kDebug() << "Offer Tube succeeded.";
}
}
void TubesRfbServer::onTubeStateChanged(uint state)
{
kDebug() << "Tube state changed:" << state;
}
void TubesRfbServer::onNewRemoteConnection(uint handle, QDBusVariant connectionParam, uint connectionId)
{
Q_UNUSED(connectionId);
QVariant v = connectionParam.variant();
kDebug() << "variant:" << v;
StreamTubeAddress ipv4address = qdbus_cast<StreamTubeAddress>(v);
kDebug() << "NewRemoteConnection: port:" << ipv4address.port << ipv4address.address;
Q_FOREACH(const Tp::ContactPtr & c, d->channel->groupContacts()) {
if (c->handle().value(0) == handle) {
d->contactsPerPort[ipv4address.port] = c;
if (d->clientsPerPort.contains(ipv4address.port)) {
kDebug() << "client already exists";
d->clientsPerPort[ipv4address.port]->setContact(c);
}
break;
}
}
}
void TubesRfbServer::onChannelInvalidated(Tp::DBusProxy *proxy,
const QString &errorName, const QString &errorMessage)
{
Q_UNUSED(proxy);
kDebug() << "Tube channel invalidated:" << errorName << errorMessage;
cleanup();
}
#include "tubesrfbserver.moc"

View File

@@ -1,52 +0,0 @@
/*
Copyright (C) 2009-2010 Collabora Ltd. <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
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 Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TUBESRFBSERVER_H
#define TUBESRFBSERVER_H
#include "rfbserver.h"
#include <TelepathyQt4/Channel>
class TubesRfbServer : public RfbServer
{
Q_OBJECT
public:
TubesRfbServer(const Tp::ChannelPtr & channel, QObject* parent = 0);
virtual ~TubesRfbServer();
virtual PendingRfbClient* newClient(rfbClientPtr client);
private Q_SLOTS:
void close();
void cleanup();
void onChannelReady(Tp::PendingOperation *op);
void onContactsUpgraded(Tp::PendingOperation *op);
void offerTube();
void onOfferTubeFinished(QDBusPendingCallWatcher *watcher);
void onTubeStateChanged(uint state);
void onNewRemoteConnection(uint handle, QDBusVariant connectionParam, uint connectionId);
void onChannelInvalidated(Tp::DBusProxy *proxy,
const QString &errorName,
const QString &errorMessage);
private:
struct Private;
Private *const d;
};
#endif // TUBESRFBSERVER_H

View File

@@ -1,114 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TubesConnectionWidget</class>
<widget class="QWidget" name="TubesConnectionWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>162</height>
</rect>
</property>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel" name="pixmapLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout">
<item>
<widget class="QLabel" name="TextLabel5">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>13</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Confirmation</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="indent">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="mainTextLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="lineWidth">
<number>-1</number>
</property>
<property name="midLineWidth">
<number>5</number>
</property>
<property name="text">
<string/>
</property>
<property name="textFormat">
<enum>Qt::AutoText</enum>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>0</number>
</property>
<property name="indent">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbAllowRemoteControl">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="whatsThis">
<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>
<property name="text">
<string>Allow remote user to &amp;control keyboard and mouse</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

322
krfbserver.cpp Normal file
View File

@@ -0,0 +1,322 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
(C) 2001-2003 by Tim Jansen <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 "krfbserver.h"
#include "krfbserver.moc"
#include <QTcpServer>
#include <QTcpSocket>
#include <QTimer>
#include <QHostInfo>
#include <QApplication>
#include <QDesktopWidget>
#include <QPointer>
#include <KGlobal>
#include <KUser>
#include <KLocale>
#include <KDebug>
#include <KMessageBox>
#include <dnssd/publicservice.h>
#include "connectioncontroller.h"
#include "framebuffer.h"
#include "framebuffermanager.h"
#include "krfbconfig.h"
#include "invitationmanager.h"
#include <X11/Xutil.h>
#include <X11/extensions/XTest.h>
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;
static enum rfbNewClientAction newClientHook(struct _rfbClientRec *cl)
{
KrfbServer *server = KrfbServer::self();
return server->handleNewClient(cl);
}
static rfbBool passwordCheck(rfbClientPtr cl,
const char* encryptedPassword,
int len)
{
ConnectionController *cc = static_cast<ConnectionController *>(cl->clientData);
return cc->handleCheckPassword(cl, encryptedPassword, len);
}
static void keyboardHook(rfbBool down, rfbKeySym keySym, rfbClientPtr cl)
{
ConnectionController *cc = static_cast<ConnectionController *>(cl->clientData);
cc->handleKeyEvent(down ? true : false, keySym);
}
static void pointerHook(int bm, int x, int y, rfbClientPtr cl)
{
ConnectionController *cc = static_cast<ConnectionController *>(cl->clientData);
cc->handlePointerEvent(bm, x, y);
}
static void clipboardHook(char* str,int len, rfbClientPtr cl)
{
ConnectionController *cc = static_cast<ConnectionController *>(cl->clientData);
cc->clipboardToServer(QString::fromUtf8(str, len));
}
class KrfbServer::KrfbServerP {
public:
KrfbServerP() : screen(0), numClients(0) {};
QSharedPointer<FrameBuffer> fb;
QList< QPointer<ConnectionController> > controllers;
rfbScreenInfoPtr screen;
int numClients;
QByteArray desktopName;
QTimer rfbProcessEventTimer;
};
class KrfbServerPrivate
{
public:
KrfbServer instance;
};
K_GLOBAL_STATIC(KrfbServerPrivate, krfbServerPrivate)
KrfbServer * KrfbServer::self() {
return &krfbServerPrivate->instance;
}
KrfbServer::KrfbServer()
:d(new KrfbServerP)
{
kDebug() << "starting ";
d->fb = FrameBufferManager::instance()->frameBuffer(QApplication::desktop()->winId());
QTimer::singleShot(0, this, SLOT(startListening()));
connect(InvitationManager::self(), SIGNAL(invitationNumChanged(int)),SLOT(updatePassword()));
}
KrfbServer::~KrfbServer()
{
delete d;
}
void KrfbServer::startListening()
{
rfbScreenInfoPtr screen;
int port = KrfbConfig::port();
int w = d->fb->width();
int h = d->fb->height();
int depth = d->fb->depth();
int bpp = depth >> 3;
if (bpp != 1 && bpp != 2 && bpp != 4) bpp = 4;
kDebug() << "bpp: " << bpp;
rfbLogEnable(0);
screen = rfbGetScreen(0, 0, w, h, 8, 3, bpp);
screen->paddedWidthInBytes = d->fb->paddedWidth();
d->fb->getServerFormat(screen->serverFormat);
screen->frameBuffer = d->fb->data();
d->screen = screen;
screen->autoPort = 0;
screen->port = port;
// server hooks
screen->newClientHook = newClientHook;
screen->kbdAddEvent = keyboardHook;
screen->ptrAddEvent = pointerHook;
screen->newClientHook = newClientHook;
screen->passwordCheck = passwordCheck;
screen->setXCutText = clipboardHook;
d->desktopName = i18n("%1@%2 (shared desktop)", KUser().loginName(), QHostInfo::localHostName()).toLatin1();
screen->desktopName = d->desktopName.constData();
if (!myCursor) {
myCursor = rfbMakeXCursor(19, 19, (char*) cur, (char*) mask);
}
screen->cursor = myCursor;
// configure passwords and desktop control here
updateSettings();
rfbInitServer(screen);
if (!rfbIsActive(screen)) {
KMessageBox::error(0,i18n("Address already in use"),"krfb");
shutdown();
qApp->quit();
return;
};
if (KrfbConfig::publishService()) {
DNSSD::PublicService *service = new DNSSD::PublicService(i18n("%1@%2 (shared desktop)", KUser().loginName(), QHostInfo::localHostName()),"_rfb._tcp",port);
service->publishAsync();
}
/* Integrate the rfb event mechanism with qt's event loop.
* Call processRfbEvents() every time the qt event loop is run,
* so that it also processes and delivers rfb events and call
* shutdown() when QApplication exits to shutdown the rfb server
* before the X11 connection goes down.
*/
connect(&d->rfbProcessEventTimer, SIGNAL(timeout()), SLOT(processRfbEvents()));
connect(qApp, SIGNAL(aboutToQuit()), SLOT(shutdown()));
d->rfbProcessEventTimer.start(0);
}
void KrfbServer::processRfbEvents()
{
foreach(const QRect &r, d->fb->modifiedTiles()) {
rfbMarkRectAsModified(d->screen, r.x(), r.y(), r.right(), r.bottom());
}
rfbProcessEvents(d->screen, 100);
}
void KrfbServer::shutdown()
{
rfbShutdownServer(d->screen, true);
// framebuffer has to be deleted before X11 connection goes down
d->fb.clear();
}
void KrfbServer::enableDesktopControl(bool enable)
{
foreach (QPointer<ConnectionController> ptr, d->controllers) {
if (ptr) {
if (ptr->controlCanBeEnabled()) {
ptr->setControlEnabled(enable);
}
}
}
}
enum rfbNewClientAction KrfbServer::handleNewClient(struct _rfbClientRec * cl)
{
ConnectionController *cc = new ConnectionController(cl, this);
if (d->numClients++ == 0)
d->fb->startMonitor();
d->controllers.append(cc);
cc->setControlEnabled(KrfbConfig::allowDesktopControl());
cc->setControlCanBeEnabled(KrfbConfig::allowDesktopControl());
connect(cc, SIGNAL(sessionEstablished(QString)), SIGNAL(sessionEstablished(QString)));
connect(cc, SIGNAL(clientDisconnected(ConnectionController *)),SLOT(clientDisconnected(ConnectionController *)));
return cc->handleNewClient();
}
void KrfbServer::updateSettings()
{
enableDesktopControl(KrfbConfig::allowDesktopControl());
updatePassword();
}
void KrfbServer::updatePassword()
{
if (!d->screen) return;
QString pw = KrfbConfig::uninvitedConnectionPassword();
kDebug() << "password: " << pw << " allow " <<
KrfbConfig::allowUninvitedConnections() <<
" invitations " << InvitationManager::self()->activeInvitations() << endl;
if (pw.isEmpty() && InvitationManager::self()->activeInvitations() == 0) {
kDebug() << "no password from now on";
d->screen->authPasswdData = (void *)0;
} else {
kDebug() << "Ask for password to accept connections";
d->screen->authPasswdData = (void *)1;
}
}
bool KrfbServer::checkX11Capabilities() {
int bp1, bp2, majorv, minorv;
Bool r = XTestQueryExtension(QX11Info::display(), &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;
}
void KrfbServer::clientDisconnected(ConnectionController *cc)
{
kDebug() << "clients--: " << d->numClients;
if (!--d->numClients) {
d->fb->stopMonitor();
kDebug() << "stopMonitor: d->numClients = " << d->numClients;
}
disconnect(cc, SIGNAL(clientDisconnected(ConnectionController*)),this, SLOT(clientDisconnected(ConnectionController*)));
Q_EMIT sessionFinished();
}

59
krfbserver.h Normal file
View File

@@ -0,0 +1,59 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
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 KRFBSERVER_H
#define KRFBSERVER_H
#include <QObject>
#include <rfb/rfb.h>
class ConnectionController;
/**
This class implements the listening server for the RFB protocol.
@author Alessandro Praduroux <pradu@pradu.it>
*/
class KrfbServer : public QObject
{
Q_OBJECT
friend class KrfbServerPrivate;
public:
static KrfbServer *self();
~KrfbServer();
enum rfbNewClientAction handleNewClient(struct _rfbClientRec *cl);
bool checkX11Capabilities();
signals:
void sessionEstablished(QString);
void sessionFinished();
void desktopControlSettingChanged(bool);
public Q_SLOTS:
void startListening();
void processRfbEvents();
void shutdown();
void enableDesktopControl(bool);
void updateSettings();
void updatePassword();
void clientDisconnected(ConnectionController *);
private:
KrfbServer();
static KrfbServer *_self;
class KrfbServerP;
KrfbServerP * const d;
};
#endif

View File

@@ -1,132 +0,0 @@
# Striped down version of libvncserver's original CMakeLists.txt
project(LibVNCServer)
include(CheckFunctionExists)
include(CheckIncludeFile)
include(CheckTypeSize)
include(TestBigEndian)
include(MacroBoolTo01)
set(FULL_PACKAGE_NAME "Krfb LibVNCServer")
set(PACKAGE_VERSION "0.9.8-10-g17ce0c5")
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
macro_optional_find_package(ZLIB)
macro_log_feature(ZLIB_FOUND "ZLib" "The Zlib compression library" "http://www.zlib.net" FALSE "" "Used by the vncserver library.")
macro_optional_find_package(JPEG)
macro_log_feature(JPEG_FOUND "LibJPEG" "The JPEG library" "" FALSE "" "Used by the vncserver library")
macro_bool_to_01(ZLIB_FOUND LIBVNCSERVER_HAVE_LIBZ)
macro_bool_to_01(JPEG_FOUND LIBVNCSERVER_HAVE_LIBJPEG)
option(LIBVNCSERVER_ALLOW24BPP "Allow 24 bpp" ON)
# if(GNUTLS_FOUND)
# set(LIBVNCSERVER_WITH_CLIENT_TLS 1)
# endif(GNUTLS_FOUND)
# if(LIBGCRYPT_LIBRARIES)
# message(STATUS "Found libgcrypt: ${LIBGCRYPT_LIBRARIES}")
# set(LIBVNCSERVER_WITH_CLIENT_GCRYPT 1)
# endif(LIBGCRYPT_LIBRARIES)
check_include_file("fcntl.h" LIBVNCSERVER_HAVE_FCNTL_H)
check_include_file("netinet/in.h" LIBVNCSERVER_HAVE_NETINET_IN_H)
check_include_file("sys/socket.h" LIBVNCSERVER_HAVE_SYS_SOCKET_H)
check_include_file("sys/stat.h" LIBVNCSERVER_HAVE_SYS_STAT_H)
check_include_file("sys/time.h" LIBVNCSERVER_HAVE_SYS_TIME_H)
check_include_file("sys/types.h" LIBVNCSERVER_HAVE_SYS_TYPES_H)
check_include_file("sys/wait.h" LIBVNCSERVER_HAVE_SYS_WAIT_H)
check_include_file("unistd.h" LIBVNCSERVER_HAVE_UNISTD_H)
# headers needed for check_type_size()
check_include_file("arpa/inet.h" HAVE_ARPA_INET_H)
check_include_file("stdint.h" HAVE_STDINT_H)
check_include_file("stddef.h" HAVE_STDDEF_H)
check_include_file("sys/types.h" HAVE_SYS_TYPES_H)
check_function_exists(gettimeofday LIBVNCSERVER_HAVE_GETTIMEOFDAY)
macro_bool_to_01(CMAKE_USE_PTHREADS_INIT LIBVNCSERVER_HAVE_LIBPTHREAD)
if(LIBVNCSERVER_HAVE_SYS_SOCKET_H)
# socklen_t
list(APPEND CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h")
endif(LIBVNCSERVER_HAVE_SYS_SOCKET_H)
if(HAVE_ARPA_INET_H)
# in_addr_t
list(APPEND CMAKE_EXTRA_INCLUDE_FILES "arpa/inet.h")
endif(HAVE_ARPA_INET_H)
check_type_size(pid_t LIBVNCSERVER_PID_T)
check_type_size(size_t LIBVNCSERVER_SIZE_T)
check_type_size(socklen_t LIBVNCSERVER_SOCKLEN_T)
check_type_size(in_addr_t LIBVNCSERVER_IN_ADDR_T)
if(NOT HAVE_LIBVNCSERVER_IN_ADDR_T)
set(LIBVNCSERVER_NEED_INADDR_T 1)
endif(NOT HAVE_LIBVNCSERVER_IN_ADDR_T)
test_big_endian(LIBVNCSERVER_WORDS_BIGENDIAN)
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/libvncserver-config.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/libvncserver-config.h
)
set(LIBVNCSERVER_SOURCES
main.c
rfbserver.c
rfbregion.c
auth.c
sockets.c
stats.c
corre.c
hextile.c
rre.c
translate.c
cutpaste.c
httpd.c
cursor.c
font.c
draw.c
selbox.c
d3des.c
vncauth.c
cargs.c
minilzo.c
ultra.c
scale.c
)
if(ZLIB_FOUND)
add_definitions(-DLIBVNCSERVER_HAVE_LIBZ)
include_directories(${ZLIB_INCLUDE_DIR})
set(LIBVNCSERVER_SOURCES
${LIBVNCSERVER_SOURCES}
zlib.c
zrle.c
zrleoutstream.c
zrlepalettehelper.c
)
endif(ZLIB_FOUND)
if(JPEG_FOUND)
add_definitions(-DLIBVNCSERVER_HAVE_LIBJPEG)
include_directories(${JPEG_INCLUDE_DIR})
set(LIBVNCSERVER_SOURCES
${LIBVNCSERVER_SOURCES}
tight.c
)
endif(JPEG_FOUND)
add_library(vncserver STATIC ${LIBVNCSERVER_SOURCES})
if(WIN32)
set(ADDITIONAL_LIBS ws2_32)
endif(WIN32)
target_link_libraries(vncserver
${ADDITIONAL_LIBS}
${ZLIB_LIBRARIES}
${JPEG_LIBRARIES}
)

View File

@@ -1,375 +0,0 @@
/*
* auth.c - deal with authentication.
*
* This file implements the VNC authentication protocol when setting up an RFB
* connection.
*/
/*
* Copyright (C) 2005 Rohit Kumar, Johannes E. Schindelin
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
* 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.
*/
#include "rfb/rfb.h"
/* RFB 3.8 clients are well informed */
void rfbClientSendString(rfbClientPtr cl, const char *reason);
/*
* Handle security types
*/
static rfbSecurityHandler* securityHandlers = NULL;
/*
* This method registers a list of new security types.
* It avoids same security type getting registered multiple times.
* The order is not preserved if multiple security types are
* registered at one-go.
*/
void
rfbRegisterSecurityHandler(rfbSecurityHandler* handler)
{
rfbSecurityHandler *head = securityHandlers, *next = NULL;
if(handler == NULL)
return;
next = handler->next;
while(head != NULL) {
if(head == handler) {
rfbRegisterSecurityHandler(next);
return;
}
head = head->next;
}
handler->next = securityHandlers;
securityHandlers = handler;
rfbRegisterSecurityHandler(next);
}
/*
* This method unregisters a list of security types.
* These security types won't be available for any new
* client connection.
*/
void
rfbUnregisterSecurityHandler(rfbSecurityHandler* handler)
{
rfbSecurityHandler *cur = NULL, *pre = NULL;
if(handler == NULL)
return;
if(securityHandlers == handler) {
securityHandlers = securityHandlers->next;
rfbUnregisterSecurityHandler(handler->next);
return;
}
cur = pre = securityHandlers;
while(cur) {
if(cur == handler) {
pre->next = cur->next;
break;
}
pre = cur;
cur = cur->next;
}
rfbUnregisterSecurityHandler(handler->next);
}
/*
* Send the authentication challenge.
*/
static void
rfbVncAuthSendChallenge(rfbClientPtr cl)
{
/* 4 byte header is alreay sent. Which is rfbSecTypeVncAuth
(same as rfbVncAuth). Just send the challenge. */
rfbRandomBytes(cl->authChallenge);
if (rfbWriteExact(cl, (char *)cl->authChallenge, CHALLENGESIZE) < 0) {
rfbLogPerror("rfbAuthNewClient: write");
rfbCloseClient(cl);
return;
}
/* Dispatch client input to rfbVncAuthProcessResponse. */
cl->state = RFB_AUTHENTICATION;
}
/*
* Send the NO AUTHENTICATION. SCARR
*/
static void
rfbVncAuthNone(rfbClientPtr cl)
{
uint32_t authResult;
if (cl->protocolMajorVersion==3 && cl->protocolMinorVersion > 7) {
rfbLog("rfbProcessClientSecurityType: returning securityResult for client rfb version >= 3.8\n");
authResult = Swap32IfLE(rfbVncAuthOK);
if (rfbWriteExact(cl, (char *)&authResult, 4) < 0) {
rfbLogPerror("rfbAuthProcessClientMessage: write");
rfbCloseClient(cl);
return;
}
}
cl->state = RFB_INITIALISATION;
return;
}
/*
* Advertise the supported security types (protocol 3.7). Here before sending
* the list of security types to the client one more security type is added
* to the list if primaryType is not set to rfbSecTypeInvalid. This security
* type is the standard vnc security type which does the vnc authentication
* or it will be security type for no authentication.
* Different security types will be added by applications using this library.
*/
static rfbSecurityHandler VncSecurityHandlerVncAuth = {
rfbSecTypeVncAuth,
rfbVncAuthSendChallenge,
NULL
};
static rfbSecurityHandler VncSecurityHandlerNone = {
rfbSecTypeNone,
rfbVncAuthNone,
NULL
};
static void
rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
{
/* The size of the message is the count of security types +1,
* since the first byte is the number of types. */
int size = 1;
rfbSecurityHandler* handler;
#define MAX_SECURITY_TYPES 255
uint8_t buffer[MAX_SECURITY_TYPES+1];
/* Fill in the list of security types in the client structure. (NOTE: Not really in the client structure) */
switch (primaryType) {
case rfbSecTypeNone:
rfbRegisterSecurityHandler(&VncSecurityHandlerNone);
break;
case rfbSecTypeVncAuth:
rfbRegisterSecurityHandler(&VncSecurityHandlerVncAuth);
break;
}
for (handler = securityHandlers;
handler && size<MAX_SECURITY_TYPES; handler = handler->next) {
buffer[size] = handler->type;
size++;
}
buffer[0] = (unsigned char)size-1;
/* Send the list. */
if (rfbWriteExact(cl, (char *)buffer, size) < 0) {
rfbLogPerror("rfbSendSecurityTypeList: write");
rfbCloseClient(cl);
return;
}
/*
* if count is 0, we need to send the reason and close the connection.
*/
if(size <= 1) {
/* This means total count is Zero and so reason msg should be sent */
/* The execution should never reach here */
char* reason = "No authentication mode is registered!";
rfbClientSendString(cl, reason);
return;
}
/* Dispatch client input to rfbProcessClientSecurityType. */
cl->state = RFB_SECURITY_TYPE;
}
/*
* Tell the client what security type will be used (protocol 3.3).
*/
static void
rfbSendSecurityType(rfbClientPtr cl, int32_t securityType)
{
uint32_t value32;
/* Send the value. */
value32 = Swap32IfLE(securityType);
if (rfbWriteExact(cl, (char *)&value32, 4) < 0) {
rfbLogPerror("rfbSendSecurityType: write");
rfbCloseClient(cl);
return;
}
/* Decide what to do next. */
switch (securityType) {
case rfbSecTypeNone:
/* Dispatch client input to rfbProcessClientInitMessage. */
cl->state = RFB_INITIALISATION;
break;
case rfbSecTypeVncAuth:
/* Begin the standard VNC authentication procedure. */
rfbVncAuthSendChallenge(cl);
break;
default:
/* Impossible case (hopefully). */
rfbLogPerror("rfbSendSecurityType: assertion failed");
rfbCloseClient(cl);
}
}
/*
* rfbAuthNewClient is called right after negotiating the protocol
* version. Depending on the protocol version, we send either a code
* for authentication scheme to be used (protocol 3.3), or a list of
* possible "security types" (protocol 3.7).
*/
void
rfbAuthNewClient(rfbClientPtr cl)
{
int32_t securityType = rfbSecTypeInvalid;
if (!cl->screen->authPasswdData || cl->reverseConnection) {
/* chk if this condition is valid or not. */
securityType = rfbSecTypeNone;
} else if (cl->screen->authPasswdData) {
securityType = rfbSecTypeVncAuth;
}
if (cl->protocolMajorVersion==3 && cl->protocolMinorVersion < 7)
{
/* Make sure we use only RFB 3.3 compatible security types. */
if (securityType == rfbSecTypeInvalid) {
rfbLog("VNC authentication disabled - RFB 3.3 client rejected\n");
rfbClientConnFailed(cl, "Your viewer cannot handle required "
"authentication methods");
return;
}
rfbSendSecurityType(cl, securityType);
} else {
/* Here it's ok when securityType is set to rfbSecTypeInvalid. */
rfbSendSecurityTypeList(cl, securityType);
}
}
/*
* Read the security type chosen by the client (protocol 3.7).
*/
void
rfbProcessClientSecurityType(rfbClientPtr cl)
{
int n;
uint8_t chosenType;
rfbSecurityHandler* handler;
/* Read the security type. */
n = rfbReadExact(cl, (char *)&chosenType, 1);
if (n <= 0) {
if (n == 0)
rfbLog("rfbProcessClientSecurityType: client gone\n");
else
rfbLogPerror("rfbProcessClientSecurityType: read");
rfbCloseClient(cl);
return;
}
/* Make sure it was present in the list sent by the server. */
for (handler = securityHandlers; handler; handler = handler->next) {
if (chosenType == handler->type) {
rfbLog("rfbProcessClientSecurityType: executing handler for type %d\n", chosenType);
handler->handler(cl);
return;
}
}
rfbLog("rfbProcessClientSecurityType: wrong security type (%d) requested\n", chosenType);
rfbCloseClient(cl);
}
/*
* rfbAuthProcessClientMessage is called when the client sends its
* authentication response.
*/
void
rfbAuthProcessClientMessage(rfbClientPtr cl)
{
int n;
uint8_t response[CHALLENGESIZE];
uint32_t authResult;
if ((n = rfbReadExact(cl, (char *)response, CHALLENGESIZE)) <= 0) {
if (n != 0)
rfbLogPerror("rfbAuthProcessClientMessage: read");
rfbCloseClient(cl);
return;
}
if(!cl->screen->passwordCheck(cl,(const char*)response,CHALLENGESIZE)) {
rfbErr("rfbAuthProcessClientMessage: password check failed\n");
authResult = Swap32IfLE(rfbVncAuthFailed);
if (rfbWriteExact(cl, (char *)&authResult, 4) < 0) {
rfbLogPerror("rfbAuthProcessClientMessage: write");
}
/* support RFB 3.8 clients, they expect a reason *why* it was disconnected */
if (cl->protocolMinorVersion > 7) {
rfbClientSendString(cl, "password check failed!");
}
else
rfbCloseClient(cl);
return;
}
authResult = Swap32IfLE(rfbVncAuthOK);
if (rfbWriteExact(cl, (char *)&authResult, 4) < 0) {
rfbLogPerror("rfbAuthProcessClientMessage: write");
rfbCloseClient(cl);
return;
}
cl->state = RFB_INITIALISATION;
}

View File

@@ -1,213 +0,0 @@
/*
* This parses the command line arguments. It was seperated from main.c by
* Justin Dearing <jdeari01@longisland.poly.edu>.
*/
/*
* LibVNCServer (C) 2001 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* Original OSXvnc (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* Original Xvnc (C) 1999 AT&T Laboratories Cambridge.
* All Rights Reserved.
*
* see GPL (latest version) for full details
*/
#include "rfb/rfb.h"
extern int rfbStringToAddr(char *str, in_addr_t *iface);
void
rfbUsage(void)
{
rfbProtocolExtension* extension;
fprintf(stderr, "-rfbport port TCP port for RFB protocol\n");
fprintf(stderr, "-rfbwait time max time in ms to wait for RFB client\n");
fprintf(stderr, "-rfbauth passwd-file use authentication on RFB protocol\n"
" (use 'storepasswd' to create a password file)\n");
fprintf(stderr, "-rfbversion 3.x Set the version of the RFB we choose to advertise\n");
fprintf(stderr, "-permitfiletransfer permit file transfer support\n");
fprintf(stderr, "-passwd plain-password use authentication \n"
" (use plain-password as password, USE AT YOUR RISK)\n");
fprintf(stderr, "-deferupdate time time in ms to defer updates "
"(default 40)\n");
fprintf(stderr, "-deferptrupdate time time in ms to defer pointer updates"
" (default none)\n");
fprintf(stderr, "-desktop name VNC desktop name (default \"LibVNCServer\")\n");
fprintf(stderr, "-alwaysshared always treat new clients as shared\n");
fprintf(stderr, "-nevershared never treat new clients as shared\n");
fprintf(stderr, "-dontdisconnect don't disconnect existing clients when a "
"new non-shared\n"
" connection comes in (refuse new connection "
"instead)\n");
fprintf(stderr, "-httpdir dir-path enable http server using dir-path home\n");
fprintf(stderr, "-httpport portnum use portnum for http connection\n");
fprintf(stderr, "-enablehttpproxy enable http proxy support\n");
fprintf(stderr, "-progressive height enable progressive updating for slow links\n");
fprintf(stderr, "-listen ipaddr listen for connections only on network interface with\n");
fprintf(stderr, " addr ipaddr. '-listen localhost' and hostname work too.\n");
for(extension=rfbGetExtensionIterator();extension;extension=extension->next)
if(extension->usage)
extension->usage();
rfbReleaseExtensionIterator();
}
/* purges COUNT arguments from ARGV at POSITION and decrements ARGC.
POSITION points to the first non purged argument afterwards. */
void rfbPurgeArguments(int* argc,int* position,int count,char *argv[])
{
int amount=(*argc)-(*position)-count;
if(amount)
memmove(argv+(*position),argv+(*position)+count,sizeof(char*)*amount);
(*argc)-=count;
}
rfbBool
rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[])
{
int i,i1;
if(!argc) return TRUE;
for (i = i1 = 1; i < *argc;) {
if (strcmp(argv[i], "-help") == 0) {
rfbUsage();
return FALSE;
} else if (strcmp(argv[i], "-rfbport") == 0) { /* -rfbport port */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
rfbScreen->port = atoi(argv[++i]);
} else if (strcmp(argv[i], "-rfbwait") == 0) { /* -rfbwait ms */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
rfbScreen->maxClientWait = atoi(argv[++i]);
} else if (strcmp(argv[i], "-rfbauth") == 0) { /* -rfbauth passwd-file */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
rfbScreen->authPasswdData = argv[++i];
} else if (strcmp(argv[i], "-permitfiletransfer") == 0) { /* -permitfiletransfer */
rfbScreen->permitFileTransfer = TRUE;
} else if (strcmp(argv[i], "-rfbversion") == 0) { /* -rfbversion 3.6 */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
sscanf(argv[++i],"%d.%d", &rfbScreen->protocolMajorVersion, &rfbScreen->protocolMinorVersion);
} else if (strcmp(argv[i], "-passwd") == 0) { /* -passwd password */
char **passwds = malloc(sizeof(char**)*2);
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
passwds[0] = argv[++i];
passwds[1] = NULL;
rfbScreen->authPasswdData = (void*)passwds;
rfbScreen->passwordCheck = rfbCheckPasswordByList;
} else if (strcmp(argv[i], "-deferupdate") == 0) { /* -deferupdate milliseconds */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
rfbScreen->deferUpdateTime = atoi(argv[++i]);
} else if (strcmp(argv[i], "-deferptrupdate") == 0) { /* -deferptrupdate milliseconds */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
rfbScreen->deferPtrUpdateTime = atoi(argv[++i]);
} else if (strcmp(argv[i], "-desktop") == 0) { /* -desktop desktop-name */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
rfbScreen->desktopName = argv[++i];
} else if (strcmp(argv[i], "-alwaysshared") == 0) {
rfbScreen->alwaysShared = TRUE;
} else if (strcmp(argv[i], "-nevershared") == 0) {
rfbScreen->neverShared = TRUE;
} else if (strcmp(argv[i], "-dontdisconnect") == 0) {
rfbScreen->dontDisconnect = TRUE;
} else if (strcmp(argv[i], "-httpdir") == 0) { /* -httpdir directory-path */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
rfbScreen->httpDir = argv[++i];
} else if (strcmp(argv[i], "-httpport") == 0) { /* -httpport portnum */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
rfbScreen->httpPort = atoi(argv[++i]);
} else if (strcmp(argv[i], "-enablehttpproxy") == 0) {
rfbScreen->httpEnableProxyConnect = TRUE;
} else if (strcmp(argv[i], "-progressive") == 0) { /* -httpport portnum */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
rfbScreen->progressiveSliceHeight = atoi(argv[++i]);
} else if (strcmp(argv[i], "-listen") == 0) { /* -listen ipaddr */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
if (! rfbStringToAddr(argv[++i], &(rfbScreen->listenInterface))) {
return FALSE;
}
} else {
rfbProtocolExtension* extension;
int handled=0;
for(extension=rfbGetExtensionIterator();handled==0 && extension;
extension=extension->next)
if(extension->processArgument)
handled = extension->processArgument(*argc - i, argv + i);
rfbReleaseExtensionIterator();
if(handled==0) {
i++;
i1=i;
continue;
}
i+=handled-1;
}
/* we just remove the processed arguments from the list */
rfbPurgeArguments(argc,&i1,i-i1+1,argv);
i=i1;
}
return TRUE;
}
rfbBool
rfbProcessSizeArguments(int* width,int* height,int* bpp,int* argc, char *argv[])
{
int i,i1;
if(!argc) return TRUE;
for (i = i1 = 1; i < *argc-1;) {
if (strcmp(argv[i], "-bpp") == 0) {
*bpp = atoi(argv[++i]);
} else if (strcmp(argv[i], "-width") == 0) {
*width = atoi(argv[++i]);
} else if (strcmp(argv[i], "-height") == 0) {
*height = atoi(argv[++i]);
} else {
i++;
i1=i;
continue;
}
rfbPurgeArguments(argc,&i1,i-i1,argv);
i=i1;
}
return TRUE;
}

View File

@@ -1,342 +0,0 @@
/*
* corre.c
*
* Routines to implement Compact Rise-and-Run-length Encoding (CoRRE). This
* code is based on krw's original javatel rfbserver.
*/
/*
* Copyright (C) 2002 RealVNC Ltd.
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
* 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.
*/
#include "rfb/rfb.h"
/*
* cl->beforeEncBuf contains pixel data in the client's format.
* cl->afterEncBuf contains the RRE encoded version. If the RRE encoded version is
* larger than the raw data or if it exceeds cl->afterEncBufSize then
* raw encoding is used instead.
*/
static int subrectEncode8(rfbClientPtr cl, uint8_t *data, int w, int h);
static int subrectEncode16(rfbClientPtr cl, uint16_t *data, int w, int h);
static int subrectEncode32(rfbClientPtr cl, uint32_t *data, int w, int h);
static uint32_t getBgColour(char *data, int size, int bpp);
static rfbBool rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl, int x, int y,
int w, int h);
/*
* rfbSendRectEncodingCoRRE - send an arbitrary size rectangle using CoRRE
* encoding.
*/
rfbBool
rfbSendRectEncodingCoRRE(rfbClientPtr cl,
int x,
int y,
int w,
int h)
{
if (h > cl->correMaxHeight) {
return (rfbSendRectEncodingCoRRE(cl, x, y, w, cl->correMaxHeight) &&
rfbSendRectEncodingCoRRE(cl, x, y + cl->correMaxHeight, w,
h - cl->correMaxHeight));
}
if (w > cl->correMaxWidth) {
return (rfbSendRectEncodingCoRRE(cl, x, y, cl->correMaxWidth, h) &&
rfbSendRectEncodingCoRRE(cl, x + cl->correMaxWidth, y,
w - cl->correMaxWidth, h));
}
rfbSendSmallRectEncodingCoRRE(cl, x, y, w, h);
return TRUE;
}
/*
* rfbSendSmallRectEncodingCoRRE - send a small (guaranteed < 256x256)
* rectangle using CoRRE encoding.
*/
static rfbBool
rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl,
int x,
int y,
int w,
int h)
{
rfbFramebufferUpdateRectHeader rect;
rfbRREHeader hdr;
int nSubrects;
int i;
char *fbptr = (cl->scaledScreen->frameBuffer + (cl->scaledScreen->paddedWidthInBytes * y)
+ (x * (cl->scaledScreen->bitsPerPixel / 8)));
int maxRawSize = (cl->scaledScreen->width * cl->scaledScreen->height
* (cl->format.bitsPerPixel / 8));
if (cl->beforeEncBufSize < maxRawSize) {
cl->beforeEncBufSize = maxRawSize;
if (cl->beforeEncBuf == NULL)
cl->beforeEncBuf = (char *)malloc(cl->beforeEncBufSize);
else
cl->beforeEncBuf = (char *)realloc(cl->beforeEncBuf, cl->beforeEncBufSize);
}
if (cl->afterEncBufSize < maxRawSize) {
cl->afterEncBufSize = maxRawSize;
if (cl->afterEncBuf == NULL)
cl->afterEncBuf = (char *)malloc(cl->afterEncBufSize);
else
cl->afterEncBuf = (char *)realloc(cl->afterEncBuf, cl->afterEncBufSize);
}
(*cl->translateFn)(cl->translateLookupTable,&(cl->screen->serverFormat),
&cl->format, fbptr, cl->beforeEncBuf,
cl->scaledScreen->paddedWidthInBytes, w, h);
switch (cl->format.bitsPerPixel) {
case 8:
nSubrects = subrectEncode8(cl, (uint8_t *)cl->beforeEncBuf, w, h);
break;
case 16:
nSubrects = subrectEncode16(cl, (uint16_t *)cl->beforeEncBuf, w, h);
break;
case 32:
nSubrects = subrectEncode32(cl, (uint32_t *)cl->beforeEncBuf, w, h);
break;
default:
rfbLog("getBgColour: bpp %d?\n",cl->format.bitsPerPixel);
return FALSE;
}
if (nSubrects < 0) {
/* RRE encoding was too large, use raw */
return rfbSendRectEncodingRaw(cl, x, y, w, h);
}
rfbStatRecordEncodingSent(cl,rfbEncodingCoRRE,
sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader + cl->afterEncBufLen,
sz_rfbFramebufferUpdateRectHeader + w * h * (cl->format.bitsPerPixel / 8));
if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader
> UPDATE_BUF_SIZE)
{
if (!rfbSendUpdateBuf(cl))
return FALSE;
}
rect.r.x = Swap16IfLE(x);
rect.r.y = Swap16IfLE(y);
rect.r.w = Swap16IfLE(w);
rect.r.h = Swap16IfLE(h);
rect.encoding = Swap32IfLE(rfbEncodingCoRRE);
memcpy(&cl->updateBuf[cl->ublen], (char *)&rect,
sz_rfbFramebufferUpdateRectHeader);
cl->ublen += sz_rfbFramebufferUpdateRectHeader;
hdr.nSubrects = Swap32IfLE(nSubrects);
memcpy(&cl->updateBuf[cl->ublen], (char *)&hdr, sz_rfbRREHeader);
cl->ublen += sz_rfbRREHeader;
for (i = 0; i < cl->afterEncBufLen;) {
int bytesToCopy = UPDATE_BUF_SIZE - cl->ublen;
if (i + bytesToCopy > cl->afterEncBufLen) {
bytesToCopy = cl->afterEncBufLen - i;
}
memcpy(&cl->updateBuf[cl->ublen], &cl->afterEncBuf[i], bytesToCopy);
cl->ublen += bytesToCopy;
i += bytesToCopy;
if (cl->ublen == UPDATE_BUF_SIZE) {
if (!rfbSendUpdateBuf(cl))
return FALSE;
}
}
return TRUE;
}
/*
* subrectEncode() encodes the given multicoloured rectangle as a background
* colour overwritten by single-coloured rectangles. It returns the number
* of subrectangles in the encoded buffer, or -1 if subrect encoding won't
* fit in the buffer. It puts the encoded rectangles in cl->afterEncBuf. The
* single-colour rectangle partition is not optimal, but does find the biggest
* horizontal or vertical rectangle top-left anchored to each consecutive
* coordinate position.
*
* The coding scheme is simply [<bgcolour><subrect><subrect>...] where each
* <subrect> is [<colour><x><y><w><h>].
*/
#define DEFINE_SUBRECT_ENCODE(bpp) \
static int \
subrectEncode##bpp(rfbClientPtr client, uint##bpp##_t *data, int w, int h) { \
uint##bpp##_t cl; \
rfbCoRRERectangle subrect; \
int x,y; \
int i,j; \
int hx=0,hy,vx=0,vy; \
int hyflag; \
uint##bpp##_t *seg; \
uint##bpp##_t *line; \
int hw,hh,vw,vh; \
int thex,they,thew,theh; \
int numsubs = 0; \
int newLen; \
uint##bpp##_t bg = (uint##bpp##_t)getBgColour((char*)data,w*h,bpp); \
\
*((uint##bpp##_t*)client->afterEncBuf) = bg; \
\
client->afterEncBufLen = (bpp/8); \
\
for (y=0; y<h; y++) { \
line = data+(y*w); \
for (x=0; x<w; x++) { \
if (line[x] != bg) { \
cl = line[x]; \
hy = y-1; \
hyflag = 1; \
for (j=y; j<h; j++) { \
seg = data+(j*w); \
if (seg[x] != cl) {break;} \
i = x; \
while ((seg[i] == cl) && (i < w)) i += 1; \
i -= 1; \
if (j == y) vx = hx = i; \
if (i < vx) vx = i; \
if ((hyflag > 0) && (i >= hx)) {hy += 1;} else {hyflag = 0;} \
} \
vy = j-1; \
\
/* We now have two possible subrects: (x,y,hx,hy) and (x,y,vx,vy) \
* We'll choose the bigger of the two. \
*/ \
hw = hx-x+1; \
hh = hy-y+1; \
vw = vx-x+1; \
vh = vy-y+1; \
\
thex = x; \
they = y; \
\
if ((hw*hh) > (vw*vh)) { \
thew = hw; \
theh = hh; \
} else { \
thew = vw; \
theh = vh; \
} \
\
subrect.x = thex; \
subrect.y = they; \
subrect.w = thew; \
subrect.h = theh; \
\
newLen = client->afterEncBufLen + (bpp/8) + sz_rfbCoRRERectangle; \
if ((newLen > (w * h * (bpp/8))) || (newLen > client->afterEncBufSize)) \
return -1; \
\
numsubs += 1; \
*((uint##bpp##_t*)(client->afterEncBuf + client->afterEncBufLen)) = cl; \
client->afterEncBufLen += (bpp/8); \
memcpy(&client->afterEncBuf[client->afterEncBufLen],&subrect,sz_rfbCoRRERectangle); \
client->afterEncBufLen += sz_rfbCoRRERectangle; \
\
/* \
* Now mark the subrect as done. \
*/ \
for (j=they; j < (they+theh); j++) { \
for (i=thex; i < (thex+thew); i++) { \
data[j*w+i] = bg; \
} \
} \
} \
} \
} \
\
return numsubs; \
}
DEFINE_SUBRECT_ENCODE(8)
DEFINE_SUBRECT_ENCODE(16)
DEFINE_SUBRECT_ENCODE(32)
/*
* getBgColour() gets the most prevalent colour in a byte array.
*/
static uint32_t
getBgColour(char *data, int size, int bpp)
{
#define NUMCLRS 256
static int counts[NUMCLRS];
int i,j,k;
int maxcount = 0;
uint8_t maxclr = 0;
if (bpp != 8) {
if (bpp == 16) {
return ((uint16_t *)data)[0];
} else if (bpp == 32) {
return ((uint32_t *)data)[0];
} else {
rfbLog("getBgColour: bpp %d?\n",bpp);
return 0;
}
}
for (i=0; i<NUMCLRS; i++) {
counts[i] = 0;
}
for (j=0; j<size; j++) {
k = (int)(((uint8_t *)data)[j]);
if (k >= NUMCLRS) {
rfbLog("getBgColour: unusual colour = %d\n", k);
return 0;
}
counts[k] += 1;
if (counts[k] > maxcount) {
maxcount = counts[k];
maxclr = ((uint8_t *)data)[j];
}
}
return maxclr;
}

Some files were not shown because too many files have changed in this diff Show More