diff --git a/CMakeLists.txt b/CMakeLists.txt index a85cbd2..5b94706 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,99 +1,105 @@ cmake_minimum_required(VERSION 3.0) # KDE Application Version, managed by release script -set (KDE_APPLICATIONS_VERSION_MAJOR "18") +set (KDE_APPLICATIONS_VERSION_MAJOR "19") set (KDE_APPLICATIONS_VERSION_MINOR "07") set (KDE_APPLICATIONS_VERSION_MICRO "70") set (KDE_APPLICATIONS_VERSION "${KDE_APPLICATIONS_VERSION_MAJOR}.${KDE_APPLICATIONS_VERSION_MINOR}.${KDE_APPLICATIONS_VERSION_MICRO}") project(krfb VERSION ${KDE_APPLICATIONS_VERSION}) set(QT_MIN_VERSION 5.6.0) set(KF5_MIN_VERSION 5.31.0) -find_package(Qt5 REQUIRED COMPONENTS Core DBus Widgets X11Extras) - find_package(ECM ${KF5_MIN_VERSION} NO_MODULE REQUIRED) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" ${ECM_MODULE_PATH}) include(KDEInstallDirs) include(KDECMakeSettings) include(KDECompilerSettings NO_POLICY_SCOPE) include(ECMInstallIcons) include(ECMAddAppIcon) include(ECMSetupVersion) include(FeatureSummary) include(CheckIncludeFile) check_include_file("linux/input.h" HAVE_LINUX_INPUT_H) -ecm_setup_version(PROJECT - VARIABLE_PREFIX KRFB - VERSION_HEADER "krfb_version.h") +find_package(Qt5 ${QT_MIN_VERSION} REQUIRED COMPONENTS Core DBus Widgets X11Extras) -find_package(KF5 REQUIRED COMPONENTS +find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS I18n Completion Config CoreAddons Crash DBusAddons DNSSD DocTools Notifications Wallet WidgetsAddons XmlGui ) find_package(X11 REQUIRED) find_package(XCB REQUIRED COMPONENTS XCB RENDER SHAPE XFIXES DAMAGE SHM IMAGE ) if(WIN32) set(CMAKE_REQUIRED_LIBRARIES ${KDEWIN32_LIBRARIES}) set(CMAKE_REQUIRED_INCLUDES ${KDEWIN32_INCLUDES}) endif(WIN32) -add_definitions(${QT_DEFINITIONS} ${QT_QTDBUS_DEFINITIONS}) -add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS) -include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ) - -set(CMAKE_MODULE_PATH - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" - ${CMAKE_MODULE_PATH} +add_definitions( + -DQT_DEPRECATED_WARNINGS + -DQT_DISABLE_DEPRECATED_BEFORE=0x050600 + -DQT_USE_QSTRINGBUILDER + -DQT_NO_CAST_TO_ASCII + -DQT_NO_CAST_FROM_ASCII + -DQT_NO_CAST_FROM_BYTEARRAY + -DQT_STRICT_ITERATORS + -DQT_NO_URL_CAST_FROM_STRING + -DQT_NO_SIGNALS_SLOTS_KEYWORDS + -DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT ) +include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ) + find_package(LibVNCServer REQUIRED) find_package(PipeWire) set_package_properties(PipeWire PROPERTIES TYPE OPTIONAL PURPOSE "Required for pipewire screencast plugin" ) +ecm_setup_version(PROJECT + VARIABLE_PREFIX KRFB + VERSION_HEADER "krfb_version.h") + include_directories ("${CMAKE_CURRENT_BINARY_DIR}/krfb" "${CMAKE_CURRENT_SOURCE_DIR}/krfb" "${CMAKE_CURRENT_SOURCE_DIR}/krfb/ui" ) if(Q_WS_X11) if(NOT X11_XTest_FOUND) - message(FATAL_ERROR "krfb requires the libXtst (http://xorg.freedesktop.org) to be built") + message(FATAL_ERROR "krfb requires the libXtst (https://xorg.freedesktop.org) to be built") endif(NOT X11_XTest_FOUND) endif(Q_WS_X11) add_subdirectory(krfb) add_subdirectory(framebuffers) add_subdirectory(doc) add_subdirectory(icons) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/cmake/modules/FindLibVNCServer.cmake b/cmake/modules/FindLibVNCServer.cmake index 503e135..715da96 100644 --- a/cmake/modules/FindLibVNCServer.cmake +++ b/cmake/modules/FindLibVNCServer.cmake @@ -1,41 +1,41 @@ # cmake macro to test LIBVNCSERVER LIB # Copyright (c) 2006, Alessandro Praduroux # Copyright (c) 2007, Urs Wolfer # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. INCLUDE(CheckStructHasMember) IF (LIBVNCSERVER_INCLUDE_DIR AND LIBVNCSERVER_LIBRARIES) # Already in cache, be silent SET(LIBVNCSERVER_FIND_QUIETLY TRUE) ENDIF (LIBVNCSERVER_INCLUDE_DIR AND LIBVNCSERVER_LIBRARIES) FIND_PATH(LIBVNCSERVER_INCLUDE_DIR rfb/rfb.h) FIND_LIBRARY(LIBVNCSERVER_LIBRARIES NAMES vncserver libvncserver) # libvncserver and libvncclient are in the same package, so it does # not make sense to add a new cmake script for finding libvncclient. # instead just find the libvncclient also in this file. FIND_PATH(LIBVNCCLIENT_INCLUDE_DIR rfb/rfbclient.h) FIND_LIBRARY(LIBVNCCLIENT_LIBRARIES NAMES vncclient libvncclient) IF (LIBVNCSERVER_INCLUDE_DIR AND LIBVNCSERVER_LIBRARIES) SET(CMAKE_REQUIRED_INCLUDES "${LIBVNCSERVER_INCLUDE_DIR}" "${CMAKE_REQUIRED_INCLUDES}") CHECK_STRUCT_HAS_MEMBER("struct _rfbClient" GotXCutText rfb/rfbclient.h LIBVNCSERVER_FOUND) ENDIF (LIBVNCSERVER_INCLUDE_DIR AND LIBVNCSERVER_LIBRARIES) IF (LIBVNCSERVER_FOUND) IF (NOT LIBVNCSERVER_FIND_QUIETLY) MESSAGE(STATUS "Found LibVNCServer: ${LIBVNCSERVER_LIBRARIES}") ENDIF (NOT LIBVNCSERVER_FIND_QUIETLY) ELSE (LIBVNCSERVER_FOUND) IF (LIBVNCSERVER_FIND_REQUIRED) MESSAGE(FATAL_ERROR "Could NOT find acceptable version of LibVNCServer (version 0.9 or later required).") ENDIF (LIBVNCSERVER_FIND_REQUIRED) ENDIF (LIBVNCSERVER_FOUND) -MARK_AS_ADVANCED(LIBVNCSERVER_INCLUDE_DIR LIBVNCSERVER_LIBRARIES) \ No newline at end of file +MARK_AS_ADVANCED(LIBVNCSERVER_INCLUDE_DIR LIBVNCSERVER_LIBRARIES) diff --git a/doc/index.docbook b/doc/index.docbook index 7325663..0ca7f39 100644 --- a/doc/index.docbook +++ b/doc/index.docbook @@ -1,399 +1,399 @@ ]> The &krfb; Handbook &Brad.Hards; &Brad.Hards.mail; 2003 &Brad.Hards; &FDLNotice; 2016-07-25 5.0 (Applications 16.08) &krfb; is a server application that allows you to share your current session with a user on another machine, who can use a VNC client to view or even control the desktop. KDE kdenetwork krfb VNC RFB krdc Desktop Sharing Remote Control Remote Assistance Remote Desktop Introduction &krfb; is a server application that allows you to share your current session with a user on another machine, who can use a VNC client to view or even control the desktop. You would typically use &krfb; with the &kde; VNC client, which is &krdc;, since it closely matches the special features of &krfb;. &krfb; doesn't require you to start a new X session - it can share the current session. This makes it very useful when you want someone to help you perform a task. Please report any problems or feature requests to the &kde; mailing lists or file a bug at http://bugs.kde.org. +url="https://bugs.kde.org">https://bugs.kde.org. The Remote Frame Buffer protocol This chapter provides a brief description of the Remote Frame Buffer protocol used by &krfb; and by other compatible systems. If you are already familiar with Remote Frame Buffer, you can safely skip this chapter. The high level implementation of a system using the Remote Frame Buffer protocol is known as Virtual Network Computer, or more often just as VNC. Remote Frame Buffer (or RFB for short) is a simple protocol for remote access to graphical user interfaces. It works at the frame-buffer level, which roughly corresponds to the rendered screen image, which means that it can be applied to all windowing systems (including X11, &MacOS; and &Microsoft; &Windows;). Remote Frame Buffer applications exist for many platforms, and can often be freely re-distributed. In the Remote Frame Buffer protocol, the application that runs on the machine where the user sits (containing the display, keyboard and pointer) is called the client. The application that runs on the machine where the framebuffer is located (which is running the windowing system and applications that the user is remotely controlling) is called the server. &krfb; is the &kde; server for the Remote Frame Buffer protocol. &krdc; is the &kde; client for the Remote Frame Buffer protocol. It takes a reasonable amount of network traffic to send an image of the framebuffer, so Remote Frame Buffer works best over high bandwidth links, such as a local area network. It is still possible to use &krfb; over other links, but performance is unlikely to be as good. Using &krfb; &krfb; Main Window It is very easy to use &krfb; - it has a simple interface, as shown in the screenshot below. Here's a screenshot of &krfb; &krfb; main window When you want to allow someone to access your desktop, you have to enable the checkbox Enable Desktop Sharing, which will start the server. Connection Details The Address contains the address of your computer and the port number, separated by a colon. The address is just a hint - you can use any address that can reach your computer. &krfb; tries to guess your address from your network configuration, but does not always succeed in doing so. If your computer is behind a firewall it may have a different address or be unreachable for other computers. You can change the port on the Network page in the configuration dialog. The next field is prefilled with an automatically generated password. Click in the icon at the right of the field to change the password. Unattended Access Any remote user with the desktop sharing password will have to be authenticated. If unattended access is activated, and the remote user provides the password for unattended mode, desktop sharing access will be granted without explicit confirmation. By default the password for this mode is empty, to change that click on the button and enter a password. If unattended access is allowed, then you should probably specify a password. If the machine is a server and you are using &krfb; for remote administration, you probably want to use unattended access. Transfer Login Information &krfb; has no invitation feature any more as in previous versions. So you have to transfer the login information yourself using email or a personal invitation. If you cannot encrypt the email (or otherwise secure the link), sending a password by email is a very serious security risk, since anyone can read the password and address from the email as it passes over the network. This means that they can potentially take control of your machine. If you cannot encrypt the email message, it may be better to use a personal invitation, telephone the person you are giving access to, verify the identity of that person, and provide the required information that way. &krfb; uses the normal RFB password system, which does not transfer your password in the clear across the network. Instead, it uses a challenge-response system. This is reasonably secure, as long as the password is securely guarded. Quit &krfb; If you close the &krfb; main window by clicking on the window close icon or using the shortcut &Alt;F4 the server keeps running, which is indicated by an icon in the system tray. To stop &krfb; either use FileQuit in the main window or right click on the icon in the system tray and select Quit. Configuring &krfb; In addition to the main &krfb; interface shown and described above, you can also control &krfb; using the Configure... on the &krfb; main window. The &krfb; configuration has two pages, as shown in the screenshot below: The Network page allows control over the port that &krfb; uses, as shown below. &krfb; Configuration (Network page) &krfb; Configuration (Network page) The Announce service on the local network checkbox controls whether &krfb; announces the service over the local network using Service Location Protocol. This is normally a good idea, but only works really well with a Service Location Protocol aware client, such as &krdc;. If you select the Use default port checkbox, then &krfb; will locate a suitable port. If you deselect 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 the correct port. The Security page allows you to configure whether the person connecting to the &krfb; server can control the desktop, or only view. &krfb; Configuration (Security page) &krfb; Configuration (Security page) Connecting to &krfb; When someone connects to &krfb; on your machine, you will get a pop-up notification that looks like the following screenshot, unless you are accepting unattended access without confirmation. &krfb; Connection Window &krfb; Connection Window If you Accept Connection, the client can proceed to authenticate, which requires the correct password for a login. If you Refuse Connection, then the attempt to connect will be terminated. The Allow remote user to control keyboard and mouse check box determines whether this client can only observe, or can take control of your machine. Credits and License &krfb; Program copyright 2002 Tim Jansen tim@tjansen.de Contributors: Ian Reinhart Geiser geiseri@kde.org Documentation Copyright © 2003 &Brad.Hards; &Brad.Hards.mail; &underFDL; &underGPL; &documentation.index; diff --git a/framebuffers/qt/krfb_framebuffer_qt.desktop b/framebuffers/qt/krfb_framebuffer_qt.desktop deleted file mode 100644 index 3f93e16..0000000 --- a/framebuffers/qt/krfb_framebuffer_qt.desktop +++ /dev/null @@ -1,109 +0,0 @@ -[Desktop Entry] -Encoding=UTF-8 -Comment=Qt based Framebuffer for KRfb. -Comment[ast]=Búfer de cuadros basáu en Qt pa KRfb. -Comment[bg]=Основан на Qt фреймбуфер за KRfb. -Comment[bs]=Kadrobafer za KRfb na osnovu Qt. -Comment[ca]=«Framebuffer» basat en les Qt per al KRfb. -Comment[ca@valencia]=«Framebuffer» basat en les 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[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[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[id]=Framebuffer berbasiskan Qt untuk KRfb. -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[ru]=Буфер экрана для KRfb на базе Qt. -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]=Кадробафер за КРФБ на основу КуТ‑у -Comment[sr@ijekavian]=Кадробафер за КРФБ на основу КуТ‑у -Comment[sr@ijekavianlatin]=Kadrobafer za KRFB na osnovu Qt‑u -Comment[sr@latin]=Kadrobafer za KRFB na osnovu Qt‑u -Comment[sv]=Qt-baserad rambuffert för Krfb. -Comment[tr]=KRfb için Qt temelli Çerçeve tamponu. -Comment[uk]=Заснований на Qt буфер кадрів для KRfb. -Comment[x-test]=xxQt based Framebuffer for KRfb.xx -Comment[zh_CN]=基于 Qt 的 KRfb 帧缓冲机制 -Comment[zh_TW]=KRfb 的 Qt-based Framebuffer -Name=Qt Framebuffer for KRfb -Name[ast]=Búfer de cuadros Qt pa KRfb -Name[bg]=Qt фреймбуфер за KRfb -Name[bs]=Qt-ov kadrobafer za KRFB -Name[ca]=«Framebuffer» de les Qt per al KRfb. -Name[ca@valencia]=«Framebuffer» de les 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[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[id]=Qt Framebuffer untuk KRfb -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[ru]=Буфер экрана Qt для KRfb -Name[si]=KRfb සඳහා වන Qt රාමුබෆරය -Name[sk]=Qt Framebuffer pre KRfb -Name[sl]=Slikovni medpomnilnik Qt za KRFB -Name[sr]=КуТ‑ов кадробафер за КРФБ -Name[sr@ijekavian]=КуТ‑ов кадробафер за КРФБ -Name[sr@ijekavianlatin]=Qt‑ov kadrobafer za KRFB -Name[sr@latin]=Qt‑ov kadrobafer za KRFB -Name[sv]=Qt-rambuffert för Krfb -Name[tr]=KRfb için Qt Çerçeve tamponu -Name[uk]=Буфер кадрів на Qt для KRfb -Name[x-test]=xxQt Framebuffer for KRfbxx -Name[zh_CN]=KRfb 的 Qt 帧缓冲机制 -Name[zh_TW]=Krfb 的 Qt Framebuffer -Type=Service -ServiceTypes=krfb/framebuffer - -X-KDE-Library=krfb_framebuffer_qt -X-KDE-PluginInfo-Name=qt -X-KDE-PluginInfo-Version=0.1 -X-KDE-PluginInfo-Website=http://www.kde.org -X-KDE-PluginInfo-License=GPL -X-KDE-PluginInfo-EnabledByDefault=true diff --git a/framebuffers/qt/krfb_framebuffer_qt.json b/framebuffers/qt/krfb_framebuffer_qt.json index 2236820..feedcd5 100644 --- a/framebuffers/qt/krfb_framebuffer_qt.json +++ b/framebuffers/qt/krfb_framebuffer_qt.json @@ -1,83 +1,82 @@ { - "Encoding": "UTF-8", "KPlugin": { "Description": "Qt based Framebuffer for KRfb.", - "Description[ast]": "Búfer de cuadros basáu en Qt pa KRfb.", "Description[ca@valencia]": "«Framebuffer» basat en les Qt per al KRfb.", "Description[ca]": "«Framebuffer» basat en les Qt per al KRfb.", "Description[cs]": "Framebuffer založený na Qt pro KRfb.", "Description[da]": "Qt-baseret framebuffer til KRfb.", "Description[de]": "Qt-basierter Framebuffer für KRfb", "Description[el]": "Μνήμη ανανέωσης βίντεο με βάση τhn Qt για το KRfb.", + "Description[en_GB]": "Qt based Framebuffer for KRfb.", "Description[es]": "Framebuffer basado en Qt para KRfb.", "Description[et]": "KRfb Qt põhine kaadripuhver", "Description[fi]": "QT-perustainen Kehyspuskuri KRfb:lle", "Description[fr]": "Tampon d'images utilisant Qt pour KRfb.", "Description[gl]": "Framebuffer baseado en Qt para KRfb.", "Description[ia]": "Framebuffer basate sur Qt per KRfb", "Description[id]": "Framebuffer berbasiskan Qt untuk KRfb.", "Description[it]": "Framebuffer basato su Qt per KRfb.", "Description[ko]": "KRfb용 Qt 기반 프레임버퍼입니다.", "Description[nl]": "Op Qt gebaseerd framebuffer voor KRfb.", "Description[nn]": "Qt-basert biletbuffer for KRfb.", "Description[pl]": "Bufor ramki na podstawie Qt dla KRfb.", "Description[pt]": "'Framebuffer' baseado no Qt para o KRfb.", "Description[pt_BR]": "Framebuffer baseado no Qt para o KRfb.", "Description[ru]": "Буфер кадров для KRfb на базе Qt", "Description[sk]": "Framebuffer založený na Qt pre KRfb.", "Description[sl]": "Slikovni medpomnilnik za KRfb, ki temelji na Qt", "Description[sr@ijekavian]": "Кадробафер за КРФБ на основу КуТ‑у", "Description[sr@ijekavianlatin]": "Kadrobafer za KRFB na osnovu Qt‑u", "Description[sr@latin]": "Kadrobafer za KRFB na osnovu Qt‑u", "Description[sr]": "Кадробафер за КРФБ на основу КуТ‑у", "Description[sv]": "X11-rambuffert för Krfb.", "Description[tr]": "KRfb için Qt tabanlı Çerçeve tamponu.", "Description[uk]": "Заснований на Qt буфер кадрів для KRfb.", "Description[x-test]": "xxQt based Framebuffer for KRfb.xx", "Description[zh_CN]": "KRfb 的基于 Qt 的帧缓冲。", "Description[zh_TW]": "KRfb 的 Qt-based Framebuffer", "EnabledByDefault": true, "Id": "qt", "License": "GPL", "Name": "Qt Framebuffer for KRfb", - "Name[ast]": "Búfer de cuadros Qt pa KRfb", "Name[ca@valencia]": "«Framebuffer» de les Qt per al KRfb.", "Name[ca]": "«Framebuffer» de les 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 για το KRfb", + "Name[en_GB]": "Qt Framebuffer for KRfb", "Name[es]": "Framebuffer de Qt para KRfb", "Name[et]": "KRfb Qt kaadripuhver", "Name[fi]": "QT-kehyspuskuri KRfb:lle", "Name[fr]": "Tampon d'images Qt pour KRfb", "Name[gl]": "Framebuffer de Qt para KRfb", "Name[ia]": "Framebuffer Qt per KRfb", "Name[id]": "Qt Framebuffer untuk KRfb", "Name[it]": "Framebuffer Qt per KRfb", "Name[ko]": "KRfb용 Qt 프레임버퍼", "Name[nl]": "Qt-framebuffer voor KRfb", "Name[nn]": "Qt-biletbuffer 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[ru]": "Буфер кадров Qt для KRfb", "Name[sk]": "Qt Framebuffer pre KRfb", "Name[sl]": "Slikovni medpomnilnik Qt za KRfb", "Name[sr@ijekavian]": "КуТ‑ов кадробафер за КРФБ", "Name[sr@ijekavianlatin]": "Qt‑ov kadrobafer za KRFB", "Name[sr@latin]": "Qt‑ov kadrobafer za KRFB", "Name[sr]": "КуТ‑ов кадробафер за КРФБ", "Name[sv]": "X11-rambuffert för Krfb", "Name[tr]": "KRfb için Qt Çerçeve tamponu", "Name[uk]": "Буфер кадрів на Qt для KRfb", "Name[x-test]": "xxQt Framebuffer for KRfbxx", "Name[zh_CN]": "KRfb 的 Qt 帧缓冲", "Name[zh_TW]": "Krfb 的 Qt Framebuffer", "ServiceTypes": [ "krfb/framebuffer" ], "Version": "0.1", - "Website": "http://www.kde.org" + "Website": "https://www.kde.org" } } diff --git a/framebuffers/qt/qtframebuffer.cpp b/framebuffers/qt/qtframebuffer.cpp index 61ffc92..10479fe 100644 --- a/framebuffers/qt/qtframebuffer.cpp +++ b/framebuffers/qt/qtframebuffer.cpp @@ -1,127 +1,126 @@ /* This file is part of the KDE project Copyright (C) 2007 Alessandro Praduroux 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 "qtframebuffer.h" -#include "qtframebuffer.moc" #include #include #include #include #include #include const int UPDATE_TIME = 500; QtFrameBuffer::QtFrameBuffer(WId id, QObject *parent) : FrameBuffer(id, parent) { QScreen *screen = QGuiApplication::primaryScreen(); if (screen) { primaryScreen = screen; fbImage = screen->grabWindow(win).toImage(); fb = new char[fbImage.byteCount()]; } else { - fb = Q_NULLPTR; - primaryScreen = Q_NULLPTR; + fb = nullptr; + primaryScreen = nullptr; } t = new QTimer(this); connect(t, &QTimer::timeout, this, &QtFrameBuffer::updateFrameBuffer); } QtFrameBuffer::~QtFrameBuffer() { if (fb) delete [] fb; - fb = 0; + fb = nullptr; } int QtFrameBuffer::depth() { return fbImage.depth(); } int QtFrameBuffer::height() { return fbImage.height(); } int QtFrameBuffer::width() { return fbImage.width(); } void QtFrameBuffer::getServerFormat(rfbPixelFormat &format) { format.bitsPerPixel = 32; format.depth = 32; format.trueColour = true; format.bigEndian = false; format.redShift = 16; format.greenShift = 8; format.blueShift = 0; format.redMax = 0xff; format.greenMax = 0xff; format.blueMax = 0xff; } void QtFrameBuffer::updateFrameBuffer() { if (!fb || !primaryScreen) return; QImage img = primaryScreen->grabWindow(win).toImage(); #if 0 // This is actually slower than updating the whole desktop... QSize imgSize = img.size(); // verify what part of the image need to be marked as changed // fbImage is the previous version of the image, // img is the current one QImage map(imgSize, QImage::Format_Mono); 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); } } } QRegion r(QBitmap::fromImage(map)); tiles = tiles + r.rects(); #else tiles.append(img.rect()); #endif memcpy(fb, (const char *)img.bits(), img.byteCount()); fbImage = img; } int QtFrameBuffer::paddedWidth() { return fbImage.width() * 4; } void QtFrameBuffer::startMonitor() { t->start(UPDATE_TIME); } void QtFrameBuffer::stopMonitor() { t->stop(); } diff --git a/framebuffers/qt/qtframebuffer.h b/framebuffers/qt/qtframebuffer.h index b364bdf..303201b 100644 --- a/framebuffers/qt/qtframebuffer.h +++ b/framebuffers/qt/qtframebuffer.h @@ -1,46 +1,46 @@ /* This file is part of the KDE project Copyright (C) 2007 Alessandro Praduroux 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 KRFB_FRAMEBUFFER_QT_QTFRAMEBUFFER_H #define KRFB_FRAMEBUFFER_QT_QTFRAMEBUFFER_H #include #include "framebuffer.h" class QTimer; class QScreen; /** @author Alessandro Praduroux */ class QtFrameBuffer : public FrameBuffer { Q_OBJECT public: - explicit QtFrameBuffer(WId id, QObject *parent = 0); + explicit QtFrameBuffer(WId id, QObject *parent = nullptr); - ~QtFrameBuffer(); + ~QtFrameBuffer() override; int depth() override; int height() override; int width() override; int paddedWidth() override; void getServerFormat(rfbPixelFormat &format) override; void startMonitor() override; void stopMonitor() override; public Q_SLOTS: void updateFrameBuffer(); private: QImage fbImage; QTimer *t; QScreen *primaryScreen; }; #endif diff --git a/framebuffers/qt/qtframebufferplugin.h b/framebuffers/qt/qtframebufferplugin.h index e9ed03c..e796e77 100644 --- a/framebuffers/qt/qtframebufferplugin.h +++ b/framebuffers/qt/qtframebufferplugin.h @@ -1,46 +1,46 @@ /* This file is part of the KDE project Copyright (C) 2009 Collabora Ltd @author George Goldberg 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_FRAMEBUFFER_QT_QTFRAMEBUFFERPLUGIN_H #define KRFB_FRAMEBUFFER_QT_QTFRAMEBUFFERPLUGIN_H #include "framebufferplugin.h" #include class FrameBuffer; class QtFrameBufferPlugin : public FrameBufferPlugin { Q_OBJECT public: QtFrameBufferPlugin(QObject *parent, const QVariantList &args); - virtual ~QtFrameBufferPlugin(); + ~QtFrameBufferPlugin() override; FrameBuffer *frameBuffer(WId id) override; private: Q_DISABLE_COPY(QtFrameBufferPlugin) }; #endif // Header guard diff --git a/framebuffers/xcb/krfb_framebuffer_xcb.desktop b/framebuffers/xcb/krfb_framebuffer_xcb.desktop deleted file mode 100644 index 082fd75..0000000 --- a/framebuffers/xcb/krfb_framebuffer_xcb.desktop +++ /dev/null @@ -1,109 +0,0 @@ -[Desktop Entry] -Encoding=UTF-8 -Comment=X11 XDamage/XShm based Framebuffer for KRfb. -Comment[ast]=Búfer de cuadros basáu en XDamage/XShm de X11 pa KRfb. -Comment[bg]=Основан на X11 XDamage/XShm фреймбуфер за KRfb. -Comment[bs]=X11 XDamage/XShm baziran framebafer za KRfb. -Comment[ca]=«Framebuffer» basat en XDamage/XShmQt del X11 per al KRfb. -Comment[ca@valencia]=«Framebuffer» basat en XDamage/XShmQt del 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[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[gl]=Framebuffer baseado en X11 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[id]=Framebuffer berbasiskan X11 XDamage/XShm untuk KRfb. -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[ru]=Буфер экрана для KRfb на базе X11 XDamage/XShm -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. -Comment[sr@ijekavian]=Кадробафер за КРФБ на основу Икс‑демиџа/Икс‑схма у Иксу11. -Comment[sr@ijekavianlatin]=Kadrobafer za KRFB na osnovu XDamagea/XShma u X11. -Comment[sr@latin]=Kadrobafer za KRFB na osnovu XDamagea/XShma u X11. -Comment[sv]=X11 XDamage/XShm-baserad rambuffert för Krfb. -Comment[tr]=KRfb için X11 XDamage/XShm temelli Çerçeve Tamponu. -Comment[uk]=Заснований на XDamage/XShm X11 буфер кадрів для KRfb. -Comment[x-test]=xxX11 XDamage/XShm based Framebuffer for KRfb.xx -Comment[zh_CN]=基于 X11 XDamage/XShm 扩展的 KRfb 帧缓冲机制。 -Comment[zh_TW]=KRfb 的 X11 XDamage/XShm based Framebuffer -Name=X11 Framebuffer for KRfb -Name[ast]=Búfer de cuadros de X11 pa KRfb -Name[bg]=X11 фреймбуфер за KRfb -Name[bs]=X11 frame bafer za KRfb -Name[ca]=«Framebuffer» del X11 per al KRfb. -Name[ca@valencia]=«Framebuffer» del 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[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[id]=Framebuffer X11 untuk KRfb -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[ru]=Буфер экрана X11 для KRfb -Name[si]=KRfb සඳහා X11 රාමු බෆරය -Name[sk]=X11 Framebuffer pre KRfb -Name[sl]=Slikovni medpomnilnik X11 za KRFB -Name[sr]=Икс11 кадробафер за КРФБ. -Name[sr@ijekavian]=Икс11 кадробафер за КРФБ. -Name[sr@ijekavianlatin]=X11 kadrobafer za KRFB. -Name[sr@latin]=X11 kadrobafer za KRFB. -Name[sv]=X11-rambuffert för Krfb -Name[tr]=KRfb için X11 Çerçeve Tamponu -Name[uk]=Буфер кадрів X11 для KRfb -Name[x-test]=xxX11 Framebuffer for KRfbxx -Name[zh_CN]=KRfb 的 X11 帧缓冲机制 -Name[zh_TW]=KRfb 的 X11 Framebuffer -Type=Service -ServiceTypes=krfb/framebuffer - -X-KDE-Library=krfb_framebuffer_xcb -X-KDE-PluginInfo-Name=xcb -X-KDE-PluginInfo-Version=0.1 -X-KDE-PluginInfo-Website=http://www.kde.org -X-KDE-PluginInfo-License=GPL -X-KDE-PluginInfo-EnabledByDefault=true diff --git a/framebuffers/xcb/krfb_framebuffer_xcb.json b/framebuffers/xcb/krfb_framebuffer_xcb.json index d998dd0..fdabe3a 100644 --- a/framebuffers/xcb/krfb_framebuffer_xcb.json +++ b/framebuffers/xcb/krfb_framebuffer_xcb.json @@ -1,83 +1,82 @@ { - "Encoding": "UTF-8", "KPlugin": { "Description": "X11 XDamage/XShm based Framebuffer for KRfb.", - "Description[ast]": "Búfer de cuadros basáu en XDamage/XShm de X11 pa KRfb.", "Description[ca@valencia]": "«Framebuffer» basat en XDamage/XShmQt del X11 per al KRfb.", "Description[ca]": "«Framebuffer» basat en XDamage/XShmQt del X11 per al KRfb.", "Description[cs]": "Framebuffer založený na X11 XDamage/XShm pro KRfb.", "Description[da]": "X11 XDamage/XShm-baseret framebuffer til KRfb.", "Description[de]": "X11 XDamage/XShm-basierter Framebuffer für KRfb.", "Description[el]": "Μνήμη ανανέωσης βίντεο με βάση το X11 XDamage/XShm για το KRfb.", + "Description[en_GB]": "X11 XDamage/XShm based Framebuffer for KRfb.", "Description[es]": "Framebuffer basado en XDamage/XShm de X11 para KRfb.", "Description[et]": "KRfb X11 XDamage/XShm põhine kaadripuhver", "Description[fi]": "X11 XDamage/XShm-perustainen kehyspuskui KRfb:lle.", "Description[fr]": "Tampon d'images utilisant XDamage/XShm de X11 pour KRfb.", "Description[gl]": "Framebuffer baseado en X11 XDamage/Xshm para XRfb.", "Description[ia]": "Framebuffer basate sur X11 XDamage/XShm per KRfb.", "Description[id]": "Framebuffer berbasiskan X11 XDamage/XShm untuk KRfb.", "Description[it]": "Framebuffer basato su XDamage/XShm di X11 per KRfb.", "Description[ko]": "KRfb용 X11 XDamage/XShm 기반 프레임버퍼입니다.", "Description[nl]": "Op X11 XDamage/XShm gebaseerd framebuffer voor KRfb.", "Description[nn]": "X11 XDamage/XShm-basert biletbuffer for KRfb.", "Description[pl]": "Bufor ramki na podstawie X11 XDamage/XShm dla KRfb.", "Description[pt]": "'Framebuffer' do X11, baseado no XDamage/XShm, para o KRfb.", "Description[pt_BR]": "Framebuffer baseado no XDamage/XShm do X11 para o KRfb.", "Description[ru]": "Буфер кадров для KRfb на базе X11 XDamage/XShm", "Description[sk]": "Framebuffer založený na X11 XDamage/XShm pre KRfb.", "Description[sl]": "Slikovni medpomnilnik za KRfb, ki temelji na X11 XDamage/XShm", "Description[sr@ijekavian]": "Кадробафер за КРФБ на основу Икс‑демиџа/Икс‑схма у Иксу11.", "Description[sr@ijekavianlatin]": "Kadrobafer za KRFB na osnovu XDamagea/XShma u X11.", "Description[sr@latin]": "Kadrobafer za KRFB na osnovu XDamagea/XShma u X11.", "Description[sr]": "Кадробафер за КРФБ на основу Икс‑демиџа/Икс‑схма у Иксу11.", "Description[sv]": "X11 XDamage/XShm-baserad rambuffert för Krfb.", "Description[tr]": "KRfb için X11 XDamage/XShm tabanlı Çerçeve tamponu.", "Description[uk]": "Заснований на XDamage/XShm X11 буфер кадрів для KRfb.", "Description[x-test]": "xxX11 XDamage/XShm based Framebuffer for KRfb.xx", "Description[zh_CN]": "KRfb 的基于 X11 XDamage/XShm 的帧缓冲。", "Description[zh_TW]": "KRfb 的 X11 XDamage/XShm based Framebuffer", "EnabledByDefault": true, "Id": "xcb", "License": "GPL", "Name": "X11 Framebuffer for KRfb", - "Name[ast]": "Búfer de cuadros de X11 pa KRfb", "Name[ca@valencia]": "«Framebuffer» del X11 per al KRfb.", "Name[ca]": "«Framebuffer» del 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 για το KRfb.", + "Name[en_GB]": "X11 Framebuffer for KRfb", "Name[es]": "Framebuffer X11 para KRfb", "Name[et]": "KRfb X11 kaadripuhver", "Name[fi]": "X11-kehyspuskuri KRfb:lle", "Name[fr]": "Tampon d'images X11 pour KRfb", "Name[gl]": "Framebuffer de X11 para KRfb", "Name[ia]": "Framebuffer X11 per KRfb", "Name[id]": "Framebuffer X11 untuk KRfb", "Name[it]": "Framebuffer X11 per KRfb", "Name[ko]": "KRfb용 X11 프레임버퍼", "Name[nl]": "X11 framebuffer voor KRfb", "Name[nn]": "X11-biletbuffer 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[ru]": "Буфер кадров X11 для KRfb", "Name[sk]": "X11 Framebuffer pre KRfb", "Name[sl]": "Slikovni medpomnilnik X11 za KRfb", "Name[sr@ijekavian]": "Икс11 кадробафер за КРФБ.", "Name[sr@ijekavianlatin]": "X11 kadrobafer za KRFB.", "Name[sr@latin]": "X11 kadrobafer za KRFB.", "Name[sr]": "Икс11 кадробафер за КРФБ.", "Name[sv]": "X11-rambuffert för Krfb", "Name[tr]": "KRfb için X11 Çerçeve tamponu", "Name[uk]": "Буфер кадрів X11 для KRfb", "Name[x-test]": "xxX11 Framebuffer for KRfbxx", "Name[zh_CN]": "XRfb 的 X11 帧缓冲", "Name[zh_TW]": "KRfb 的 X11 Framebuffer", "ServiceTypes": [ "krfb/framebuffer" ], "Version": "0.1", - "Website": "http://www.kde.org" + "Website": "https://www.kde.org" } } diff --git a/framebuffers/xcb/xcb_framebuffer.cpp b/framebuffers/xcb/xcb_framebuffer.cpp index 2f52516..f455b73 100644 --- a/framebuffers/xcb/xcb_framebuffer.cpp +++ b/framebuffers/xcb/xcb_framebuffer.cpp @@ -1,685 +1,684 @@ /* This file is part of the KDE project Copyright (C) 2017 Alexey Min 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 "xcb_framebuffer.h" -#include "xcb_framebuffer.moc" #include #include #include #include #include #include #include #include #include #include #include #include #include class KrfbXCBEventFilter: public QAbstractNativeEventFilter { public: KrfbXCBEventFilter(XCBFrameBuffer *owner); public: - virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result); + bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) override; public: int xdamageBaseEvent; int xdamageBaseError; int xshmBaseEvent; int xshmBaseError; bool xshmAvail; XCBFrameBuffer *fb_owner; }; KrfbXCBEventFilter::KrfbXCBEventFilter(XCBFrameBuffer *owner): xdamageBaseEvent(0), xdamageBaseError(0), xshmBaseEvent(0), xshmBaseError(0), xshmAvail(false), fb_owner(owner) { const xcb_query_extension_reply_t *xdamage_data = xcb_get_extension_data( QX11Info::connection(), &xcb_damage_id); if (xdamage_data) { // also query extension version! // ATTENTION: if we don't do that, xcb_damage_create() will always FAIL! xcb_damage_query_version_reply_t *xdamage_version = xcb_damage_query_version_reply( QX11Info::connection(), xcb_damage_query_version( QX11Info::connection(), XCB_DAMAGE_MAJOR_VERSION, XCB_DAMAGE_MINOR_VERSION), - NULL); + nullptr); if (!xdamage_version) { qWarning() << "xcb framebuffer: ERROR: Failed to get XDamage extension version!\n"; return; } #ifdef _DEBUG qDebug() << "xcb framebuffer: XDamage extension version:" << xdamage_version->major_version << "." << xdamage_version->minor_version; #endif free(xdamage_version); xdamageBaseEvent = xdamage_data->first_event; xdamageBaseError = xdamage_data->first_error; // XShm presence is optional. If it is present, all image getting // operations will be faster, without XShm it will only be slower. const xcb_query_extension_reply_t *xshm_data = xcb_get_extension_data( QX11Info::connection(), &xcb_shm_id); if (xshm_data) { xshmAvail = true; xshmBaseEvent = xshm_data->first_event; xshmBaseError = xshm_data->first_error; } else { xshmAvail = false; qWarning() << "xcb framebuffer: WARNING: XSHM extension not available!"; } } else { // if there is no xdamage available, this plugin can be considered useless anyway. // you can use just qt framebuffer plugin instead... qWarning() << "xcb framebuffer: ERROR: no XDamage extension available. I am useless."; qWarning() << "xcb framebuffer: use qt framebuffer plugin instead."; } } bool KrfbXCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result) { Q_UNUSED(result); // "result" is only used on windows if (xdamageBaseEvent == 0) return false; // no xdamage extension if (eventType == "xcb_generic_event_t") { xcb_generic_event_t* ev = static_cast(message); if ((ev->response_type & 0x7F) == (xdamageBaseEvent + XCB_DAMAGE_NOTIFY)) { // this is xdamage notification this->fb_owner->handleXDamageNotify(ev); return true; // filter out this event, stop its processing } } // continue event processing return false; } class XCBFrameBuffer::P { public: xcb_damage_damage_t damage; xcb_shm_segment_info_t shminfo; xcb_screen_t *rootScreen; // X screen info (all monitors) xcb_image_t *framebufferImage; xcb_image_t *updateTile; KrfbXCBEventFilter *x11EvtFilter; bool running; QRect area; // capture area, primary monitor coordinates }; static xcb_screen_t *get_xcb_screen(xcb_connection_t *conn, int screen_num) { - xcb_screen_t *screen = NULL; + xcb_screen_t *screen = nullptr; xcb_screen_iterator_t screens_iter = xcb_setup_roots_iterator(xcb_get_setup(conn)); for (; screens_iter.rem; --screen_num, xcb_screen_next(&screens_iter)) if (screen_num == 0) screen = screens_iter.data; return screen; } XCBFrameBuffer::XCBFrameBuffer(WId winid, QObject *parent): FrameBuffer(winid, parent), d(new XCBFrameBuffer::P) { d->running = false; d->damage = XCB_NONE; - d->framebufferImage = Q_NULLPTR; - d->shminfo.shmaddr = Q_NULLPTR; + d->framebufferImage = nullptr; + d->shminfo.shmaddr = nullptr; d->shminfo.shmid = XCB_NONE; d->shminfo.shmseg = XCB_NONE; - d->updateTile = Q_NULLPTR; + d->updateTile = nullptr; d->area.setRect(0, 0, 0, 0); d->x11EvtFilter = new KrfbXCBEventFilter(this); d->rootScreen = get_xcb_screen(QX11Info::connection(), QX11Info::appScreen()); - this->fb = Q_NULLPTR; + this->fb = nullptr; QScreen *primaryScreen = QGuiApplication::primaryScreen(); if (primaryScreen) { qDebug() << "xcb framebuffer: Primary screen: " << primaryScreen->name() << ", geometry: " << primaryScreen->geometry() << ", depth: " << primaryScreen->depth(); // d->area = primaryScreen->geometry(); } else { qWarning() << "xcb framebuffer: ERROR: Failed to get application's primary screen info!"; return; } d->framebufferImage = xcb_image_get(QX11Info::connection(), this->win, d->area.left(), d->area.top(), d->area.width(), d->area.height(), 0xFFFFFFFF, // == Xlib: AllPlanes ((unsigned long)~0L) XCB_IMAGE_FORMAT_Z_PIXMAP); if (d->framebufferImage) { #ifdef _DEBUG qDebug() << "xcb framebuffer: Got primary screen image. bpp: " << d->framebufferImage->bpp << ", size (" << d->framebufferImage->width << d->framebufferImage->height << ")" << ", depth: " << d->framebufferImage->depth << ", padded width: " << d->framebufferImage->stride; #endif this->fb = (char *)d->framebufferImage->data; } else { qWarning() << "xcb framebuffer: ERROR: Failed to get primary screen image!"; return; } // all XShm operations should take place only if Xshm extension was loaded if (d->x11EvtFilter->xshmAvail) { // Create xcb_image_t structure, but do not automatically allocate memory // for image data storage - it will be allocated as shared memory. // "If base == 0 and bytes == ~0 and data == 0, no storage will be auto-allocated." // Width and height of the image = size of the capture area. d->updateTile = xcb_image_create_native( QX11Info::connection(), d->area.width(), // width d->area.height(), // height XCB_IMAGE_FORMAT_Z_PIXMAP, // image format d->rootScreen->root_depth, // depth - NULL, // base address = 0 + nullptr, // base address = 0 (uint32_t)~0, // bytes = 0xffffffff - NULL); // data = 0 + nullptr); // data = 0 if (d->updateTile) { #ifdef _DEBUG qDebug() << "xcb framebuffer: Successfully created new empty image in native format"; qDebug() << " size: " << d->updateTile->width << "x" << d->updateTile->height << "(stride: " << d->updateTile->stride << ")"; qDebug() << " bpp, depth: " << d->updateTile->bpp << d->updateTile->depth; // 32, 24 qDebug() << " addr of base, data: " << d->updateTile->base << (void *)d->updateTile->data; qDebug() << " size: " << d->updateTile->size; qDebug() << " image byte order = " << d->updateTile->byte_order; // == 0 .._LSB_FIRST qDebug() << " image bit order = " << d->updateTile->bit_order; // == 1 .._MSB_FIRST qDebug() << " image plane_mask = " << d->updateTile->plane_mask; // == 16777215 == 0x00FFFFFF #endif // allocate shared memory block only once, make its size large enough // to fit whole capture area (d->area rect) // so, we get as many bytes as needed for image (updateTile->size) d->shminfo.shmid = shmget(IPC_PRIVATE, d->updateTile->size, IPC_CREAT | 0777); // attached shared memory address is stored both in shminfo structure and in xcb_image_t->data - d->shminfo.shmaddr = (uint8_t *)shmat(d->shminfo.shmid, NULL, 0); + d->shminfo.shmaddr = (uint8_t *)shmat(d->shminfo.shmid, nullptr, 0); d->updateTile->data = d->shminfo.shmaddr; // we keep updateTile->base == NULL here, so xcb_image_destroy() will not attempt // to free this block, just in case. // attach this shm segment also to X server d->shminfo.shmseg = xcb_generate_id(QX11Info::connection()); xcb_shm_attach(QX11Info::connection(), d->shminfo.shmseg, d->shminfo.shmid, 0); #ifdef _DEBUG qDebug() << " shm id: " << d->shminfo.shmseg << ", addr: " << (void *)d->shminfo.shmaddr; #endif // will return 1 on success (yes!) int shmget_res = xcb_image_shm_get( QX11Info::connection(), this->win, d->updateTile, d->shminfo, d->area.left(), // x d->area.top(), // y (size taken from image structure itself)? 0xFFFFFFFF); if (shmget_res == 0) { // error! shared mem not working? // will not use shared mem! detach and cleanup xcb_shm_detach(QX11Info::connection(), d->shminfo.shmseg); shmdt(d->shminfo.shmaddr); - shmctl(d->shminfo.shmid, IPC_RMID, 0); // mark shm segment as removed + shmctl(d->shminfo.shmid, IPC_RMID, nullptr); // mark shm segment as removed d->x11EvtFilter->xshmAvail = false; - d->shminfo.shmaddr = Q_NULLPTR; + d->shminfo.shmaddr = nullptr; d->shminfo.shmid = XCB_NONE; d->shminfo.shmseg = XCB_NONE; qWarning() << "xcb framebuffer: ERROR: xcb_image_shm_get() result: " << shmget_res; } // image is freed, and recreated again for every new damage rectangle // data was allocated manually and points to shared mem; // tell xcb_image_destroy() do not free image data - d->updateTile->data = NULL; + d->updateTile->data = nullptr; xcb_image_destroy(d->updateTile); - d->updateTile = NULL; + d->updateTile = nullptr; } } #ifdef _DEBUG qDebug() << "xcb framebuffer: XCBFrameBuffer(), xshm base event = " << d->x11EvtFilter->xshmBaseEvent << ", xshm base error = " << d->x11EvtFilter->xdamageBaseError << ", xdamage base event = " << d->x11EvtFilter->xdamageBaseEvent << ", xdamage base error = " << d->x11EvtFilter->xdamageBaseError; #endif QCoreApplication::instance()->installNativeEventFilter(d->x11EvtFilter); } XCBFrameBuffer::~XCBFrameBuffer() { // first - uninstall x11 event filter QCoreApplication::instance()->removeNativeEventFilter(d->x11EvtFilter); // if (d->framebufferImage) { xcb_image_destroy(d->framebufferImage); - fb = Q_NULLPTR; // image data was already destroyed by above call + fb = nullptr; // image data was already destroyed by above call } if (d->x11EvtFilter->xshmAvail) { // detach shared memory if (d->shminfo.shmseg != XCB_NONE) xcb_shm_detach(QX11Info::connection(), d->shminfo.shmseg); // detach from X server if (d->shminfo.shmaddr) shmdt(d->shminfo.shmaddr); // detach addr from our address space if (d->shminfo.shmid != XCB_NONE) - shmctl(d->shminfo.shmid, IPC_RMID, 0); // mark shm segment as removed + shmctl(d->shminfo.shmid, IPC_RMID, nullptr); // mark shm segment as removed } // and delete image used for shared mem if (d->updateTile) { - d->updateTile->base = NULL; - d->updateTile->data = NULL; + d->updateTile->base = nullptr; + d->updateTile->data = nullptr; xcb_image_destroy(d->updateTile); } // we don't use d->x11EvtFilter anymore, can delete it now if (d->x11EvtFilter) { delete d->x11EvtFilter; } delete d; } int XCBFrameBuffer::depth() { if (d->framebufferImage) { return d->framebufferImage->depth; } return 0; } int XCBFrameBuffer::height() { if (d->framebufferImage) { return d->framebufferImage->height; } return 0; } int XCBFrameBuffer::width() { if (d->framebufferImage) { return d->framebufferImage->width; } return 0; } int XCBFrameBuffer::paddedWidth() { if (d->framebufferImage) { return d->framebufferImage->stride; } return 0; } void XCBFrameBuffer::getServerFormat(rfbPixelFormat &format) { if (!d->framebufferImage) return; // get information about XCB visual params - xcb_visualtype_t *root_visualtype = NULL; // visual info + xcb_visualtype_t *root_visualtype = nullptr; // visual info if (d->rootScreen) { xcb_visualid_t root_visual = d->rootScreen->root_visual; xcb_depth_iterator_t depth_iter; // To get the xcb_visualtype_t structure, it's a bit less easy. // You have to get the xcb_screen_t structure that you want, get its // root_visual member, then iterate over the xcb_depth_t's and the // xcb_visualtype_t's, and compare the xcb_visualid_t of these // xcb_visualtype_ts: with root_visual depth_iter = xcb_screen_allowed_depths_iterator(d->rootScreen); for (; depth_iter.rem; xcb_depth_next(&depth_iter)) { xcb_visualtype_iterator_t visual_iter; visual_iter = xcb_depth_visuals_iterator(depth_iter.data); for (; visual_iter.rem; xcb_visualtype_next(&visual_iter)) { if (root_visual == visual_iter.data->visual_id) { root_visualtype = visual_iter.data; break; } } } } // fill in format common info format.bitsPerPixel = d->framebufferImage->bpp; format.depth = d->framebufferImage->depth; format.trueColour = true; // not using color palettes format.bigEndian = false; // always false for ZPIXMAP format! // information about pixels layout if (root_visualtype) { uint16_t pixelmaxValue = (1 << root_visualtype->bits_per_rgb_value) - 1; #ifdef _DEBUG qDebug("xcb framebuffer: Got info about root visual:\n" " bits per rgb value: %d\n" " red mask: %08x\n" " green mask: %08x\n" " blue mask: %08x\n" " pixelMaxValue = %d\n", (int)root_visualtype->bits_per_rgb_value, root_visualtype->red_mask, root_visualtype->green_mask, root_visualtype->blue_mask, (int)pixelmaxValue); #endif // calculate shifts format.redShift = 0; format.redMax = pixelmaxValue; if (root_visualtype->red_mask) { while (!(root_visualtype->red_mask & (1 << format.redShift))) { format.redShift++; } } format.greenShift = 0; format.greenMax = pixelmaxValue; if (root_visualtype->green_mask) { while (!(root_visualtype->green_mask & (1 << format.greenShift))) { format.greenShift++; } } format.blueShift = 0; format.blueMax = pixelmaxValue; if (root_visualtype->blue_mask) { while (!(root_visualtype->blue_mask & (1 << format.blueShift))) { format.blueShift++; } } #ifdef _DEBUG qDebug() << " Calculated redShift =" << (int)format.redShift; qDebug() << " Calculated greenShift =" << (int)format.greenShift; qDebug() << " Calculated blueShift =" << (int)format.blueShift; #endif } else { // some kind of fallback (unlikely code execution will go this way) // idea taken from qt framefuffer sources if (format.bitsPerPixel == 8) { format.redShift = 0; format.greenShift = 3; format.blueShift = 6; format.redMax = 7; format.greenMax = 7; format.blueMax = 3; } else if (format.bitsPerPixel == 16) { // TODO: 16 bits per pixel format ?? // what format of pixels does X server use for 16-bpp? } else if (format.bitsPerPixel == 32) { format.redMax = 0xff; format.greenMax = 0xff; format.blueMax = 0xff; if (format.bigEndian) { format.redShift = 0; format.greenShift = 8; format.blueShift = 16; } else { format.redShift = 16; format.greenShift = 8; format.blueShift = 0; } } } } /** * This function contents was taken from X11 framebuffer source code. * It simply several intersecting rectangles into one bigger rect. * Non-intersecting rects are treated as different rects and exist * separately in this->tiles QList. */ void XCBFrameBuffer::cleanupRects() { QList cpy = tiles; bool inserted = false; tiles.clear(); QListIterator iter(cpy); while (iter.hasNext()) { const QRect &r = iter.next(); // skip rects not intersecting with primary monitor if (!r.intersects(d->area)) continue; // only take intersection of this rect with primary monitor rect QRect ri = r.intersected(d->area); if (tiles.size() > 0) { for (int i = 0; i < tiles.size(); i++) { // if current rect has intersection with tiles[i], unite them if (ri.intersects(tiles[i])) { tiles[i] |= ri; inserted = true; break; } } if (!inserted) { // else, append to list as different rect tiles.append(ri); } } else { // tiles list is empty, append first item tiles.append(ri); } } // increase all rectangles size by 30 pixels each side. // limit coordinates to primary monitor boundaries. for (int i = 0; i < tiles.size(); i++) { tiles[i].adjust(-30, -30, 30, 30); if (tiles[i].top() < d->area.top()) { tiles[i].setTop(d->area.top()); } if (tiles[i].bottom() > d->area.bottom()) { tiles[i].setBottom(d->area.bottom()); } // if (tiles[i].left() < d->area.left()) { tiles[i].setLeft(d->area.left()); } if (tiles[i].right() > d->area.right()) { tiles[i].setRight(d->area.right()); } // move update rects so that they are positioned relative to // framebuffer image, not whole screen tiles[i].moveTo(tiles[i].left() - d->area.left(), tiles[i].top() - d->area.top()); } } /** * This function is called by RfbServerManager::updateScreens() * approximately every 50ms (!!), driven by QTimer to get all * modified rectangles on the screen */ QList XCBFrameBuffer::modifiedTiles() { QList ret; if (!d->running) { return ret; } cleanupRects(); if (tiles.size() > 0) { if (d->x11EvtFilter->xshmAvail) { // loop over all damage rectangles gathered up to this time QListIterator iter(tiles); //foreach(const QRect &r, tiles) { while (iter.hasNext()) { const QRect &r = iter.next(); // get image data into shared memory segment // now rects are positioned relative to framebufferImage, // but we need to get image from the whole screen, so // translate whe coordinates xcb_shm_get_image_cookie_t sgi_cookie = xcb_shm_get_image( QX11Info::connection(), this->win, d->area.left() + r.left(), d->area.top() + r.top(), r.width(), r.height(), 0xFFFFFFFF, XCB_IMAGE_FORMAT_Z_PIXMAP, d->shminfo.shmseg, 0); xcb_shm_get_image_reply_t *sgi_reply = xcb_shm_get_image_reply( - QX11Info::connection(), sgi_cookie, NULL); + QX11Info::connection(), sgi_cookie, nullptr); if (sgi_reply) { // create temporary image to get update rect contents into d->updateTile = xcb_image_create_native( QX11Info::connection(), r.width(), r.height(), XCB_IMAGE_FORMAT_Z_PIXMAP, d->rootScreen->root_depth, - NULL, // base == 0 + nullptr, // base == 0 (uint32_t)~0, // bytes == ~0 - NULL); + nullptr); if (d->updateTile) { d->updateTile->data = d->shminfo.shmaddr; // copy pixels from this damage rectangle image // to our total framebuffer image int pxsize = d->framebufferImage->bpp / 8; char *dest = fb + ((d->framebufferImage->stride * r.top()) + (r.left() * pxsize)); char *src = (char *)d->updateTile->data; for (int i = 0; i < d->updateTile->height; i++) { memcpy(dest, src, d->updateTile->stride); // copy whole row of pixels dest += d->framebufferImage->stride; src += d->updateTile->stride; } // delete temporary image - d->updateTile->data = NULL; + d->updateTile->data = nullptr; xcb_image_destroy(d->updateTile); - d->updateTile = NULL; + d->updateTile = nullptr; } free(sgi_reply); } } // foreach } else { // not using shared memory // will use just xcb_image_get() and copy pixels - foreach(const QRect &r, tiles) { + for (const QRect& r : qAsConst(tiles)) { // I did not find XGetSubImage() analog in XCB!! // need function that copies pixels from one image to another xcb_image_t *damagedImage = xcb_image_get( QX11Info::connection(), this->win, r.left(), r.top(), r.width(), r.height(), 0xFFFFFFFF, // AllPlanes XCB_IMAGE_FORMAT_Z_PIXMAP); // manually copy pixels int pxsize = d->framebufferImage->bpp / 8; char *dest = fb + ((d->framebufferImage->stride * r.top()) + (r.left() * pxsize)); char *src = (char *)damagedImage->data; // loop every row in damaged image for (int i = 0; i < damagedImage->height; i++) { // copy whole row of pixels from src image to dest memcpy(dest, src, damagedImage->stride); dest += d->framebufferImage->stride; // move 1 row down in dest src += damagedImage->stride; // move 1 row down in src } // xcb_image_destroy(damagedImage); } } } // if (tiles.size() > 0) ret = tiles; tiles.clear(); // ^^ If we clear here all our known "damage areas", then we can also clear // damaged area for xdamage? No, we don't need to in our case // (XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES report mode) //xcb_damage_subtract(QX11Info::connection(), d->damage, XCB_NONE, XCB_NONE); return ret; } void XCBFrameBuffer::startMonitor() { if (d->running) return; d->running = true; d->damage = xcb_generate_id(QX11Info::connection()); xcb_damage_create(QX11Info::connection(), d->damage, this->win, XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES); // (currently) we do not call xcb_damage_subtract() EVER, because // RAW rectangles are reported. every time some area of the screen // was changed, we get only that rectangle //xcb_damage_subtract(QX11Info::connection(), d->damage, XCB_NONE, XCB_NONE); } void XCBFrameBuffer::stopMonitor() { if (!d->running) return; d->running = false; xcb_damage_destroy(QX11Info::connection(), d->damage); } // void XCBFrameBuffer::acquireEvents() {} // this function was totally unused // in X11 framebuffer, but it was the only function where XDamageSubtract() was called? // Also it had a blocking event loop like: // // XEvent ev; // while (XCheckTypedEvent(QX11Info::display(), d->xdamageBaseEvent + XDamageNotify, &ev)) { // handleXDamage(&ev); // } // XDamageSubtract(QX11Info::display(), d->damage, None, None); // // This loop takes all available Xdamage events from queue, and ends if there are no // more such events in input queue. void XCBFrameBuffer::handleXDamageNotify(xcb_generic_event_t *xevent) { xcb_damage_notify_event_t *xdevt = (xcb_damage_notify_event_t *)xevent; QRect r((int)xdevt->area.x, (int)xdevt->area.y, (int)xdevt->area.width, (int)xdevt->area.height); this->tiles.append(r); } diff --git a/framebuffers/xcb/xcb_framebuffer.h b/framebuffers/xcb/xcb_framebuffer.h index 703e4e5..684c566 100644 --- a/framebuffers/xcb/xcb_framebuffer.h +++ b/framebuffers/xcb/xcb_framebuffer.h @@ -1,48 +1,48 @@ /* This file is part of the KDE project Copyright (C) 2017 Alexey Min 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 KRFB_FRAMEBUFFER_XCB_XCB_FRAMEBUFFER_H #define KRFB_FRAMEBUFFER_XCB_XCB_FRAMEBUFFER_H #include "framebuffer.h" #include #include /** @author Alexey Min */ class XCBFrameBuffer: public FrameBuffer { Q_OBJECT public: - XCBFrameBuffer(WId winid, QObject *parent = 0); - ~XCBFrameBuffer(); + explicit XCBFrameBuffer(WId winid, QObject *parent = nullptr); + ~XCBFrameBuffer() override; public: - QList modifiedTiles() Q_DECL_OVERRIDE; - int depth() Q_DECL_OVERRIDE; - int height() Q_DECL_OVERRIDE; - int width() Q_DECL_OVERRIDE; - int paddedWidth() Q_DECL_OVERRIDE; - void getServerFormat(rfbPixelFormat &format) Q_DECL_OVERRIDE; - void startMonitor() Q_DECL_OVERRIDE; - void stopMonitor() Q_DECL_OVERRIDE; + QList modifiedTiles() override; + int depth() override; + int height() override; + int width() override; + int paddedWidth() override; + void getServerFormat(rfbPixelFormat &format) override; + void startMonitor() override; + void stopMonitor() override; public: void handleXDamageNotify(xcb_generic_event_t *xevent); private: void cleanupRects(); class P; P *const d; }; #endif diff --git a/framebuffers/xcb/xcb_framebufferplugin.cpp b/framebuffers/xcb/xcb_framebufferplugin.cpp index 5e01c66..0efa4b1 100644 --- a/framebuffers/xcb/xcb_framebufferplugin.cpp +++ b/framebuffers/xcb/xcb_framebufferplugin.cpp @@ -1,46 +1,46 @@ /* This file is part of the KDE project - @author Alexey Min + Copyright (C) 2017 Alexey Min 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 "xcb_framebufferplugin.h" #include "xcb_framebuffer.h" #include K_PLUGIN_FACTORY_WITH_JSON(XCBFrameBufferPluginFactory, "krfb_framebuffer_xcb.json", registerPlugin();) XCBFrameBufferPlugin::XCBFrameBufferPlugin(QObject *parent, const QVariantList &args) : FrameBufferPlugin(parent, args) { } XCBFrameBufferPlugin::~XCBFrameBufferPlugin() { } FrameBuffer *XCBFrameBufferPlugin::frameBuffer(WId id) { return new XCBFrameBuffer(id); } #include "xcb_framebufferplugin.moc" diff --git a/framebuffers/xcb/xcb_framebufferplugin.h b/framebuffers/xcb/xcb_framebufferplugin.h index 6c60836..bf614f7 100644 --- a/framebuffers/xcb/xcb_framebufferplugin.h +++ b/framebuffers/xcb/xcb_framebufferplugin.h @@ -1,45 +1,45 @@ /* This file is part of the KDE project @author Alexey Min 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_FRAMEBUFFER_XCB_XCBFRAMEBUFFERPLUGIN_H #define KRFB_FRAMEBUFFER_XCB_XCBFRAMEBUFFERPLUGIN_H #include "framebufferplugin.h" #include class FrameBuffer; class XCBFrameBufferPlugin: public FrameBufferPlugin { Q_OBJECT public: XCBFrameBufferPlugin(QObject *parent, const QVariantList &args); - virtual ~XCBFrameBufferPlugin(); + ~XCBFrameBufferPlugin() override; FrameBuffer *frameBuffer(WId id) override; private: Q_DISABLE_COPY(XCBFrameBufferPlugin) }; #endif // Header guard diff --git a/krfb/CMakeLists.txt b/krfb/CMakeLists.txt index 72e117c..8259de0 100644 --- a/krfb/CMakeLists.txt +++ b/krfb/CMakeLists.txt @@ -1,136 +1,140 @@ configure_file (${CMAKE_CURRENT_SOURCE_DIR}/config-krfb.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-krfb.h ) include(GenerateExportHeader) ##################################### # First target: libkrfbprivate - a library # for linking plugins against. set (krfbprivate_SRCS framebuffer.cpp framebufferplugin.cpp ) add_library (krfbprivate SHARED ${krfbprivate_SRCS} ) generate_export_header(krfbprivate BASE_NAME krfbprivate) target_link_libraries (krfbprivate Qt5::Core Qt5::Widgets Qt5::X11Extras ${X11_X11_LIB} ${LIBVNCSERVER_LIBRARIES} ) set_target_properties (krfbprivate PROPERTIES VERSION 5 SOVERSION 5.0 ) 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. set (krfb_SRCS connectiondialog.cpp events.cpp framebuffermanager.cpp main.cpp mainwindow.cpp sockethelpers.cpp trayicon.cpp rfbservermanager.cpp rfbserver.cpp rfbclient.cpp invitationsrfbserver.cpp invitationsrfbclient.cpp ) kconfig_add_kcfg_files (krfb_SRCS krfbconfig.kcfgc ) ki18n_wrap_ui (krfb_SRCS ui/configtcp.ui ui/configsecurity.ui ui/configframebuffer.ui ui/connectionwidget.ui ui/mainwidget.ui ) qt5_add_dbus_interface( krfb_SRCS dbus/xdp_dbus_screencast_interface.xml dbus/xdp_dbus_screencast_interface ) qt5_add_dbus_interface( krfb_SRCS dbus/xdp_dbus_remotedesktop_interface.xml dbus/xdp_dbus_remotedesktop_interface + +qt5_add_resources(krfb_SRCS + krfb.qrc + ) add_executable (krfb ${krfb_SRCS} ) target_link_libraries (krfb krfbprivate ${JPEG_LIBRARIES} ${X11_Xext_LIB} ${X11_X11_LIB} ${X11_Xdamage_LIB} Qt5::DBus Qt5::Network KF5::Completion KF5::CoreAddons KF5::DBusAddons KF5::DNSSD KF5::I18n KF5::Notifications KF5::Wallet KF5::WidgetsAddons KF5::XmlGui ${LIBVNCSERVER_LIBRARIES} ) 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 (PROGRAMS org.kde.krfb.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) install(FILES org.kde.krfb.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) install (FILES krfb.notifyrc DESTINATION ${DATA_INSTALL_DIR}/krfb ) diff --git a/krfb/connectiondialog.cpp b/krfb/connectiondialog.cpp index 0d12f7e..f122aa4 100644 --- a/krfb/connectiondialog.cpp +++ b/krfb/connectiondialog.cpp @@ -1,86 +1,82 @@ /* This file is part of the KDE project Copyright (C) 2010 Collabora Ltd @author George Kiagiadakis Copyright (C) 2004 Nadeem Hasan 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 #include #include #include #include #include #include #include #include template ConnectionDialog::ConnectionDialog(QWidget *parent) : QDialog(parent) { setWindowTitle(i18n("New Connection")); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel); QWidget *mainWidget = new QWidget(this); QVBoxLayout *mainLayout = new QVBoxLayout; setLayout(mainLayout); mainLayout->addWidget(mainWidget); QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); okButton->setDefault(true); okButton->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox, &QDialogButtonBox::accepted, this, &ConnectionDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &ConnectionDialog::reject); buttonBox->button(QDialogButtonBox::Cancel)->setDefault(true); setModal(true); setMinimumSize(500, 200); m_connectWidget = new QWidget(this); m_ui.setupUi(m_connectWidget); - m_ui.pixmapLabel->setPixmap(QIcon::fromTheme("krfb").pixmap(128)); + m_ui.pixmapLabel->setPixmap(QIcon::fromTheme(QStringLiteral("krfb")).pixmap(128)); KGuiItem accept = KStandardGuiItem::ok(); accept.setText(i18n("Accept Connection")); KGuiItem::assign(okButton, accept); KGuiItem refuse = KStandardGuiItem::cancel(); refuse.setText(i18n("Refuse Connection")); KGuiItem::assign(buttonBox->button(QDialogButtonBox::Cancel), refuse); mainLayout->addWidget(m_connectWidget); mainLayout->addWidget(buttonBox); } //********** InvitationsConnectionDialog::InvitationsConnectionDialog(QWidget *parent) : ConnectionDialog(parent) { } void InvitationsConnectionDialog::setRemoteHost(const QString &host) { m_ui.remoteHost->setText(host); } - -//********** - -#include "connectiondialog.moc" diff --git a/krfb/connectiondialog.h b/krfb/connectiondialog.h index aca813d..9988b2d 100644 --- a/krfb/connectiondialog.h +++ b/krfb/connectiondialog.h @@ -1,69 +1,69 @@ /* This file is part of the KDE project Copyright (C) 2010 Collabora Ltd @author George Kiagiadakis Copyright (C) 2004 Nadeem Hasan 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 template class ConnectionDialog : public QDialog { public: - ConnectionDialog(QWidget *parent); - ~ConnectionDialog() {}; + explicit ConnectionDialog(QWidget *parent); + ~ConnectionDialog() override {}; void setAllowRemoteControl(bool b); bool allowRemoteControl(); protected: QWidget *m_connectWidget; UI m_ui; }; template void ConnectionDialog::setAllowRemoteControl(bool b) { m_ui.cbAllowRemoteControl->setChecked(b); m_ui.cbAllowRemoteControl->setVisible(b); } template bool ConnectionDialog::allowRemoteControl() { return m_ui.cbAllowRemoteControl->isChecked(); } //********* class InvitationsConnectionDialog : public ConnectionDialog { Q_OBJECT public: - InvitationsConnectionDialog(QWidget *parent); + explicit InvitationsConnectionDialog(QWidget *parent); void setRemoteHost(const QString & host); }; //********* #endif // CONNECTIONDIALOG_H diff --git a/krfb/framebuffer.cpp b/krfb/framebuffer.cpp index 5579648..507364c 100644 --- a/krfb/framebuffer.cpp +++ b/krfb/framebuffer.cpp @@ -1,78 +1,74 @@ /* This file is part of the KDE project Copyright (C) 2007 Alessandro Praduroux 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 "framebuffer.h" -#include "config-krfb.h" +#include #include FrameBuffer::FrameBuffer(WId id, QObject *parent) : QObject(parent), win(id) { } FrameBuffer::~FrameBuffer() { delete fb; } char *FrameBuffer::data() { return fb; } QList< QRect > FrameBuffer::modifiedTiles() { QList ret = tiles; tiles.clear(); return ret; } int FrameBuffer::width() { return 0; } int FrameBuffer::height() { return 0; } void FrameBuffer::getServerFormat(rfbPixelFormat &) { } QVariant FrameBuffer::customProperty(const QString &property) const { return QVariant(); } int FrameBuffer::depth() { return 32; } int FrameBuffer::paddedWidth() { return width() * depth() / 8; } void FrameBuffer::startMonitor() { } void FrameBuffer::stopMonitor() { } - - -#include "framebuffer.moc" - diff --git a/krfb/framebuffer.h b/krfb/framebuffer.h index 0b8f7e2..7a4bfb2 100644 --- a/krfb/framebuffer.h +++ b/krfb/framebuffer.h @@ -1,62 +1,61 @@ /* This file is part of the KDE project Copyright (C) 2007 Alessandro Praduroux 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 FRAMEBUFFER_H #define FRAMEBUFFER_H #include "rfb.h" #include "krfbprivate_export.h" -#include -#include -#include -#include +#include +#include +#include #include class FrameBuffer; /** @author Alessandro Praduroux */ class KRFBPRIVATE_EXPORT FrameBuffer : public QObject { Q_OBJECT public: - explicit FrameBuffer(WId id, QObject *parent = 0); + explicit FrameBuffer(WId id, QObject *parent = nullptr); - virtual ~FrameBuffer(); + ~FrameBuffer() override; char *data(); virtual QList modifiedTiles(); virtual int paddedWidth(); virtual int width(); virtual int height(); virtual int depth(); virtual void startMonitor(); virtual void stopMonitor(); virtual void getServerFormat(rfbPixelFormat &format); virtual QVariant customProperty(const QString &property) const; Q_SIGNALS: void frameBufferChanged(); protected: WId win; char *fb; QList tiles; private: Q_DISABLE_COPY(FrameBuffer) }; #endif diff --git a/krfb/framebuffermanager.cpp b/krfb/framebuffermanager.cpp index 1a36d8b..342ddb9 100644 --- a/krfb/framebuffermanager.cpp +++ b/krfb/framebuffermanager.cpp @@ -1,141 +1,137 @@ /* This file is part of the KDE project Copyright (C) 2009 Collabora Ltd @author George Goldberg 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 "framebuffermanager.h" #include "framebufferplugin.h" #include "krfbconfig.h" #include #include #include #include #include -#include +#include class FrameBufferManagerStatic { public: FrameBufferManager instance; }; Q_GLOBAL_STATIC(FrameBufferManagerStatic, frameBufferManagerStatic) FrameBufferManager::FrameBufferManager() { //qDebug(); loadPlugins(); } FrameBufferManager::~FrameBufferManager() { //qDebug(); } FrameBufferManager *FrameBufferManager::instance() { //qDebug(); return &frameBufferManagerStatic->instance; } void FrameBufferManager::loadPlugins() { //qDebug(); const QVector plugins = KPluginLoader::findPlugins(QStringLiteral("krfb"), [](const KPluginMetaData & md) { return md.serviceTypes().contains(QStringLiteral("krfb/framebuffer")); }); QVectorIterator i(plugins); i.toBack(); QSet unique; while (i.hasPrevious()) { const KPluginMetaData &data = i.previous(); // only load plugins once, even if found multiple times! if (unique.contains(data.name())) continue; KPluginFactory *factory = KPluginLoader(data.fileName()).factory(); if (!factory) { qDebug() << "KPluginFactory could not load the plugin:" << data.fileName(); } else { qDebug() << "found plugin at " << data.fileName(); } FrameBufferPlugin *plugin = factory->create(this); if (plugin) { m_plugins.insert(data.pluginId(), plugin); qDebug() << "Loaded plugin with name " << data.pluginId(); } else { qDebug() << "unable to load pluign for " << data.fileName(); } unique.insert (data.name()); } } QSharedPointer FrameBufferManager::frameBuffer(WId id) { //qDebug(); // See if there is still an existing framebuffer to this WId. if (m_frameBuffers.contains(id)) { QWeakPointer weakFrameBuffer = m_frameBuffers.value(id); if (weakFrameBuffer) { //qDebug() << "Found cached frame buffer."; return weakFrameBuffer.toStrongRef(); } else { //qDebug() << "Found deleted cached frame buffer. Don't use."; m_frameBuffers.remove(id); } } // We don't already have that frame buffer. QMap::const_iterator iter = m_plugins.constBegin(); while (iter != m_plugins.constEnd()) { if (iter.key() == KrfbConfig::preferredFrameBufferPlugin()) { qDebug() << "Using FrameBuffer:" << KrfbConfig::preferredFrameBufferPlugin(); QSharedPointer frameBuffer(iter.value()->frameBuffer(id)); if (frameBuffer) { m_frameBuffers.insert(id, frameBuffer.toWeakRef()); return frameBuffer; } } ++iter; } // No valid framebuffer plugin found. qDebug() << "No valid framebuffer found. returning null."; return QSharedPointer(); } - - -#include "framebuffermanager.moc" - diff --git a/krfb/framebuffermanager.h b/krfb/framebuffermanager.h index 6a1e86b..d12a216 100644 --- a/krfb/framebuffermanager.h +++ b/krfb/framebuffermanager.h @@ -1,63 +1,63 @@ /* This file is part of the KDE project Copyright (C) 2009 Collabora Ltd @author George Goldberg 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_FRAMEBUFFERMANAGER_H #define KRFB_FRAMEBUFFERMANAGER_H #include "framebuffer.h" #include "krfbprivate_export.h" -#include -#include -#include -#include +#include +#include +#include +#include #include class FrameBufferPlugin; class KPluginFactory; class KRFBPRIVATE_EXPORT FrameBufferManager : public QObject { Q_OBJECT friend class FrameBufferManagerStatic; public: static FrameBufferManager *instance(); - virtual ~FrameBufferManager(); + ~FrameBufferManager() override; QSharedPointer frameBuffer(WId id); private: Q_DISABLE_COPY(FrameBufferManager) FrameBufferManager(); void loadPlugins(); QMap m_plugins; QMap > m_frameBuffers; }; #endif // Header guard diff --git a/krfb/framebufferplugin.cpp b/krfb/framebufferplugin.cpp index 8312a48..5f67cc3 100644 --- a/krfb/framebufferplugin.cpp +++ b/krfb/framebufferplugin.cpp @@ -1,36 +1,32 @@ /* This file is part of the KDE project Copyright (C) 2009 Collabora Ltd @author George Goldberg 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 "framebufferplugin.h" #include "framebuffer.h" FrameBufferPlugin::FrameBufferPlugin(QObject *parent, const QVariantList &) : QObject(parent) { } FrameBufferPlugin::~FrameBufferPlugin() { } - - -#include "framebufferplugin.moc" - diff --git a/krfb/framebufferplugin.h b/krfb/framebufferplugin.h index eed8eb3..94a9d83 100644 --- a/krfb/framebufferplugin.h +++ b/krfb/framebufferplugin.h @@ -1,44 +1,44 @@ /* This file is part of the KDE project Copyright (C) 2009 Collabora Ltd @author George Goldberg 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 LIB_KRFB_FRAMEBUFFERPLUGIN_H #define LIB_KRFB_FRAMEBUFFERPLUGIN_H #include "krfbprivate_export.h" -#include +#include #include class FrameBuffer; class KRFBPRIVATE_EXPORT FrameBufferPlugin : public QObject { Q_OBJECT public: FrameBufferPlugin(QObject *parent, const QVariantList &args); - virtual ~FrameBufferPlugin(); + ~FrameBufferPlugin() override; virtual FrameBuffer *frameBuffer(WId id) = 0; }; #endif // Header guard diff --git a/krfb/invitationsrfbclient.cpp b/krfb/invitationsrfbclient.cpp index 3a881cd..72fd263 100644 --- a/krfb/invitationsrfbclient.cpp +++ b/krfb/invitationsrfbclient.cpp @@ -1,153 +1,151 @@ /* Copyright (C) 2009-2010 Collabora Ltd @author George Goldberg @author George Kiagiadakis Copyright (C) 2007 Alessandro Praduroux Copyright (C) 2001-2003 by Tim Jansen 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 . */ #include "rfb.h" #include "invitationsrfbclient.h" #include "invitationsrfbserver.h" #include "krfbconfig.h" #include "sockethelpers.h" #include "connectiondialog.h" #include #include #include -#include +#include #include #include struct PendingInvitationsRfbClient::Private { Private(rfbClientPtr client) : client(client), askOnConnect(true) {} rfbClientPtr client; QSocketNotifier *notifier; bool askOnConnect; }; static void clientGoneHookNoop(rfbClientPtr cl) { Q_UNUSED(cl); } PendingInvitationsRfbClient::PendingInvitationsRfbClient(rfbClientPtr client, QObject *parent) : PendingRfbClient(client, parent), d(new Private(client)) { d->client->clientGoneHook = clientGoneHookNoop; d->notifier = new QSocketNotifier(client->sock, QSocketNotifier::Read, this); d->notifier->setEnabled(true); connect(d->notifier, &QSocketNotifier::activated, this, &PendingInvitationsRfbClient::onSocketActivated); } PendingInvitationsRfbClient::~PendingInvitationsRfbClient() { delete d; } void PendingInvitationsRfbClient::processNewClient() { - QString host = peerAddress(m_rfbClient->sock) + ":" + QString::number(peerPort(m_rfbClient->sock)); + QString host = peerAddress(m_rfbClient->sock) + QLatin1Char(':') + QString::number(peerPort(m_rfbClient->sock)); if (d->askOnConnect == false) { - KNotification::event("NewConnectionAutoAccepted", + KNotification::event(QStringLiteral("NewConnectionAutoAccepted"), i18n("Accepted connection from %1", host)); accept(new InvitationsRfbClient(m_rfbClient, parent())); } else { - KNotification::event("NewConnectionOnHold", + KNotification::event(QStringLiteral("NewConnectionOnHold"), i18n("Received connection from %1, on hold (waiting for confirmation)", host)); - InvitationsConnectionDialog *dialog = new InvitationsConnectionDialog(0); + InvitationsConnectionDialog *dialog = new InvitationsConnectionDialog(nullptr); dialog->setRemoteHost(host); dialog->setAllowRemoteControl(KrfbConfig::allowDesktopControl()); connect(dialog, &InvitationsConnectionDialog::accepted, this, &PendingInvitationsRfbClient::dialogAccepted); connect(dialog, &InvitationsConnectionDialog::rejected, this, &PendingInvitationsRfbClient::reject); dialog->show(); } } void PendingInvitationsRfbClient::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) { if(d->client->state == rfbClientRec::RFB_INITIALISATION) { d->notifier->setEnabled(false); //Client is Authenticated processNewClient(); break; } 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) { qDebug() << "disconnected from socket signal"; d->notifier->setEnabled(false); rfbClientConnectionGone(d->client); break; } } } bool PendingInvitationsRfbClient::checkPassword(const QByteArray & encryptedPassword) { QByteArray password ; - qDebug() << "about to start autentication"; + qDebug() << "about to start authentication"; if(InvitationsRfbServer::instance->allowUnattendedAccess() && vncAuthCheckPassword( InvitationsRfbServer::instance->unattendedPassword().toLocal8Bit(), encryptedPassword) ) { d->askOnConnect = false; return true; } return vncAuthCheckPassword( InvitationsRfbServer::instance->desktopPassword().toLocal8Bit(), encryptedPassword); } void PendingInvitationsRfbClient::dialogAccepted() { InvitationsConnectionDialog *dialog = qobject_cast(sender()); Q_ASSERT(dialog); InvitationsRfbClient *client = new InvitationsRfbClient(m_rfbClient, parent()); client->setControlEnabled(dialog->allowRemoteControl()); accept(client); } - -#include "invitationsrfbclient.moc" diff --git a/krfb/invitationsrfbclient.h b/krfb/invitationsrfbclient.h index 3f71c5f..3e4fe51 100644 --- a/krfb/invitationsrfbclient.h +++ b/krfb/invitationsrfbclient.h @@ -1,51 +1,51 @@ /* Copyright (C) 2010 Collabora Ltd @author George Kiagiadakis 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 . */ #ifndef INVITATIONSRFBCLIENT_H #define INVITATIONSRFBCLIENT_H #include "rfbclient.h" class InvitationsRfbClient : public RfbClient { public: - InvitationsRfbClient(rfbClientPtr client, QObject* parent = 0) + explicit InvitationsRfbClient(rfbClientPtr client, QObject* parent = nullptr) : RfbClient(client, parent) {} }; class PendingInvitationsRfbClient : public PendingRfbClient { Q_OBJECT public: - PendingInvitationsRfbClient(rfbClientPtr client, QObject *parent = 0); - virtual ~PendingInvitationsRfbClient(); + explicit PendingInvitationsRfbClient(rfbClientPtr client, QObject *parent = nullptr); + ~PendingInvitationsRfbClient() override; protected Q_SLOTS: void processNewClient() override; virtual void onSocketActivated(); bool checkPassword(const QByteArray & encryptedPassword) override; private Q_SLOTS: void dialogAccepted(); private: struct Private; Private* const d; }; #endif // INVITATIONSRFBCLIENT_H diff --git a/krfb/invitationsrfbserver.cpp b/krfb/invitationsrfbserver.cpp index 33dac04..c25701b 100644 --- a/krfb/invitationsrfbserver.cpp +++ b/krfb/invitationsrfbserver.cpp @@ -1,227 +1,238 @@ /* Copyright (C) 2009-2010 Collabora Ltd @author George Goldberg @author George Kiagiadakis Copyright (C) 2007 Alessandro Praduroux Copyright (C) 2001-2003 by Tim Jansen 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 . */ #include "invitationsrfbserver.h" #include "invitationsrfbclient.h" #include "krfbconfig.h" #include "rfbservermanager.h" -#include +#include #include -#include +#include #include #include #include #include #include #include #include using KWallet::Wallet; //static InvitationsRfbServer *InvitationsRfbServer::instance; //static void InvitationsRfbServer::init() { instance = new InvitationsRfbServer; instance->m_publicService = new KDNSSD::PublicService( i18n("%1@%2 (shared desktop)", KUser().loginName(), QHostInfo::localHostName()), - "_rfb._tcp", + QStringLiteral("_rfb._tcp"), KrfbConfig::port()); instance->setListeningAddress("0.0.0.0"); instance->setListeningPort(KrfbConfig::port()); instance->setPasswordRequired(true); + instance->m_wallet = nullptr; if (KrfbConfig::noWallet()) { - instance->walletOpened(false); - } - else { - instance->m_wallet = Wallet::openWallet( - Wallet::NetworkWallet(), 0, Wallet::Asynchronous); - if(instance->m_wallet) { - connect(instance->m_wallet, &KWallet::Wallet::walletOpened, - instance, &InvitationsRfbServer::walletOpened); - } + instance->walletOpened(false); + } else { + instance->openKWallet(); } } const QString& InvitationsRfbServer::desktopPassword() const { return m_desktopPassword; } void InvitationsRfbServer::setDesktopPassword(const QString& password) { m_desktopPassword = password; } const QString& InvitationsRfbServer::unattendedPassword() const { return m_unattendedPassword; } void InvitationsRfbServer::setUnattendedPassword(const QString& password) { m_unattendedPassword = password; } bool InvitationsRfbServer::allowUnattendedAccess() const { return m_allowUnattendedAccess; } bool InvitationsRfbServer::start() { if(RfbServer::start()) { if(KrfbConfig::publishService()) m_publicService->publishAsync(); return true; } return false; } void InvitationsRfbServer::stop() { if(m_publicService->isPublished()) m_publicService->stop(); RfbServer::stop(); } void InvitationsRfbServer::toggleUnattendedAccess(bool allow) { m_allowUnattendedAccess = allow; } InvitationsRfbServer::InvitationsRfbServer() { - m_desktopPassword = readableRandomString(4)+"-"+readableRandomString(3); - m_unattendedPassword = readableRandomString(4)+"-"+readableRandomString(3); + m_desktopPassword = readableRandomString(4) + QLatin1Char('-') + readableRandomString(3); + m_unattendedPassword = readableRandomString(4) + QLatin1Char('-') + readableRandomString(3); KConfigGroup krfbConfig(KSharedConfig::openConfig(),"Security"); m_allowUnattendedAccess = krfbConfig.readEntry( "allowUnattendedAccess", QVariant(false)).toBool(); } InvitationsRfbServer::~InvitationsRfbServer() { stop(); - KConfigGroup krfbConfig(KSharedConfig::openConfig(),"Security"); - krfbConfig.writeEntry("allowUnattendedAccess",m_allowUnattendedAccess); - if(!KrfbConfig::noWallet()) { - if (m_wallet && m_wallet->isOpen()) { - if( (m_wallet->currentFolder()=="krfb") || - ((m_wallet->hasFolder("krfb") || m_wallet->createFolder("krfb")) && - m_wallet->setFolder("krfb")) ) { - - m_wallet->writePassword("desktopSharingPassword",m_desktopPassword); - m_wallet->writePassword("unattendedAccessPassword",m_unattendedPassword); - } - } + KConfigGroup krfbConfig(KSharedConfig::openConfig(), "Security"); + krfbConfig.writeEntry("allowUnattendedAccess", m_allowUnattendedAccess); + + if (!KrfbConfig::noWallet() && m_wallet) { + closeKWallet(); } else { krfbConfig.writeEntry("desktopPassword", KStringHandler::obscure(m_desktopPassword)); krfbConfig.writeEntry("unattendedPassword", KStringHandler::obscure(m_unattendedPassword)); krfbConfig.writeEntry("allowUnattendedAccess", m_allowUnattendedAccess); } } PendingRfbClient* InvitationsRfbServer::newClient(rfbClientPtr client) { return new PendingInvitationsRfbClient(client, this); } +void InvitationsRfbServer::openKWallet() +{ + m_wallet = Wallet::openWallet(Wallet::NetworkWallet(), 0, Wallet::Asynchronous); + if (m_wallet) { + connect(instance->m_wallet, &KWallet::Wallet::walletOpened, + this, &InvitationsRfbServer::walletOpened); + } +} + +void InvitationsRfbServer::closeKWallet() +{ + if (m_wallet && m_wallet->isOpen()) { + const QString krfbFolderName = QStringLiteral("krfb"); + if ((m_wallet->currentFolder() == krfbFolderName) || + ((m_wallet->hasFolder(krfbFolderName) || m_wallet->createFolder(krfbFolderName)) && + m_wallet->setFolder(krfbFolderName)) ) { + m_wallet->writePassword(QStringLiteral("desktopSharingPassword"), m_desktopPassword); + m_wallet->writePassword(QStringLiteral("unattendedAccessPassword"), m_unattendedPassword); + } + delete m_wallet; // closes the wallet + m_wallet = nullptr; + } +} + void InvitationsRfbServer::walletOpened(bool opened) { QString desktopPassword; QString unattendedPassword; Q_ASSERT(m_wallet); + const QString krfbFolderName = QStringLiteral("krfb"); if( opened && - ( m_wallet->hasFolder("krfb") || m_wallet->createFolder("krfb") ) && - m_wallet->setFolder("krfb") ) { + ( m_wallet->hasFolder(krfbFolderName) || m_wallet->createFolder(krfbFolderName) ) && + m_wallet->setFolder(krfbFolderName) ) { - if(m_wallet->readPassword("desktopSharingPassword", desktopPassword)==0 && + if(m_wallet->readPassword(QStringLiteral("desktopSharingPassword"), desktopPassword)==0 && !desktopPassword.isEmpty()) { m_desktopPassword = desktopPassword; emit passwordChanged(m_desktopPassword); } - if(m_wallet->readPassword("unattendedAccessPassword", unattendedPassword)==0 && + if(m_wallet->readPassword(QStringLiteral("unattendedAccessPassword"), unattendedPassword)==0 && !unattendedPassword.isEmpty()) { m_unattendedPassword = unattendedPassword; } } else { qDebug() << "Could not open KWallet, Falling back to config file"; KConfigGroup krfbConfig(KSharedConfig::openConfig(),"Security"); desktopPassword = KStringHandler::obscure(krfbConfig.readEntry( "desktopPassword", QString())); if(!desktopPassword.isEmpty()) { m_desktopPassword = desktopPassword; emit passwordChanged(m_desktopPassword); } unattendedPassword = KStringHandler::obscure(krfbConfig.readEntry( "unattendedPassword", QString())); if(!unattendedPassword.isEmpty()) { m_unattendedPassword = unattendedPassword; } } } // a random string that doesn't contain i, I, o, O, 1, l, 0 // based on KRandom::randomString() QString InvitationsRfbServer::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 == 'l') || (c == 'o') || (c == 'O') || (c == '0')) { continue; } - str += c; + str += QLatin1Char(c); length--; } return str; } - -#include "invitationsrfbserver.moc" diff --git a/krfb/invitationsrfbserver.h b/krfb/invitationsrfbserver.h index 34f7165..6b6b16d 100644 --- a/krfb/invitationsrfbserver.h +++ b/krfb/invitationsrfbserver.h @@ -1,73 +1,75 @@ /* Copyright (C) 2009-2010 Collabora Ltd @author George Goldberg @author George Kiagiadakis Copyright (C) 2007 Alessandro Praduroux 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 . */ #ifndef INVITATIONSRFBSERVER_H #define INVITATIONSRFBSERVER_H #include "rfbserver.h" namespace KWallet { class Wallet; } namespace KDNSSD { class PublicService; } class InvitationsRfbServer : public RfbServer { Q_OBJECT public: static InvitationsRfbServer *instance; static void init(); const QString& desktopPassword() const; void setDesktopPassword(const QString&); const QString& unattendedPassword() const; void setUnattendedPassword(const QString&); bool allowUnattendedAccess() const; Q_SIGNALS: void passwordChanged(const QString&); public Q_SLOTS: bool start() override; void stop() override; void toggleUnattendedAccess(bool allow); + void openKWallet(); + void closeKWallet(); protected: InvitationsRfbServer(); - virtual ~InvitationsRfbServer(); + ~InvitationsRfbServer() override; PendingRfbClient* newClient(rfbClientPtr client) override; private Q_SLOTS: void walletOpened(bool); private: KDNSSD::PublicService *m_publicService; bool m_allowUnattendedAccess; QString m_desktopPassword; QString m_unattendedPassword; KWallet::Wallet *m_wallet; QString readableRandomString(int); Q_DISABLE_COPY(InvitationsRfbServer) }; #endif // INVITATIONSRFBSERVER_H diff --git a/krfb/krfb-framebuffer.desktop b/krfb/krfb-framebuffer.desktop index c897b3a..3269470 100644 --- a/krfb/krfb-framebuffer.desktop +++ b/krfb/krfb-framebuffer.desktop @@ -1,56 +1,55 @@ [Desktop Entry] Type=ServiceType X-KDE-ServiceType=krfb/framebuffer Comment=Frame Buffer plugins for KRfb -Comment[ast]=Complementos del búfer de cuadros pa KRfb Comment[bg]=Приставки за фреймбуфер за 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[et]=KRfb kaadripuhvri plugin Comment[eu]=Irteerako bideoaren pluginak KRfb-rentzako Comment[fi]=Kehyspuskuriliitännäinen kohteelle KRfb Comment[fr]=Modules externes de sortie vidéo pour Krfb Comment[ga]=Breiseáin Mhaoláin Fráma le haghaidh KRfb Comment[gl]=Complementos de búfer de fotograma 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[id]=Plugin Frame Buffer untuk KRfb 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 papildiniai 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]=Plugins 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]=Прикључци кадробафера за КРФБ 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 -Comment[zh_CN]=KRfb 帧缓冲插件 +Comment[zh_CN]=KRfb 的帧缓冲插件 Comment[zh_TW]=KRfb 的 Frame Buffer 外掛程式 diff --git a/krfb/krfb-framebuffer.json b/krfb/krfb-framebuffer.json index c30e40a..44ea65f 100644 --- a/krfb/krfb-framebuffer.json +++ b/krfb/krfb-framebuffer.json @@ -1,40 +1,40 @@ { "KPlugin": { "Description": "Frame Buffer plugins for KRfb", - "Description[ast]": "Complementos del búfer de cuadros pa KRfb", "Description[ca@valencia]": "Connectors de «framebuffer» per al KRfb.", "Description[ca]": "Connectors de «framebuffer» per al KRfb.", "Description[cs]": "Moduly Frame bufferu pro KRfb", "Description[da]": "Framebuffer-plugins til KRfb", "Description[de]": "Framebuffer-Module für KRfb", "Description[el]": "Πρόσθετα μνήμης ανανέωσης βίντεο καρέ για το KRfb", + "Description[en_GB]": "Frame Buffer plugins for KRfb", "Description[es]": "Complementos de framebuffer para KRfb", "Description[et]": "KRfb kaadripuhvri pluginad", "Description[fi]": "Kehyspuskuriliitännäinen kohteelle KRfb", "Description[fr]": "Modules de tampons d'image pour KRfb", "Description[gl]": "Complemento de búfer de fotograma para KRfb", "Description[ia]": "Plug-ins de Frame Buffer per KRfb", "Description[id]": "Plugin Frame Buffer untuk KRfb", "Description[it]": "Estensioni del framebuffer per KRfb", "Description[ko]": "KRfb 프레임버퍼 플러그인", "Description[nl]": "Framebuffer-plugins voor KRfb", "Description[nn]": "Biletbuffer-tillegg KRfb", "Description[pl]": "Wtyczki buforów ramek dla KRfb", "Description[pt]": "'Plugins' do 'Framebuffer' para o KRfb", "Description[pt_BR]": "Plugins de framebuffers para o KRfb", "Description[ru]": "Модули буфера кадров для KRfb", "Description[sk]": "Frame Buffer modul pre KRfb", "Description[sl]": "Vstavki slikovnih medpomnilnikov za KRfb", "Description[sr@ijekavian]": "Прикључци кадробафера за КРФБ", "Description[sr@ijekavianlatin]": "Priključci kadrobafera za KRFB", "Description[sr@latin]": "Priključci kadrobafera za KRFB", "Description[sr]": "Прикључци кадробафера за КРФБ", "Description[sv]": "Insticksprogram med rambuffert för Krfb", "Description[tr]": "KRfb için Çerçeve Tamponu eklentileri", "Description[uk]": "Додатки буфера кадрів для KRfb", "Description[x-test]": "xxFrame Buffer plugins for KRfbxx", "Description[zh_CN]": "KRfb 的帧缓冲插件", "Description[zh_TW]": "KRfb 的 Frame Buffer 外掛程式" }, "X-KDE-ServiceType": "krfb/framebuffer" } diff --git a/krfb/krfb.kcfg b/krfb/krfb.kcfg index 29aefba..c1699f5 100644 --- a/krfb/krfb.kcfg +++ b/krfb/krfb.kcfg @@ -1,52 +1,53 @@ - - - + + false true 5900 true false true false xcb diff --git a/krfb/krfb.notifyrc b/krfb/krfb.notifyrc index 5f80dcc..9ab5e40 100644 --- a/krfb/krfb.notifyrc +++ b/krfb/krfb.notifyrc @@ -1,1296 +1,1278 @@ [Global] IconName=krfb Comment=Desktop Sharing Comment[af]=Werkskerm Deeling Comment[ar]=مشاركة سطح المكتب -Comment[ast]=Compartición d'escritoriu Comment[bg]=Споделяне на работния плот Comment[bn]=ডেস্কটপ ভাগাভাগি Comment[br]=Rannañ ar vurev Comment[bs]=Dijeljenje radne površine Comment[ca]=Compartir l'escriptori Comment[ca@valencia]=Compartir l'escriptori Comment[cs]=Sdílení pracovní plochy Comment[cy]=Rhannu Penbwrdd Comment[da]=Skrivebordsdeling Comment[de]=Arbeitsflächen-Freigabe Comment[el]=Κοινή χρήση επιφάνειας εργασίας Comment[en_GB]=Desktop Sharing Comment[eo]=Tabula komunigado Comment[es]=Escritorio compartido Comment[et]=Töölaua jagamine Comment[eu]=Mahaigaina partekatzea Comment[fi]=Työpöydän jakaminen Comment[fr]=Partage de bureaux Comment[ga]=Roinnt Deisce Comment[gl]=Compartición do escritorio Comment[he]=שיתוף שולחנות עבודה Comment[hi]=डेस्कटॉप साझेदारी Comment[hne]=डेस्कटाप साझेदारी Comment[hr]=Dijeljenje radne površine Comment[hu]=Munkaasztal-megosztás Comment[ia]=Compartir de scriptorio Comment[id]=Desktop Sharing Comment[is]=Skjáborðamiðlun Comment[it]=Condivisione del desktop Comment[ja]=デスクトップ共有 Comment[kk]=Үстелді ортақтастыру Comment[km]=ការ​ចែក​រំលែក​ផ្ទែ​តុ Comment[ko]=데스크톱 공유 Comment[lt]=Dalinimasis darbalaukiu Comment[lv]=Darbvirsmas koplietošana Comment[mk]=Делење на работната површина Comment[ml]=പണിയിടം പങ്കുവെക്കല്‍ Comment[mr]=डेस्कटॉप शेअरींग Comment[ms]=Perkongsian Ruang Kerja Comment[nb]=Delte skrivebord Comment[nds]=Schriefdisch-Freegaav Comment[nl]=Bureaublad delen Comment[nn]=Skrivebordsdeling Comment[pa]=ਡੈਸਕਟਾਪ ਸ਼ੇਅਰਿੰਗ Comment[pl]=Współdzielenie pulpitu 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]=Souporaba namizja Comment[sr]=Дељење површи Comment[sr@ijekavian]=Дијељење површи Comment[sr@ijekavianlatin]=Dijeljenje površi 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 Comment[zh_CN]=桌面共享 Comment[zh_HK]=桌面分享 Comment[zh_TW]=桌面分享 [Event/UserAcceptsConnection] 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í Name[da]=Bruger accepterer forbindelse Name[de]=Benutzer akzeptiert Verbindung Name[el]=Ο χρήστης δέχεται τη σύνδεση Name[en_GB]=User Accepts Connection Name[eo]=Uzanto akceptas la konekton Name[es]=El usuario acepta la conexión Name[et]=Kasutaja nõustub ühendusega Name[eu]=Erabiltzaileak konexioa onartu du Name[fi]=Käyttäjä hyväksyy yhteyden Name[fr]=L'utilisateur accepte la connexion Name[ga]=Glacann an tÚsáideoir Le Ceangal Name[gl]=O usuario acepta a conexión 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[id]=Pengguna Menyetujui Sambungan +Name[id]=Pengguna Menyetujui Koneksi 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ą Name[lv]=Lietotājs atļauj savienojumu Name[ml]=ഉപയോക്താവ് ബന്ധം സ്വീകരിക്കുന്നു Name[mr]=वापरकर्ता जुळवणी स्वीकारतो Name[nb]=Bruker godtar tilkobling Name[nds]=Bruker lett tokoppeln to Name[nl]=Gebruiker accepteert de verbinding Name[nn]=Brukar godtek tilkopling Name[pa]=ਯੂਜ਼ਰ ਨੇ ਕੁਨੈਕਸ਼ਨ ਮਨਜ਼ੂਰ ਕੀਤਾ Name[pl]=Połączenie zaakceptowane przez użytkownika 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 sprejema povezavo Name[sr]=Корисник прихвата везу 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[ug]=ئىشلەتكۈچى باغلىنىشقا قوشۇلدى Name[uk]=Користувач приймає з’єднання Name[x-test]=xxUser Accepts Connectionxx Name[zh_CN]=用户接受连接 Name[zh_TW]=使用者接受連線 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í Comment[cy]=Mae'r defnyddiwr yn derbyn y cysylltiad Comment[da]=Bruger accepterer forbindelse Comment[de]=Der Benutzer akzeptiert die Verbindung Comment[el]=Ο χρήστης δέχεται τη σύνδεση Comment[en_GB]=User accepts connection Comment[eo]=Uzanto akceptas la konekton Comment[es]=El usuario acepta la conexión Comment[et]=Kasutaja nõustub ühendusega Comment[eu]=Erabiltzaileak konexioa onartu du Comment[fi]=Käyttäjä hyväksyy yhteyden Comment[fr]=L'utilisateur accepte la connexion Comment[ga]=Glacann úsáideoir le ceangal Comment[gl]=O usuario acepta a conexión Comment[he]=המשתמש מקבל את החיבור 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[id]=Pengguna menyetujui sambungan +Comment[id]=Pengguna menyetujui koneksi 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ą Comment[lv]=Lietotājs atļauj savienojumu Comment[mk]=Корисникот прифаќа поврзување Comment[ml]=ഉപയോക്താവ് ബന്ധം സ്വീകരിക്കുന്നു Comment[mr]=वापरकर्ता जुळवणी स्वीकारतो Comment[ms]= Pengguna menerima sambungan Comment[nb]=Bruker godtar tilkobling Comment[nds]=Bruker nimmt Tokoppelanfraag an Comment[nl]=Gebruiker accepteert de verbinding Comment[nn]=Brukaren godtek tilkoplinga Comment[pa]=ਯੂਜ਼ਰ ਨੇ ਕੁਨੈਕਸ਼ਨ ਮੰਨਿਆ Comment[pl]=Użytkownik akceptuje połączenie Comment[pt]=O utilizador aceita a ligação Comment[pt_BR]=O usuário aceita a conexão Comment[ro]=Utilizatorul acceptă conexiunea Comment[ru]=Пользователь принимает соединения Comment[si]=සබැඳිය පරිශීලකයා තහවුරු කරයි Comment[sk]=Užívateľ akceptuje pripojenie Comment[sl]=Uporabnik sprejema povezavo Comment[sr]=Корисник прихвата везу Comment[sr@ijekavian]=Корисник прихвата везу Comment[sr@ijekavianlatin]=Korisnik prihvata vezu 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[ug]=ئىشلەتكۈچى باغلىنىشقا قوشۇلدى Comment[uk]=Користувач приймає з’єднання Comment[xh]=Umsebenzisi wamkela uxhulumaniso Comment[x-test]=xxUser accepts connectionxx Comment[zh_CN]=用户接受连接 Comment[zh_HK]=用戶接受連線 Comment[zh_TW]=使用者接受連線 Action=Popup [Event/UserRefusesConnection] 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í Name[da]=Bruger afslår forbindelse Name[de]=Benutzer verweigert Verbindung Name[el]=Ο χρήστης απέρριψε τη σύνδεση Name[en_GB]=User Refuses Connection Name[eo]=Uzanto rifuzas la konekton Name[es]=El usuario rechaza la conexión Name[et]=Kasutaja keeldub ühendusest Name[eu]=Erabiltzaileak konexioa ukatu du Name[fi]=Käyttäjä hylkää yhteyden Name[fr]=L'utilisateur refuse la connexion Name[ga]=Diúltaíonn an tÚsáideoir Le Ceangal Name[gl]=O usuario rexeita a conexión 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[id]=Pengguna Menampik Sambungan +Name[id]=Pengguna Menampik Koneksi 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ą Name[lv]=Lietotājs noraida savienojumu Name[ml]=ഉപയോക്താവ് ബന്ധം തിരസ്കരിക്കുന്നു Name[mr]=वापरकर्ता जुळवणी अस्वीकारतो Name[nb]=Bruker nekter tilkobling Name[nds]=Bruker wiest tokoppeln af Name[nl]=Gebruiker weigert de verbinding Name[nn]=Brukar avslår tilkopling Name[pa]=ਯੂਜ਼ਰ ਨੇ ਕੁਨੈਕਸ਼ਨ ਤੋਂ ਇਨਕਾਰ ਕੀਤਾ Name[pl]=Połączenie odrzucone przez użytkownika 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 zavrača povezavo Name[sr]=Корисник одбија везу 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[ug]=ئىشلەتكۈچى باغلىنىشنى رەت قىلدى Name[uk]=Користувач не приймає з’єднання Name[x-test]=xxUser Refuses Connectionxx Name[zh_CN]=用户拒绝连接 Name[zh_TW]=使用者拒絕連線 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í Comment[cy]=Mae'r defnyddiwr yn gwrthod y cysylltiad Comment[da]=Bruger afslår forbindelse Comment[de]=Der Benutzer verweigert die Verbindung Comment[el]=Ο χρήστης απέρριψε τη σύνδεση Comment[en_GB]=User refuses connection Comment[eo]=Uzanto rifuzas konektojn Comment[es]=El usuario rechaza la conexión Comment[et]=Kasutaja keeldub ühendusest Comment[eu]=Erabiltzaileak konexioa ukatu du Comment[fi]=Käyttäjä hylkää yhteyden Comment[fr]=L'utilisateur refuse la connexion Comment[ga]=Diúltaíonn úsáideoir ceangal Comment[gl]=O usuario rexeita a conexión Comment[he]=המשתמש מסרב לחיבור 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[id]=Pengguna menampik sambungan +Comment[id]=Pengguna menampik koneksi 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ą Comment[lv]=Lietotājs noraida savienojumu Comment[mk]=Корисникот одбива поврзување Comment[ml]=ഉപയോക്താവ് ബന്ധം തിരസ്കരിക്കുന്നു Comment[mr]=वापरकर्ता जुळवणी अस्वीकारतो Comment[ms]=Pengguna menolak sambungan Comment[nb]=Bruker nekter tilkobling Comment[nds]=Bruker wiest Tokoppelanfraag af Comment[nl]=Gebruiker weigert de verbinding Comment[nn]=Brukaren avslår tilkoplinga Comment[pa]=ਯੂਜ਼ਰ ਨੇ ਕੁਨੈਕਸ਼ਨ ਤੋਂ ਇਨਕਾਰ ਕੀਤਾ Comment[pl]=Użytkownik odrzuca połączenie Comment[pt]=O utilizador recusa a ligação Comment[pt_BR]=O usuário rejeita a conexão Comment[ro]=Utilizatorul refuză conexiunea Comment[ru]=Пользователь отклоняет соединения Comment[si]=සබැඳිය පරිශීලකයා තහවුරු නොකරයි Comment[sk]=Užívateľ odmieta pripojenie Comment[sl]=Uporabnik zavrača povezavo Comment[sr]=Корисник одбија везу Comment[sr@ijekavian]=Корисник одбија везу Comment[sr@ijekavianlatin]=Korisnik odbija vezu 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[ug]=ئىشلەتكۈچى باغلىنىشنى رەت قىلدى Comment[uk]=Користувач не приймає з’єднання Comment[xh]=Umsebenzisi wala uxhulumaniso Comment[x-test]=xxUser refuses connectionxx Comment[zh_CN]=用户拒绝连接 Comment[zh_HK]=用戶拒絕連線 Comment[zh_TW]=使用者拒絕連線使用者 Action=Popup [Event/ConnectionClosed] 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 Name[da]=Forbindelse lukket Name[de]=Verbindung geschlossen Name[el]=Η σύνδεση έκλεισε Name[en_GB]=Connection Closed Name[eo]=Konekto fermita Name[es]=Conexión cerrada Name[et]=Ühendus suletud Name[eu]=Konexioa itxi da Name[fi]=Yhteys suljettu Name[fr]=Connexion fermée Name[ga]=Ceangal Dúnta Name[gl]=Conexión pechada Name[hi]=कनेक्शन बन्द Name[hne]=कनेक्सन बन्द Name[hr]=Veza prekinuta Name[hu]=A kapcsolat megszűnt Name[ia]=Connexion claudite -Name[id]=Sambungan Ditutup +Name[id]=Koneksi Ditutup Name[is]=Tengingu lokað Name[it]=Connessione chiusa Name[ja]=接続切断 Name[kk]=Қосылымдан жабылды Name[km]=បាន​បិទ​ការ​ត​ភ្ជាប់ Name[ko]=연결이 닫힘 Name[lt]=Ryšys baigtas Name[lv]=Savienojums slēgts Name[mai]=संबंधन बन्न भ' गेल Name[ml]=ബന്ധം അടച്ചു Name[mr]=जुळवणी बंद केली Name[nb]=Forbindelsen lukket Name[nds]=Afkoppelt Name[nl]=Verbinding gesloten Name[nn]=Tilkopling vart avslutta Name[pa]=ਕੁਨੈਕਸ਼ਨ ਬੰਦ ਕੀਤਾ Name[pl]=Połączenia zakończone 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[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[ug]=باغلىنىش يېپىلدى Name[uk]=З'єднання закрито Name[x-test]=xxConnection Closedxx Name[zh_CN]=连接关闭 Name[zh_TW]=連線已關閉 Comment=Connection closed Comment[af]=Verbinding gesluit Comment[ar]=تمّ غلق الاتصال -Comment[ast]=Zarróse la conexón 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 Comment[cy]=Mae'r cysylltiad ar gau Comment[da]=Forbindelse lukket Comment[de]=Verbindung geschlossen Comment[el]=Η σύνδεση έκλεισε Comment[en_GB]=Connection closed Comment[eo]=Konekto fermita Comment[es]=Conexión cerrada Comment[et]=Ühendus suletud Comment[eu]=Konexioa itxi da Comment[fi]=Yhteys suljettu Comment[fr]=Connexion fermée Comment[ga]=Ceangal dúnta Comment[gl]=A conexión está pechada Comment[he]=החיבור נסגר Comment[hi]=कनेक्शन बन्द Comment[hne]=कनेक्सन बन्द Comment[hr]=Veza prekinuta Comment[hu]=A kapcsolat megszűnt Comment[ia]=Connexion claudite -Comment[id]=Sambungan ditutup +Comment[id]=Koneksi ditutup Comment[is]=Tengingu lokað Comment[it]=Connessione chiusa Comment[ja]=接続が閉じられました Comment[kk]=Қосылым жабылды Comment[km]=បាន​បិទ​ការ​ត​ភ្ជាប់ Comment[ko]=연결이 닫힘 Comment[lt]=Ryšys baigtas Comment[lv]=Savienojums tika slēgts Comment[mk]=Поврзувањето е затворено Comment[ml]=ബന്ധം അടച്ചു Comment[mr]=जुळवणी बंद केली Comment[ms]=Sambungan ditutup Comment[nb]=Forbindelsen lukket Comment[nds]=Afkoppelt Comment[nl]=Verbinding gesloten Comment[nn]=Tilkoplinga vart avslutta Comment[pa]=ਕੁਨੈਕਸ਼ਨ ਬੰਦ ਕੀਤਾ Comment[pl]=Połączenie zakończone 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[sl]=Povezava zaprta Comment[sq]=Lidhja u mbyll Comment[sr]=Веза је затворена Comment[sr@ijekavian]=Веза је затворена Comment[sr@ijekavianlatin]=Veza je zatvorena 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]=Алоқа узилди Comment[xh]=Uxhulumaniso luvaliwe Comment[x-test]=xxConnection closedxx Comment[zh_CN]=连接关闭 Comment[zh_HK]=連線已關閉 Comment[zh_TW]=連線已關閉 Action=Popup [Event/InvalidPassword] Name=Invalid Password Name[ar]=كلمة المرور غير صحيحة -Name[ast]=Contraseña non válida Name[bg]=Неправилна парола Name[bs]=Neispravna šifra Name[ca]=Contrasenya no vàlida Name[ca@valencia]=Contrasenya no vàlida Name[cs]=Neplatné heslo Name[da]=Ugyldig adgangskode Name[de]=Passwort ungültig Name[el]=Μη έγκυρος κωδικός πρόσβασης Name[en_GB]=Invalid Password Name[eo]=Nevalida pasvorto Name[es]=Contraseña incorrecta Name[et]=Vale parool Name[eu]=Baliogabeko pasahitza Name[fi]=Virheellinen salasana Name[fr]=Mot de passe non valable Name[ga]=Focal Faire Neamhbhailí Name[gl]=O contrasinal é incorrecto Name[hi]=अवैध पासवर्ड Name[hne]=अवैध पासवर्ड Name[hr]=Nevažeća zaporka Name[hu]=Érvénytelen jelszó Name[ia]=Contrasigno invalide -Name[id]=Sandi Tidak Sah +Name[id]=Sandi Tidak Absah Name[is]=Ógilt lykilorð Name[it]=Password non valida Name[ja]=無効なパスワード Name[kk]=Жарамсыз паролі Name[km]=ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ Name[ko]=잘못된 암호 Name[lt]=Neteisingas slaptažodžis Name[lv]=Nederīga parole Name[ml]=അസാധുവായ അടയാളവാക്ക് Name[mr]=अवैध गुप्तशब्द Name[nb]=Ugyldig passord Name[nds]=Leeg Passwoort Name[nl]=Ongeldig wachtwoord Name[nn]=Ugyldig passord Name[pa]=ਗਲਤ ਪਾਸਵਰਡ Name[pl]=Błędne hasło 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]=不正確的密碼 Comment=Invalid password Comment[af]=Ongeldige wagwoord Comment[ar]=كلمة المرور غير صحيحة -Comment[ast]=La contraseña nun ye válida 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 Comment[cy]=Cyfrinair annilys Comment[da]=Ugyldig adgangskode Comment[de]=Passwort ungültig Comment[el]=Μη έγκυρος κωδικός πρόσβασης Comment[en_GB]=Invalid password Comment[eo]=Nevalida pasvorto Comment[es]=Contraseña incorrecta Comment[et]=Vale parool Comment[eu]=Baliogabeko pasahitza Comment[fi]=Virheellinen salasana Comment[fr]=Mot de passe non valable Comment[ga]=Focal faire neamhbhailí Comment[gl]=Este contrasinal é incorrecto Comment[he]=הסיסמה שגויה Comment[hi]=अवैध पासवर्ड Comment[hne]=अवैध पासवर्ड Comment[hr]=Nevažeća šifra Comment[hu]=Érvénytelen jelszó Comment[ia]=Contrasigno invalide -Comment[id]=Sandi tidak sah +Comment[id]=Sandi tidak absah Comment[is]=Lykilorð ógilt Comment[it]=Password non valida Comment[ja]=無効なパスワード Comment[kk]=Паролі дұрыс емес Comment[km]=ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ Comment[ko]=잘못된 암호 Comment[lt]=Neteisingas slaptažodis Comment[lv]=Parole nav derīga Comment[mai]=अवैध कूटशब्द Comment[mk]=Невалидна лозинка Comment[ml]=അസാധുവായ അടയാളവാക്ക് Comment[mr]=अवैध गुप्तशब्द Comment[ms]=Kata laluan tidak sah Comment[nb]=Ugyldig passord Comment[nds]=Leeg Passwoort Comment[nl]=Ongeldig wachtwoord Comment[nn]=Passordet var ugyldig Comment[oc]=Mot de pas invalid Comment[pa]=ਗਲਤ ਪਾਸਵਰਡ Comment[pl]=Błędne hasło 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 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]=Махфий сўз ҳақиқий эмас Comment[wa]=Sicret nén valide Comment[xh]=Igama lokugqitha elingasebenziyo Comment[x-test]=xxInvalid passwordxx Comment[zh_CN]=无效密码 Comment[zh_HK]=無效的密碼 Comment[zh_TW]=不正確的密碼 Action=Popup [Event/InvalidPasswordInvitations] Name=Invalid Password Invitations Name[ar]=كلمة المرور الدعوات غير صحيحة 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 Name[da]=Ugyldige adgangskodeinvitationer Name[de]=Ungültiges Einladungs-Passwort Name[el]=Μη έγκυρος κωδικός πρόσβασης πρόσκλησης 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[fi]=Virheellinen salasana kutsuun Name[fr]=Invitations de mots de passe non valables Name[ga]=Cuirí Neamhbhailí Focal Faire Name[gl]=O contrasinal de convidado incorrecto 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[id]=Undangan Sandi Tidak Sah +Name[id]=Undangan Sandi Tidak Absah Name[is]=Ógild lykilorðsboð Name[it]=Password di invito non valida Name[ja]=招待に対する無効なパスワード Name[kk]=Жарамсыз паролімен шақыру Name[km]=ការ​អញ្ជើញ​ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ Name[ko]=잘못된 암호 초대장 Name[lt]=Neteisingas kvietimo slaptažodis Name[lv]=Nepareiza parole ar ielūgumu Name[ml]=അസാധുവായ അടയാളവാക്ക് ക്ഷണങ്ങള്‍ Name[mr]=अवैध गुप्तशब्द निमंत्रण Name[nb]=Ugyldig invitasjonspassord Name[nds]=Leeg Passwoort bi Inladen Name[nl]=Ongeldig wachtwoord uitnodiging Name[nn]=Ugyldig invitasjonspassord Name[pa]=ਗਲਤ ਪਾਸਵਰਡ ਸੱਦਾ Name[pl]=Informacja o błędnym haśle 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]=Неисправна лозинка позивнице 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[ug]=ئىناۋەتسىز ئىم تەكلىپلىرى Name[uk]=Запрошення з некоректними паролями Name[x-test]=xxInvalid Password Invitationsxx Name[zh_CN]=无效密码邀请 Name[zh_TW]=不合法的密碼邀請 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]=La parte invitada unvió una contraseña non válida. Refugóse la conexón. 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. Comment[cy]=Anfonodd y person gwahodd cyfrinair annilys. Gwrthodwyd y cysylltiad. Comment[da]=Den inviterede part sendte en ugyldig adgangskode. Forbindelse afslået. Comment[de]=Die eingeladene Person hat ein ungültiges Passwort gesendet: Verbindung abgelehnt. Comment[el]=Η πρόσκληση περιέχει μη έγκυρο κωδικό πρόσβασης. Η σύνδεση απορρίφθηκε. 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[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. Comment[gl]=A parte convidada envioulle un contrasinal incorrecto. Rexeitouse a conexión. Comment[he]=הצד המוזמן שלח סיסמה שגויה. החיבור נדחה. 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[id]=Undangan mengirimkan sebuah sandi tidak sah. Sambungan ditampik. +Comment[id]=Undangan mengirimkan sebuah sandi tidak absah. Koneksi ditampik. 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[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]=Поканетата страна испрати невалидна лозинка. Поврзувањето е одбиено. Comment[ml]=ക്ഷണിച്ച പാര്‍ട്ടി അസാധുവായ അടയാളവാക്കാണ് അയച്ചത്. ബന്ധം നിഷേധിച്ചു. Comment[ms]=Pihak yang dijemput telah menghantar kata laluan yang salah. Sambungan ditolak. Comment[nb]=Den inviterte brukeren sendte et ugyldig passord. Tilkobling nektet. Comment[nds]=De inlaadt Deel hett en leeg Passwoort angeven. Tokoppeln torüchwiest. Comment[nl]=De uitgenodigde partij stuurde een ongeldig wachtwoord. De verbinding is geweigerd. Comment[nn]=Ugyldig passordsvar på invitasjon. Tilkoplinga vart avslått. 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[sl]=Povabljena stranka je poslala neveljavno geslo. Povezava zavrnjena. Comment[sr]=Позвана страна је послала погрешну лозинку. Веза је одбијена. Comment[sr@ijekavian]=Позвана страна је послала погрешну лозинку. Веза је одбијена. Comment[sr@ijekavianlatin]=Pozvana strana je poslala pogrešnu lozinku. Veza je odbijena. 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[ug]=تەكلىپ قىلغۇچى ئەۋەتكەن ئىم ئىناۋەتسىز. باغلىنىش رەت قىلىندى. 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 Comment[zh_CN]=受邀请方发送的密码不对。连接被拒绝。 Comment[zh_HK]=被邀請的一方送出無效的密碼。已拒絕連線。 Comment[zh_TW]=邀請的人送出了不合法的密碼邀請。連線已拒絕。 Action=Popup [Event/NewConnectionOnHold] Name=New Connection on Hold Name[ar]=اتصال جديد على التوقف -Name[ast]=Conexón nueva n'espera Name[bg]=Изчакване на новата връзка Name[bs]=Nova veza je na čekanju Name[ca]=Connexió nova en espera Name[ca@valencia]=Connexió nova en espera Name[cs]=Nové spojení pozdrženo Name[da]=Ny forbindelse sat til at vente Name[de]=Neue Verbindung wartet Name[el]=Νέα σύνδεση σε αναμονή Name[en_GB]=New Connection on Hold Name[eo]=Nova konekto atendante Name[es]=Conexión nueva a la espera Name[et]=Uus ühendus ootel Name[eu]=Konexio berria itxarote moduan Name[fi]=Uusi yhteys odottaa Name[fr]=Nouvelle connexion en attente Name[ga]=Ceangal Nua Ag Fanacht Name[gl]=Nova conexión en espera Name[hi]=नया कनेक्शन होल्ड पर रखा Name[hne]=नवा कनेक्सन होल्ड मं रखा Name[hr]=Nova veza na čekanju Name[hu]=Új kapcsolat tartva Name[ia]=Nove connexion in pausa -Name[id]=Sambungan Baru sedang Tertahan +Name[id]=Koneksi Baru sedang Tertahan Name[is]=Ný tenging á bið Name[it]=Nuova connessione in attesa Name[ja]=保留中の新しい接続 Name[kk]=Жаңа қосылым күтілуде Name[km]=ការ​តភ្ជាប់​ថ្មី កំពុង​ស្ថិត​នៅ​ក្នុង​ការ​រង់ចាំ Name[ko]=새 연결 대기 중 Name[lt]=Naujas kvietimas ryšiui sulaikytas Name[lv]=Jauns savienojums gaida Name[ml]=പുതിയ ബന്ധം തത്കാലം നിര്‍ത്തിയിരിയ്ക്കുന്നു Name[mr]=नवीन जुळवणी थांबविलेली आहे Name[nb]=Ny tilkobling venter Name[nds]=Nieg Verbinnen töövt Name[nl]=Nieuwe verbinding in de wacht Name[nn]=Ny tilkopling ventar Name[pa]=ਨਵਾਂ ਕੁਨੈਕਸ਼ਨ ਹੋਲਡ ਉੱਤੇ ਹੈ Name[pl]=Nowe połączenie wstrzymane 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[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 Name[zh_CN]=新连接已搁置 Name[zh_TW]=新連線等待處理 Comment=Connection requested, user must accept Comment[af]=Verbinding versoekte, gebruiker moet aanvaar Comment[ar]=الاتصال طلب، يجب موافقة المستخدم -Comment[ast]=Solicitóse la conexón, l'usuariu ha aceutar Comment[bg]=Поискана е връзка, следва потребителят да приеме Comment[bn]=সংযোগ অনুরোধ করা হল, ব্যবহারকারীকে অবশ্যই স্বীকার করতে হবে Comment[bs]=Veza je zahtijevana, korinik mora da je prihvati Comment[ca]=Connexió sol·licitada, l'usuari l'ha d'acceptar Comment[ca@valencia]=Connexió sol·licitada, l'usuari l'ha d'acceptar Comment[cs]=Vyžadováno spojení, uživatel musí přijmout Comment[cy]=Cais wedi'i wneud am gysylltiad,rhaid i'r ddefnyddiwr ei dderbyn Comment[da]=Forbindelse forespurgt, bruger skal acceptere Comment[de]=Verbindungsanfrage, Benutzer muss bestätigen Comment[el]=Αίτηση για σύνδεση, απαιτείται παρέμβαση του χρήστη Comment[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[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 Comment[gl]=Pediuse a conexión; o usuario debe aceptar Comment[he]=נתבקש חיבור, על המשתמש לקבלו 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[id]=Sambungan diminta, pengguna harus menyetujui +Comment[id]=Koneksi diminta, pengguna harus menyetujui 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ą Comment[lv]=Ir pieprasīts jauns savienojums, kurš lietotājam ir jāapstiprina Comment[mk]=Побарано е поврзување, корисникот мора да прифати Comment[ml]=ബന്ധം ആവശ്യ‌പ്പെട്ടിട്ടുണ്ട്, ഉപയോക്താവ് സ്വീകരിക്കണം Comment[ms]=Sambungan diminta, pengguna mesti menerima Comment[nb]=Anmodning om tilkobling, bruker må godta Comment[nds]=Tokoppeln anfraagt, Bruker mutt verlöven Comment[nl]=Verbindingsverzoek, gebruiker dient toe te stemmen Comment[nn]=Ei tilkopling er førespurd. Brukaren må godta. Comment[pa]=ਕੁਨੈਕਸ਼ਨ ਦੀ ਮੰਗ ਕੀਤੀ ਗਈ, ਯੂਜ਼ਰ ਵਲੋਂ ਮਨਜ਼ੂਰ ਲਾਜ਼ਮੀ Comment[pl]=Próba połączenia, musi być zaakceptowana przez użytkownika 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[sl]=Povezava zahtevana, uporabnik mora sprejeti Comment[sr]=Захтевана је веза, корисник мора да је прихвати Comment[sr@ijekavian]=Захтијевана је веза, корисник мора да је прихвати Comment[sr@ijekavianlatin]=Zahtijevana je veza, korisnik mora da je prihvati 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[ug]=باغلىنىش ئىلتىماس قىلىندى، ئىشلەتكۈچى قوشۇلۇشى كېرەك Comment[uk]=Отримано запит на з’єднання, користувач має його прийняти Comment[xh]=Uxhulumaniso luceliwe, umsebenzisi kufanele amkele Comment[x-test]=xxConnection requested, user must acceptxx Comment[zh_CN]=连接已请求,用户必须接受 Comment[zh_HK]=已請求連線,用戶必須接受 Comment[zh_TW]=連線已要求,必須等使用者接受 Action=Popup [Event/NewConnectionAutoAccepted] Name=New Connection Auto Accepted Name[ar]=اتصال جديد مقبول تلقائيا -Name[ast]=Conexón nueva auto-aceutada Name[bg]=Автоматично приемане на новата връзка Name[bs]=Nova veza je automatski prihvaćena Name[ca]=Connexió nova acceptada automàticament Name[ca@valencia]=Connexió nova acceptada automàticament Name[cs]=Nové spojení automaticky přijato Name[da]=Ny forbindelse automatisk accepteret Name[de]=Neue Verbindung automatisch angenommen Name[el]=Αυτόματη αποδοχή νέας σύνδεσης 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[fi]=Uusi yhteys hyväksyttiin automaattisesti Name[fr]=Nouvelle connexion acceptée automatiquement Name[ga]=Ceangal nua bunaithe go huathoibríoch Name[gl]=Nova conexión aceptada automaticamente 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[id]=Sambungan Baru Tersetujui Otomatis +Name[id]=Koneksi Baru Tersetujui Otomatis Name[is]=Ný tenging sjálfvirkt samþykkt Name[it]=Nuova connessione accettata automaticamente Name[ja]=新しい接続の自動受け入れ Name[kk]=Жаңа қосылым автоқабылданды Name[km]=បាន​ទទួល​យក​ការ​តភ្ជាប់​ថ្មី​ដោយ​ស្វ័យ​ប្រវត្តិ Name[ko]=새 연결 자동 수락 Name[lt]=Naujas kvietimas ryšiui automatiškai priimtas Name[lv]=Automātiski pieņemts jauns savienojums Name[ml]=പുതിയ ബന്ധം തനിയെ സ്വീകരിക്കപ്പെട്ടു Name[nb]=Ny tilkobling automatisk godtatt Name[nds]=Nieg Verbinnen automaatsch tolaten Name[nl]=Nieuwe verbinding automatisch accepteren Name[nn]=Ny tilkopling automatisk godteken Name[pa]=ਨਵਾਂ ਕੁਨੈਕਸ਼ਨ ਆਟੋ ਮਨਜ਼ੂਰ Name[pl]=Nowe połączenie automatycznie przyjęte 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[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[ug]=يېڭى باغلىنىش ئۆزلۈكىدىن قوشۇلدى Name[uk]=Нове з’єднання автоматично прийнято Name[x-test]=xxNew Connection Auto Acceptedxx Name[zh_CN]=新连接自动接受 Name[zh_TW]=新連線自動接受 Comment=New connection automatically established Comment[af]=Nuwe verbinding automaties vasgestel Comment[ar]=اتصال جديد مفعل تلقائيا -Comment[ast]=Afitóse automáticamente la conexón nueva Comment[bg]=Новата връзка е автоматично приета Comment[bn]=নতুন সংযোগ স্বয়ংক্রীয়ভাবে স্থাপন করা হল Comment[bs]=Nova veza je automatski uspostavljena Comment[ca]=Connexió nova establerta automàticament Comment[ca@valencia]=Connexió nova establida automàticament Comment[cs]=Automaticky navázáno nové spojení Comment[cy]=Sefydlwyd cysylltiad newydd yn awtomatig Comment[da]=Ny forbindelse automatisk etableret Comment[de]=Neue Verbindung automatisch hergestellt Comment[el]=Μια νέα σύνδεση δημιουργήθηκε αυτόματα Comment[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[fi]=Uusi yhteys muodostettiin automaattisesti Comment[fr]=Nouvelle connexion établie automatiquement Comment[ga]=Ceangal nua bunaithe go huathoibríoch Comment[gl]=Estabeleceuse automaticamente unha conexión nova Comment[he]=נוצר חיבור חדש באופן אוטומטי 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[id]=Sambungan baru secara otomatis terpancang +Comment[id]=Koneksi baru secara otomatis terpancang Comment[is]=Nýjar tengingar sjálfkrafa samþykktar Comment[it]=Nuova connessione stabilita automaticamente Comment[ja]=新しい接続を自動的に確立しました Comment[kk]=Жаңа қосылым автоматты түрде орнатылды Comment[km]=បាន​បង្កើត​ការ​ត​ភ្ជាប់​ថ្មី​ដោយ​ស្វ័យ​ប្រវត្តិ Comment[ko]=새 연결이 자동으로 성립됨 Comment[lt]=Naujas ryšys užmegztas automatiškai Comment[lv]=Automātiski izveidots jauns savienojums Comment[mk]=Автоматски е воспоставено ново поврзување Comment[ml]=പുതിയ ബന്ധം യാന്ത്രികമായി സ്ഥാപിക്കപ്പെട്ടു Comment[ms]=Sambungan baru secara automatik terjalin Comment[nb]=En ny tilkobling er automatisk opprettet Comment[nds]=Nieg Verbinnen automaatsch inricht Comment[nl]=Nieuwe verbinding automatisch opgebouwd Comment[nn]=Ei ny tilkopling vart automatisk starta Comment[pa]=ਨਵਾਂ ਕੁਨੈਕਸ਼ਨ ਆਟੋਮੈਟਿਕ ਹੀ ਬਣਾਇਆ ਗਿਆ Comment[pl]=Nowe połączenie ustanowiono automatycznie 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[sl]=Nova povezava samodejno vzpostavljena Comment[sr]=Нова веза је аутоматски успостављена Comment[sr@ijekavian]=Нова веза је аутоматски успостављена Comment[sr@ijekavianlatin]=Nova veza je automatski uspostavljena 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[ug]=يېڭى باغلىنىش ئۆزلۈكىدىن قۇرۇلدى Comment[uk]=Автоматично встановлено нове з’єднання Comment[xh]=Uxhulumaniso olutsha lufunyenwe ngokuzenzekelayo Comment[x-test]=xxNew connection automatically establishedxx Comment[zh_CN]=自动建立新连接 Comment[zh_HK]=已自動建立新連線 Comment[zh_TW]=新連線自動建立 Action=Popup [Event/TooManyConnections] Name=Too Many Connections Name[ar]=اتصالات عديدة -Name[ast]=Milenta conexones Name[bg]=Твърде много връзки Name[bs]=Previše veza Name[ca]=Massa connexions Name[ca@valencia]=Massa connexions Name[cs]=Příliš mnoho spojení Name[da]=For mange forbindelser Name[de]=Zu viele Verbindungen Name[el]=Πάρα πολλές συνδέσεις Name[en_GB]=Too Many Connections Name[eo]=Tro multaj konektoj Name[es]=Demasiadas conexiones Name[et]=Liiga palju ühendusi Name[eu]=Konexio gehiegi Name[fi]=Liikaa yhteyksiä Name[fr]=Trop de connexions Name[ga]=An Iomarca Ceangal Name[gl]=Demasiadas conexións Name[hi]=बहुत सारे कनेक्शन Name[hne]=बहुत अकन कनेक्सन Name[hr]=Previše veza Name[hu]=Túl sok kapcsolat Name[ia]=Nimie connexiones -Name[id]=Terlalu Banyak Sambungan +Name[id]=Terlalu Banyak Koneksi 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ų Name[lv]=Pārāk daudz savienojumu Name[ml]=വളരെ അധികം ബന്ധങ്ങള്‍ Name[nb]=For mange tilkoblinger Name[nds]=To vele Verbinnen Name[nl]=Teveel verbindingen Name[nn]=For mange tilkoplingar Name[pa]=ਬਹੁਤ ਸਾਰੇ ਕੁਨੈਕਸ਼ਨ Name[pl]=Zbyt wiele połączeń 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]=Исувише веза 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[ug]=باغلىنىش بەك كۆپ Name[uk]=Забагато з’єднань Name[x-test]=xxToo Many Connectionsxx Name[zh_CN]=连接过多 Name[zh_TW]=太多連線 Comment=Busy, connection refused Comment[af]=Besig, verbinding geweier Comment[ar]=مشغول، الإتصال رفض -Comment[ast]=Ocupáu, refugóse la conexón Comment[bg]=Заето. Връзката е отказана. Comment[bn]=ব্যস্ত, সংযোগ অস্বীকার করল Comment[br]=Dalc'het, kevreadenn disteuleret Comment[bs]=Zauzeto, veza je odbijena Comment[ca]=Ocupat, connexió rebutjada Comment[ca@valencia]=Ocupat, connexió rebutjada Comment[cs]=Zaneprázdněn, spojení odmítnuto Comment[cy]=Prysur, gwrthodwyd y cysylltiad Comment[da]=Optaget, forbindelse afslået Comment[de]=Beschäftigt, Verbindung abgelehnt Comment[el]=Απασχολημένος, η σύνδεση απορρίφθηκε Comment[en_GB]=Busy, connection refused Comment[eo]=Okupata, konekto rifuzita Comment[es]=Ocupado, conexión rechazada Comment[et]=Hõivatud, ühendusest keelduti Comment[eu]=Lanpetuta, konexioa ukatu da Comment[fi]=Varattu, yhteys hylättiin Comment[fr]=Occupé. Connexion refusée Comment[ga]=Gnóthach; ceangal diúltaithe Comment[gl]=Ocupado, rexeitouse a conexión. Comment[he]=תפוס, החיבור נדחה 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[id]=Sibuk, sambungan ditampik +Comment[id]=Sibuk, koneksi ditampik 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 Comment[lv]=Aizņemts, savienojums noraidīts Comment[mk]=Зафатено, поврзувањето е одбиено Comment[ml]=തിരക്കിലാണ്, ബന്ധം നിഷേധിച്ചു Comment[ms]=Sibuk, sambungan ditolak Comment[nb]=Opptatt, tilkobling nektet Comment[nds]=Bunnen, Verbinnen torüchwiest Comment[nl]=Bezet, verbinding geweigerd Comment[nn]=Oppteken, så tilkoplinga vart avslått Comment[pa]=ਬਿਜ਼ੀ, ਕੁਨੈਕਸ਼ਨ ਤੋਂ ਇਨਕਾਰ Comment[pl]=Zajęte, połączenie odrzucone 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[sl]=Zaposlen, povezava zavrnjena Comment[sr]=Заузето, веза је одбијена Comment[sr@ijekavian]=Заузето, веза је одбијена Comment[sr@ijekavianlatin]=Zauzeto, veza je odbijena 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[ug]=ئالدىراش، باغلىنىش رەت قىلىندى Comment[uk]=Зайнято, у з’єднанні відмовлено Comment[uz]=Band, aloqa rad etildi Comment[uz@cyrillic]=Банд, алоқа рад этилди Comment[xh]=Uxhulumaniso, olu xakekileyo lwaliwe Comment[x-test]=xxBusy, connection refusedxx Comment[zh_CN]=对方处于忙碌状态,连接被拒绝 Comment[zh_HK]=忙碌,已拒絕連線 Comment[zh_TW]=忙碌,連線被拒 Action=Popup [Event/UnexpectedConnection] 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í Name[da]=Uventet forbindelse Name[de]=Unerwartete Verbindung Name[el]=Μη αναμενόμενη σύνδεση Name[en_GB]=Unexpected Connection Name[eo]=Neatendita konekto Name[es]=Conexión inesperada Name[et]=Ootamatu ühendus Name[eu]=Ustekabeko konexioa Name[fi]=Odottamaton yhteys Name[fr]=Connexion inattendue Name[ga]=Ceangal Gan Choinne Name[gl]=Conexión non agardada Name[hi]=अप्रत्याशित कनेक्शन Name[hne]=अप्रत्यासित कनेक्सन Name[hr]=Neočekivana veza Name[hu]=Nem várt kapcsolat Name[ia]=Connexion impreviste -Name[id]=Sambungan Tak Terduga +Name[id]=Koneksi Tak Terduga Name[is]=Óvænt Tenging Name[it]=Connessione inattesa Name[ja]=予期しない接続 Name[kk]=Күтпеген қосылым Name[km]=ការ​តភ្ជាប់​ដែល​មិន​បាន​រំពឹង​ទុក Name[ko]=예상하지 않은 연결 Name[lt]=Netikėtas kvietimas ryšiui Name[lv]=Negaidīts savienojums Name[ml]=അപ്രതീക്ഷിതമായ ബന്ധം Name[nb]=Uventet tilkobling Name[nds]=Nich verwacht Tokoppeln Name[nl]=Onverwachte verbinding Name[nn]=Uventa tilkopling Name[pa]=ਅਣਜਾਣ ਕੁਨੈਕਸ਼ਨ Name[pl]=Niespodziewane połączenie 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]=未预料的连接 Name[zh_TW]=未知的連線 Comment=Received unexpected connection, abort Comment[af]=Ontvang onverwagte verbinding, staak Comment[ar]=استقبال اتصال غير متوقع، إنهاء -Comment[ast]=Recibióse una conexón inesperada, albortando Comment[bg]=Получена е неочаквана връзка. Прекъсване. Comment[bn]=অপ্রত্যাশিত সংযোগ গ্রহণ করল, বাতিল করুন Comment[bs]=Primljena je neočekivana veza, prekini Comment[ca]=S'ha rebut una connexió inesperada, avortant Comment[ca@valencia]=S'ha rebut una connexió inesperada, avortant Comment[cs]=Obdrženo neočekávané spojení, přerušeno Comment[cy]=Derbynwyd cysylltiad annisgwyl,terfynu Comment[da]=Modtog uventet forbindelse, afbrød Comment[de]=Unerwartete Verbindung hergestellt, Abbruch Comment[el]=Λήφθηκε μια μη αναμενόμενη σύνδεση· εγκατάλειψη Comment[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[fi]=Vastaanotettiin odottamaton yhteys, lopeta Comment[fr]=Connexion inattendue reçue. Annulation Comment[ga]=Fuarthas ceangal gan choinne, á thobscor -Comment[gl]=Recibiuse unha conexión non agardada; cancélase +Comment[gl]=Recibiuse unha conexión non agardada; interrómpese Comment[he]=נתקבל חיבור בלתי צפוי, בוטל 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[id]=Diperoleh sambungan tak terduga, gugurkan +Comment[id]=Diperoleh koneksi tak terduga, gugurkan 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 Comment[lv]=Saņemts negaidīts savienojums, pārtraukts Comment[mk]=Примено е неочекувано поврзување, се прекинува Comment[ml]=അപ്രതീക്ഷിതമായ ബന്ധം ലഭിച്ചു, നിരസിക്കുക Comment[ms]=Menerima sambungan luar jangka, menamatkan Comment[nb]=Mottok uventet tilkobling, avbrutt Comment[nds]=Unverwacht Verbinnen kregen, afbraken Comment[nl]=Ontving een onverwachte verbinding, afgebroken Comment[nn]=Fekk ei uventa tilkopling, så avbryt no Comment[pl]=Otrzymano niespodziewane połączenie. Przerwane. 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]=Примљена је неочекивана веза, прекидам Comment[sr@ijekavian]=Примљена је неочекивана веза, прекидам Comment[sr@ijekavianlatin]=Primljena je neočekivana veza, prekidam 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[ug]=ئويلاشمىغان باغلىنىشنى تاپشۇرۇۋالدى، توختات Comment[uk]=Отримано з’єднання, яке не очікувалось, припиняється Comment[xh]=Ufumene uxhulumaniso olungalindelekanga, lahla Comment[x-test]=xxReceived unexpected connection, abortxx Comment[zh_CN]=收到意外连接,已中止 Comment[zh_HK]=接收到非預期的連線,中止 Comment[zh_TW]=已接收到未知的連線,中止。 Action=Popup diff --git a/krfb/krfb.qrc b/krfb/krfb.qrc new file mode 100644 index 0000000..83260c0 --- /dev/null +++ b/krfb/krfb.qrc @@ -0,0 +1,6 @@ + + + + krfbui.rc + + diff --git a/krfb/krfbui.rc b/krfb/krfbui.rc new file mode 100644 index 0000000..70980c9 --- /dev/null +++ b/krfb/krfbui.rc @@ -0,0 +1,7 @@ + + + + + + + diff --git a/krfb/main.cpp b/krfb/main.cpp index 5606cb2..b46c9c4 100644 --- a/krfb/main.cpp +++ b/krfb/main.cpp @@ -1,151 +1,151 @@ /*************************************************************************** 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 "mainwindow.h" #include "trayicon.h" #include "invitationsrfbserver.h" #include "krfbconfig.h" #include "krfb_version.h" #include #include #include #include #include #include #include #include #include #include #include #include static const char description[] = I18N_NOOP("VNC-compatible server to share " "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, + KMessageBox::error(nullptr, 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; } static void checkOldX11PluginConfig() { if (KrfbConfig::preferredFrameBufferPlugin() == QStringLiteral("x11")) { qDebug() << "Detected deprecated configuration: preferredFrameBufferPlugin = x11"; KConfigSkeletonItem *config_item = KrfbConfig::self()->findItem( QStringLiteral("preferredFrameBufferPlugin")); if (config_item) { config_item->setProperty(QStringLiteral("xcb")); KrfbConfig::self()->save(); qDebug() << " Fixed preferredFrameBufferPlugin from x11 to xcb."; } } } int main(int argc, char *argv[]) { QApplication app(argc, argv); KLocalizedString::setApplicationDomain("krfb"); - KAboutData aboutData("krfb", + KAboutData aboutData(QStringLiteral("krfb"), i18n("Desktop Sharing"), QStringLiteral(KRFB_VERSION_STRING), i18n(description), KAboutLicense::GPL, i18n("(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(i18n("George Goldberg"), i18n("Telepathy tubes support"), - "george.goldberg@collabora.co.uk"); + QStringLiteral("george.goldberg@collabora.co.uk")); aboutData.addAuthor(i18n("George Kiagiadakis"), QString(), - "george.kiagiadakis@collabora.co.uk"); - aboutData.addAuthor(i18n("Alessandro Praduroux"), i18n("KDE4 porting"), "pradu@pradu.it"); - aboutData.addAuthor(i18n("Tim Jansen"), i18n("Original author"), "tim@tjansen.de"); + QStringLiteral("george.kiagiadakis@collabora.co.uk")); + aboutData.addAuthor(i18n("Alessandro Praduroux"), i18n("KDE4 porting"), QStringLiteral("pradu@pradu.it")); + aboutData.addAuthor(i18n("Tim Jansen"), i18n("Original author"), QStringLiteral("tim@tjansen.de")); aboutData.addCredit(i18n("Johannes E. Schindelin"), i18n("libvncserver")); aboutData.addCredit(i18n("Const Kaplinsky"), i18n("TightVNC encoder")); aboutData.addCredit(i18n("Tridia Corporation"), i18n("ZLib encoder")); aboutData.addCredit(i18n("AT&T Laboratories Boston"), i18n("original VNC encoders and " "protocol design")); - QCommandLineParser parser; KAboutData::setApplicationData(aboutData); - parser.addVersionOption(); - parser.addHelpOption(); + + QCommandLineParser parser; aboutData.setupCommandLine(&parser); + const QCommandLineOption nodialogOption(QStringList{ QStringLiteral("nodialog") }, i18n("Do not show the invitations management dialog at startup")); + parser.addOption(nodialogOption); + parser.process(app); aboutData.processCommandLine(&parser); KDBusService service(KDBusService::Unique, &app); - parser.addOption(QCommandLineOption(QStringList() << QLatin1String("nodialog"), i18n("Do not show the invitations management dialog at startup"))); - app.setQuitOnLastWindowClosed(false); if (QX11Info::isPlatformX11()) { if (!checkX11Capabilities()) { return 1; } // upgrade the configuration checkOldX11PluginConfig(); } //init the core InvitationsRfbServer::init(); //init the GUI MainWindow mainWindow; TrayIcon trayicon(&mainWindow); if (KrfbConfig::startMinimized()) { mainWindow.hide(); } else if (app.isSessionRestored() && KMainWindow::canBeRestored(1)) { mainWindow.restore(1, false); - } else if (!parser.isSet("nodialog")) { + } else if (!parser.isSet(nodialogOption)) { mainWindow.show(); } sigset_t sigs; sigemptyset(&sigs); sigaddset(&sigs, SIGPIPE); - sigprocmask(SIG_BLOCK, &sigs, 0); + sigprocmask(SIG_BLOCK, &sigs, nullptr); return app.exec(); } diff --git a/krfb/mainwindow.cpp b/krfb/mainwindow.cpp index b88cd93..8de7822 100644 --- a/krfb/mainwindow.cpp +++ b/krfb/mainwindow.cpp @@ -1,266 +1,293 @@ /* This file is part of the KDE project Copyright (C) 2007 Alessandro Praduroux Copyright (C) 2013 Amandeep Singh 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 "mainwindow.h" #include "invitationsrfbserver.h" #include "krfbconfig.h" #include "ui_configtcp.h" #include "ui_configsecurity.h" #include "ui_configframebuffer.h" #include #include #include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include class TCP: public QWidget, public Ui::TCP { public: - TCP(QWidget *parent = 0) : QWidget(parent) { + TCP(QWidget *parent = nullptr) : QWidget(parent) { setupUi(this); } }; class Security: public QWidget, public Ui::Security { public: - Security(QWidget *parent = 0) : QWidget(parent) { + Security(QWidget *parent = nullptr) : QWidget(parent) { setupUi(this); + walletWarning = new KMessageWidget(this); + walletWarning->setText(i18n("Storing passwords in config file is insecure!")); + walletWarning->setCloseButtonVisible(false); + walletWarning->setMessageType(KMessageWidget::Warning); + walletWarning->hide(); + vboxLayout->addWidget(walletWarning); + + // show warning when "noWallet" checkbox is checked + QObject::connect(kcfg_noWallet, &QCheckBox::toggled, [this](bool checked){ + walletWarning->setVisible(checked); + }); } + + KMessageWidget *walletWarning = nullptr; }; class ConfigFramebuffer: public QWidget, public Ui::Framebuffer { public: - ConfigFramebuffer(QWidget *parent = 0) : QWidget(parent) { + ConfigFramebuffer(QWidget *parent = nullptr) : QWidget(parent) { setupUi(this); // hide the line edit with framebuffer string kcfg_preferredFrameBufferPlugin->hide(); // fill drop-down combo with a list of real existing plugins this->fillFrameBuffersCombo(); // initialize combo with currently configured framebuffer plugin cb_preferredFrameBufferPlugin->setCurrentText(KrfbConfig::preferredFrameBufferPlugin()); // connect signals between combo<->lineedit // if we change selection in combo, lineedit is updated QObject::connect(cb_preferredFrameBufferPlugin, &QComboBox::currentTextChanged, kcfg_preferredFrameBufferPlugin, &QLineEdit::setText); } void fillFrameBuffersCombo() { const QVector plugins = KPluginLoader::findPlugins( QStringLiteral("krfb"), [](const KPluginMetaData & md) { return md.serviceTypes().contains(QStringLiteral("krfb/framebuffer")); }); QSet unique; QVectorIterator i(plugins); i.toBack(); while (i.hasPrevious()) { const KPluginMetaData &metadata = i.previous(); if (unique.contains(metadata.pluginId())) continue; cb_preferredFrameBufferPlugin->addItem(metadata.pluginId()); unique.insert(metadata.pluginId()); } } }; MainWindow::MainWindow(QWidget *parent) : KXmlGuiWindow(parent) { setAttribute(Qt::WA_DeleteOnClose, false); m_passwordEditable = false; m_passwordLineEdit = new KLineEdit(this); m_passwordLineEdit->setVisible(false); m_passwordLineEdit->setAlignment(Qt::AlignHCenter); QWidget *mainWidget = new QWidget; m_ui.setupUi(mainWidget); - m_ui.krfbIconLabel->setPixmap(QIcon::fromTheme("krfb").pixmap(128)); + m_ui.krfbIconLabel->setPixmap(QIcon::fromTheme(QStringLiteral("krfb")).pixmap(128)); m_ui.enableUnattendedCheckBox->setChecked( InvitationsRfbServer::instance->allowUnattendedAccess()); setCentralWidget(mainWidget); connect(m_ui.passwordEditButton, &QToolButton::clicked, this, &MainWindow::editPassword); connect(m_ui.enableSharingCheckBox, &QCheckBox::toggled, this, &MainWindow::toggleDesktopSharing); connect(m_ui.enableUnattendedCheckBox, &QCheckBox::toggled, InvitationsRfbServer::instance, &InvitationsRfbServer::toggleUnattendedAccess); connect(m_ui.unattendedPasswordButton, &QPushButton::clicked, this, &MainWindow::editUnattendedPassword); connect(m_ui.addressAboutButton, &QToolButton::clicked, this, &MainWindow::aboutConnectionAddress); connect(m_ui.unattendedAboutButton, &QToolButton::clicked, this, &MainWindow::aboutUnattendedMode); connect(InvitationsRfbServer::instance, &InvitationsRfbServer::passwordChanged, this, &MainWindow::passwordChanged); // Figure out the address int port = KrfbConfig::port(); - QList interfaceList = QNetworkInterface::allInterfaces(); - foreach(const QNetworkInterface & interface, interfaceList) { + const QList interfaceList = QNetworkInterface::allInterfaces(); + for (const QNetworkInterface& interface : interfaceList) { if(interface.flags() & QNetworkInterface::IsLoopBack) continue; if(interface.flags() & QNetworkInterface::IsRunning && !interface.addressEntries().isEmpty()) - m_ui.addressDisplayLabel->setText(QString("%1 : %2") + m_ui.addressDisplayLabel->setText(QStringLiteral("%1 : %2") .arg(interface.addressEntries().first().ip().toString()) .arg(port)); } //Figure out the password m_ui.passwordDisplayLabel->setText( InvitationsRfbServer::instance->desktopPassword()); KStandardAction::quit(QCoreApplication::instance(), SLOT(quit()), actionCollection()); KStandardAction::preferences(this, SLOT(showConfiguration()), actionCollection()); setupGUI(); if (KrfbConfig::allowDesktopControl()) { m_ui.enableSharingCheckBox->setChecked(true); } setAutoSaveSettings(); } MainWindow::~MainWindow() { } void MainWindow::editPassword() { if(m_passwordEditable) { m_passwordEditable = false; - m_ui.passwordEditButton->setIcon(QIcon::fromTheme("document-properties")); + m_ui.passwordEditButton->setIcon(QIcon::fromTheme(QStringLiteral("document-properties"))); m_ui.passwordGridLayout->removeWidget(m_passwordLineEdit); InvitationsRfbServer::instance->setDesktopPassword( m_passwordLineEdit->text()); m_ui.passwordDisplayLabel->setText( InvitationsRfbServer::instance->desktopPassword()); m_passwordLineEdit->setVisible(false); } else { m_passwordEditable = true; - m_ui.passwordEditButton->setIcon(QIcon::fromTheme("document-save")); + m_ui.passwordEditButton->setIcon(QIcon::fromTheme(QStringLiteral("document-save"))); m_ui.passwordGridLayout->addWidget(m_passwordLineEdit,0,0); m_passwordLineEdit->setText( InvitationsRfbServer::instance->desktopPassword()); m_passwordLineEdit->setVisible(true); m_passwordLineEdit->setFocus(Qt::MouseFocusReason); } } void MainWindow::editUnattendedPassword() { KNewPasswordDialog dialog(this); dialog.setPrompt(i18n("Enter a new password for Unattended Access")); if(dialog.exec()) { InvitationsRfbServer::instance->setUnattendedPassword(dialog.password()); } } void MainWindow::toggleDesktopSharing(bool enable) { if(enable) { if(!InvitationsRfbServer::instance->start()) { KMessageBox::error(this, i18n("Failed to start the krfb server. Desktop sharing " "will not work. Try setting another port in the settings " "and restart krfb.")); } } else { InvitationsRfbServer::instance->stop(); if(m_passwordEditable) { m_passwordEditable = false; m_passwordLineEdit->setVisible(false); - m_ui.passwordEditButton->setIcon(QIcon::fromTheme("document-properties")); + m_ui.passwordEditButton->setIcon(QIcon::fromTheme(QStringLiteral("document-properties"))); } } } void MainWindow::passwordChanged(const QString& password) { m_passwordLineEdit->setText(password); m_ui.passwordDisplayLabel->setText(password); } void MainWindow::aboutConnectionAddress() { KMessageBox::about(this, i18n("This field contains the address of your computer and the port number, separated by a colon.\n\nThe address is just a hint - you can use any address that can reach your computer.\n\nDesktop Sharing tries to guess your address from your network configuration, but does not always succeed in doing so.\n\nIf your computer is behind a firewall it may have a different address or be unreachable for other computers."), i18n("KDE Desktop Sharing")); } void MainWindow::aboutUnattendedMode() { KMessageBox::about(this, i18n("Any remote user with normal desktop sharing password will have to be authenticated.\n\nIf unattended access is on, and the remote user provides unattended mode password, desktop sharing access will be granted without explicit confirmation."), i18n("KDE Desktop Sharing")); } void MainWindow::showConfiguration() { static QString s_prevFramebufferPlugin; + static bool s_prevNoWallet; // ^^ needs to be static, because lambda will be called long time // after showConfiguration() ends, so auto variable would go out of scope // save previously selected framebuffer plugin config s_prevFramebufferPlugin = KrfbConfig::preferredFrameBufferPlugin(); + s_prevNoWallet = KrfbConfig::noWallet(); - if (KConfigDialog::showDialog("settings")) { + if (KConfigDialog::showDialog(QStringLiteral("settings"))) { return; } - KConfigDialog *dialog = new KConfigDialog(this, "settings", KrfbConfig::self()); - dialog->addPage(new TCP, i18n("Network"), "network-wired"); - dialog->addPage(new Security, i18n("Security"), "security-high"); - dialog->addPage(new ConfigFramebuffer, i18n("Screen capture"), "video-display"); + KConfigDialog *dialog = new KConfigDialog(this, QStringLiteral("settings"), KrfbConfig::self()); + dialog->addPage(new TCP, i18n("Network"), QStringLiteral("network-wired")); + dialog->addPage(new Security, i18n("Security"), QStringLiteral("security-high")); + dialog->addPage(new ConfigFramebuffer, i18n("Screen capture"), QStringLiteral("video-display")); dialog->show(); connect(dialog, &KConfigDialog::settingsChanged, [this] () { // check if framebuffer plugin config has changed if (s_prevFramebufferPlugin != KrfbConfig::preferredFrameBufferPlugin()) { KMessageBox::information(this, i18n("To apply framebuffer plugin setting, " "you need to restart the program.")); } + // check if kwallet config has changed + if (s_prevNoWallet != KrfbConfig::noWallet()) { + // try to apply settings immediately + if (KrfbConfig::noWallet()) { + InvitationsRfbServer::instance->closeKWallet(); + } else { + InvitationsRfbServer::instance->openKWallet(); + // erase stored passwords from krfbconfig file + KConfigGroup securityConfigGroup(KSharedConfig::openConfig(), "Security"); + securityConfigGroup.deleteEntry("desktopPassword"); + securityConfigGroup.deleteEntry("unattendedPassword"); + } + } }); } void MainWindow::readProperties(const KConfigGroup& group) { if (group.readEntry("Visible", true)) { show(); } KMainWindow::readProperties(group); } void MainWindow::saveProperties(KConfigGroup& group) { group.writeEntry("Visible", isVisible()); KMainWindow::saveProperties(group); } - -#include "mainwindow.moc" diff --git a/krfb/mainwindow.h b/krfb/mainwindow.h index fab6e69..9f2939e 100644 --- a/krfb/mainwindow.h +++ b/krfb/mainwindow.h @@ -1,49 +1,49 @@ /* This file is part of the KDE project Copyright (C) 2007 Alessandro Praduroux Copyright (C) 2013 Amandeep Singh 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 MANAGEINVITATIONSDIALOG_H -#define MANAGEINVITATIONSDIALOG_H +#ifndef KRFB_MAINWINDOW_H +#define KRFB_MAINWINDOW_H #include "ui_mainwidget.h" #include class KLineEdit; class MainWindow : public KXmlGuiWindow { Q_OBJECT public: - MainWindow(QWidget *parent = 0); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; public Q_SLOTS: void showConfiguration(); protected: void readProperties(const KConfigGroup & group) override; void saveProperties(KConfigGroup & group) override; private Q_SLOTS: void editPassword(); void editUnattendedPassword(); void toggleDesktopSharing(bool enable); void passwordChanged(const QString&); void aboutConnectionAddress(); void aboutUnattendedMode(); private: Ui::MainWidget m_ui; bool m_passwordEditable; KLineEdit *m_passwordLineEdit; }; #endif diff --git a/krfb/org.kde.krfb.appdata.xml b/krfb/org.kde.krfb.appdata.xml index 7cd4cfd..eea2f67 100644 --- a/krfb/org.kde.krfb.appdata.xml +++ b/krfb/org.kde.krfb.appdata.xml @@ -1,118 +1,141 @@ org.kde.krfb.desktop CC0-1.0 GPL-2.0+ Krfb - Krfb Krfb Krfb Krfb Krfb Krfb Krfb Krfb Krfb Krfb Krfb Krfb Krfb Krfb Krfb Krfb Krfb Krfb Krfb Krfb Krfb Krfb Krfb КРФБ KRFB КРФБ KRFB Krfb Krfb Krfb xxKrfbxx Krfb + Krfb Desktop sharing - Compartición d'escritoriu Compartició de l'escriptori Compartició de l'escriptori Sdílení pracovní plochy Skrivebordsdeling Freigabe der Arbeitsfläche Κοινή χρήση επιφάνειας εργασίας Desktop sharing Compartir el escritorio Työpöydän jako Partage de bureau Compartición do escritorio Compartir de scriptorio Desktop sharing Condivisione del desktop 데스크톱 공유 Bureaublad delen Współdzielenie pulpitu Partilha do ecrã Compartilhamento de tela Общий рабочий стол Zdieľanie pracovnej plochy Souporaba namizja Дељење површи Deljenje površi Дељење површи Deljenje površi Skrivbordsdelning Masaüstü paylaşımı Спільне користування стільницею xxDesktop sharingxx 桌面共享 + 桌面分享

Krfb Desktop Sharing is a server application that allows you to share your current session with a user on another machine, who can use a VNC client to view or even control the desktop.

-

Krfb ye una aplicación sirvidora que te permite compartir la to sesión actual con un usuariu n'otra máquina que puea usar un veceru VNC pa ver o controlar l'escritoriu.

El Krfb és una aplicació de servidor que permet compartir la vostra sessió actual amb un usuari en una altra màquina, la qual pot emprar un client VNC per veure o controlar l'escriptori.

El Krfb és una aplicació de servidor que permet compartir la vostra sessió actual amb un usuari en una altra màquina, la qual pot emprar un client VNC per veure o controlar l'escriptori.

Krfb-skrivebordsdeling er et serverprogram der giver dig mulighed for at dele din nuværende session med en bruger på en anden maskine som kan bruge en VNC-klient til at vise eller endda styrer skrivebordet.

Krfb ist eine Serveranwendung, welche die gemeinsame Benutzung der aktuellen Sitzung mit einem Benutzer auf einem anderen Rechner ermöglicht, der mit Hilfe eines VNC-Programms den Bildschirminhalt sehen oder sogar die Arbeitsfläche bedienen kann.

Η κοινή χρήση επιφάνειας εργασίας Krfb είναι μια εφαρμογή εξυπηρετητή που σας επιτρέπει να μοιράζεστε την τρέχουσα συνεδρία σας με έναν χρήστη σε άλλο μηχάνημα, ο οποίος μπορεί να χρησιμοποιεί έναν πελάτη VNC για να παρακολουθεί ή και να ελέγχει την επιφάνεια εργασίας σας.

Krfb Desktop Sharing is a server application that allows you to share your current session with a user on another machine, who can use a VNC client to view or even control the desktop.

Krfb para compartir el escritorio es una aplicación de servidor que le permite compartir su sesión actual con un usuario de otra máquina, que puede usar un cliente VNC para ver e incluso controlar su escritorio.

Krfb-työpöytäjako on palvelinsovellus, jolla voit jakaa nykyisen istuntosi toisen koneen käyttäjälle, joka voi VNC-asiakkaalla nähdä tai jopa hallita työpöytääsi.

Le partage de bureau Krfb est une application de serveur qui vous permet de partager votre session courante avec un utilisateur sur une autre machine, qui peut utiliser un client VNC pour afficher et même contrôler le bureau.

Krfb é un aplicativo de servidor que permite compartir a sesión actual cun usuario que está noutro equipo, que pode usar un cliente VNC para ver ou mesmo controlar o escritorio.

-

Krfb Desktop Sharing adalah aplikasi server yang membolehkan Anda untuk berbagi sesi Anda saat ini dengan pengguna di mesin lain, yang bisa menggunakan klien VNC untuk menampilkan atau bahkan mengendalikan desktop.

+

Krfb Desktop Sharing adalah aplikasi server yang memungkinkan kamu untuk berbagi sesimu saat ini dengan pengguna di mesin lain, yang bisa menggunakan klien VNC untuk menampilkan atau bahkan mengendalikan desktop.

Condivisione del desktop Krfb è un'applicazione server che permette di condividere la sessione attuale con un utente su un'altra macchina, che potrà usare un client VNC per visualizzare ed anche controllare il desktop.

Krfb 데스크톱 공유는 현재 세션을 다른 머신의 사용자와 VNC를 통해서 공유하거나 원격 제어를 요청할 수 있는 서버 프로그램입니다.

Bureaublad delen is een server-applicatie die u in staat stelt uw huidige sessie te delen met een gebruiker op een andere machine, die een VNC-client kan gebruiken om uw bureaublad te bekijken of zelfs te besturen.

Współdzielenie pulpitu Krfb jest aplikacją serwerową, która umożliwia współdzielenie twojej bieżącej sesji z użytkownikiem na innym komputerze, który może użyć klienta VNC do oglądania,a a nawet sterowania twoim pulpitem.

A Partilha de Ecrã Krfb é uma aplicação de servidor que lhe permite partilhar a sua sessão actual com um utilizador noutra máquina, o qual poderá usar um cliente de VNC para ver ou mesmo controlar o ambiente de trabalho.

+

Krfb Desktop Sharing é um aplicativo de servidor que lhe permite compartilhar a sua sessão atual com um usuário em outra máquina, que poderá usar um cliente de VNC para ver ou mesmo controlar a máquina.

Krfb является сервером, который позволяет вам предоставлять доступ к своему текущему сеансу пользователю на другом компьютере, который использует клиент VNC для просмотра или управления вашим рабочим столом.

Krfb je serverová aplikácia, ktorá vám umožní zdieľať vaše aktuálne sedenie s používateľom na inom stroji, ktorý môže používať VNC klienta na pripojenie alebo ovládanie stanice.

Souporaba namizja Krfb je strežniški program, ki vam dovoli, da delite vašo trenutno sejo z uporabnikom na drugem računalniku, ki ima odjemalec VNC. Uporabnik lahko gleda ali celo nadzira namizje.

КРФБ је серверски програм за дељење површи, којим можете да поделите своју текућу сесију са корисником на другој машини. Удаљени корисник може да употреби неки ВНЦ клијент за гледање површи, па чак и управљање њоме.

KRFB je serverski program za deljenje površi, kojim možete da podelite svoju tekuću sesiju sa korisnikom na drugoj mašini. Udaljeni korisnik može da upotrebi neki VNC klijent za gledanje površi, pa čak i upravljanje njome.

КРФБ је серверски програм за дељење површи, којим можете да поделите своју текућу сесију са корисником на другој машини. Удаљени корисник може да употреби неки ВНЦ клијент за гледање површи, па чак и управљање њоме.

KRFB je serverski program za deljenje površi, kojim možete da podelite svoju tekuću sesiju sa korisnikom na drugoj mašini. Udaljeni korisnik može da upotrebi neki VNC klijent za gledanje površi, pa čak i upravljanje njome.

Krfb-skrivbordsdelning är ett serverprogram som gör det möjligt att dela aktuell session med en användare på en annan dator, som kan använda en VNC-klient för att betrakta eller till och med kontrollera skrivbordet.

Krfb Masaüstü Paylaşımı, mevcut oturumu masaüstünü görüntülemek veya kontrol etmek için, VNC istemcisi kullanan başka bir makinedeki, kullanıcıyla paylaşmanızı sağlayan bir sunucu uygulamasıdır.

Програма для спільного використання стільниці Krfb — це серверна програма, яка надає вам змогу розділити ваш поточний сеанс роботи з користувачем, який працює на іншому комп’ютері, так, щоб цей користувач зміг скористатися клієнтом VNC для перегляду або навіть керування вашою стільницею.

xxKrfb Desktop Sharing is a server application that allows you to share your current session with a user on another machine, who can use a VNC client to view or even control the desktop.xx

Krfb 桌面共享是一个可以让您与另一个在其他机器上的用户共享当前会话的服务器程序,他可以使用 VNC 客户端来查看甚至控制桌面。

+

Krfb 桌面分享是款伺服器應用程式,它可以將您目前的桌面階段分享給一位於其他主機上的使用者,以讓他能使用 VNC 客戶端檢視、甚至控制您的桌面。

- https://www.kde.org - https://bugs.kde.org + https://userbase.kde.org/Krfb + https://bugs.kde.org/enter_bug.cgi?format=guided&product=krfb https://www.kde.org/community/donations + https://docs.kde.org/?application=krfb - - https://cdn.kde.org/screenshots/krfb/krfb.png - + Sharing desktop with Krfb + Compartint l'escriptori amb el Krfb + Compartint l'escriptori amb el Krfb + Sdílím pracovní plochu pomocí Krfb + Deler skrivebord med Krfb + Freigabe der Arbeitsfläche mit Krfb + Sharing desktop with Krfb + Compartiendo el escritorio con Krfb + Työpöydän jakaminen Krfb:llä + Partage de bureau grâce à Krfb + Compartindo o escritorio con Krfb + Berbagi desktop dengan Krfb + Condivisone del desktop con Krfb + Bureaublad delen met Krfb + Udostępnienie pulpitu przy użyciu Krfb + Partilha do ecrã com o Krfb + Compartilhando a área de trabalho com o Krfb + Общий доступ к рабочему столу с использованием Krfb + Dela skrivbord med Krfb + Спільне використання стільниці за допомогою Krfb + xxSharing desktop with Krfbxx + 使用 Krfb 共享桌面 + 使用 Krfb 分享桌面 + https://cdn.kde.org/screenshots/krfb/krfb.png krfb KDE
diff --git a/krfb/org.kde.krfb.desktop b/krfb/org.kde.krfb.desktop index 1b2eec7..df9890f 100755 --- a/krfb/org.kde.krfb.desktop +++ b/krfb/org.kde.krfb.desktop @@ -1,222 +1,219 @@ # KDE Config File [Desktop Entry] Type=Application Exec=krfb -qwindowtitle %c %i Icon=krfb X-DBUS-StartupType=Unique X-DocPath=krfb/index.html Terminal=false Name=Krfb Name[ar]=Krfb -Name[ast]=Krfb Name[bg]=Krfb Name[bn]=কে-আর-এফ-বি Name[br]=Krfb Name[bs]=Krfb Name[ca]=Krfb Name[ca@valencia]=Krfb Name[cs]=Krfb Name[da]=Krfb Name[de]=Krfb Name[el]=Krfb Name[en_GB]=Krfb Name[eo]=Krfb Name[es]=Krfb Name[et]=Krfb Name[eu]=Krfb Name[fi]=Krfb Name[fr]=Krfb Name[ga]=Krfb Name[gl]=Krfb Name[he]=Krfb Name[hi]=केआरएफबी Name[hne]=केआरएफबी Name[hr]=Krfb Name[hu]=Krfb Name[ia]=Krfb Name[id]=Krfb Name[is]=Krfb Name[it]=Krfb Name[ja]=Krfb Name[kk]=Krfb Name[km]=Krfb Name[ko]=Krfb Name[lt]=Krfb Name[lv]=Krfb Name[ml]=കെആര്‍എഫ്ബി Name[mr]=के-आर-एफ-बी Name[nb]=Krfb Name[nds]=KRfb Name[ne]=Krfb Name[nl]=Krfb Name[nn]=Krfb Name[pa]=Krfb Name[pl]=Krfb 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 Name[vi]=Krfb Name[x-test]=xxKrfbxx Name[zh_CN]=Krfb Name[zh_HK]=Krfb Name[zh_TW]=桌面分享_Krfb GenericName=Desktop Sharing GenericName[ar]=مشاركة سطح المكتب -GenericName[ast]=Compartición d'escritoriu GenericName[bg]=Споделяне на работния плот GenericName[bn]=ডেস্কটপ ভাগাভাগি GenericName[br]=Rannañ ar vurev GenericName[bs]=Dijeljenje radne površine GenericName[ca]=Compartir l'escriptori GenericName[ca@valencia]=Compartir l'escriptori GenericName[cs]=Sdílení pracovní plochy GenericName[cy]=Rhannu Penbwrdd GenericName[da]=Skrivebordsdeling GenericName[de]=Arbeitsfläche freigeben GenericName[el]=Κοινή χρήση επιφάνειας εργασίας GenericName[en_GB]=Desktop Sharing GenericName[eo]=Tabula komunigado GenericName[es]=Escritorio compartido GenericName[et]=Töölaua jagamine GenericName[eu]=Mahaigaina partekatzea GenericName[fa]=اشتراک رومیزی GenericName[fi]=Työpöydän jakaminen GenericName[fr]=Partage de bureaux GenericName[ga]=Roinnt Deisce GenericName[gl]=Compartimento de escritorio GenericName[he]=שיתוף שולחנות עבודה GenericName[hi]=डेस्कटॉप साझेदारी GenericName[hne]=डेस्कटाप साझेदारी GenericName[hr]=Dijeljenje radne površine GenericName[hu]=Munkaasztal-megosztás GenericName[ia]=Compartir de scriptorio GenericName[id]=Desktop Sharing GenericName[is]=Skjáborðsmiðlun GenericName[it]=Condivisione del desktop GenericName[ja]=デスクトップ共有 GenericName[kk]=Үстелді ортақтастыру GenericName[km]=ការ​ចែក​រំលែក​ផ្ទៃ​តុ GenericName[ko]=데스크톱 공유 GenericName[lt]=Dalinimasis darbalaukiu GenericName[lv]=Darbvirsmas koplietošana GenericName[ml]=പണിയിടം പങ്കുവെക്കല്‍ GenericName[mr]=डेस्कटॉप शेअरींग GenericName[nb]=Delte skrivebord GenericName[nds]=Schriefdisch-Freegaav GenericName[ne]=डेस्कटप साझेदारी GenericName[nl]=Bureaublad delen GenericName[nn]=Skrivebordsdeling GenericName[pa]=ਡੈਸਕਟਾਪ ਸ਼ੇਅਰਿੰਗ GenericName[pl]=Współdzielenie pulpitu GenericName[pt]=Partilha do 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]=Souporaba namizja GenericName[sr]=Дељење површи 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]=Иш столи билан бўлишиш GenericName[vi]=Chia sẻ màn hình nền GenericName[x-test]=xxDesktop Sharingxx GenericName[zh_CN]=桌面共享 GenericName[zh_HK]=桌面分享 GenericName[zh_TW]=桌面分享 Comment=Desktop Sharing Comment[af]=Werkskerm Deeling Comment[ar]=مشاركة سطح المكتب -Comment[ast]=Compartición d'escritoriu Comment[bg]=Споделяне на работния плот Comment[bn]=ডেস্কটপ ভাগাভাগি Comment[br]=Rannañ ar vurev Comment[bs]=Dijeljenje radne površine Comment[ca]=Compartir l'escriptori Comment[ca@valencia]=Compartir l'escriptori Comment[cs]=Sdílení pracovní plochy Comment[cy]=Rhannu Penbwrdd Comment[da]=Skrivebordsdeling Comment[de]=Arbeitsflächen-Freigabe Comment[el]=Κοινή χρήση επιφάνειας εργασίας Comment[en_GB]=Desktop Sharing Comment[eo]=Tabula komunigado Comment[es]=Escritorio compartido Comment[et]=Töölaua jagamine Comment[eu]=Mahaigaina partekatzea Comment[fi]=Työpöydän jakaminen Comment[fr]=Partage de bureaux Comment[ga]=Roinnt Deisce Comment[gl]=Compartición do escritorio Comment[he]=שיתוף שולחנות עבודה Comment[hi]=डेस्कटॉप साझेदारी Comment[hne]=डेस्कटाप साझेदारी Comment[hr]=Dijeljenje radne površine Comment[hu]=Munkaasztal-megosztás Comment[ia]=Compartir de scriptorio Comment[id]=Desktop Sharing Comment[is]=Skjáborðamiðlun Comment[it]=Condivisione del desktop Comment[ja]=デスクトップ共有 Comment[kk]=Үстелді ортақтастыру Comment[km]=ការ​ចែក​រំលែក​ផ្ទែ​តុ Comment[ko]=데스크톱 공유 Comment[lt]=Dalinimasis darbalaukiu Comment[lv]=Darbvirsmas koplietošana Comment[mk]=Делење на работната површина Comment[ml]=പണിയിടം പങ്കുവെക്കല്‍ Comment[mr]=डेस्कटॉप शेअरींग Comment[ms]=Perkongsian Ruang Kerja Comment[nb]=Delte skrivebord Comment[nds]=Schriefdisch-Freegaav Comment[nl]=Bureaublad delen Comment[nn]=Skrivebordsdeling Comment[pa]=ਡੈਸਕਟਾਪ ਸ਼ੇਅਰਿੰਗ Comment[pl]=Współdzielenie pulpitu 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]=Souporaba namizja Comment[sr]=Дељење површи Comment[sr@ijekavian]=Дијељење површи Comment[sr@ijekavianlatin]=Dijeljenje površi 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 Comment[zh_CN]=桌面共享 Comment[zh_HK]=桌面分享 Comment[zh_TW]=桌面分享 Categories=Qt;KDE;System;Network;RemoteAccess; X-DBUS-ServiceName=org.kde.krfb diff --git a/krfb/rfbclient.cpp b/krfb/rfbclient.cpp index 8a44913..d2156a4 100644 --- a/krfb/rfbclient.cpp +++ b/krfb/rfbclient.cpp @@ -1,232 +1,230 @@ /* Copyright (C) 2009-2010 Collabora Ltd @author George Goldberg @author George Kiagiadakis Copyright (C) 2007 Alessandro Praduroux 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 . */ #include "rfbclient.h" #include "connectiondialog.h" #include "krfbconfig.h" #include "sockethelpers.h" #include "events.h" -#include +#include #include #include #include //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) + ":" + + d->remoteAddressString = peerAddress(d->client->sock) + QLatin1Char(':') + QString::number(peerPort(d->client->sock)); d->notifier = new QSocketNotifier(client->sock, QSocketNotifier::Read, this); d->notifier->setEnabled(false); connect(d->notifier, &QSocketNotifier::activated, this, &RfbClient::onSocketActivated); } RfbClient::~RfbClient() { //qDebug(); 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); } rfbClientPtr RfbClient::getRfbClientPtr() { return 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); } } 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) { //qDebug() << "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) { //qDebug() << "disconnected during update"; d->notifier->setEnabled(false); rfbClientConnectionGone(d->client); } } //************* PendingRfbClient::PendingRfbClient(rfbClientPtr client, QObject *parent) : QObject(parent), m_rfbClient(client) { m_rfbClient->clientData = this; } PendingRfbClient::~PendingRfbClient() {} void PendingRfbClient::accept(RfbClient *newClient) { //qDebug() << "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() { //qDebug() << "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); + Q_EMIT finished(nullptr); deleteLater(); } bool PendingRfbClient::checkPassword(const QByteArray & encryptedPassword) { Q_UNUSED(encryptedPassword); - return m_rfbClient->screen->authPasswdData == (void*)0; + return m_rfbClient->screen->authPasswdData == (void*)nullptr; } bool PendingRfbClient::vncAuthCheckPassword(const QByteArray& password, const QByteArray& encryptedPassword) const { if (password.isEmpty() && encryptedPassword.isEmpty()) { return true; } char passwd[MAXPWLEN]; unsigned char challenge[CHALLENGESIZE]; memcpy(challenge, m_rfbClient->authChallenge, CHALLENGESIZE); bzero(passwd, MAXPWLEN); if (!password.isEmpty()) { - strncpy(passwd, password, + strncpy(passwd, password.constData(), (MAXPWLEN <= password.size()) ? MAXPWLEN : password.size()); } rfbEncryptBytes(challenge, passwd); - return memcmp(challenge, encryptedPassword, encryptedPassword.size()) == 0; + return memcmp(challenge, encryptedPassword.constData(), encryptedPassword.size()) == 0; } - -#include "rfbclient.moc" diff --git a/krfb/rfbclient.h b/krfb/rfbclient.h index 9c43f01..4b3b02d 100644 --- a/krfb/rfbclient.h +++ b/krfb/rfbclient.h @@ -1,109 +1,109 @@ /* Copyright (C) 2009-2010 Collabora Ltd @author George Goldberg @author George Kiagiadakis Copyright (C) 2007 Alessandro Praduroux 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 . */ #ifndef RFBCLIENT_H #define RFBCLIENT_H #include "rfb.h" -#include +#include 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(); + explicit RfbClient(rfbClientPtr client, QObject *parent = nullptr); + ~RfbClient() override; /** 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 rfbClientPtr getRfbClientPtr(); virtual void handleKeyboardEvent(bool down, rfbKeySym keySym); virtual void handleMouseEvent(int buttonMask, int x, int y); 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(); + explicit PendingRfbClient(rfbClientPtr client, QObject *parent = nullptr); + ~PendingRfbClient() override; Q_SIGNALS: void finished(RfbClient *client); protected Q_SLOTS: virtual void processNewClient() = 0; void accept(RfbClient *newClient); void reject(); protected: friend class RfbServer; //Following two methods are handled by RfbServer /** 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 + * user matches the \a password that you have specified locally 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; rfbClientPtr m_rfbClient; }; #endif // RFBCLIENT_H diff --git a/krfb/rfbserver.cpp b/krfb/rfbserver.cpp index ee4d8e2..252aa60 100644 --- a/krfb/rfbserver.cpp +++ b/krfb/rfbserver.cpp @@ -1,296 +1,301 @@ /* Copyright (C) 2009-2010 Collabora Ltd @author George Goldberg @author George Kiagiadakis Copyright (C) 2007 Alessandro Praduroux 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 . */ #include "rfbserver.h" #include "rfbservermanager.h" -#include +#include #include #include +#include #include #include struct RfbServer::Private { QByteArray listeningAddress; int listeningPort; bool passwordRequired; rfbScreenInfoPtr screen; - QSocketNotifier *notifier; + QPointer ipv4notifier; + QPointer ipv6notifier; }; 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; + d->screen = nullptr; RfbServerManager::instance()->registerServer(this); } RfbServer::~RfbServer() { 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) { qDebug() << "Unable to get rbfserver 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; + d->screen->authPasswdData = (void *)nullptr; } qDebug() << "Starting server. Listen port:" << listeningPort() << "Listen Address:" << listeningAddress() << "Password enabled:" << passwordRequired(); rfbInitServer(d->screen); if (!rfbIsActive(d->screen)) { qDebug() << "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, &QSocketNotifier::activated, this, &RfbServer::onListenSocketActivated); + d->ipv4notifier = new QSocketNotifier(d->screen->listenSock, QSocketNotifier::Read, this); + connect(d->ipv4notifier, &QSocketNotifier::activated, this, &RfbServer::onListenSocketActivated); + if (d->screen->listen6Sock > 0) { + // we're also listening on additional IPv6 socket, get events from there + d->ipv6notifier = new QSocketNotifier(d->screen->listen6Sock, QSocketNotifier::Read, this); + connect(d->ipv6notifier, &QSocketNotifier::activated, this, &RfbServer::onListenSocketActivated); + } + if (QX11Info::isPlatformX11()) { connect(QApplication::clipboard(), &QClipboard::dataChanged, this, &RfbServer::krfbSendServerCutText); } return true; } void RfbServer::stop() { if (d->screen) { rfbShutdownServer(d->screen, true); - if (d->notifier) { - d->notifier->setEnabled(false); - d->notifier->deleteLater(); - d->notifier = NULL; + for (auto notifier : {d->ipv4notifier, d->ipv6notifier}) { + if (notifier) { + notifier->setEnabled(false); + notifier->deleteLater(); + } } } } void RfbServer::updateFrameBuffer(char *fb, int width, int height, int depth) { int bpp = depth >> 3; if (bpp != 1 && bpp != 2 && bpp != 4) { bpp = 4; } rfbNewFramebuffer(d->screen, fb, width, height, 8, 3, bpp); } void RfbServer::updateScreen(const QList & modifiedTiles) { if (d->screen) { QList::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) { + while ((cl = rfbClientIteratorNext(iterator)) != nullptr) { 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()); + krfb_rfbSetCursorPosition(d->screen, nullptr, position.x(), position.y()); } } void RfbServer::krfbSendServerCutText() { if(d->screen) { QString text = QApplication::clipboard()->text(); rfbSendServerCutText(d->screen, text.toLocal8Bit().data(),text.length()); } } void RfbServer::onListenSocketActivated() { rfbProcessNewConnection(d->screen); } void RfbServer::pendingClientFinished(RfbClient *client) { //qDebug(); if (client) { RfbServerManager::instance()->addClient(client); client->getRfbClientPtr()->clientGoneHook = clientGoneHook; } } //static rfbNewClientAction RfbServer::newClientHook(rfbClientPtr cl) { //qDebug() << "New client"; RfbServer *server = static_cast(cl->screen->screenData); PendingRfbClient *pendingClient = server->newClient(cl); connect(pendingClient, &PendingRfbClient::finished, server, &RfbServer::pendingClientFinished); return RFB_CLIENT_ON_HOLD; } //static void RfbServer::clientGoneHook(rfbClientPtr cl) { //qDebug() << "client gone"; RfbClient *client = static_cast(cl->clientData); RfbServerManager::instance()->removeClient(client); client->deleteLater(); } //static rfbBool RfbServer::passwordCheck(rfbClientPtr cl, const char *encryptedPassword, int len) { PendingRfbClient *client = static_cast(cl->clientData); Q_ASSERT(client); return client->checkPassword(QByteArray::fromRawData(encryptedPassword, len)); } //static void RfbServer::keyboardHook(rfbBool down, rfbKeySym keySym, rfbClientPtr cl) { RfbClient *client = static_cast(cl->clientData); client->handleKeyboardEvent(down ? true : false, keySym); } //static void RfbServer::pointerHook(int bm, int x, int y, rfbClientPtr cl) { RfbClient *client = static_cast(cl->clientData); client->handleMouseEvent(bm, x, y); } //static void RfbServer::clipboardHook(char *str, int len, rfbClientPtr /*cl*/) { QApplication::clipboard()->setText(QString::fromLocal8Bit(str,len)); } - -#include "rfbserver.moc" diff --git a/krfb/rfbserver.h b/krfb/rfbserver.h index 731acc3..22de299 100644 --- a/krfb/rfbserver.h +++ b/krfb/rfbserver.h @@ -1,73 +1,73 @@ /* Copyright (C) 2009-2010 Collabora Ltd @author George Goldberg @author George Kiagiadakis Copyright (C) 2007 Alessandro Praduroux 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 . */ #ifndef RFBSERVER_H #define RFBSERVER_H #include "rfb.h" #include "rfbclient.h" -#include +#include class RfbServer : public QObject { Q_OBJECT public: - RfbServer(QObject *parent = 0); - virtual ~RfbServer(); + explicit RfbServer(QObject *parent = nullptr); + ~RfbServer() override; 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: virtual bool start(); virtual void stop(); void updateFrameBuffer(char *fb, int width, int height, int depth); void updateScreen(const QList & modifiedTiles); void updateCursorPosition(const QPoint & position); private Q_SLOTS: void krfbSendServerCutText(); 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 diff --git a/krfb/rfbservermanager.cpp b/krfb/rfbservermanager.cpp index 7f68801..e7262c4 100644 --- a/krfb/rfbservermanager.cpp +++ b/krfb/rfbservermanager.cpp @@ -1,247 +1,243 @@ /* Copyright (C) 2009-2010 Collabora Ltd @author George Goldberg @author George Kiagiadakis Copyright (C) 2007 Alessandro Praduroux Copyright (C) 2001-2003 by Tim Jansen 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 . */ #include "rfbservermanager.h" #include "rfbserver.h" #include "framebuffer.h" #include "framebuffermanager.h" #include "sockethelpers.h" #include "krfbconfig.h" -#include +#include #include #include #include -#include +#include #include #include #include #include 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; }; Q_GLOBAL_STATIC(RfbServerManagerStatic, s_instance) RfbServerManager* RfbServerManager::instance() { return &s_instance->server; } struct RfbServerManager::Private { QSharedPointer fb; rfbCursorPtr myCursor; QByteArray desktopName; QTimer rfbUpdateTimer; QSet servers; QSet clients; }; RfbServerManager::RfbServerManager() : QObject(), d(new Private) { init(); } RfbServerManager::~RfbServerManager() { delete d; } QSharedPointer RfbServerManager::framebuffer() const { return d->fb; } void RfbServerManager::init() { //qDebug(); 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 + d->desktopName = QStringLiteral("%1@%2 (shared desktop)") //FIXME check if we can use utf8 .arg(KUser().loginName(),QHostInfo::localHostName()).toLatin1(); connect(d->fb.data(), &FrameBuffer::frameBufferChanged, this, &RfbServerManager::updateFrameBuffer); connect(&d->rfbUpdateTimer, &QTimer::timeout, this, &RfbServerManager::updateScreens); connect(qApp, &QApplication::aboutToQuit, this, &RfbServerManager::cleanup); } void RfbServerManager::updateFrameBuffer() { Q_FOREACH(RfbServer *server, d->servers) { server->updateFrameBuffer(d->fb->data(), d->fb->width(), d->fb->height(), d->fb->depth()); } } void RfbServerManager::updateScreens() { QList rects = d->fb->modifiedTiles(); QPoint currentCursorPos = QCursor::pos(); - Q_FOREACH(RfbServer *server, d->servers) { + for (RfbServer* server : qAsConst(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 clients = d->clients; - Q_FOREACH(RfbClient *client, clients) { + const QSet clients = d->clients; + for (RfbClient* client : clients) { client->update(); } } void RfbServerManager::cleanup() { //qDebug(); //copy because d->servers is going to be modified while we delete the servers - QSet servers = d->servers; - Q_FOREACH(RfbServer *server, servers) { - delete server; - } + const QSet servers = d->servers; + qDeleteAll(servers); 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; + rfbScreenInfoPtr screen = nullptr; 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; } //qDebug() << "bpp: " << bpp; rfbLogEnable(0); - screen = rfbGetScreen(0, 0, w, h, 8, 3, bpp); + screen = rfbGetScreen(nullptr, nullptr, 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) { //qDebug() << "Starting framebuffer monitor"; d->fb->startMonitor(); d->rfbUpdateTimer.start(50); } d->clients.insert(cc); - KNotification::event("UserAcceptsConnection", + KNotification::event(QStringLiteral("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) { //qDebug() << "Stopping framebuffer monitor"; d->fb->stopMonitor(); d->rfbUpdateTimer.stop(); } - KNotification::event("ConnectionClosed", i18n("The remote user %1 disconnected.", cc->name())); + KNotification::event(QStringLiteral("ConnectionClosed"), i18n("The remote user %1 disconnected.", cc->name())); Q_EMIT clientDisconnected(cc); } - -#include "rfbservermanager.moc" diff --git a/krfb/rfbservermanager.h b/krfb/rfbservermanager.h index e9359ae..4a1a58c 100644 --- a/krfb/rfbservermanager.h +++ b/krfb/rfbservermanager.h @@ -1,68 +1,68 @@ /* Copyright (C) 2009-2010 Collabora Ltd @author George Goldberg @author George Kiagiadakis Copyright (C) 2007 Alessandro Praduroux 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 . */ #ifndef RFBSERVERMANAGER_H #define RFBSERVERMANAGER_H #include "rfb.h" #include "framebuffer.h" -#include +#include class RfbClient; struct RfbServerManagerStatic; class RfbServer; class RfbServerManager : public QObject { Q_OBJECT public: static RfbServerManager *instance(); QSharedPointer framebuffer() const; Q_SIGNALS: void clientConnected(RfbClient *cc); void clientDisconnected(RfbClient *cc); private Q_SLOTS: void init(); void updateFrameBuffer(); 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(); + ~RfbServerManager() override; Q_DISABLE_COPY(RfbServerManager) friend class RfbServer; friend struct RfbServerManagerStatic; struct Private; Private *const d; }; #endif // RFBSERVERMANAGER_H diff --git a/krfb/sockethelpers.cpp b/krfb/sockethelpers.cpp index 97fcc87..c10387b 100644 --- a/krfb/sockethelpers.cpp +++ b/krfb/sockethelpers.cpp @@ -1,106 +1,106 @@ /* This file is part of the KDE project Copyright (C) 2009 Collabora Ltd @author George Goldberg Copyright (C) 2007 Alessandro Praduroux Copyright (C) 2001-2003 by Tim Jansen 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 #include #include 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)); + return QString::fromLatin1(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::fromLatin1(inetbuf); } - return QString("not a network address"); + return QStringLiteral("not a network address"); } - return QString("unable to determine..."); + return QStringLiteral("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)); + return QString::fromLatin1(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::fromLatin1(inetbuf); } - return QString("not a network address"); + return QStringLiteral("not a network address"); } - return QString("unable to determine..."); + return QStringLiteral("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; } diff --git a/krfb/sockethelpers.h b/krfb/sockethelpers.h index dae2dcc..74f64cf 100644 --- a/krfb/sockethelpers.h +++ b/krfb/sockethelpers.h @@ -1,30 +1,34 @@ /* This file is part of the KDE project Copyright (C) 2009 Collabora Ltd @author George Goldberg Copyright (C) 2007 Alessandro Praduroux Copyright (C) 2001-2003 by Tim Jansen 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 +#ifndef SOCKETHELPERS_H +#define SOCKETHELPERS_H + +#include QString peerAddress(int sock); unsigned short peerPort(int sock); QString localAddress(int sock); unsigned short localPort(int sock); +#endif diff --git a/krfb/trayicon.cpp b/krfb/trayicon.cpp index 295ecb3..3eeb456 100644 --- a/krfb/trayicon.cpp +++ b/krfb/trayicon.cpp @@ -1,147 +1,145 @@ /* Copyright (C) 2010 Collabora Ltd @author George Kiagiadakis Copyright (C) 2001-2002 Tim Jansen 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 . */ #include "trayicon.h" #include "mainwindow.h" #include "rfbservermanager.h" #include "rfbclient.h" #include #include #include #include #include #include #include #include #include #include class ClientActions { public: ClientActions(RfbClient *client, QMenu *menu, QAction *before); virtual ~ClientActions(); private: QMenu *m_menu; QAction *m_title; QAction *m_disconnectAction; QAction *m_enableControlAction; QAction *m_separator; }; ClientActions::ClientActions(RfbClient* client, QMenu* menu, QAction* before) : m_menu(menu) { m_title = m_menu->insertSection(before, client->name()); m_disconnectAction = new QAction(i18n("Disconnect"), m_menu); m_menu->insertAction(before, m_disconnectAction); QObject::connect(m_disconnectAction, &QAction::triggered, client, &RfbClient::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, &KToggleAction::triggered, client, &RfbClient::setControlEnabled); QObject::connect(client, &RfbClient::controlEnabledChanged, m_enableControlAction, &KToggleAction::setChecked); } else { - m_enableControlAction = NULL; + m_enableControlAction = nullptr; } m_separator = m_menu->insertSeparator(before); } ClientActions::~ClientActions() { 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(QIcon::fromTheme("krfb").pixmap(22, 22, QIcon::Disabled)); + setIconByPixmap(QIcon::fromTheme(QStringLiteral("krfb")).pixmap(22, 22, QIcon::Disabled)); setToolTipTitle(i18n("Desktop Sharing - disconnected")); setCategory(KStatusNotifierItem::ApplicationStatus); connect(RfbServerManager::instance(), &RfbServerManager::clientConnected, this, &TrayIcon::onClientConnected); connect(RfbServerManager::instance(), &RfbServerManager::clientDisconnected, this, &TrayIcon::onClientDisconnected); m_aboutAction = KStandardAction::aboutApp(this, SLOT(showAbout()), this); contextMenu()->addAction(m_aboutAction); } void TrayIcon::onClientConnected(RfbClient* client) { if (m_clientActions.isEmpty()) { //first client connected - setIconByName("krfb"); + setIconByName(QStringLiteral("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) { ClientActions *actions = m_clientActions.take(client); delete actions; if (m_clientActions.isEmpty()) { - setIconByPixmap(QIcon::fromTheme("krfb").pixmap(22, 22, QIcon::Disabled)); + setIconByPixmap(QIcon::fromTheme(QStringLiteral("krfb")).pixmap(22, 22, QIcon::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() { KHelpMenu menu; menu.aboutApplication(); } - -#include "trayicon.moc" diff --git a/krfb/trayicon.h b/krfb/trayicon.h index 4744ff1..6517e4a 100644 --- a/krfb/trayicon.h +++ b/krfb/trayicon.h @@ -1,47 +1,47 @@ /*************************************************************************** trayicon.h - description ------------------- begin : Tue Dec 11 2001 copyright : (C) 2001-2002 by Tim Jansen email : tim@tjansen.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TRAYICON_H #define TRAYICON_H #include class RfbClient; class ClientActions; /** * Implements the trayicon. * @author Tim Jansen */ class TrayIcon : public KStatusNotifierItem { Q_OBJECT public: - TrayIcon(QWidget *mainWindow); + explicit TrayIcon(QWidget *mainWindow); public Q_SLOTS: void onClientConnected(RfbClient *client); void onClientDisconnected(RfbClient *client); void showAbout(); private: QAction *m_aboutAction; QHash m_clientActions; }; #endif diff --git a/krfb/ui/configsecurity.ui b/krfb/ui/configsecurity.ui index 93d59f3..531591b 100644 --- a/krfb/ui/configsecurity.ui +++ b/krfb/ui/configsecurity.ui @@ -1,41 +1,48 @@ Security 0 0 507 201 Allow remote connections to control your desktop true + + + + Do not store passwords using KDE wallet + + + Qt::Vertical 20 40 diff --git a/krfb/ui/configtcp.ui b/krfb/ui/configtcp.ui index a47538f..31aef1e 100644 --- a/krfb/ui/configtcp.ui +++ b/krfb/ui/configtcp.ui @@ -1,94 +1,107 @@ TCP 0 0 400 169 - - 9 - - - 6 - Announce the service on the local network true Use default port true - - + + 0 - - 6 + + 0 + + + 0 + + + 0 - + Listening port: kcfg_port - + false 65535 + + + + Qt::Vertical + + + + 20 + 40 + + + + kcfg_useDefaultPort kcfg_port kcfg_useDefaultPort toggled(bool) kcfg_port setDisabled(bool) 120 53 277 122